From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 13914 invoked by alias); 10 Jun 2009 20:44:46 -0000 Received: (qmail 13906 invoked by uid 22791); 10 Jun 2009 20:44:45 -0000 X-SWARE-Spam-Status: No, hits=-1.2 required=5.0 tests=BAYES_00,MIME_QP_LONG_LINE X-Spam-Check-By: sourceware.org Received: from ugmailsb.ugent.be (HELO ugmailsb.ugent.be) (157.193.71.46) by sourceware.org (qpsmtpd/0.43rc1) with ESMTP; Wed, 10 Jun 2009 20:44:37 +0000 Received: from localhost (localhost [127.0.0.1]) by ugmailsb.ugent.be (Postfix) with ESMTP id 7CF7E2AB294 for ; Wed, 10 Jun 2009 22:44:28 +0200 (CEST) Received: from ugmailsb.ugent.be ([127.0.0.1]) by localhost (ugmailsb.ugent.be [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id 0FNUjzL0iZqM for ; Wed, 10 Jun 2009 22:44:28 +0200 (CEST) Received: from cypress.ugent.be (cypress.ugent.be [157.193.71.48]) by ugmailsb.ugent.be (Postfix) with ESMTP id 3909A2AB293 for ; Wed, 10 Jun 2009 22:44:28 +0200 (CEST) X-IronPort-Anti-Spam-Filtered: true X-IronPort-Anti-Spam-Result: ArMEAO+3L0qdwc4w/2dsb2JhbACXILoYhA0F Received: from mail.elis.ugent.be ([157.193.206.48]) by relayrec.ugent.be with ESMTP; 10 Jun 2009 22:44:27 +0200 Received: from localhost (localhost [127.0.0.1]) by mail.elis.ugent.be (Postfix) with ESMTP id A7599918F1D; Wed, 10 Jun 2009 22:44:27 +0200 (CEST) Received: from mail.elis.ugent.be ([127.0.0.1]) by localhost (mail.elis.ugent.be [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id BJJZzLddIgX0; Wed, 10 Jun 2009 22:44:24 +0200 (CEST) Received: from firefly.lan (unknown [91.176.14.27]) by mail.elis.ugent.be (Postfix) with ESMTP id 367E4918F12; Wed, 10 Jun 2009 22:44:24 +0200 (CEST) Cc: Mark Kettenis , gdb-patches@sourceware.org Message-Id: <5AA3BCA9-1ECF-446E-8B49-3132F0E470FB@elis.ugent.be> From: Jonas Maebe To: tromey@redhat.com In-Reply-To: Content-Type: multipart/mixed; boundary=Apple-Mail-5-71490988 Mime-Version: 1.0 (Apple Message framework v926) Subject: Re: [patch] Set calling convention of methods Date: Wed, 10 Jun 2009 20:44:00 -0000 References: <7B6EF4DA-76C8-4D9C-8B9F-94153EF1C4E1@elis.ugent.be> <691B0BA8-C606-42FF-A796-76CC9C31556A@elis.ugent.be> <200904222215.n3MMF0p2006994@brahms.sibelius.xs4all.nl> <19C107AA-5271-4C23-A6D2-AFF75BBAC4E4@elis.ugent.be> 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: 2009-06/txt/msg00273.txt.bz2 --Apple-Mail-5-71490988 Content-Type: text/plain; charset=US-ASCII; format=flowed; delsp=yes Content-Transfer-Encoding: 7bit Content-length: 1643 On 04 Jun 2009, at 20:17, Tom Tromey wrote: >>>>>> "Jonas" == Jonas Maebe writes: > > Jonas> It took quite a while, but I'm happy to say that my copyright > Jonas> assignment is now complete. I've received my confirmation > mail from > Jonas> FSF that they received all necessary documents. > > Thanks. Could you send the URLs of the last versions of your pending > patches? That would help. I've attached my first patch. Other patches will modify code in this one, so I'd prefer to get this one out of the way first. To Mark: it's slightly different from the last one that I previously sent you. There was still a bug whereby the address of the complex function result was pushed in the wrong order in case it has to passed on the stack (parameters are pushed from right to right, and the function result should be pushed before the rightmost parameter rather than after the leftmost). Hence, I moved the code to push the function result address from the end to the start of the loop pushing the memory parameter. This patch is against the current git://sourceware.org/git/gdb.git Thanks, Jonas 2009-06-10 Jonas Maebe Add support for the "Borland fastcall" calling convention. * elf/dwarf2.h: Add DW_CC_GNU_borland_fastcall_i386 constant. * i386-tdep.c: #include elf/dwarf2.h (i386_borland_fastcall_push_dummy_call): New. (i386_push_dummy_generic_call): Renamed i386_push_dummy_call. (i386_push_dummy_call): New dispatch function that calls i386_generic_push_dummy_call or i386_push_dummy_borland_fast_call depending on the calling convention. --Apple-Mail-5-71490988 Content-Disposition: attachment; filename=gdb_borland_fastcall5.patch Content-Type: application/octet-stream; x-unix-mode=0644; name="gdb_borland_fastcall5.patch" Content-Transfer-Encoding: quoted-printable Content-length: 8517 diff --git a/gdb/i386-tdep.c b/gdb/i386-tdep.c=0A= index 60526b0..d559707 100644=0A= --- a/gdb/i386-tdep.c=0A= +++ b/gdb/i386-tdep.c=0A= @@ -53,6 +53,8 @@=0A= #include "record.h"=0A= #include =0A= =20=0A= +#include "elf/dwarf2.h"=0A= +=0A= /* Register names. */=0A= =20=0A= static char *i386_register_names[] =3D=0A= @@ -1408,7 +1410,7 @@ i386_frame_this_id (struct frame_info *this_frame, vo= id **this_cache,=0A= if (cache->base =3D=3D 0)=0A= return;=0A= =20=0A= - /* See the end of i386_push_dummy_call. */=0A= + /* See the end of i386_generic_push_dummy_call. */=0A= (*this_id) =3D frame_id_build (cache->base + 8, cache->pc);=0A= }=0A= =20=0A= @@ -1517,7 +1519,7 @@ i386_sigtramp_frame_this_id (struct frame_info *this_= frame, void **this_cache,=0A= struct i386_frame_cache *cache =3D=0A= i386_sigtramp_frame_cache (this_frame, this_cache);=0A= =20=0A= - /* See the end of i386_push_dummy_call. */=0A= + /* See the end of i386_generic_push_dummy_call. */=0A= (*this_id) =3D frame_id_build (cache->base + 8, get_frame_pc (this_frame= ));=0A= }=0A= =20=0A= @@ -1594,7 +1596,7 @@ i386_dummy_id (struct gdbarch *gdbarch, struct frame_= info *this_frame)=0A= =20=0A= fp =3D get_frame_register_unsigned (this_frame, I386_EBP_REGNUM);=0A= =20=0A= - /* See the end of i386_push_dummy_call. */=0A= + /* See the end of i386_generic_push_dummy_call. */=0A= return frame_id_build (fp + 8, get_frame_pc (this_frame));=0A= }=0A= =0C=0A= @@ -1661,10 +1663,10 @@ i386_16_byte_align_p (struct type *type)=0A= }=0A= =20=0A= static CORE_ADDR=0A= -i386_push_dummy_call (struct gdbarch *gdbarch, struct value *function,=0A= - struct regcache *regcache, CORE_ADDR bp_addr, int nargs,=0A= - struct value **args, CORE_ADDR sp, int struct_return,=0A= - CORE_ADDR struct_addr)=0A= +i386_generic_push_dummy_call (struct gdbarch *gdbarch, struct value *funct= ion,=0A= + struct regcache *regcache, CORE_ADDR bp_addr,=0A= + int nargs, struct value **args, CORE_ADDR sp,=0A= + int struct_return, CORE_ADDR struct_addr)=0A= {=0A= gdb_byte buf[4];=0A= int i;=0A= @@ -1756,6 +1758,162 @@ i386_push_dummy_call (struct gdbarch *gdbarch, stru= ct value *function,=0A= return sp + 8;=0A= }=0A= =20=0A= +/* Borland fastcall: register parameters are passed from left to right, th= en=0A= + stack parameters also from left to right. The first three unstructured= =0A= + parameters <=3D 32 bits are passed in %eax, %edx and %ecx. The others = are=0A= + passed on the stack. Furthermore, in case of a struct return by refere= nce,=0A= + the address of this struct is passed as the last parameter. */=0A= +static CORE_ADDR=20=0A= +i386_borland_fastcall_push_dummy_call (struct gdbarch *gdbarch,=20=0A= + struct value *function,=0A= + struct regcache *regcache,=0A= + CORE_ADDR bp_addr, int nargs,=0A= + struct value **args, CORE_ADDR sp,=0A= + int struct_return, CORE_ADDR struct_addr)=0A= +{=0A= + static const int para_regs[3] =3D { I386_EAX_REGNUM, I386_EDX_REGNUM,=0A= + I386_ECX_REGNUM };=0A= +=0A= + gdb_byte buf[4];=0A= + int reg_paras[3] =3D { -1, -1, -1 };=20=0A= + int i, j;=0A= + int write_pass;=0A= + int para_regnum =3D 0;=0A= +=0A= + /* First assign the register parameters (left to right). */=0A= + for (i =3D 0; i < nargs && para_regnum < 3; i++)=0A= + {=0A= + struct type *type =3D check_typedef (value_enclosing_type (args[i]))= ;=0A= + int len =3D TYPE_LENGTH (type);=0A= +=0A= + if (len <=3D 4=0A= + && TYPE_CODE (type) !=3D TYPE_CODE_ARRAY=0A= + && TYPE_CODE (type) !=3D TYPE_CODE_STRUCT=0A= + && TYPE_CODE (type) !=3D TYPE_CODE_FLT)=0A= + {=0A= + regcache_cooked_write (regcache, para_regs[para_regnum],=0A= + value_contents_all (args[i]));=0A= + reg_paras[para_regnum] =3D i;=0A= + para_regnum++;=0A= + }=0A= + }=20=20=0A= + if (struct_return)=0A= + {=0A= + if (para_regnum < 3)=0A= + {=0A= + store_unsigned_integer (buf, 4, struct_addr);=0A= + regcache_cooked_write (regcache, para_regs[para_regnum],=0A= + buf);=0A= + /* Use the otherwise invalid "nargs" argument index to denote the=0A= + function result. */=0A= + reg_paras[para_regnum] =3D nargs;=0A= + para_regnum++;=0A= + }=0A= + }=0A= +=0A= + /* Now process the stack parameters from left to right. */=0A= + for (write_pass =3D 0; write_pass < 2; write_pass++)=0A= + {=0A= + int args_space =3D 0;=0A= + int have_16_byte_aligned_arg =3D 0;=0A= +=0A= + /* If we have a struct_return then para_regnum cannot be 0, since at= =0A= + least this return struct would have been passed in a register.=0A= + Additionally, if it is passed via a register, it will always be in=0A= + the last used position of the reg_paras array. */=0A= + if (struct_return=0A= + && reg_paras[para_regnum-1] !=3D nargs)=0A= + {=0A= + if (write_pass)=0A= + {=0A= + /* Push value address. */=0A= + store_unsigned_integer (buf, 4, struct_addr);=0A= + write_memory (sp + args_space, buf, 4);=0A= + }=0A= + args_space +=3D 4;=0A= + }=0A= +=0A= + for (i =3D nargs - 1; i >=3D 0; i--)=0A= + {=0A= + struct type *type =3D check_typedef (value_enclosing_type (args[i]));= =0A= + int len =3D TYPE_LENGTH (type);=0A= + int processed =3D 0;=0A= +=0A= + /* Skip parameters already assigned to registers. */=0A= + for (j =3D 0; j < para_regnum; j++)=0A= + if (reg_paras[j] =3D=3D i)=0A= + {=0A= + processed =3D 1;=0A= + break;=0A= + }=0A= + if (processed)=0A= + continue;=0A= +=0A= + if (i386_16_byte_align_p (value_enclosing_type (args[i])))=0A= + {=0A= + args_space =3D align_up (args_space, 16);=0A= + have_16_byte_aligned_arg =3D 1;=0A= + }=0A= + if (write_pass)=0A= + {=0A= + write_memory (sp + args_space,=0A= + value_contents_all (args[i]), len);=0A= + }=0A= + args_space +=3D align_up (len, 4);=0A= + }=0A= +=0A= + if (!write_pass)=0A= + {=0A= + /* Early exit if nothing to do. */=0A= + if (!args_space)=0A= + break;=0A= + if (have_16_byte_aligned_arg)=0A= + args_space =3D align_up (args_space, 16);=0A= + sp -=3D args_space;=0A= + }=0A= + }=0A= +=0A= + /* Store return address. */=0A= + sp -=3D 4;=0A= + store_unsigned_integer (buf, 4, bp_addr);=0A= + write_memory (sp, buf, 4);=0A= +=0A= + /* Finally, update the stack pointer... */=0A= + store_unsigned_integer (buf, 4, sp);=0A= + regcache_cooked_write (regcache, I386_ESP_REGNUM, buf);=0A= +=0A= + /* ...and fake a frame pointer. */=0A= + regcache_cooked_write (regcache, I386_EBP_REGNUM, buf);=0A= +=0A= + /* See the end of i386_generic_push_dummy_call. */=0A= + return sp + 8;=0A= +}=0A= +=0A= +static CORE_ADDR=0A= +i386_push_dummy_call (struct gdbarch *gdbarch, struct value *function,=0A= + struct regcache *regcache, CORE_ADDR bp_addr, int nargs,=0A= + struct value **args, CORE_ADDR sp, int struct_return,=0A= + CORE_ADDR struct_addr)=0A= +{=0A= + struct type *type =3D check_typedef (value_type (function));=0A= +=0A= + /* Look up the target type in case of a function/method pointer. */=0A= + while (type=0A= + && can_dereference (type))=0A= + type =3D TYPE_TARGET_TYPE (type);=0A= +=0A= + /* Check calling convention. */=0A= + if (type=0A= + && TYPE_CALLING_CONVENTION (type) =3D=3D DW_CC_GNU_borland_fastcall_= i386)=0A= + return i386_borland_fastcall_push_dummy_call (gdbarch, function, regca= che,=0A= + bp_addr, nargs, args, sp,=0A= + struct_return, struct_addr);=0A= + else=0A= + return i386_generic_push_dummy_call (gdbarch, function, regcache, bp_a= ddr,=0A= + nargs, args, sp, struct_return,=0A= + struct_addr);=0A= +}=0A= +=0A= /* These registers are used for returning integers (and on some=0A= targets also for returning `struct' and `union' values when their=0A= size and alignment match an integer type). */=0A= diff --git a/include/elf/dwarf2.h b/include/elf/dwarf2.h=0A= index a7448dc..efa786e 100644=0A= --- a/include/elf/dwarf2.h=0A= +++ b/include/elf/dwarf2.h=0A= @@ -662,7 +662,8 @@ enum dwarf_calling_convention=0A= DW_CC_normal =3D 0x1,=0A= DW_CC_program =3D 0x2,=0A= DW_CC_nocall =3D 0x3,=0A= - DW_CC_GNU_renesas_sh =3D 0x40=0A= + DW_CC_GNU_renesas_sh =3D 0x40,=0A= + DW_CC_GNU_borland_fastcall_i386 =3D 0x41=0A= };=0A= =20=0A= #define DW_CC_lo_user 0x40=0A= --Apple-Mail-5-71490988 Content-Type: text/plain; charset=US-ASCII; format=flowed Content-Transfer-Encoding: 7bit Content-length: 1 --Apple-Mail-5-71490988--