This is the mail archive of the
gdb-patches@sourceware.cygnus.com
mailing list for the GDB project.
[PATCH] AIX 4.3 changes
- To: gdb-patches at sourceware dot cygnus dot com
- Subject: [PATCH] AIX 4.3 changes
- From: Kevin Buettner <kevinb at cygnus dot com>
- Date: Tue, 15 Feb 2000 14:30:13 -0700
I've just checked in the changes below for AIX 4.3. There will be
further changes to rs6000-tdep.c later this week. In particular, I'm
going to attempt to make all PPC ports use generic dummy frames for
calling the inferior.
* rs6000-tdep.c (rs6000_fix_call_dummy): Set TOC register
to correct value for generic dummy frames. When using
generic dummy frames, don't attempt to write TOC value or
function to call into the call dummy.
(rs6000_push_arguments): Adapt USE_GENERIC_DUMMY_FRAMES
code to also handle the PowerOpen ABI.
(ppc_push_return_address): Enable for all ports.
* config/powerpc/tm-ppc-aix.h (USE_GENERIC_DUMMY_FRAMES,
PUSH_DUMMY_FRAME, PUSH_RETURN_ADDRESS, GET_SAVED_REGISTER,
CALL_DUMMY_BREAKPOINT_OFFSET, CALL_DUMMY_LOCATION,
CALL_DUMMY_ADDRESS, CALL_DUMMY_START_OFFSET): Override defaults
provided by generic RS6000 definitions so that call dummies
are implemented using generic dummy frames instead.
* rs6000-nat.c (store_inferior_registers): Call exec_one_dummy_insn()
prior to changing the stack pointer via ptrace(). Also, ignore
attempts to store to undefined registers that are less than
NUM_REGS.
* rs6000-tdep.c (DUMMY_FRAME_SIZE): Change size of the dummy
frame from 436 to 448 to account for alignment padding.
(rs6000_push_arguments): Obtain actual register size instead
of assuming the register is 4 bytes long. [There's still
more work to be done to totally remove the 4 byte assumption,
however.] Make sure the stack is 16 byte aligned as required
by the PowerOpen ABI. Also, make sure that small structures
passed in registers are properly aligned within the register.
Index: rs6000-nat.c
===================================================================
RCS file: /cvs/src/src/gdb/rs6000-nat.c,v
retrieving revision 1.1.1.7
diff -u -p -r1.1.1.7 rs6000-nat.c
--- rs6000-nat.c 1999/10/12 04:37:24 1.1.1.7
+++ rs6000-nat.c 2000/02/15 20:59:58
@@ -215,6 +215,8 @@ store_inferior_registers (regno)
else if (regno < FP0_REGNUM) /* a GPR */
{
+ if (regno == SP_REGNUM)
+ exec_one_dummy_insn ();
ptrace (PT_WRITE_GPR, inferior_pid, (PTRACE_ARG3_TYPE) regno,
*(int *) ®isters[REGISTER_BYTE (regno)], 0);
}
@@ -231,6 +233,11 @@ store_inferior_registers (regno)
ptrace (PT_WRITE_GPR, inferior_pid,
(PTRACE_ARG3_TYPE) special_regs[regno - FIRST_UISA_SP_REGNUM],
*(int *) ®isters[REGISTER_BYTE (regno)], 0);
+ }
+
+ else if (regno < NUM_REGS)
+ {
+ /* Ignore it. */
}
else
Index: rs6000-tdep.c
===================================================================
RCS file: /cvs/src/src/gdb/rs6000-tdep.c,v
retrieving revision 1.1.1.9
diff -u -p -r1.1.1.9 rs6000-tdep.c
--- rs6000-tdep.c 1999/10/05 23:08:45 1.1.1.9
+++ rs6000-tdep.c 2000/02/15 21:00:00
@@ -481,6 +481,16 @@ skip_prologue (pc, fdata)
minimal_toc_loaded = 1;
continue;
+ /* move parameters from argument registers to local variable
+ registers */
+ }
+ else if ((op & 0xfc0007fe) == 0x7c000378 && /* mr(.) Rx,Ry */
+ (((op >> 21) & 31) >= 3) && /* R3 >= Ry >= R10 */
+ (((op >> 21) & 31) <= 10) &&
+ (((op >> 16) & 31) >= fdata->saved_gpr)) /* Rx: local var reg */
+ {
+ continue;
+
/* store parameters in stack */
}
else if ((op & 0xfc1f0000) == 0x90010000 || /* st rx,NUM(r1) */
@@ -559,21 +569,23 @@ skip_prologue (pc, fdata)
/*************************************************************************
- Support for creating pushind a dummy frame into the stack, and popping
+ Support for creating pushing a dummy frame into the stack, and popping
frames, etc.
*************************************************************************/
/* The total size of dummy frame is 436, which is;
- 32 gpr's - 128 bytes
- 32 fpr's - 256 "
- 7 the rest - 28 "
- and 24 extra bytes for the callee's link area. The last 24 bytes
- for the link area might not be necessary, since it will be taken
- care of by push_arguments(). */
+ 32 gpr's - 128 bytes
+ 32 fpr's - 256 bytes
+ 7 the rest - 28 bytes
+ callee's link area - 24 bytes
+ padding - 12 bytes
-#define DUMMY_FRAME_SIZE 436
+ Note that the last 24 bytes for the link area might not be necessary,
+ since it will be taken care of by push_arguments(). */
+#define DUMMY_FRAME_SIZE 448
+
#define DUMMY_FRAME_ADDR_SIZE 10
/* Make sure you initialize these in somewhere, in case gdb gives up what it
@@ -834,28 +846,39 @@ rs6000_fix_call_dummy (dummyname, pc, fu
int ii;
CORE_ADDR target_addr;
- if (find_toc_address_hook != NULL)
+ if (USE_GENERIC_DUMMY_FRAMES)
+ {
+ if (find_toc_address_hook != NULL)
+ {
+ CORE_ADDR tocvalue = (*find_toc_address_hook) (fun);
+ write_register (TOC_REGNUM, tocvalue);
+ }
+ }
+ else
{
- CORE_ADDR tocvalue;
+ if (find_toc_address_hook != NULL)
+ {
+ CORE_ADDR tocvalue;
- tocvalue = (*find_toc_address_hook) (fun);
- ii = *(int *) ((char *) dummyname + TOC_ADDR_OFFSET);
- ii = (ii & 0xffff0000) | (tocvalue >> 16);
- *(int *) ((char *) dummyname + TOC_ADDR_OFFSET) = ii;
+ tocvalue = (*find_toc_address_hook) (fun);
+ ii = *(int *) ((char *) dummyname + TOC_ADDR_OFFSET);
+ ii = (ii & 0xffff0000) | (tocvalue >> 16);
+ *(int *) ((char *) dummyname + TOC_ADDR_OFFSET) = ii;
- ii = *(int *) ((char *) dummyname + TOC_ADDR_OFFSET + 4);
- ii = (ii & 0xffff0000) | (tocvalue & 0x0000ffff);
- *(int *) ((char *) dummyname + TOC_ADDR_OFFSET + 4) = ii;
- }
+ ii = *(int *) ((char *) dummyname + TOC_ADDR_OFFSET + 4);
+ ii = (ii & 0xffff0000) | (tocvalue & 0x0000ffff);
+ *(int *) ((char *) dummyname + TOC_ADDR_OFFSET + 4) = ii;
+ }
- target_addr = fun;
- ii = *(int *) ((char *) dummyname + TARGET_ADDR_OFFSET);
- ii = (ii & 0xffff0000) | (target_addr >> 16);
- *(int *) ((char *) dummyname + TARGET_ADDR_OFFSET) = ii;
+ target_addr = fun;
+ ii = *(int *) ((char *) dummyname + TARGET_ADDR_OFFSET);
+ ii = (ii & 0xffff0000) | (target_addr >> 16);
+ *(int *) ((char *) dummyname + TARGET_ADDR_OFFSET) = ii;
- ii = *(int *) ((char *) dummyname + TARGET_ADDR_OFFSET + 4);
- ii = (ii & 0xffff0000) | (target_addr & 0x0000ffff);
- *(int *) ((char *) dummyname + TARGET_ADDR_OFFSET + 4) = ii;
+ ii = *(int *) ((char *) dummyname + TARGET_ADDR_OFFSET + 4);
+ ii = (ii & 0xffff0000) | (target_addr & 0x0000ffff);
+ *(int *) ((char *) dummyname + TARGET_ADDR_OFFSET + 4) = ii;
+ }
}
/* Pass the arguments in either registers, or in the stack. In RS6000,
@@ -928,6 +951,7 @@ rs6000_push_arguments (nargs, args, sp,
for (argno = 0, argbytes = 0; argno < nargs && ii < 8; ++ii)
{
+ int reg_size = REGISTER_RAW_SIZE (ii + 3);
arg = args[argno];
type = check_typedef (VALUE_TYPE (arg));
@@ -950,17 +974,18 @@ rs6000_push_arguments (nargs, args, sp,
++f_argno;
}
- if (len > 4)
+ if (len > reg_size)
{
/* Argument takes more than one register. */
while (argbytes < len)
{
- memset (®isters[REGISTER_BYTE (ii + 3)], 0, sizeof (int));
+ memset (®isters[REGISTER_BYTE (ii + 3)], 0, reg_size);
memcpy (®isters[REGISTER_BYTE (ii + 3)],
((char *) VALUE_CONTENTS (arg)) + argbytes,
- (len - argbytes) > 4 ? 4 : len - argbytes);
- ++ii, argbytes += 4;
+ (len - argbytes) > reg_size
+ ? reg_size : len - argbytes);
+ ++ii, argbytes += reg_size;
if (ii >= 8)
goto ran_out_of_registers_for_arguments;
@@ -970,8 +995,10 @@ rs6000_push_arguments (nargs, args, sp,
}
else
{ /* Argument can fit in one register. No problem. */
- memset (®isters[REGISTER_BYTE (ii + 3)], 0, sizeof (int));
- memcpy (®isters[REGISTER_BYTE (ii + 3)], VALUE_CONTENTS (arg), len);
+ int adj = TARGET_BYTE_ORDER == BIG_ENDIAN ? reg_size - len : 0;
+ memset (®isters[REGISTER_BYTE (ii + 3)], 0, reg_size);
+ memcpy ((char *)®isters[REGISTER_BYTE (ii + 3)] + adj,
+ VALUE_CONTENTS (arg), len);
}
++argno;
}
@@ -981,6 +1008,16 @@ ran_out_of_registers_for_arguments:
if (USE_GENERIC_DUMMY_FRAMES)
{
saved_sp = read_sp ();
+#ifndef ELF_OBJECT_FORMAT
+ /* location for 8 parameters are always reserved. */
+ sp -= 4 * 8;
+
+ /* another six words for back chain, TOC register, link register, etc. */
+ sp -= 24;
+
+ /* stack pointer must be quadword aligned */
+ sp &= -16;
+#endif
}
else
{
@@ -989,6 +1026,9 @@ ran_out_of_registers_for_arguments:
/* another six words for back chain, TOC register, link register, etc. */
sp -= 24;
+
+ /* stack pointer must be quadword aligned */
+ sp &= -16;
}
/* if there are more arguments, allocate space for them in
@@ -1013,7 +1053,7 @@ ran_out_of_registers_for_arguments:
}
/* add location required for the rest of the parameters */
- space = (space + 7) & -8;
+ space = (space + 15) & -16;
sp -= space;
/* This is another instance we need to be concerned about securing our
@@ -1083,7 +1123,7 @@ ran_out_of_registers_for_arguments:
target_store_registers (-1);
return sp;
}
-#ifdef ELF_OBJECT_FORMAT
+/* #ifdef ELF_OBJECT_FORMAT */
/* Function: ppc_push_return_address (pc, sp)
Set up the return address for the inferior function call. */
@@ -1097,7 +1137,7 @@ ppc_push_return_address (pc, sp)
return sp;
}
-#endif
+/* #endif */
/* a given return value in `regbuf' with a type `valtype', extract and copy its
value into `valbuf' */
--
Kevin Buettner
kev@primenet.com, kevinb@redhat.com