From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 32761 invoked by alias); 22 Aug 2003 08:41:02 -0000 Mailing-List: contact gdb-help@sources.redhat.com; run by ezmlm Precedence: bulk List-Subscribe: List-Archive: List-Post: List-Help: , Sender: gdb-owner@sources.redhat.com Received: (qmail 32752 invoked from network); 22 Aug 2003 08:41:00 -0000 Received: from unknown (HELO mx1.redhat.com) (66.187.233.31) by sources.redhat.com with SMTP; 22 Aug 2003 08:41:00 -0000 Received: from int-mx2.corp.redhat.com (nat-pool-rdu-dmz.redhat.com [172.16.52.200]) by mx1.redhat.com (8.11.6/8.11.6) with ESMTP id h7M8exl28693 for ; Fri, 22 Aug 2003 04:40:59 -0400 Received: from potter.sfbay.redhat.com (potter.sfbay.redhat.com [172.16.27.15]) by int-mx2.corp.redhat.com (8.11.6/8.11.6) with ESMTP id h7M8exL19648 for ; Fri, 22 Aug 2003 04:40:59 -0400 Received: from cygbert.vinschen.de (vpn50-26.rdu.redhat.com [172.16.50.26]) by potter.sfbay.redhat.com (8.11.6/8.11.6) with ESMTP id h7M8evO17568 for ; Fri, 22 Aug 2003 01:40:57 -0700 Received: by cygbert.vinschen.de (Postfix, from userid 500) id CA51D5821D; Fri, 22 Aug 2003 10:40:54 +0200 (CEST) Date: Fri, 22 Aug 2003 08:41:00 -0000 From: Corinna Vinschen To: gdb@sources.redhat.com Subject: [RFC] Supporting alternative ABIs Message-ID: <20030822084054.GA1110@cygbert.vinschen.de> Reply-To: gdb@sources.redhat.com Mail-Followup-To: gdb@sources.redhat.com Mime-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline User-Agent: Mutt/1.4.1i X-SW-Source: 2003-08/txt/msg00252.txt.bz2 Hi, we're working on GDB support for a platform that supports two different calling conventions; the user can choose which to use on a per-function basis. Obviously, calling a function from GDB should work, no matter which convention the function uses. We'd like folks' thoughts on how this information should be carried through, from the compiler, which actually has the information, to GDB's inferior function call code, which needs it. Since this problem might arise more often in future, we are looking forward to a generic solution. Thanks to Jim Blandy, who wrote the first draft of this document after a long discussion. The problem: The platform has a "native" compiler which uses a calling convention different from the calling convention used by gcc. Both ABIs are valid concurrently and it should be possible to create functions with gcc, which use the other ABI and to call these functions from other functions using the gcc ABI and vice versa. To allow this in gcc per function, you declare a function with an appropriate attribute: int __attribute__ ((use_alternate_abi)) foo (int x, double y) { ...; } This function will expect to be called using the chip's alternative ABI. Note that this attribute actually applies to the *type* of the function, as well. Suppose `pf' is a pointer to a function; in order for the compiler to generate the right code for: (*pf) (1, 2.0) it needs to know which calling convention the function '*pf' uses. To look at it another way, if I declare two functions like this: double bar (int x, double y) { return x + 2 * y; } double __attribute__ ((use_alternate_abi)) baz (int x, double y) { return x + 2 * y; } Then '&bar' and '&baz' must be incompatible function types; if we don't know which one 'pf' is pointing to, we can't generate code to call through it. We write the types of '&bar' and '&baz' as follows: double ( *) (int, double) double (__attribute__ ((use_alternate_abi)) *) (int, double) So, in the general case, GDB needs to be able to successfully call such functions. If *pf is &baz, then GDB should work like this: (gdb) print (*pf) (1, 2.0) $42 = 5.0 (gdb) Since functions are immediately promoted to function pointers when they appear as the operand of almost anything in a C expression, supporting the case above will automatically support the more straightforward uses, like: (gdb) print baz (1, 2.0) $43 = 5.0 (gdb) The proposal: There needs to be a way for the compiler to indicate to the debugger which functions use the alternative calling convention. This platform uses Dwarf 2 as its normal debugging format; it's straightforward to extend Dwarf 2 to carry this information. The Dwarf 2 attribute DW_AT_calling_convention would seem to be appropriate here. The spec only describes its use for actual DW_TAG_subprogram nodes (for functions themselves) not DW_TAG_subroutine_type nodes (for subroutine types) but it seems like a reasonable extension. We can specify new DW_CC_ values, in the range reserved for user extensions, in the chip's ABI. GDB needs to read this information, store it in its symbol tables, and use it in call_function_by_hand. It's not clear to us how best to do this, but here is our straw-man proposal. - Add the following member to 'struct main_type': /* For TYPE_CODE_FUNC, target-specific information about how to call this function. This is zero if the function uses the platform's standard calling convention. */ int calling_convention; - The dwarf2read.c function responsible for reading function types, read_subroutine_type, would check for a DW_AT_calling_convention attribute on the DW_TAG_subroutine_type die; if present, it would pass the attribute's value, an integer, to a new gdbarch method, gdbarch_parse_dwarf2_calling_convention. Actually, gdbarch_parse_dwarf2_calling_convention would have three arguments: attribute_present, calling_convention, and gcc_compiled. `attribute_present' is a flag, indicating if DW_AT_calling_convention is present in this node, `calling_convention' contains the actual value, if any, and `gcc_compiled' is a flag indicating if the function has been build using gcc or not. We'd call gdbarch_parse_dwarf2_calling_convention for every subroutine type node. The method would return another int, to be stored in the subroutine type's `calling_convention'. - EXTRACT_RETURN_VALUE, STORE_RETURN_VALUE, USE_STRUCT_CONVENTION and gdbarch_push_dummy_code gdbarch methods would be changed to expect the type of the function, not the type of its return value. They can use TYPE_TARGET_TYPE to get the return value type, but this will also give them access to the `calling_convention' for the function type. - gdbarch_push_dummy_call and EXTRACT_STRUCT_VALUE_ADDRESS would receive the function's type as an additional argument, to give them access to the function's calling convention information. - USE_STRUCT_CONVENTION and gdbarch_push_dummy_code would not require the `gcc_p' and `using_gcc' flags anymore since this information is now given in the function type node. Due to the way, gdbarch_parse_dwarf2_calling_convention evaluates the `calling_convention' value, all inferior call-related gdbarch methods could simply trust its value. The advantage of this approach is that it leaves the details about how to interpret the value of the DW_CC_calling_convention attribute, and how to represent the calling conventions supported for a particular architecture, in the hands of target-specific code. GDB's core code simply carries that target-specific information from the debug info reader to the inferior call code. And having the gdbarch methods that support inferior calls take the function type, instead of the return value type, seems natural. The disadvantage of this is that changing all the gdbarch methods mentioned above would be a lot of work --- although not that difficult. Corinna -- Corinna Vinschen Cygwin Developer Red Hat, Inc.