This is the mail archive of the gdb-patches@sourceware.cygnus.com mailing list for the GDB project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]

Re: Fix for call-ar-st.exp failure on x86



> When GDB calls a function it incorrectly pads the arguments - that is,
> GDB's behavior differs from GCC and also from the x86 ABI at
> http://www.sco.com/developer/devspecs

Sure --- it makes sense to parameterize the generic argument passer
this way, rather than write a custom push_arguments function for IA32.

Some comments, though:
- You enlarge `len' to the nearest boundary, and then read garbage off
  the end of GDB's value buffer.  This probably won't make GDB crash,
  but it seems sloppy.
- The PARM_BOUNDARY has an obvious extension to big-endian
  architectures, but the code you supplied works only on little-endian
  architectures.
- As Stan points out, new architecture parameters should be done in a
  gdbarch-friendly way.

In principle, we should send patches back to the author for revision,
but these problems are pretty easy to fix, and I'm especially happy
to get rid of those call-ar-st.exp failures.

Here's what I did in valops.c.  If you see anything dumb, let me know.

1999-10-11  Jim Blandy  <jimb@zenia.red-bean.com>

	Fix from Jim Kingdon <kingdon@redhat.com>, with tweaks to make it
	gdbarch- and bigendian-friendly:
	* valops.c (PARM_BOUNDARY): If not #defined, default to zero.
	(value_push): If PARM_BOUNDARY is not zero, align arguments to
	that boundary.
	* config/i386/tm-i386.h: Define PARM_BOUNDARY.

Index: valops.c
===================================================================
RCS file: /cvs/cvsfiles/devo/gdb/valops.c,v
retrieving revision 1.180
diff -c -c -b -F'^(' -r1.180 valops.c
*** valops.c	1999/09/16 21:06:03	1.180
--- valops.c	1999/10/12 00:11:36
***************
*** 1061,1086 ****
    return sp;
  }
  
! /* Push onto the stack the specified value VALUE.  */
  
  static CORE_ADDR
  value_push (sp, arg)
       register CORE_ADDR sp;
       value_ptr arg;
  {
    register int len = TYPE_LENGTH (VALUE_ENCLOSING_TYPE (arg));
  
    if (INNER_THAN (1, 2))
      {
        /* stack grows downward */
!       sp -= len;
!       write_memory (sp, VALUE_CONTENTS_ALL (arg), len);
      }
    else
      {
        /* stack grows upward */
!       write_memory (sp, VALUE_CONTENTS_ALL (arg), len);
!       sp += len;
      }
  
    return sp;
--- 1061,1104 ----
    return sp;
  }
  
! #ifndef PARM_BOUNDARY
! #define PARM_BOUNDARY (0)
! #endif
  
+ /* Push onto the stack the specified value VALUE.  Pad it correctly for
+    it to be an argument to a function.  */
+ 
  static CORE_ADDR
  value_push (sp, arg)
       register CORE_ADDR sp;
       value_ptr arg;
  {
    register int len = TYPE_LENGTH (VALUE_ENCLOSING_TYPE (arg));
+   register int container_len;
+   register int offset;
+ 
+   /* How big is the container we're going to put this value in?  */
+   if (PARM_BOUNDARY)
+     container_len = ((len + PARM_BOUNDARY / TARGET_CHAR_BIT - 1)
+ 		     & ~(PARM_BOUNDARY / TARGET_CHAR_BIT - 1));
+ 
+   /* Are we going to put it at the high or low end of the container?  */
+   if (TARGET_BYTE_ORDER == BIG_ENDIAN)
+     offset = container_len - len;
+   else
+     offset = 0;
  
    if (INNER_THAN (1, 2))
      {
        /* stack grows downward */
!       sp -= container_len;
!       write_memory (sp + offset, VALUE_CONTENTS_ALL (arg), len);
      }
    else
      {
        /* stack grows upward */
!       write_memory (sp + offset, VALUE_CONTENTS_ALL (arg), len);
!       sp += container_len;
      }
  
    return sp;

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]