From f6077098c92bc7d5a4426324319c3a84e57a93a7 Mon Sep 17 00:00:00 2001 From: Kevin Buettner Date: Tue, 15 Feb 2000 21:17:04 +0000 Subject: [PATCH] AIX 4.3 changes. --- gdb/ChangeLog | 38 +++++++++++ gdb/config/powerpc/tm-ppc-aix.h | 17 +++++ gdb/rs6000-nat.c | 7 +++ gdb/rs6000-tdep.c | 108 ++++++++++++++++++++++---------- 4 files changed, 136 insertions(+), 34 deletions(-) diff --git a/gdb/ChangeLog b/gdb/ChangeLog index f45561d688b..7f74a0cfeb7 100644 --- a/gdb/ChangeLog +++ b/gdb/ChangeLog @@ -1,3 +1,41 @@ +2000-02-15 Kevin Buettner + + 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 + + Patch applied by Kevin Buettner + + * rs6000-tdep.c (skip_prologue): skip copying of argument + registers to local variable registers. + 2000-02-14 Jim Kingdon * elfread.c (elf_symtab_read): Revert changes by Amit S. Kale. A diff --git a/gdb/config/powerpc/tm-ppc-aix.h b/gdb/config/powerpc/tm-ppc-aix.h index d3afbd5d0a7..ae55e075780 100644 --- a/gdb/config/powerpc/tm-ppc-aix.h +++ b/gdb/config/powerpc/tm-ppc-aix.h @@ -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 */ diff --git a/gdb/rs6000-nat.c b/gdb/rs6000-nat.c index d109f3319e8..63fadcf9616 100644 --- a/gdb/rs6000-nat.c +++ b/gdb/rs6000-nat.c @@ -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", diff --git a/gdb/rs6000-tdep.c b/gdb/rs6000-tdep.c index fa483b237f4..5b6dcad0848 100644 --- a/gdb/rs6000-tdep.c +++ b/gdb/rs6000-tdep.c @@ -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) + { + 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, 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 @@ 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' */ -- 2.30.2