From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 1037 invoked by alias); 18 Apr 2012 13:18:16 -0000 Received: (qmail 820 invoked by uid 22791); 18 Apr 2012 13:18:14 -0000 X-SWARE-Spam-Status: No, hits=-3.9 required=5.0 tests=AWL,BAYES_00,FROM_12LTRDOM,KHOP_RCVD_UNTRUST,KHOP_THREADED,RCVD_IN_HOSTKARMA_W,RCVD_IN_HOSTKARMA_WL,TW_EG X-Spam-Check-By: sourceware.org Received: from relay1.mentorg.com (HELO relay1.mentorg.com) (192.94.38.131) by sourceware.org (qpsmtpd/0.43rc1) with ESMTP; Wed, 18 Apr 2012 13:17:40 +0000 Received: from svr-orw-exc-10.mgc.mentorg.com ([147.34.98.58]) by relay1.mentorg.com with esmtp id 1SKUlQ-0007Ph-4F from Yao_Qi@mentor.com for gdb-patches@sourceware.org; Wed, 18 Apr 2012 06:17:40 -0700 Received: from SVR-ORW-FEM-03.mgc.mentorg.com ([147.34.97.39]) by SVR-ORW-EXC-10.mgc.mentorg.com with Microsoft SMTPSVC(6.0.3790.4675); Wed, 18 Apr 2012 06:16:58 -0700 Received: from localhost.localdomain (147.34.91.1) by svr-orw-fem-03.mgc.mentorg.com (147.34.97.39) with Microsoft SMTP Server id 14.1.289.1; Wed, 18 Apr 2012 06:17:38 -0700 From: Yao Qi To: CC: Subject: [PATCH 2/4] tic6x: Install return_with_first_hidden_param_p Date: Wed, 18 Apr 2012 13:18:00 -0000 Message-ID: <1334755073-26528-2-git-send-email-yao@codesourcery.com> In-Reply-To: <1334755073-26528-1-git-send-email-yao@codesourcery.com> References: <1334755073-26528-1-git-send-email-yao@codesourcery.com> MIME-Version: 1.0 Content-Type: text/plain X-IsSubscribed: yes Mailing-List: contact gdb-patches-help@sourceware.org; run by ezmlm Precedence: bulk List-Id: List-Subscribe: List-Archive: List-Post: List-Help: , Sender: gdb-patches-owner@sourceware.org X-SW-Source: 2012-04/txt/msg00563.txt.bz2 This patch can be logically separated to two parts, - 1) Remove local variable `cplus_return_struct_by_reference' in tic6x_push_dummy_call - 2) Implement hook return_with_first_hidden_param_p. As we can see in the comment to `cplus_return_struct_by_reference', it is used to address the same problem as what gdbarch hook `return_with_first_hidden_param_p' tries to address. Originally, I used a tic6x-specific approach (`cplus_return_struct_by_reference') to address this issue, because at that moment, I thought that problem is tic6x specific. Today, we realize that this kind of problem exists on targets more than tic6x, such as SH, m68k, etc. This patch is to remove code of using `cplus_return_struct_by_reference', and switch to use this new gdbarch hook. Regression tested for tic6x-uclinux. gdb: 2012-04-16 Yao Qi * tic6x-tdep.c (tic6x_push_dummy_call): Remove local variable `cplus_return_struct_by_reference'. (tic6x_return_value): Handle language cplusplus. (tic6x_return_with_first_hidden_param_p): New. (tic6x_gdbarch_init): Install tic6x_return_with_first_hidden_param_p. --- 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 2dce8da..815522f 100644 --- a/gdb/tic6x-tdep.c +++ b/gdb/tic6x-tdep.c @@ -825,6 +825,19 @@ tic6x_return_value (struct gdbarch *gdbarch, struct type *func_type, 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; @@ -915,32 +928,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); @@ -950,12 +938,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); @@ -970,10 +952,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) @@ -989,7 +969,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]; @@ -1210,6 +1190,16 @@ tic6x_get_longjmp_target (struct frame_info *frame, CORE_ADDR *pc) return 1; } +/* This is the implementation of gdbarch method + return_with_first_hidden_param_p. */ + +static int +tic6x_return_with_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) { @@ -1368,6 +1358,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_with_first_hidden_param_p (gdbarch, + tic6x_return_with_first_hidden_param_p); + /* Hook in ABI-specific overrides, if they have been registered. */ gdbarch_init_osabi (info, gdbarch); -- 1.7.0.4