📄 700-debian_cp-pass-by-reference.patch
字号:
This patch needs to be submitted for the FSF. Also, there may be testcasesalready in the GDB testsuite (currently disabled) that it would probably fix.Index: gdb-6.3/gdb/infcall.c===================================================================--- gdb-6.3.orig/gdb/infcall.c 2004-10-08 04:15:56.000000000 -0400+++ gdb-6.3/gdb/infcall.c 2004-11-10 12:30:07.000000000 -0500@@ -36,6 +36,7 @@ #include "gdb_string.h" #include "infcall.h" #include "dummy-frame.h"+#include "cp-abi.h" /* NOTE: cagney/2003-04-16: What's the future of this code? @@ -297,8 +298,8 @@ call_function_by_hand (struct value *fun { CORE_ADDR sp; CORE_ADDR dummy_addr;- struct type *value_type;- unsigned char struct_return;+ struct type *value_type, *target_value_type;+ unsigned char struct_return = 0, cp_struct_return = 0; CORE_ADDR struct_addr = 0; struct regcache *retbuf; struct cleanup *retbuf_cleanup;@@ -312,6 +313,7 @@ call_function_by_hand (struct value *fun struct regcache *caller_regcache; struct cleanup *caller_regcache_cleanup; struct frame_id dummy_id;+ struct cleanup *args_cleanup; if (!target_has_execution) noprocess ();@@ -410,10 +412,31 @@ call_function_by_hand (struct value *fun using_gcc = (b == NULL ? 2 : BLOCK_GCC_COMPILED (b)); } - /* Are we returning a value using a structure return or a normal- value return? */+ /* Are we returning a value using a structure return (passing a+ hidden argument pointing to storage) or a normal value return?+ There are two cases: C++ ABI mandated structure return and+ target ABI structure return. The variable STRUCT_RETURN only+ describes the latter. The C++ version is handled by passing+ the return location as the first parameter to the function,+ even preceding "this". This is different from the target+ ABI version, which is target-specific; for instance, on ia64+ the first argument is passed in out0 but the hidden structure+ return pointer would normally be passed in r8. */ - struct_return = using_struct_return (value_type, using_gcc);+ if (current_language->la_language == language_cplus+ && cp_pass_by_reference (value_type))+ {+ cp_struct_return = 1;++ /* Tell the target specific argument pushing routine not to+ expect a value. */+ target_value_type = builtin_type_void;+ }+ else+ {+ struct_return = using_struct_return (value_type, using_gcc);+ target_value_type = value_type;+ } /* Determine the location of the breakpoint (and possibly other stuff) that the called function will return to. The SPARC, for a@@ -432,7 +455,7 @@ call_function_by_hand (struct value *fun if (INNER_THAN (1, 2)) { sp = push_dummy_code (current_gdbarch, sp, funaddr,- using_gcc, args, nargs, value_type,+ using_gcc, args, nargs, target_value_type, &real_pc, &bp_addr); dummy_addr = sp; }@@ -440,7 +463,7 @@ call_function_by_hand (struct value *fun { dummy_addr = sp; sp = push_dummy_code (current_gdbarch, sp, funaddr,- using_gcc, args, nargs, value_type,+ using_gcc, args, nargs, target_value_type, &real_pc, &bp_addr); } break;@@ -507,9 +530,15 @@ call_function_by_hand (struct value *fun param_type = TYPE_FIELD_TYPE (ftype, i); else param_type = NULL;- + args[i] = value_arg_coerce (args[i], param_type, prototyped); + /* FIXME: Is current_language the right language? */+ if (current_language->la_language == language_cplus+ && param_type != NULL+ && cp_pass_by_reference (param_type))+ args[i] = value_addr (args[i]);+ /* elz: this code is to handle the case in which the function to be called has a pointer to function as parameter and the corresponding actual argument is the address of a function@@ -607,7 +636,7 @@ You must use a pointer to function type stack, if necessary. Make certain that the value is correctly aligned. */ - if (struct_return)+ if (struct_return || cp_struct_return) { int len = TYPE_LENGTH (value_type); if (INNER_THAN (1, 2))@@ -632,6 +661,22 @@ You must use a pointer to function type } } + if (cp_struct_return)+ {+ struct value **new_args;++ /* Add the new argument to the front of the argument list. */+ new_args = xmalloc (sizeof (struct value *) * (nargs + 1));+ new_args[0] = value_from_pointer (lookup_pointer_type (value_type),+ struct_addr);+ memcpy (&new_args[1], &args[0], sizeof (struct value *) * nargs);+ args = new_args;+ nargs++;+ args_cleanup = make_cleanup (xfree, args);+ }+ else+ args_cleanup = make_cleanup (null_cleanup, NULL);+ /* Create the dummy stack frame. Pass in the call dummy address as, presumably, the ABI code knows where, in the call dummy, the return address should be pointed. */@@ -649,6 +694,8 @@ You must use a pointer to function type else error ("This target does not support function calls"); + do_cleanups (args_cleanup);+ /* Set up a frame ID for the dummy frame so we can pass it to set_momentary_breakpoint. We need to give the breakpoint a frame ID so that the breakpoint code can correctly re-identify the@@ -839,11 +886,7 @@ the function call).", name); /* Figure out the value returned by the function, return that. */ { struct value *retval;- if (TYPE_CODE (value_type) == TYPE_CODE_VOID)- /* If the function returns void, don't bother fetching the- return value. */- retval = allocate_value (value_type);- else if (struct_return)+ if (struct_return || cp_struct_return) /* NOTE: cagney/2003-09-27: This assumes that PUSH_DUMMY_CALL has correctly stored STRUCT_ADDR in the target. In the past that hasn't been the case, the old MIPS PUSH_ARGUMENTS@@ -853,6 +896,10 @@ the function call).", name); "struct return convention", check that PUSH_DUMMY_CALL isn't playing tricks. */ retval = value_at (value_type, struct_addr, NULL);+ else if (TYPE_CODE (value_type) == TYPE_CODE_VOID)+ /* If the function returns void, don't bother fetching the+ return value. */+ retval = allocate_value (value_type); else { /* This code only handles "register convention". */Index: gdb-6.3/gdb/cp-abi.h===================================================================--- gdb-6.3.orig/gdb/cp-abi.h 2003-04-12 13:41:25.000000000 -0400+++ gdb-6.3/gdb/cp-abi.h 2004-11-10 12:30:07.000000000 -0500@@ -1,7 +1,7 @@ /* Abstraction of various C++ ABI's we support, and the info we need to get from them. Contributed by Daniel Berlin <dberlin@redhat.com>- Copyright 2001 Free Software Foundation, Inc.+ Copyright 2001, 2002, 2003, 2004 Free Software Foundation, Inc. This file is part of GDB. @@ -145,6 +145,10 @@ extern struct type *value_rtti_type (str extern int baseclass_offset (struct type *type, int index, char *valaddr, CORE_ADDR address); +/* Return non-zero if an argument of type TYPE should be passed by reference+ instead of value. */+extern int cp_pass_by_reference (struct type *type);+ struct cp_abi_ops { const char *shortname;@@ -162,6 +166,7 @@ struct cp_abi_ops int *using_enc); int (*baseclass_offset) (struct type *type, int index, char *valaddr, CORE_ADDR address);+ int (*pass_by_reference) (struct type *type); }; Index: gdb-6.3/gdb/cp-abi.c===================================================================--- gdb-6.3.orig/gdb/cp-abi.c 2003-11-26 17:04:00.000000000 -0500+++ gdb-6.3/gdb/cp-abi.c 2004-11-10 12:30:07.000000000 -0500@@ -1,5 +1,5 @@ /* Generic code for supporting multiple C++ ABI's- Copyright 2001, 2002, 2003 Free Software Foundation, Inc.+ Copyright 2001, 2002, 2003, 2004 Free Software Foundation, Inc. This file is part of GDB. @@ -94,6 +94,14 @@ value_rtti_type (struct value *v, int *f return (*current_cp_abi.rtti_type) (v, full, top, using_enc); } +int+cp_pass_by_reference (struct type *type)+{+ if ((current_cp_abi.pass_by_reference) == NULL)+ return 0;+ return (*current_cp_abi.pass_by_reference) (type);+}+ /* Set the current C++ ABI to SHORT_NAME. */ static intIndex: gdb-6.3/gdb/gnu-v3-abi.c===================================================================--- gdb-6.3.orig/gdb/gnu-v3-abi.c 2004-03-15 15:38:08.000000000 -0500+++ gdb-6.3/gdb/gnu-v3-abi.c 2004-11-10 12:30:07.000000000 -0500@@ -1,7 +1,7 @@ /* Abstraction of GNU v3 abi.
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -