diff options
author | Yao Qi <yao@codesourcery.com> | 2012-06-08 14:24:57 +0000 |
---|---|---|
committer | Yao Qi <yao@codesourcery.com> | 2012-06-08 14:24:57 +0000 |
commit | 18648a37491f7c0a459750048611bd2e83aa54bf (patch) | |
tree | 4a5d0b3c65985e5982b2cbff9c4cc0a27940014e /gdb/tic6x-tdep.c | |
parent | 16bdd41fc61515376a944d7e81b7adcb126bcb4e (diff) | |
download | gdb-18648a37491f7c0a459750048611bd2e83aa54bf.zip gdb-18648a37491f7c0a459750048611bd2e83aa54bf.tar.gz gdb-18648a37491f7c0a459750048611bd2e83aa54bf.tar.bz2 |
gdb/
* arch-utils.c (default_return_in_first_hidden_param_p): New.
* arch-utils.h: Declare.
* gdbarch.sh: Add return_in_first_hidden_param_p.
* gdbarch.c, gdbarch.h: Regenerated.
* infcall.c (call_function_by_hand): Call
gdbarch_return_in_first_hidden_param_p instead of
language_pass_by_reference.
* m68k-tdep.c (m68k_return_in_first_hidden_param_p): New.
(m68k_gdbarch_init): Install m68k_return_in_first_hidden_param_p.
* sh-tdep.c (sh_return_in_first_hidden_param_p): New.
(sh_gdbarch_init): Install sh_return_in_first_hidden_param_p.
* tic6x-tdep.c (tic6x_push_dummy_call): Remove local variable
`cplus_return_struct_by_reference'.
(tic6x_return_value): Handle language cplusplus.
(tic6x_return_in_first_hidden_param_p): New.
(tic6x_gdbarch_init): Install tic6x_return_in_first_hidden_param_p.
Diffstat (limited to 'gdb/tic6x-tdep.c')
-rw-r--r-- | gdb/tic6x-tdep.c | 65 |
1 files changed, 29 insertions, 36 deletions
diff --git a/gdb/tic6x-tdep.c b/gdb/tic6x-tdep.c index 8573222..1fefcf3 100644 --- a/gdb/tic6x-tdep.c +++ b/gdb/tic6x-tdep.c @@ -822,6 +822,19 @@ tic6x_return_value (struct gdbarch *gdbarch, struct value *function, struct type *type, struct regcache *regcache, gdb_byte *readbuf, const gdb_byte *writebuf) { + /* In C++, when function returns an object, even its size is small + enough, it stii has to be passed via reference, pointed by register + A3. */ + if (current_language->la_language == language_cplus) + { + if (type != NULL) + { + CHECK_TYPEDEF (type); + if (language_pass_by_reference (type)) + return RETURN_VALUE_STRUCT_CONVENTION; + } + } + if (TYPE_LENGTH (type) > 8) return RETURN_VALUE_STRUCT_CONVENTION; @@ -912,32 +925,7 @@ tic6x_push_dummy_call (struct gdbarch *gdbarch, struct value *function, /* The first arg passed on stack. Mostly the first 10 args are passed by registers. */ int first_arg_on_stack = 10; - /* If this inf-call is a cpp method call, and return value is passed by - reference, this flag is set to 1, otherwise set to 0. We need this flag - because computation of the return location in - infcall.c:call_function_by_hand is wrong for C6000 ELF ABI. In - call_function_by_hand, the language is considered first, and then - target ABI is considered. If language_pass_by_reference returns true, - the return location is passed as the first parameter to the function, - which is conflict with C6000 ELF ABI. If this flag is true, we should - adjust args and return locations accordingly to comply with C6000 ELF - ABI. */ - int cplus_return_struct_by_reference = 0; - - if (current_language->la_language == language_cplus) - { - struct type *values_type; - - find_function_addr (function, &values_type); - - if (values_type) - { - CHECK_TYPEDEF (values_type); - if (language_pass_by_reference (values_type)) - cplus_return_struct_by_reference = 1; - } - } /* Set the return address register to point to the entry point of the program, where a breakpoint lies in wait. */ regcache_cooked_write_unsigned (regcache, TIC6X_RA_REGNUM, bp_addr); @@ -947,12 +935,6 @@ tic6x_push_dummy_call (struct gdbarch *gdbarch, struct value *function, the address in A3. */ if (struct_return) regcache_cooked_write_unsigned (regcache, 3, struct_addr); - else if (cplus_return_struct_by_reference) - /* When cplus_return_struct_by_reference is 1, means local variable - lang_struct_return in call_function_by_hand is 1, so struct is - returned by reference, even STRUCT_RETURN is 0. Note that STRUCT_ADDR - is still valid in this case. */ - regcache_cooked_write_unsigned (regcache, 3, struct_addr); /* Determine the type of this function. */ func_type = check_typedef (func_type); @@ -967,10 +949,8 @@ tic6x_push_dummy_call (struct gdbarch *gdbarch, struct value *function, if (TYPE_VARARGS (func_type)) first_arg_on_stack = TYPE_NFIELDS (func_type) - 1; - /* Now make space on the stack for the args. If - cplus_return_struct_by_reference is 1, means GDB pass an extra parameter - in ARGS, which is useless here, skip it. */ - for (argnum = cplus_return_struct_by_reference; argnum < nargs; argnum++) + /* Now make space on the stack for the args. */ + for (argnum = 0; argnum < nargs; argnum++) { int len = align_up (TYPE_LENGTH (value_type (args[argnum])), 4); if (argnum >= 10 - argreg) @@ -986,7 +966,7 @@ tic6x_push_dummy_call (struct gdbarch *gdbarch, struct value *function, /* Now load as many as possible of the first arguments into registers, and push the rest onto the stack. Loop through args from first to last. */ - for (argnum = cplus_return_struct_by_reference; argnum < nargs; argnum++) + for (argnum = 0; argnum < nargs; argnum++) { const gdb_byte *val; struct value *arg = args[argnum]; @@ -1207,6 +1187,16 @@ tic6x_get_longjmp_target (struct frame_info *frame, CORE_ADDR *pc) return 1; } +/* This is the implementation of gdbarch method + return_in_first_hidden_param_p. */ + +static int +tic6x_return_in_first_hidden_param_p (struct gdbarch *gdbarch, + struct type *type) +{ + return 0; +} + static struct gdbarch * tic6x_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches) { @@ -1365,6 +1355,9 @@ tic6x_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches) set_gdbarch_in_function_epilogue_p (gdbarch, tic6x_in_function_epilogue_p); + set_gdbarch_return_in_first_hidden_param_p (gdbarch, + tic6x_return_in_first_hidden_param_p); + /* Hook in ABI-specific overrides, if they have been registered. */ gdbarch_init_osabi (info, gdbarch); |