This is the mail archive of the
gdb-patches@sources.redhat.com
mailing list for the GDB project.
[Patch] Fix ABI incompatibilities on s390x
- From: Gerhard Tonn <ton at de dot ibm dot com>
- To: gdb-patches at sources dot redhat dot com
- Date: Tue, 19 Nov 2002 09:44:49 +0100
- Subject: [Patch] Fix ABI incompatibilities on s390x
- Organization: IBM Deutschland GmbH
Hi,
attached is a patch that fixes some ABI incompatibilities for the s390x
architecture.
2002-11-19 Gerhard Tonn <ton@de.ibm.com>
* s390-tdep.c (s390_push_arguments, s390_get_frame_info):
Fix the s390x ELF ABI implementation bugs.
--- gdb-5.2.cvs20020401/gdb/s390-tdep.c Mon Apr 1 03:09:43 2002
+++ gdb-5.2.cvs20020401-new/gdb/s390-tdep.c Fri Jul 26 11:53:57 2002
@@ -95,6 +95,8 @@
#define S390_UC_MCONTEXT_OFFSET (256)
#define S390X_UC_MCONTEXT_OFFSET (344)
#define S390_STACK_FRAME_OVERHEAD (GDB_TARGET_IS_ESAME ? 160:96)
+#define S390_STACK_PARAMETER_ALIGNMENT (GDB_TARGET_IS_ESAME ? 8:4)
+#define S390_NUM_FP_PARAMETER_REGISTERS (GDB_TARGET_IS_ESAME ? 4:2)
#define S390_SIGNAL_FRAMESIZE (GDB_TARGET_IS_ESAME ? 160:96)
#define s390_NR_sigreturn 119
#define s390_NR_rt_sigreturn 173
@@ -1378,9 +1380,9 @@
/* This is almost a direct translation of the ABI's language, except
that we have to exclude 8-byte structs; those are DOUBLE_ARGs. */
- return ((is_integer_like (type) && length <= 4)
+ return ((is_integer_like (type) && length <= REGISTER_SIZE)
|| is_pointer_like (type)
- || (is_struct_like (type) && length != 8)
+ || (is_struct_like (type) && (GDB_TARGET_IS_ESAME ? 1 : length != 8))
|| (is_float_like (type) && length == 16));
}
@@ -1393,7 +1395,8 @@
{
unsigned length = TYPE_LENGTH (type);
- return ((is_struct_like (type) && length != 1 && length != 2 && length != 4)
+ return ((is_struct_like (type) && length != 1 && length != 2 && length != 4
+ && (GDB_TARGET_IS_ESAME ? length != 8 : 1))
|| (is_float_like (type) && length == 16));
}
@@ -1551,9 +1554,9 @@
sp = round_down (sp, alignment_of (type));
- /* SIMPLE_ARG values get extended to 32 bits. Assume every
- argument is. */
- if (length < 4) length = 4;
+ /* SIMPLE_ARG values get extended to REGISTER_SIZE bytes.
+ Assume every argument is. */
+ if (length < REGISTER_SIZE) length = REGISTER_SIZE;
sp -= length;
}
}
@@ -1574,13 +1577,17 @@
int gr = 2;
CORE_ADDR starg = sp;
+ /* A struct is returned using general register 2 */
+ if (struct_return)
+ gr++;
+
for (i = 0; i < nargs; i++)
{
struct value *arg = args[i];
struct type *type = VALUE_TYPE (arg);
if (is_double_or_float (type)
- && fr <= 2)
+ && fr <= S390_NUM_FP_PARAMETER_REGISTERS * 2 - 2)
{
/* When we store a single-precision value in an FP register,
it occupies the leftmost bits. */
@@ -1601,13 +1608,13 @@
gr++;
}
- else if (is_double_arg (type)
+ else if (!GDB_TARGET_IS_ESAME && is_double_arg (type)
&& gr <= 5)
{
write_register_gen (S390_GP0_REGNUM + gr,
VALUE_CONTENTS (arg));
write_register_gen (S390_GP0_REGNUM + gr + 1,
- VALUE_CONTENTS (arg) + 4);
+ VALUE_CONTENTS (arg) + REGISTER_SIZE);
gr += 2;
}
else
@@ -1618,14 +1625,14 @@
/* If we skipped r6 because we couldn't fit a DOUBLE_ARG
in it, then don't go back and use it again later. */
- if (is_double_arg (type) && gr == 6)
+ if (!GDB_TARGET_IS_ESAME && is_double_arg (type) && gr == 6)
gr = 7;
if (is_simple_arg (type))
{
- /* Simple args are always either extended to 32 bits,
- or pointers. */
- starg = round_up (starg, 4);
+ /* Simple args are always extended to
+ REGISTER_SIZE bytes. */
+ starg = round_up (starg, REGISTER_SIZE);
/* Do we need to pass a pointer to our copy of this
argument? */
@@ -1633,18 +1640,19 @@
write_memory_signed_integer (starg, pointer_size,
copy_addr[i]);
else
- /* Simple args are always extended to 32 bits. */
- write_memory_signed_integer (starg, 4,
+ /* Simple args are always extended to
+ REGISTER_SIZE bytes. */
+ write_memory_signed_integer (starg, REGISTER_SIZE,
extend_simple_arg (arg));
- starg += 4;
+ starg += REGISTER_SIZE;
}
else
{
/* You'd think we should say:
starg = round_up (starg, alignment_of (type));
Unfortunately, GCC seems to simply align the stack on
- a four-byte boundary, even when passing doubles. */
- starg = round_up (starg, 4);
+ a four/eight-byte boundary, even when passing doubles. */
+ starg = round_up (starg, S390_STACK_PARAMETER_ALIGNMENT);
write_memory (starg, VALUE_CONTENTS (arg), length);
starg += length;
}
@@ -1655,7 +1663,7 @@
/* Allocate the standard frame areas: the register save area, the
word reserved for the compiler (which seems kind of meaningless),
and the back chain pointer. */
- sp -= 96;
+ sp -= S390_STACK_FRAME_OVERHEAD;
/* Write the back chain pointer into the first word of the stack
frame. This will help us get backtraces from within functions
--
Regards,
Gerhard