Mirror of the gdb-patches mailing list
 help / color / mirror / Atom feed
From: Jonas Maebe <jonas.maebe@elis.ugent.be>
To: gdb-patches ml <gdb-patches@sourceware.org>
Subject: Fwd: [patch] Set calling convention of methods
Date: Thu, 18 Jun 2009 21:45:00 -0000	[thread overview]
Message-ID: <63608DF6-5980-483E-A6AA-324F2DFAC1F3@elis.ugent.be> (raw)
In-Reply-To: <5AA3BCA9-1ECF-446E-8B49-3132F0E470FB@elis.ugent.be>

[-- Attachment #1: Type: text/plain, Size: 1996 bytes --]

Ping.


Begin forwarded message:

> From: Jonas Maebe <jonas.maebe@elis.ugent.be>
> Date: Wed 10 Jun 2009 22:44:23 GMT+02:00
> To: tromey@redhat.com
> Cc: Mark Kettenis <mark.kettenis@xs4all.nl>, gdb- 
> patches@sourceware.org
> Subject: Re: [patch] Set calling convention of methods
>
>
> On 04 Jun 2009, at 20:17, Tom Tromey wrote:
>
>>>>>>> "Jonas" == Jonas Maebe <jonas.maebe@elis.ugent.be> 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  <jonas.maebe@elis.ugent.be>
>
> 	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.
>

[-- Attachment #2: gdb_borland_fastcall5.patch --]
[-- Type: application/octet-stream, Size: 7655 bytes --]

diff --git a/gdb/i386-tdep.c b/gdb/i386-tdep.c
index 60526b0..d559707 100644
--- a/gdb/i386-tdep.c
+++ b/gdb/i386-tdep.c
@@ -53,6 +53,8 @@
 #include "record.h"
 #include <stdint.h>
 
+#include "elf/dwarf2.h"
+
 /* Register names.  */
 
 static char *i386_register_names[] =
@@ -1408,7 +1410,7 @@ i386_frame_this_id (struct frame_info *this_frame, void **this_cache,
   if (cache->base == 0)
     return;
 
-  /* See the end of i386_push_dummy_call.  */
+  /* See the end of i386_generic_push_dummy_call.  */
   (*this_id) = frame_id_build (cache->base + 8, cache->pc);
 }
 
@@ -1517,7 +1519,7 @@ i386_sigtramp_frame_this_id (struct frame_info *this_frame, void **this_cache,
   struct i386_frame_cache *cache =
     i386_sigtramp_frame_cache (this_frame, this_cache);
 
-  /* See the end of i386_push_dummy_call.  */
+  /* See the end of i386_generic_push_dummy_call.  */
   (*this_id) = frame_id_build (cache->base + 8, get_frame_pc (this_frame));
 }
 
@@ -1594,7 +1596,7 @@ i386_dummy_id (struct gdbarch *gdbarch, struct frame_info *this_frame)
 
   fp = get_frame_register_unsigned (this_frame, I386_EBP_REGNUM);
 
-  /* See the end of i386_push_dummy_call.  */
+  /* See the end of i386_generic_push_dummy_call.  */
   return frame_id_build (fp + 8, get_frame_pc (this_frame));
 }
 \f
@@ -1661,10 +1663,10 @@ i386_16_byte_align_p (struct type *type)
 }
 
 static CORE_ADDR
-i386_push_dummy_call (struct gdbarch *gdbarch, struct value *function,
-		      struct regcache *regcache, CORE_ADDR bp_addr, int nargs,
-		      struct value **args, CORE_ADDR sp, int struct_return,
-		      CORE_ADDR struct_addr)
+i386_generic_push_dummy_call (struct gdbarch *gdbarch, struct value *function,
+			      struct regcache *regcache, CORE_ADDR bp_addr,
+			      int nargs, struct value **args, CORE_ADDR sp,
+			      int struct_return, CORE_ADDR struct_addr)
 {
   gdb_byte buf[4];
   int i;
@@ -1756,6 +1758,162 @@ i386_push_dummy_call (struct gdbarch *gdbarch, struct value *function,
   return sp + 8;
 }
 
+/* Borland fastcall: register parameters are passed from left to right, then
+   stack parameters also from left to right.  The first three unstructured
+   parameters <= 32 bits are passed in %eax, %edx and %ecx.  The others are
+   passed on the stack.  Furthermore, in case of a struct return by reference,
+   the address of this struct is passed as the last parameter.  */
+static CORE_ADDR 
+i386_borland_fastcall_push_dummy_call (struct gdbarch *gdbarch, 
+				       struct value *function,
+				       struct regcache *regcache,
+				       CORE_ADDR bp_addr, int nargs,
+				       struct value **args, CORE_ADDR sp,
+				       int struct_return, CORE_ADDR struct_addr)
+{
+  static const int para_regs[3] = { I386_EAX_REGNUM, I386_EDX_REGNUM,
+      I386_ECX_REGNUM };
+
+  gdb_byte buf[4];
+  int reg_paras[3] = { -1, -1, -1 }; 
+  int i, j;
+  int write_pass;
+  int para_regnum = 0;
+
+  /* First assign the register parameters (left to right).  */
+  for (i = 0; i < nargs && para_regnum < 3; i++)
+    {
+      struct type *type = check_typedef (value_enclosing_type (args[i]));
+      int len = TYPE_LENGTH (type);
+
+      if (len <= 4
+	  && TYPE_CODE (type) != TYPE_CODE_ARRAY
+	  && TYPE_CODE (type) != TYPE_CODE_STRUCT
+	  && TYPE_CODE (type) != TYPE_CODE_FLT)
+	{
+	  regcache_cooked_write (regcache, para_regs[para_regnum],
+				 value_contents_all (args[i]));
+	  reg_paras[para_regnum] = i;
+	  para_regnum++;
+	}
+    }  
+  if (struct_return)
+    {
+      if (para_regnum < 3)
+	{
+	  store_unsigned_integer (buf, 4, struct_addr);
+	  regcache_cooked_write (regcache, para_regs[para_regnum],
+				 buf);
+	  /* Use the otherwise invalid "nargs" argument index to denote the
+	     function result.  */
+	  reg_paras[para_regnum] = nargs;
+	  para_regnum++;
+	}
+    }
+
+  /* Now process the stack parameters from left to right.  */
+  for (write_pass = 0; write_pass < 2; write_pass++)
+    {
+      int args_space = 0;
+      int have_16_byte_aligned_arg = 0;
+
+      /* If we have a struct_return then para_regnum cannot be 0, since at
+	 least this return struct would have been passed in a register.
+	 Additionally, if it is passed via a register, it will always be in
+	 the last used position of the reg_paras array.  */
+      if (struct_return
+	  && reg_paras[para_regnum-1] != nargs)
+	{
+	  if (write_pass)
+	    {
+	      /* Push value address.  */
+	      store_unsigned_integer (buf, 4, struct_addr);
+	      write_memory (sp + args_space, buf, 4);
+	    }
+	  args_space += 4;
+	}
+
+      for (i = nargs - 1; i >= 0; i--)
+	{
+	  struct type *type = check_typedef (value_enclosing_type (args[i]));
+	  int len = TYPE_LENGTH (type);
+	  int processed = 0;
+
+	  /* Skip parameters already assigned to registers.  */
+	  for (j = 0; j < para_regnum; j++)
+	    if (reg_paras[j] == i)
+	      {
+		processed = 1;
+		break;
+	      }
+	  if (processed)
+	    continue;
+
+	  if (i386_16_byte_align_p (value_enclosing_type (args[i])))
+	    {
+	      args_space = align_up (args_space, 16);
+	      have_16_byte_aligned_arg = 1;
+	    }
+	  if (write_pass)
+	    {
+	      write_memory (sp + args_space,
+			    value_contents_all (args[i]), len);
+	    }
+	  args_space += align_up (len, 4);
+	}
+
+      if (!write_pass)
+	{
+	  /* Early exit if nothing to do.  */
+	  if (!args_space)
+	    break;
+	  if (have_16_byte_aligned_arg)
+	    args_space = align_up (args_space, 16);
+	  sp -= args_space;
+	}
+    }
+
+  /* Store return address.  */
+  sp -= 4;
+  store_unsigned_integer (buf, 4, bp_addr);
+  write_memory (sp, buf, 4);
+
+  /* Finally, update the stack pointer...  */
+  store_unsigned_integer (buf, 4, sp);
+  regcache_cooked_write (regcache, I386_ESP_REGNUM, buf);
+
+  /* ...and fake a frame pointer.  */
+  regcache_cooked_write (regcache, I386_EBP_REGNUM, buf);
+
+  /* See the end of i386_generic_push_dummy_call.  */
+  return sp + 8;
+}
+
+static CORE_ADDR
+i386_push_dummy_call (struct gdbarch *gdbarch, struct value *function,
+		      struct regcache *regcache, CORE_ADDR bp_addr, int nargs,
+		      struct value **args, CORE_ADDR sp, int struct_return,
+		      CORE_ADDR struct_addr)
+{
+  struct type *type = check_typedef (value_type (function));
+
+  /* Look up the target type in case of a function/method pointer.  */
+  while (type
+	 && can_dereference (type))
+    type = TYPE_TARGET_TYPE (type);
+
+  /* Check calling convention.  */
+  if (type
+      && TYPE_CALLING_CONVENTION (type) == DW_CC_GNU_borland_fastcall_i386)
+    return i386_borland_fastcall_push_dummy_call (gdbarch, function, regcache,
+					      bp_addr, nargs, args, sp,
+					      struct_return, struct_addr);
+  else
+    return i386_generic_push_dummy_call (gdbarch, function, regcache, bp_addr,
+					 nargs, args, sp, struct_return,
+					 struct_addr);
+}
+
 /* These registers are used for returning integers (and on some
    targets also for returning `struct' and `union' values when their
    size and alignment match an integer type).  */
diff --git a/include/elf/dwarf2.h b/include/elf/dwarf2.h
index a7448dc..efa786e 100644
--- a/include/elf/dwarf2.h
+++ b/include/elf/dwarf2.h
@@ -662,7 +662,8 @@ enum dwarf_calling_convention
     DW_CC_normal = 0x1,
     DW_CC_program = 0x2,
     DW_CC_nocall = 0x3,
-    DW_CC_GNU_renesas_sh = 0x40
+    DW_CC_GNU_renesas_sh = 0x40,
+    DW_CC_GNU_borland_fastcall_i386 = 0x41
   };
 
 #define DW_CC_lo_user 0x40

[-- Attachment #3: Type: text/plain, Size: 3 bytes --]

>


  reply	other threads:[~2009-06-18 21:45 UTC|newest]

Thread overview: 28+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2009-04-06 19:51 Jonas Maebe
2009-04-10 17:34 ` Tom Tromey
2009-04-20  8:40   ` Jonas Maebe
2009-04-20 18:27     ` Tom Tromey
2009-04-22 17:45       ` Jonas Maebe
2009-04-22 19:22         ` Tom Tromey
2009-04-22 22:16         ` Mark Kettenis
2009-06-04  8:23           ` Jonas Maebe
2009-06-04 18:19             ` Tom Tromey
2009-06-10 20:44               ` Jonas Maebe
2009-06-18 21:45                 ` Jonas Maebe [this message]
2009-09-30  0:02                 ` Joel Brobecker
2009-09-30 11:18                   ` Jonas Maebe
2009-09-30 14:54                     ` Jonas Maebe
2009-09-30 15:22                       ` Mark Kettenis
2009-09-30 16:25                       ` Joel Brobecker
2009-10-01  9:18                         ` Jonas Maebe
2009-10-01 22:04                           ` Joel Brobecker
2009-10-02  9:21                           ` Mark Kettenis
2009-09-30 16:10                     ` Joel Brobecker
2009-09-30 17:36                       ` Joel Brobecker
2009-09-30 16:47                     ` Tom Tromey
2009-09-30 17:32                       ` Joel Brobecker
2009-09-30 17:35                         ` Tom Tromey
2009-10-01  9:21                           ` Jonas Maebe
2009-11-03  9:43                         ` Jonas Maebe
2009-11-03 14:19                           ` Joel Brobecker
2009-07-06 20:50               ` Jonas Maebe

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=63608DF6-5980-483E-A6AA-324F2DFAC1F3@elis.ugent.be \
    --to=jonas.maebe@elis.ugent.be \
    --cc=gdb-patches@sourceware.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox