mirror of
https://sourceware.org/git/binutils-gdb.git
synced 2025-02-17 13:10:12 +08:00
AIX 4.3 changes.
This commit is contained in:
parent
70d5406d75
commit
f6077098c9
@ -1,3 +1,41 @@
|
||||
2000-02-15 Kevin Buettner <kevinb@redhat.com>
|
||||
|
||||
Changes for AIX 4.3:
|
||||
* 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.
|
||||
|
||||
2000-02-15 Jesper Skov <jskov@cygnus.co.uk>
|
||||
|
||||
Patch applied by Kevin Buettner <kevinb@redhat.com>
|
||||
|
||||
* rs6000-tdep.c (skip_prologue): skip copying of argument
|
||||
registers to local variable registers.
|
||||
|
||||
2000-02-14 Jim Kingdon <kingdon@redhat.com>
|
||||
|
||||
* elfread.c (elf_symtab_read): Revert changes by Amit S. Kale. A
|
||||
|
@ -26,4 +26,21 @@
|
||||
|
||||
#define GDB_TARGET_POWERPC
|
||||
|
||||
#undef PUSH_DUMMY_FRAME
|
||||
#define PUSH_DUMMY_FRAME generic_push_dummy_frame ()
|
||||
|
||||
#define PUSH_RETURN_ADDRESS(PC, SP) ppc_push_return_address (PC, SP)
|
||||
|
||||
/* override the standard get_saved_register function with
|
||||
one that takes account of generic CALL_DUMMY frames */
|
||||
#define GET_SAVED_REGISTER(raw_buffer, optimized, addrp, frame, regnum, lval) \
|
||||
generic_get_saved_register (raw_buffer, optimized, addrp, frame, regnum, lval)
|
||||
|
||||
#define USE_GENERIC_DUMMY_FRAMES 1
|
||||
#define CALL_DUMMY_BREAKPOINT_OFFSET (0)
|
||||
#define CALL_DUMMY_LOCATION AT_ENTRY_POINT
|
||||
#define CALL_DUMMY_ADDRESS() entry_point_address ()
|
||||
#undef CALL_DUMMY_START_OFFSET
|
||||
#define CALL_DUMMY_START_OFFSET 0
|
||||
|
||||
#endif /* TM_PPC_AIX_H */
|
||||
|
@ -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);
|
||||
}
|
||||
@ -233,6 +235,11 @@ store_inferior_registers (regno)
|
||||
*(int *) ®isters[REGISTER_BYTE (regno)], 0);
|
||||
}
|
||||
|
||||
else if (regno < NUM_REGS)
|
||||
{
|
||||
/* Ignore it. */
|
||||
}
|
||||
|
||||
else
|
||||
fprintf_unfiltered (gdb_stderr,
|
||||
"Gdb error: register no %d not implemented.\n",
|
||||
|
@ -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,20 +569,22 @@ 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
|
||||
|
||||
@ -834,28 +846,39 @@ rs6000_fix_call_dummy (dummyname, pc, fun, nargs, args, type, gcc_p)
|
||||
int ii;
|
||||
CORE_ADDR target_addr;
|
||||
|
||||
if (find_toc_address_hook != NULL)
|
||||
if (USE_GENERIC_DUMMY_FRAMES)
|
||||
{
|
||||
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;
|
||||
|
||||
ii = *(int *) ((char *) dummyname + TOC_ADDR_OFFSET + 4);
|
||||
ii = (ii & 0xffff0000) | (tocvalue & 0x0000ffff);
|
||||
*(int *) ((char *) dummyname + TOC_ADDR_OFFSET + 4) = ii;
|
||||
if (find_toc_address_hook != NULL)
|
||||
{
|
||||
CORE_ADDR tocvalue = (*find_toc_address_hook) (fun);
|
||||
write_register (TOC_REGNUM, tocvalue);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (find_toc_address_hook != NULL)
|
||||
{
|
||||
CORE_ADDR tocvalue;
|
||||
|
||||
target_addr = fun;
|
||||
ii = *(int *) ((char *) dummyname + TARGET_ADDR_OFFSET);
|
||||
ii = (ii & 0xffff0000) | (target_addr >> 16);
|
||||
*(int *) ((char *) dummyname + TARGET_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 + TARGET_ADDR_OFFSET + 4);
|
||||
ii = (ii & 0xffff0000) | (target_addr & 0x0000ffff);
|
||||
*(int *) ((char *) dummyname + TARGET_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;
|
||||
|
||||
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, struct_return, struct_addr)
|
||||
|
||||
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, struct_return, struct_addr)
|
||||
++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, struct_return, struct_addr)
|
||||
}
|
||||
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 @@ rs6000_push_arguments (nargs, args, sp, struct_return, struct_addr)
|
||||
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 @@ rs6000_push_arguments (nargs, args, sp, struct_return, struct_addr)
|
||||
|
||||
/* 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 @@ rs6000_push_arguments (nargs, args, sp, struct_return, struct_addr)
|
||||
}
|
||||
|
||||
/* 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 @@ rs6000_push_arguments (nargs, args, sp, struct_return, struct_addr)
|
||||
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' */
|
||||
|
Loading…
Reference in New Issue
Block a user