This is the mail archive of the
gdb-patches@sources.redhat.com
mailing list for the GDB project.
Re: [patch/rfa] fix call-dummies for hppa
- From: Andrew Cagney <cagney at gnu dot org>
- To: Randolph Chung <randolph at tausq dot org>
- Cc: gdb-patches at sources dot redhat dot com
- Date: Wed, 28 Apr 2004 11:42:31 -0400
- Subject: Re: [patch/rfa] fix call-dummies for hppa
- References: <20040424190231.GC2923@tausq.org>
This fixes a few bugs in the 32-bit version of the hppa push_dummy_call
method.
Tested against hppa2.0w-hp-hpux11.11 and hppa-linux.
Which compilers? I'm suspicious of GCC - it too often gets struct
parameters and return values internally consistent but wrong :-(
All of structs.exp pass, there are still some failures in call-sc.exp
and callfuncs.exp. In the latter case it appears most are due to
problems with calling malloc() in the inferior (at least on hppa-linux).
We simply allocate the appropriate amount of stack space and put
arguments into their proper slots. */
-
+
Be careful of white space change, this shouldn't be included. If you
want to fix some indention just do it separatly.
CORE_ADDR
hppa32_push_dummy_call (struct gdbarch *gdbarch, CORE_ADDR func_addr,
struct regcache *regcache, CORE_ADDR bp_addr,
int nargs, struct value **args, CORE_ADDR sp,
int struct_return, CORE_ADDR struct_addr)
{
- /* NOTE: cagney/2004-02-27: This is a guess - its implemented by
- reverse engineering testsuite failures. */
-
(I've now got a copy of the 32-bit ABI but it doesn't help much)
/* Stack base address at which any pass-by-reference parameters are
stored. */
CORE_ADDR struct_end = 0;
@@ -781,12 +779,15 @@ hppa32_push_dummy_call (struct gdbarch *
/* Two passes. First pass computes the location of everything,
second pass writes the bytes out. */
int write_pass;
+
for (write_pass = 0; write_pass < 2; write_pass++)
{
CORE_ADDR struct_ptr = 0;
- CORE_ADDR param_ptr = 0;
- int reg = 27; /* NOTE: Registers go down. */
the comment doesn't match the assignment.
+ /* The first parameter goes into sp-36, each stack slot is 4-bytes. */
+ CORE_ADDR param_ptr = 32;
int i;
+ int small_struct = 0;
+
for (i = 0; i < nargs; i++)
{
struct value *arg = args[i];
@@ -795,6 +796,7 @@ hppa32_push_dummy_call (struct gdbarch *
stack, and [possibly] passed in a register. */
char param_val[8];
int param_len;
+
memset (param_val, 0, sizeof param_val);
if (TYPE_LENGTH (type) > 8)
{
@@ -813,27 +815,76 @@ hppa32_push_dummy_call (struct gdbarch *
/* Integer value store, right aligned. "unpack_long"
takes care of any sign-extension problems. */
param_len = align_up (TYPE_LENGTH (type), 4);
+
white space
store_unsigned_integer (param_val, param_len,
unpack_long (type,
VALUE_CONTENTS (arg)));
}
+ else if (TYPE_CODE (type) == TYPE_CODE_FLT)
+ {
more comments (the rest is well commented), ``&& TYPE_LENGTH () == 4''
test needed?
+ param_len = align_up (TYPE_LENGTH (type), 4);
+ memcpy (param_val, VALUE_CONTENTS (arg), param_len);
+ }
else
{
- /* Small struct value, store right aligned? */
param_len = align_up (TYPE_LENGTH (type), 4);
+
+ /* Small struct value are stored right-aligned. */
memcpy (param_val + param_len - TYPE_LENGTH (type),
VALUE_CONTENTS (arg), TYPE_LENGTH (type));
+
+ /* Structures of size 5, 6 and 7 bytes are special in that
+ the higher-ordered word is stored in the lower-ordered
+ argument, and even though it is a 8-byte quantity the
+ registers need not be 8-byte aligned. */
+ if (param_len > 4)
+ small_struct = 1;
}
+
param_ptr += param_len;
- reg -= param_len / 4;
+ if (param_len == 8 && !small_struct)
+ param_ptr += (param_ptr & 4);
align_up?
Otherwize, yep, thanks for fixing this.
Andrew