This is the mail archive of the
gdb-patches@sources.redhat.com
mailing list for the GDB project.
[PATCH] Fix UltraSPARC return value problems
- From: Mark Kettenis <kettenis at chello dot nl>
- To: gdb-patches at sources dot redhat dot com
- Date: Sat, 3 Jan 2004 16:03:15 +0100 (CET)
- Subject: [PATCH] Fix UltraSPARC return value problems
The new structs.exp test has significantly more coverage that the old
one. It uncovered some bugs in the new SPARC target. The attached
fixes most of these for 64-bit code.
Committed,
Mark
Index: ChangeLog
from Mark Kettenis <kettenis@gnu.org>
* sparc64-tdep.c (sparc64_16_byte_align_p)
(sparc64_store_floating_fields, sparc64_store_floating_fields):
Use check_typedef to get subtypes of structures and unions.
(sparc64_store_return_value): Fix calculation of the appropriate
offset into VALBUF when storing a structure or union.
(sparc64_return_value): New function.
(sparc64_use_struct_convention): Remove function.
(sparc64_init_abi): Set return_value, don't set
extract_return_value, store_return_value and
use_struct_convention.
Index: sparc64-tdep.c
===================================================================
RCS file: /cvs/src/src/gdb/sparc64-tdep.c,v
retrieving revision 1.4
diff -u -p -r1.4 sparc64-tdep.c
--- sparc64-tdep.c 3 Jan 2004 10:08:44 -0000 1.4
+++ sparc64-tdep.c 3 Jan 2004 14:58:41 -0000
@@ -604,8 +604,12 @@ sparc64_16_byte_align_p (struct type *ty
int i;
for (i = 0; i < TYPE_NFIELDS (type); i++)
- if (sparc64_16_byte_align_p (TYPE_FIELD_TYPE (type, i)))
- return 1;
+ {
+ struct type *subtype = check_typedef (TYPE_FIELD_TYPE (type, i));
+
+ if (sparc64_16_byte_align_p (subtype))
+ return 1;
+ }
}
return 0;
@@ -657,9 +661,13 @@ sparc64_store_floating_fields (struct re
int i;
for (i = 0; i < TYPE_NFIELDS (type); i++)
- sparc64_store_floating_fields (regcache, TYPE_FIELD_TYPE (type, i),
- valbuf, element,
- bitpos + TYPE_FIELD_BITPOS (type, i));
+ {
+ struct type *subtype = check_typedef (TYPE_FIELD_TYPE (type, i));
+ int subpos = bitpos + TYPE_FIELD_BITPOS (type, i);
+
+ sparc64_store_floating_fields (regcache, subtype, valbuf,
+ element, subpos);
+ }
}
}
@@ -705,9 +713,12 @@ sparc64_extract_floating_fields (struct
int i;
for (i = 0; i < TYPE_NFIELDS (type); i++)
- sparc64_extract_floating_fields (regcache, TYPE_FIELD_TYPE (type, i),
- valbuf,
- bitpos + TYPE_FIELD_BITPOS (type, i));
+ {
+ struct type *subtype = check_typedef (TYPE_FIELD_TYPE (type, i));
+ int subpos = bitpos + TYPE_FIELD_BITPOS (type, i);
+
+ sparc64_extract_floating_fields (regcache, subtype, valbuf, subpos);
+ }
}
}
@@ -1019,7 +1030,7 @@ sparc64_store_return_value (struct type
memset (buf, 0, sizeof (buf));
memcpy (buf, valbuf, len);
for (i = 0; i < ((len + 7) / 8); i++)
- regcache_cooked_write (regcache, SPARC_O0_REGNUM + i, buf + i * 4);
+ regcache_cooked_write (regcache, SPARC_O0_REGNUM + i, buf + i * 8);
if (TYPE_CODE (type) != TYPE_CODE_UNION)
sparc64_store_floating_fields (regcache, type, buf, 0, 0);
}
@@ -1042,12 +1053,20 @@ sparc64_store_return_value (struct type
}
}
-static int
-sparc64_use_struct_convention (int gcc_p, struct type *type)
+static enum return_value_convention
+sparc64_return_value (struct gdbarch *gdbarch, struct type *type,
+ struct regcache *regcache, void *readbuf,
+ const void *writebuf)
{
- /* Structure and union types up to 32 bytes in size are returned in
- registers. */
- return (TYPE_LENGTH (type) > 32);
+ if (TYPE_LENGTH (type) > 32)
+ return RETURN_VALUE_STRUCT_CONVENTION;
+
+ if (readbuf)
+ sparc64_extract_return_value (type, regcache, readbuf);
+ if (writebuf)
+ sparc64_store_return_value (type, regcache, writebuf);
+
+ return RETURN_VALUE_REGISTER_CONVENTION;
}
@@ -1079,9 +1098,7 @@ sparc64_init_abi (struct gdbarch_info in
set_gdbarch_push_dummy_code (gdbarch, NULL);
set_gdbarch_push_dummy_call (gdbarch, sparc64_push_dummy_call);
- set_gdbarch_extract_return_value (gdbarch, sparc64_extract_return_value);
- set_gdbarch_store_return_value (gdbarch, sparc64_store_return_value);
- set_gdbarch_use_struct_convention (gdbarch, sparc64_use_struct_convention);
+ set_gdbarch_return_value (gdbarch, sparc64_return_value);
set_gdbarch_return_value_on_stack
(gdbarch, generic_return_value_on_stack_not);
set_gdbarch_stabs_argument_has_addr