X-Git-Url: http://drtracing.org/?a=blobdiff_plain;f=gdb%2Frs6000-tdep.c;h=5eef8959115048aa8420fc7e4586b1a99e5b3444;hb=f3205b34a11f36b6c6e8f9b81e08b7b4818478e8;hp=ca817f8b49ded2aad5ef7fad50e456d6fc61b744;hpb=e9582e713d95edf9e00f25a3ef2eb3520448b847;p=deliverable%2Fbinutils-gdb.git diff --git a/gdb/rs6000-tdep.c b/gdb/rs6000-tdep.c index ca817f8b49..5eef895911 100644 --- a/gdb/rs6000-tdep.c +++ b/gdb/rs6000-tdep.c @@ -1,7 +1,8 @@ /* Target-dependent code for GDB, the GNU debugger. - Copyright 1986, 1987, 1989, 1991, 1992, 1993, 1994, 1995, 1996, 1997, - 1998, 1999, 2000, 2001, 2002, 2003 - Free Software Foundation, Inc. + + Copyright 1986, 1987, 1989, 1991, 1992, 1993, 1994, 1995, 1996, + 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004 Free Software + Foundation, Inc. This file is part of GDB. @@ -27,7 +28,6 @@ #include "target.h" #include "gdbcore.h" #include "gdbcmd.h" -#include "symfile.h" #include "objfiles.h" #include "arch-utils.h" #include "regcache.h" @@ -48,6 +48,7 @@ #include "ppc-tdep.h" #include "gdb_assert.h" +#include "dis-asm.h" /* If the kernel has to deliver a signal, it pushes a sigcontext structure on the stack and then calls the signal handler, passing @@ -137,6 +138,18 @@ altivec_register_p (int regno) return (regno >= tdep->ppc_vr0_regnum && regno <= tdep->ppc_vrsave_regnum); } +/* Use the architectures FP registers? */ +int +ppc_floating_point_unit_p (struct gdbarch *gdbarch) +{ + const struct bfd_arch_info *info = gdbarch_bfd_arch_info (gdbarch); + if (info->arch == bfd_arch_powerpc) + return (info->mach != bfd_mach_ppc_e500); + if (info->arch == bfd_arch_rs6000) + return 1; + return 0; +} + /* Read a LEN-byte address from debugged memory address MEMADDR. */ static CORE_ADDR @@ -218,6 +231,16 @@ rs6000_saved_pc_after_call (struct frame_info *fi) return read_register (gdbarch_tdep (current_gdbarch)->ppc_lr_regnum); } +/* Get the ith function argument for the current function. */ +static CORE_ADDR +rs6000_fetch_pointer_argument (struct frame_info *frame, int argi, + struct type *type) +{ + CORE_ADDR addr; + get_frame_register (frame, 3 + argi, &addr); + return addr; +} + /* Calculate the destination of a branch/jump. Return -1 if not a branch. */ static CORE_ADDR @@ -293,14 +316,11 @@ branch_dest (int opcode, int instr, CORE_ADDR pc, CORE_ADDR safety) /* Sequence of bytes for breakpoint instruction. */ -#define BIG_BREAKPOINT { 0x7d, 0x82, 0x10, 0x08 } -#define LITTLE_BREAKPOINT { 0x08, 0x10, 0x82, 0x7d } - const static unsigned char * rs6000_breakpoint_from_pc (CORE_ADDR *bp_addr, int *bp_size) { - static unsigned char big_breakpoint[] = BIG_BREAKPOINT; - static unsigned char little_breakpoint[] = LITTLE_BREAKPOINT; + static unsigned char big_breakpoint[] = { 0x7d, 0x82, 0x10, 0x08 }; + static unsigned char little_breakpoint[] = { 0x08, 0x10, 0x82, 0x7d }; *bp_size = 4; if (TARGET_BYTE_ORDER == BFD_ENDIAN_BIG) return big_breakpoint; @@ -405,6 +425,10 @@ static int max_skip_non_prologue_insns = 10; the line data in the symbol table. If successful, a better guess on where the prologue ends is returned, otherwise the previous value of lim_pc is returned. */ + +/* FIXME: cagney/2004-02-14: This function and logic have largely been + superseded by skip_prologue_using_sal. */ + static CORE_ADDR refine_prologue_limit (CORE_ADDR pc, CORE_ADDR lim_pc) { @@ -517,13 +541,13 @@ skip_prologue (CORE_ADDR pc, CORE_ADDR lim_pc, struct rs6000_framedata *fdata) if ((op & 0xfc1fffff) == 0x7c0802a6) { /* mflr Rx */ - lr_reg = (op & 0x03e00000) | 0x90010000; + lr_reg = (op & 0x03e00000); continue; } else if ((op & 0xfc1fffff) == 0x7c000026) { /* mfcr Rx */ - cr_reg = (op & 0x03e00000) | 0x90010000; + cr_reg = (op & 0x03e00000); continue; } @@ -549,7 +573,7 @@ skip_prologue (CORE_ADDR pc, CORE_ADDR lim_pc, struct rs6000_framedata *fdata) { fdata->saved_gpr = reg; if ((op & 0xfc1f0003) == 0xf8010000) - op = (op >> 1) << 1; + op &= ~3UL; fdata->gpr_offset = SIGNED_SHORT (op) + offset; } continue; @@ -581,20 +605,42 @@ skip_prologue (CORE_ADDR pc, CORE_ADDR lim_pc, struct rs6000_framedata *fdata) continue; } - else if (lr_reg != -1 && (op & 0xffff0000) == lr_reg) - { /* st Rx,NUM(r1) - where Rx == lr */ - fdata->lr_offset = SIGNED_SHORT (op) + offset; + else if (lr_reg != -1 && + /* std Rx, NUM(r1) || stdu Rx, NUM(r1) */ + (((op & 0xffff0000) == (lr_reg | 0xf8010000)) || + /* stw Rx, NUM(r1) */ + ((op & 0xffff0000) == (lr_reg | 0x90010000)) || + /* stwu Rx, NUM(r1) */ + ((op & 0xffff0000) == (lr_reg | 0x94010000)))) + { /* where Rx == lr */ + fdata->lr_offset = offset; fdata->nosavedpc = 0; lr_reg = 0; + if ((op & 0xfc000003) == 0xf8000000 || /* std */ + (op & 0xfc000000) == 0x90000000) /* stw */ + { + /* Does not update r1, so add displacement to lr_offset. */ + fdata->lr_offset += SIGNED_SHORT (op); + } continue; } - else if (cr_reg != -1 && (op & 0xffff0000) == cr_reg) - { /* st Rx,NUM(r1) - where Rx == cr */ - fdata->cr_offset = SIGNED_SHORT (op) + offset; + else if (cr_reg != -1 && + /* std Rx, NUM(r1) || stdu Rx, NUM(r1) */ + (((op & 0xffff0000) == (cr_reg | 0xf8010000)) || + /* stw Rx, NUM(r1) */ + ((op & 0xffff0000) == (cr_reg | 0x90010000)) || + /* stwu Rx, NUM(r1) */ + ((op & 0xffff0000) == (cr_reg | 0x94010000)))) + { /* where Rx == cr */ + fdata->cr_offset = offset; cr_reg = 0; + if ((op & 0xfc000003) == 0xf8000000 || + (op & 0xfc000000) == 0x90000000) + { + /* Does not update r1, so add displacement to cr_offset. */ + fdata->cr_offset += SIGNED_SHORT (op); + } continue; } @@ -638,30 +684,41 @@ skip_prologue (CORE_ADDR pc, CORE_ADDR lim_pc, struct rs6000_framedata *fdata) this branch */ continue; - /* update stack pointer */ } - else if ((op & 0xffff0000) == 0x94210000 || /* stu r1,NUM(r1) */ - (op & 0xffff0003) == 0xf8210001) /* stdu r1,NUM(r1) */ - { + /* update stack pointer */ + else if ((op & 0xfc1f0000) == 0x94010000) + { /* stu rX,NUM(r1) || stwu rX,NUM(r1) */ fdata->frameless = 0; - if ((op & 0xffff0003) == 0xf8210001) - op = (op >> 1) << 1; fdata->offset = SIGNED_SHORT (op); offset = fdata->offset; continue; - } - else if (op == 0x7c21016e) - { /* stwux 1,1,0 */ + else if ((op & 0xfc1f016a) == 0x7c01016e) + { /* stwux rX,r1,rY */ + /* no way to figure out what r1 is going to be */ fdata->frameless = 0; offset = fdata->offset; continue; - - /* Load up minimal toc pointer */ } - else if ((op >> 22) == 0x20f + else if ((op & 0xfc1f0003) == 0xf8010001) + { /* stdu rX,NUM(r1) */ + fdata->frameless = 0; + fdata->offset = SIGNED_SHORT (op & ~3UL); + offset = fdata->offset; + continue; + } + else if ((op & 0xfc1f016a) == 0x7c01016a) + { /* stdux rX,r1,rY */ + /* no way to figure out what r1 is going to be */ + fdata->frameless = 0; + offset = fdata->offset; + continue; + } + /* Load up minimal toc pointer */ + else if (((op >> 22) == 0x20f || /* l r31,... or l r30,... */ + (op >> 22) == 0x3af) /* ld r31,... or ld r30,... */ && !minimal_toc_loaded) - { /* l r31,... or l r30,... */ + { minimal_toc_loaded = 1; continue; @@ -932,7 +989,8 @@ skip_prologue (CORE_ADDR pc, CORE_ADDR lim_pc, struct rs6000_framedata *fdata) initializer function as well. */ tmp = find_pc_misc_function (pc); - if (tmp >= 0 && STREQ (misc_function_vector[tmp].name, main_name ())) + if (tmp >= 0 + && strcmp (misc_function_vector[tmp].name, main_name ()) == 0) return pc + 8; } } @@ -972,13 +1030,13 @@ rs6000_pop_frame (void) } /* Make sure that all registers are valid. */ - deprecated_read_register_bytes (0, NULL, REGISTER_BYTES); + deprecated_read_register_bytes (0, NULL, DEPRECATED_REGISTER_BYTES); /* Figure out previous %pc value. If the function is frameless, it is still in the link register, otherwise walk the frames and retrieve the saved %pc value in the previous frame. */ - addr = get_pc_function_start (get_frame_pc (frame)); + addr = get_frame_func (frame); (void) skip_prologue (addr, get_frame_pc (frame), &fdata); wordsize = gdbarch_tdep (current_gdbarch)->wordsize; @@ -1001,7 +1059,7 @@ rs6000_pop_frame (void) addr = prev_sp + fdata.gpr_offset; for (ii = fdata.saved_gpr; ii <= 31; ++ii) { - read_memory (addr, &deprecated_registers[REGISTER_BYTE (ii)], + read_memory (addr, &deprecated_registers[DEPRECATED_REGISTER_BYTE (ii)], wordsize); addr += wordsize; } @@ -1012,7 +1070,7 @@ rs6000_pop_frame (void) addr = prev_sp + fdata.fpr_offset; for (ii = fdata.saved_fpr; ii <= 31; ++ii) { - read_memory (addr, &deprecated_registers[REGISTER_BYTE (ii + FP0_REGNUM)], 8); + read_memory (addr, &deprecated_registers[DEPRECATED_REGISTER_BYTE (ii + FP0_REGNUM)], 8); addr += 8; } } @@ -1022,25 +1080,6 @@ rs6000_pop_frame (void) flush_cached_frames (); } -/* Fixup the call sequence of a dummy function, with the real function - address. Its arguments will be passed by gdb. */ - -static void -rs6000_fix_call_dummy (char *dummyname, CORE_ADDR pc, CORE_ADDR fun, - int nargs, struct value **args, struct type *type, - int gcc_p) -{ - int ii; - CORE_ADDR target_addr; - - if (rs6000_find_toc_address_hook != NULL) - { - CORE_ADDR tocvalue = (*rs6000_find_toc_address_hook) (fun); - write_register (gdbarch_tdep (current_gdbarch)->ppc_toc_regnum, - tocvalue); - } -} - /* All the ABI's require 16 byte alignment. */ static CORE_ADDR rs6000_frame_align (struct gdbarch *gdbarch, CORE_ADDR addr) @@ -1065,9 +1104,12 @@ rs6000_frame_align (struct gdbarch *gdbarch, CORE_ADDR addr) starting from r4. */ static CORE_ADDR -rs6000_push_arguments (int nargs, struct value **args, CORE_ADDR sp, - int struct_return, CORE_ADDR struct_addr) +rs6000_push_dummy_call (struct gdbarch *gdbarch, CORE_ADDR func_addr, + struct regcache *regcache, CORE_ADDR bp_addr, + int nargs, struct value **args, CORE_ADDR sp, + int struct_return, CORE_ADDR struct_addr) { + struct gdbarch_tdep *tdep = gdbarch_tdep (current_gdbarch); int ii; int len = 0; int argno; /* current argument number */ @@ -1082,14 +1124,19 @@ rs6000_push_arguments (int nargs, struct value **args, CORE_ADDR sp, CORE_ADDR saved_sp; /* The first eight words of ther arguments are passed in registers. - Copy them appropriately. - - If the function is returning a `struct', then the first word (which - will be passed in r3) is used for struct return address. In that - case we should advance one word and start from r4 register to copy - parameters. */ - - ii = struct_return ? 1 : 0; + Copy them appropriately. */ + ii = 0; + + /* If the function is returning a `struct', then the first word + (which will be passed in r3) is used for struct return address. + In that case we should advance one word and start from r4 + register to copy parameters. */ + if (struct_return) + { + regcache_raw_write_unsigned (regcache, tdep->ppc_gp0_regnum + 3, + struct_addr); + ii++; + } /* effectively indirect call... gcc does... @@ -1112,7 +1159,7 @@ rs6000_push_arguments (int nargs, struct value **args, CORE_ADDR sp, for (argno = 0, argbytes = 0; argno < nargs && ii < 8; ++ii) { - int reg_size = REGISTER_RAW_SIZE (ii + 3); + int reg_size = DEPRECATED_REGISTER_RAW_SIZE (ii + 3); arg = args[argno]; type = check_typedef (VALUE_TYPE (arg)); @@ -1129,7 +1176,7 @@ rs6000_push_arguments (int nargs, struct value **args, CORE_ADDR sp, printf_unfiltered ( "Fatal Error: a floating point parameter #%d with a size > 8 is found!\n", argno); - memcpy (&deprecated_registers[REGISTER_BYTE (FP0_REGNUM + 1 + f_argno)], + memcpy (&deprecated_registers[DEPRECATED_REGISTER_BYTE (FP0_REGNUM + 1 + f_argno)], VALUE_CONTENTS (arg), len); ++f_argno; @@ -1141,9 +1188,9 @@ rs6000_push_arguments (int nargs, struct value **args, CORE_ADDR sp, /* Argument takes more than one register. */ while (argbytes < len) { - memset (&deprecated_registers[REGISTER_BYTE (ii + 3)], 0, + memset (&deprecated_registers[DEPRECATED_REGISTER_BYTE (ii + 3)], 0, reg_size); - memcpy (&deprecated_registers[REGISTER_BYTE (ii + 3)], + memcpy (&deprecated_registers[DEPRECATED_REGISTER_BYTE (ii + 3)], ((char *) VALUE_CONTENTS (arg)) + argbytes, (len - argbytes) > reg_size ? reg_size : len - argbytes); @@ -1159,8 +1206,8 @@ rs6000_push_arguments (int nargs, struct value **args, CORE_ADDR sp, { /* Argument can fit in one register. No problem. */ int adj = TARGET_BYTE_ORDER == BFD_ENDIAN_BIG ? reg_size - len : 0; - memset (&deprecated_registers[REGISTER_BYTE (ii + 3)], 0, reg_size); - memcpy ((char *)&deprecated_registers[REGISTER_BYTE (ii + 3)] + adj, + memset (&deprecated_registers[DEPRECATED_REGISTER_BYTE (ii + 3)], 0, reg_size); + memcpy ((char *)&deprecated_registers[DEPRECATED_REGISTER_BYTE (ii + 3)] + adj, VALUE_CONTENTS (arg), len); } ++argno; @@ -1207,10 +1254,10 @@ ran_out_of_registers_for_arguments: /* This is another instance we need to be concerned about securing our stack space. If we write anything underneath %sp (r1), we might conflict with the kernel who thinks he is free - to use this area. So, update %sp first before doing anything + to use this area. So, update %sp first before doing anything else. */ - write_register (SP_REGNUM, sp); + regcache_raw_write_signed (regcache, SP_REGNUM, sp); /* If the last argument copied into the registers didn't fit there completely, push the rest of it into stack. */ @@ -1242,7 +1289,7 @@ ran_out_of_registers_for_arguments: printf_unfiltered ( "Fatal Error: a floating point parameter #%d with a size > 8 is found!\n", argno); - memcpy (&deprecated_registers[REGISTER_BYTE (FP0_REGNUM + 1 + f_argno)], + memcpy (&deprecated_registers[DEPRECATED_REGISTER_BYTE (FP0_REGNUM + 1 + f_argno)], VALUE_CONTENTS (arg), len); ++f_argno; @@ -1252,86 +1299,45 @@ ran_out_of_registers_for_arguments: ii += ((len + 3) & -4) / 4; } } - else - /* Secure stack areas first, before doing anything else. */ - write_register (SP_REGNUM, sp); - /* set back chain properly */ - store_address (tmp_buffer, 4, saved_sp); + /* Set the stack pointer. According to the ABI, the SP is meant to + be set _before_ the corresponding stack space is used. On AIX, + this even applies when the target has been completely stopped! + Not doing this can lead to conflicts with the kernel which thinks + that it still has control over this not-yet-allocated stack + region. */ + regcache_raw_write_signed (regcache, SP_REGNUM, sp); + + /* Set back chain properly. */ + store_unsigned_integer (tmp_buffer, 4, saved_sp); write_memory (sp, tmp_buffer, 4); - target_store_registers (-1); - return sp; -} + /* Point the inferior function call's return address at the dummy's + breakpoint. */ + regcache_raw_write_signed (regcache, tdep->ppc_lr_regnum, bp_addr); -/* Function: ppc_push_return_address (pc, sp) - Set up the return address for the inferior function call. */ + /* Set the TOC register, get the value from the objfile reader + which, in turn, gets it from the VMAP table. */ + if (rs6000_find_toc_address_hook != NULL) + { + CORE_ADDR tocvalue = (*rs6000_find_toc_address_hook) (func_addr); + regcache_raw_write_signed (regcache, tdep->ppc_toc_regnum, tocvalue); + } -static CORE_ADDR -ppc_push_return_address (CORE_ADDR pc, CORE_ADDR sp) -{ - write_register (gdbarch_tdep (current_gdbarch)->ppc_lr_regnum, - CALL_DUMMY_ADDRESS ()); + target_store_registers (-1); return sp; } -/* Extract a function return value of type TYPE from raw register array - REGBUF, and copy that return value into VALBUF in virtual format. */ -static void -e500_extract_return_value (struct type *valtype, struct regcache *regbuf, void *valbuf) -{ - int offset = 0; - int vallen = TYPE_LENGTH (valtype); - struct gdbarch_tdep *tdep = gdbarch_tdep (current_gdbarch); +/* PowerOpen always puts structures in memory. Vectors, which were + added later, do get returned in a register though. */ - if (TYPE_CODE (valtype) == TYPE_CODE_ARRAY - && vallen == 8 - && TYPE_VECTOR (valtype)) - { - regcache_raw_read (regbuf, tdep->ppc_ev0_regnum + 3, valbuf); - } - else - { - /* Return value is copied starting from r3. Note that r3 for us - is a pseudo register. */ - int offset = 0; - int return_regnum = tdep->ppc_gp0_regnum + 3; - int reg_size = REGISTER_RAW_SIZE (return_regnum); - int reg_part_size; - char *val_buffer; - int copied = 0; - int i = 0; - - /* Compute where we will start storing the value from. */ - if (TARGET_BYTE_ORDER == BFD_ENDIAN_BIG) - { - if (vallen <= reg_size) - offset = reg_size - vallen; - else - offset = reg_size + (reg_size - vallen); - } - - /* How big does the local buffer need to be? */ - if (vallen <= reg_size) - val_buffer = alloca (reg_size); - else - val_buffer = alloca (vallen); - - /* Read all we need into our private buffer. We copy it in - chunks that are as long as one register, never shorter, even - if the value is smaller than the register. */ - while (copied < vallen) - { - reg_part_size = REGISTER_RAW_SIZE (return_regnum + i); - /* It is a pseudo/cooked register. */ - regcache_cooked_read (regbuf, return_regnum + i, - val_buffer + copied); - copied += reg_part_size; - i++; - } - /* Put the stuff in the return buffer. */ - memcpy (valbuf, val_buffer + offset, vallen); - } +static int +rs6000_use_struct_convention (int gcc_p, struct type *value_type) +{ + if ((TYPE_LENGTH (value_type) == 16 || TYPE_LENGTH (value_type) == 8) + && TYPE_VECTOR (value_type)) + return 0; + return 1; } static void @@ -1351,11 +1357,11 @@ rs6000_extract_return_value (struct type *valtype, char *regbuf, char *valbuf) if (TYPE_LENGTH (valtype) > 4) /* this is a double */ memcpy (valbuf, - ®buf[REGISTER_BYTE (FP0_REGNUM + 1)], + ®buf[DEPRECATED_REGISTER_BYTE (FP0_REGNUM + 1)], TYPE_LENGTH (valtype)); else { /* float */ - memcpy (&dd, ®buf[REGISTER_BYTE (FP0_REGNUM + 1)], 8); + memcpy (&dd, ®buf[DEPRECATED_REGISTER_BYTE (FP0_REGNUM + 1)], 8); ff = (float) dd; memcpy (valbuf, &ff, sizeof (float)); } @@ -1364,18 +1370,18 @@ rs6000_extract_return_value (struct type *valtype, char *regbuf, char *valbuf) && TYPE_LENGTH (valtype) == 16 && TYPE_VECTOR (valtype)) { - memcpy (valbuf, regbuf + REGISTER_BYTE (tdep->ppc_vr0_regnum + 2), + memcpy (valbuf, regbuf + DEPRECATED_REGISTER_BYTE (tdep->ppc_vr0_regnum + 2), TYPE_LENGTH (valtype)); } else { /* return value is copied starting from r3. */ if (TARGET_BYTE_ORDER == BFD_ENDIAN_BIG - && TYPE_LENGTH (valtype) < REGISTER_RAW_SIZE (3)) - offset = REGISTER_RAW_SIZE (3) - TYPE_LENGTH (valtype); + && TYPE_LENGTH (valtype) < DEPRECATED_REGISTER_RAW_SIZE (3)) + offset = DEPRECATED_REGISTER_RAW_SIZE (3) - TYPE_LENGTH (valtype); memcpy (valbuf, - regbuf + REGISTER_BYTE (3) + offset, + regbuf + DEPRECATED_REGISTER_BYTE (3) + offset, TYPE_LENGTH (valtype)); } } @@ -1425,7 +1431,7 @@ rs6000_in_solib_return_trampoline (CORE_ADDR pc, char *name) CORE_ADDR rs6000_skip_trampoline_code (CORE_ADDR pc) { - register unsigned int ii, op; + unsigned int ii, op; int rel; CORE_ADDR solib_target_pc; struct minimal_symbol *msymbol; @@ -1487,7 +1493,7 @@ rs6000_frameless_function_invocation (struct frame_info *fi) && !(get_frame_type (get_next_frame (fi)) == SIGTRAMP_FRAME)) return 0; - func_start = get_pc_function_start (get_frame_pc (fi)); + func_start = get_frame_func (fi); /* If we failed to find the start of the function, it is a mistake to inspect the instructions. */ @@ -1528,7 +1534,7 @@ rs6000_frame_saved_pc (struct frame_info *fi) return deprecated_read_register_dummy (get_frame_pc (fi), get_frame_base (fi), PC_REGNUM); - func_start = get_pc_function_start (get_frame_pc (fi)); + func_start = get_frame_func (fi); /* If we failed to find the start of the function, it is a mistake to inspect the instructions. */ @@ -1554,14 +1560,16 @@ rs6000_frame_saved_pc (struct frame_info *fi) return lr; } else - return read_memory_addr (FRAME_CHAIN (fi) + tdep->lr_frame_offset, + return read_memory_addr (DEPRECATED_FRAME_CHAIN (fi) + + tdep->lr_frame_offset, wordsize); } if (fdata.lr_offset == 0) return read_register (gdbarch_tdep (current_gdbarch)->ppc_lr_regnum); - return read_memory_addr (FRAME_CHAIN (fi) + fdata.lr_offset, wordsize); + return read_memory_addr (DEPRECATED_FRAME_CHAIN (fi) + fdata.lr_offset, + wordsize); } /* If saved registers of frame FI are not known yet, read and cache them. @@ -1576,14 +1584,13 @@ frame_get_saved_regs (struct frame_info *fi, struct rs6000_framedata *fdatap) struct gdbarch_tdep * tdep = gdbarch_tdep (current_gdbarch); int wordsize = tdep->wordsize; - if (get_frame_saved_regs (fi)) + if (deprecated_get_frame_saved_regs (fi)) return; if (fdatap == NULL) { fdatap = &work_fdata; - (void) skip_prologue (get_pc_function_start (get_frame_pc (fi)), - get_frame_pc (fi), fdatap); + (void) skip_prologue (get_frame_func (fi), get_frame_pc (fi), fdatap); } frame_saved_regs_zalloc (fi); @@ -1608,7 +1615,7 @@ frame_get_saved_regs (struct frame_info *fi, struct rs6000_framedata *fdatap) ->frame pointed to the outer-most address of the frame. In the mean time, the address of the prev frame is used as the base address of this frame. */ - frame_addr = FRAME_CHAIN (fi); + frame_addr = DEPRECATED_FRAME_CHAIN (fi); /* if != -1, fdatap->saved_fpr is the smallest number of saved_fpr. All fpr's from saved_fpr to fp31 are saved. */ @@ -1619,7 +1626,7 @@ frame_get_saved_regs (struct frame_info *fi, struct rs6000_framedata *fdatap) CORE_ADDR fpr_addr = frame_addr + fdatap->fpr_offset; for (i = fdatap->saved_fpr; i < 32; i++) { - get_frame_saved_regs (fi)[FP0_REGNUM + i] = fpr_addr; + deprecated_get_frame_saved_regs (fi)[FP0_REGNUM + i] = fpr_addr; fpr_addr += 8; } } @@ -1633,7 +1640,7 @@ frame_get_saved_regs (struct frame_info *fi, struct rs6000_framedata *fdatap) CORE_ADDR gpr_addr = frame_addr + fdatap->gpr_offset; for (i = fdatap->saved_gpr; i < 32; i++) { - get_frame_saved_regs (fi)[i] = gpr_addr; + deprecated_get_frame_saved_regs (fi)[tdep->ppc_gp0_regnum + i] = gpr_addr; gpr_addr += wordsize; } } @@ -1648,8 +1655,8 @@ frame_get_saved_regs (struct frame_info *fi, struct rs6000_framedata *fdatap) CORE_ADDR vr_addr = frame_addr + fdatap->vr_offset; for (i = fdatap->saved_vr; i < 32; i++) { - get_frame_saved_regs (fi)[tdep->ppc_vr0_regnum + i] = vr_addr; - vr_addr += REGISTER_RAW_SIZE (tdep->ppc_vr0_regnum); + deprecated_get_frame_saved_regs (fi)[tdep->ppc_vr0_regnum + i] = vr_addr; + vr_addr += DEPRECATED_REGISTER_RAW_SIZE (tdep->ppc_vr0_regnum); } } } @@ -1664,9 +1671,9 @@ frame_get_saved_regs (struct frame_info *fi, struct rs6000_framedata *fdatap) CORE_ADDR ev_addr = frame_addr + fdatap->ev_offset; for (i = fdatap->saved_ev; i < 32; i++) { - get_frame_saved_regs (fi)[tdep->ppc_ev0_regnum + i] = ev_addr; - get_frame_saved_regs (fi)[tdep->ppc_gp0_regnum + i] = ev_addr + 4; - ev_addr += REGISTER_RAW_SIZE (tdep->ppc_ev0_regnum); + deprecated_get_frame_saved_regs (fi)[tdep->ppc_ev0_regnum + i] = ev_addr; + deprecated_get_frame_saved_regs (fi)[tdep->ppc_gp0_regnum + i] = ev_addr + 4; + ev_addr += DEPRECATED_REGISTER_RAW_SIZE (tdep->ppc_ev0_regnum); } } } @@ -1674,17 +1681,17 @@ frame_get_saved_regs (struct frame_info *fi, struct rs6000_framedata *fdatap) /* If != 0, fdatap->cr_offset is the offset from the frame that holds the CR. */ if (fdatap->cr_offset != 0) - get_frame_saved_regs (fi)[tdep->ppc_cr_regnum] = frame_addr + fdatap->cr_offset; + deprecated_get_frame_saved_regs (fi)[tdep->ppc_cr_regnum] = frame_addr + fdatap->cr_offset; /* If != 0, fdatap->lr_offset is the offset from the frame that holds the LR. */ if (fdatap->lr_offset != 0) - get_frame_saved_regs (fi)[tdep->ppc_lr_regnum] = frame_addr + fdatap->lr_offset; + deprecated_get_frame_saved_regs (fi)[tdep->ppc_lr_regnum] = frame_addr + fdatap->lr_offset; /* If != 0, fdatap->vrsave_offset is the offset from the frame that holds the VRSAVE. */ if (fdatap->vrsave_offset != 0) - get_frame_saved_regs (fi)[tdep->ppc_vrsave_regnum] = frame_addr + fdatap->vrsave_offset; + deprecated_get_frame_saved_regs (fi)[tdep->ppc_vrsave_regnum] = frame_addr + fdatap->vrsave_offset; } /* Return the address of a frame. This is the inital %sp value when the frame @@ -1706,13 +1713,12 @@ frame_initial_stack_address (struct frame_info *fi) /* Find out if this function is using an alloca register. */ - (void) skip_prologue (get_pc_function_start (get_frame_pc (fi)), - get_frame_pc (fi), &fdata); + (void) skip_prologue (get_frame_func (fi), get_frame_pc (fi), &fdata); /* If saved registers of this frame are not known yet, read and cache them. */ - if (!get_frame_saved_regs (fi)) + if (!deprecated_get_frame_saved_regs (fi)) frame_get_saved_regs (fi, &fdata); /* If no alloca register used, then fi->frame is the value of the %sp for @@ -1727,12 +1733,12 @@ frame_initial_stack_address (struct frame_info *fi) /* There is an alloca register, use its value, in the current frame, as the initial stack pointer. */ { - char *tmpbuf = alloca (MAX_REGISTER_RAW_SIZE); + char tmpbuf[MAX_REGISTER_SIZE]; if (frame_register_read (fi, fdata.alloca_reg, tmpbuf)) { get_frame_extra_info (fi)->initial_sp = extract_unsigned_integer (tmpbuf, - REGISTER_RAW_SIZE (fdata.alloca_reg)); + DEPRECATED_REGISTER_RAW_SIZE (fdata.alloca_reg)); } else /* NOTE: cagney/2002-04-17: At present the only time @@ -1746,8 +1752,8 @@ frame_initial_stack_address (struct frame_info *fi) /* Describe the pointer in each stack frame to the previous stack frame (its caller). */ -/* FRAME_CHAIN takes a frame's nominal address - and produces the frame's chain-pointer. */ +/* DEPRECATED_FRAME_CHAIN takes a frame's nominal address and produces + the frame's chain-pointer. */ /* In the case of the RS/6000, the frame's nominal address is the address of a 4-byte word containing the calling frame's address. */ @@ -1765,7 +1771,7 @@ rs6000_frame_chain (struct frame_info *thisframe) frame. */ return read_memory_addr (get_frame_base (thisframe), wordsize); - if (inside_entry_file (get_frame_pc (thisframe)) + if (deprecated_inside_entry_file (get_frame_pc (thisframe)) || get_frame_pc (thisframe) == entry_point_address ()) return 0; @@ -1774,7 +1780,8 @@ rs6000_frame_chain (struct frame_info *thisframe) wordsize); else if (get_next_frame (thisframe) != NULL && (get_frame_type (get_next_frame (thisframe)) == SIGTRAMP_FRAME) - && FRAMELESS_FUNCTION_INVOCATION (thisframe)) + && (DEPRECATED_FRAMELESS_FUNCTION_INVOCATION_P () + && DEPRECATED_FRAMELESS_FUNCTION_INVOCATION (thisframe))) /* A frameless function interrupted by a signal did not change the frame pointer. */ fp = get_frame_base (thisframe); @@ -1842,6 +1849,10 @@ rs6000_register_virtual_type (int n) int size = regsize (reg, tdep->wordsize); switch (size) { + case 0: + return builtin_type_int0; + case 4: + return builtin_type_int32; case 8: if (tdep->ppc_ev0_regnum <= n && n <= tdep->ppc_ev31_regnum) return builtin_type_vec64; @@ -1852,8 +1863,8 @@ rs6000_register_virtual_type (int n) return builtin_type_vec128; break; default: - return builtin_type_int32; - break; + internal_error (__FILE__, __LINE__, "Register %d size %d unknown", + n, size); } } } @@ -1878,13 +1889,13 @@ static void rs6000_register_convert_to_virtual (int n, struct type *type, char *from, char *to) { - if (TYPE_LENGTH (type) != REGISTER_RAW_SIZE (n)) + if (TYPE_LENGTH (type) != DEPRECATED_REGISTER_RAW_SIZE (n)) { - double val = extract_floating (from, REGISTER_RAW_SIZE (n)); - store_floating (to, TYPE_LENGTH (type), val); + double val = deprecated_extract_floating (from, DEPRECATED_REGISTER_RAW_SIZE (n)); + deprecated_store_floating (to, TYPE_LENGTH (type), val); } else - memcpy (to, from, REGISTER_RAW_SIZE (n)); + memcpy (to, from, DEPRECATED_REGISTER_RAW_SIZE (n)); } /* Convert data from virtual format with type TYPE in buffer FROM @@ -1892,15 +1903,15 @@ rs6000_register_convert_to_virtual (int n, struct type *type, static void rs6000_register_convert_to_raw (struct type *type, int n, - char *from, char *to) + const char *from, char *to) { - if (TYPE_LENGTH (type) != REGISTER_RAW_SIZE (n)) + if (TYPE_LENGTH (type) != DEPRECATED_REGISTER_RAW_SIZE (n)) { - double val = extract_floating (from, TYPE_LENGTH (type)); - store_floating (to, REGISTER_RAW_SIZE (n), val); + double val = deprecated_extract_floating (from, TYPE_LENGTH (type)); + deprecated_store_floating (to, DEPRECATED_REGISTER_RAW_SIZE (n), val); } else - memcpy (to, from, REGISTER_RAW_SIZE (n)); + memcpy (to, from, DEPRECATED_REGISTER_RAW_SIZE (n)); } static void @@ -1909,7 +1920,7 @@ e500_pseudo_register_read (struct gdbarch *gdbarch, struct regcache *regcache, { int base_regnum; int offset = 0; - char *temp_buffer = (char*) alloca (MAX_REGISTER_RAW_SIZE); + char temp_buffer[MAX_REGISTER_SIZE]; struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch); if (reg_nr >= tdep->ppc_gp0_regnum @@ -1932,7 +1943,7 @@ e500_pseudo_register_write (struct gdbarch *gdbarch, struct regcache *regcache, { int base_regnum; int offset = 0; - char *temp_buffer = (char*) alloca (MAX_REGISTER_RAW_SIZE); + char temp_buffer[MAX_REGISTER_SIZE]; struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch); if (reg_nr >= tdep->ppc_gp0_regnum @@ -1992,40 +2003,6 @@ rs6000_stab_reg_to_regnum (int num) return regnum; } -/* Store the address of the place in which to copy the structure the - subroutine will return. */ - -static void -rs6000_store_struct_return (CORE_ADDR addr, CORE_ADDR sp) -{ - struct gdbarch_tdep *tdep = gdbarch_tdep (current_gdbarch); - write_register (tdep->ppc_gp0_regnum + 3, addr); -} - -/* Write into appropriate registers a function return value - of type TYPE, given in virtual format. */ -static void -e500_store_return_value (struct type *type, char *valbuf) -{ - struct gdbarch_tdep *tdep = gdbarch_tdep (current_gdbarch); - - /* Everything is returned in GPR3 and up. */ - int copied = 0; - int i = 0; - int len = TYPE_LENGTH (type); - while (copied < len) - { - int regnum = gdbarch_tdep (current_gdbarch)->ppc_gp0_regnum + 3 + i; - int reg_size = REGISTER_RAW_SIZE (regnum); - char *reg_val_buf = alloca (reg_size); - - memcpy (reg_val_buf, valbuf + copied, reg_size); - copied += reg_size; - deprecated_write_register_gen (regnum, reg_val_buf); - i++; - } -} - static void rs6000_store_return_value (struct type *type, char *valbuf) { @@ -2037,18 +2014,18 @@ rs6000_store_return_value (struct type *type, char *valbuf) Say a double_double_double type could be returned in FPR1/FPR2/FPR3 triple. */ - deprecated_write_register_bytes (REGISTER_BYTE (FP0_REGNUM + 1), valbuf, + deprecated_write_register_bytes (DEPRECATED_REGISTER_BYTE (FP0_REGNUM + 1), valbuf, TYPE_LENGTH (type)); else if (TYPE_CODE (type) == TYPE_CODE_ARRAY) { if (TYPE_LENGTH (type) == 16 && TYPE_VECTOR (type)) - deprecated_write_register_bytes (REGISTER_BYTE (tdep->ppc_vr0_regnum + 2), + deprecated_write_register_bytes (DEPRECATED_REGISTER_BYTE (tdep->ppc_vr0_regnum + 2), valbuf, TYPE_LENGTH (type)); } else /* Everything else is returned in GPR3 and up. */ - deprecated_write_register_bytes (REGISTER_BYTE (gdbarch_tdep (current_gdbarch)->ppc_gp0_regnum + 3), + deprecated_write_register_bytes (DEPRECATED_REGISTER_BYTE (gdbarch_tdep (current_gdbarch)->ppc_gp0_regnum + 3), valbuf, TYPE_LENGTH (type)); } @@ -2062,10 +2039,10 @@ rs6000_extract_struct_value_address (struct regcache *regcache) /* FIXME: cagney/2002-09-26: PR gdb/724: When making an inferior function call GDB knows the address of the struct return value and hence, should not need to call this function. Unfortunately, - the current hand_function_call() code only saves the most recent - struct address leading to occasional calls. The code should - instead maintain a stack of such addresses (in the dummy frame - object). */ + the current call_function_by_hand() code only saves the most + recent struct address leading to occasional calls. The code + should instead maintain a stack of such addresses (in the dummy + frame object). */ /* NOTE: cagney/2002-09-26: Return 0 which indicates that we've really got no idea where the return value is being stored. While r3, on function entry, contained the address it will have since @@ -2073,17 +2050,6 @@ rs6000_extract_struct_value_address (struct regcache *regcache) return 0; } -/* Return whether PC is in a dummy function call. - - FIXME: This just checks for the end of the stack, which is broken - for things like stepping through gcc nested function stubs. */ - -static int -rs6000_pc_in_call_dummy (CORE_ADDR pc, CORE_ADDR sp, CORE_ADDR fp) -{ - return sp < pc && pc < fp; -} - /* Hook called when a new child process is started. */ void @@ -2093,7 +2059,7 @@ rs6000_create_inferior (int pid) rs6000_set_host_arch_hook (pid); } -/* Support for CONVERT_FROM_FUNC_PTR_ADDR(ADDR). +/* Support for CONVERT_FROM_FUNC_PTR_ADDR (ARCH, ADDR, TARG). Usually a function pointer's representation is simply the address of the function. On the RS/6000 however, a function pointer is @@ -2112,8 +2078,10 @@ rs6000_create_inferior (int pid) /* Return real function address if ADDR (a function pointer) is in the data space and is therefore a special function pointer. */ -CORE_ADDR -rs6000_convert_from_func_ptr_addr (CORE_ADDR addr) +static CORE_ADDR +rs6000_convert_from_func_ptr_addr (struct gdbarch *gdbarch, + CORE_ADDR addr, + struct target_ops *targ) { struct obj_section *s; @@ -2727,9 +2695,9 @@ rs6000_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches) else { arch = bfd_arch_powerpc; - mach = 0; - bfd_default_set_arch_mach (&abfd, arch, mach); + bfd_default_set_arch_mach (&abfd, arch, 0); info.bfd_arch_info = bfd_get_arch_info (&abfd); + mach = info.bfd_arch_info->mach; } tdep = xmalloc (sizeof (struct gdbarch_tdep)); tdep->wordsize = wordsize; @@ -2785,10 +2753,16 @@ rs6000_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches) set_gdbarch_pc_regnum (gdbarch, 64); set_gdbarch_sp_regnum (gdbarch, 1); - set_gdbarch_fp_regnum (gdbarch, 1); - set_gdbarch_deprecated_extract_return_value (gdbarch, - rs6000_extract_return_value); - set_gdbarch_deprecated_store_return_value (gdbarch, rs6000_store_return_value); + set_gdbarch_deprecated_fp_regnum (gdbarch, 1); + if (sysv_abi && wordsize == 8) + set_gdbarch_return_value (gdbarch, ppc64_sysv_abi_return_value); + else if (sysv_abi && wordsize == 4) + set_gdbarch_return_value (gdbarch, ppc_sysv_abi_return_value); + else + { + set_gdbarch_deprecated_extract_return_value (gdbarch, rs6000_extract_return_value); + set_gdbarch_deprecated_store_return_value (gdbarch, rs6000_store_return_value); + } if (v->arch == bfd_arch_powerpc) switch (v->mach) @@ -2818,12 +2792,10 @@ rs6000_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches) tdep->ppc_ev31_regnum = 38; set_gdbarch_pc_regnum (gdbarch, 0); set_gdbarch_sp_regnum (gdbarch, tdep->ppc_gp0_regnum + 1); - set_gdbarch_fp_regnum (gdbarch, tdep->ppc_gp0_regnum + 1); + set_gdbarch_deprecated_fp_regnum (gdbarch, tdep->ppc_gp0_regnum + 1); set_gdbarch_dwarf2_reg_to_regnum (gdbarch, e500_dwarf2_reg_to_regnum); set_gdbarch_pseudo_register_read (gdbarch, e500_pseudo_register_read); set_gdbarch_pseudo_register_write (gdbarch, e500_pseudo_register_write); - set_gdbarch_extract_return_value (gdbarch, e500_extract_return_value); - set_gdbarch_deprecated_store_return_value (gdbarch, e500_store_return_value); break; default: tdep->ppc_vr0_regnum = -1; @@ -2858,23 +2830,16 @@ rs6000_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches) else set_gdbarch_print_insn (gdbarch, gdb_print_insn_powerpc); - set_gdbarch_read_pc (gdbarch, generic_target_read_pc); set_gdbarch_write_pc (gdbarch, generic_target_write_pc); - set_gdbarch_read_fp (gdbarch, generic_target_read_fp); - set_gdbarch_read_sp (gdbarch, generic_target_read_sp); - set_gdbarch_write_sp (gdbarch, generic_target_write_sp); set_gdbarch_num_regs (gdbarch, v->nregs); set_gdbarch_num_pseudo_regs (gdbarch, v->npregs); set_gdbarch_register_name (gdbarch, rs6000_register_name); - set_gdbarch_register_size (gdbarch, wordsize); - set_gdbarch_register_bytes (gdbarch, off); - set_gdbarch_register_byte (gdbarch, rs6000_register_byte); - set_gdbarch_register_raw_size (gdbarch, rs6000_register_raw_size); - set_gdbarch_max_register_raw_size (gdbarch, 16); - set_gdbarch_register_virtual_size (gdbarch, generic_register_size); - set_gdbarch_max_register_virtual_size (gdbarch, 16); - set_gdbarch_register_virtual_type (gdbarch, rs6000_register_virtual_type); + set_gdbarch_deprecated_register_size (gdbarch, wordsize); + set_gdbarch_deprecated_register_bytes (gdbarch, off); + set_gdbarch_deprecated_register_byte (gdbarch, rs6000_register_byte); + set_gdbarch_deprecated_register_raw_size (gdbarch, rs6000_register_raw_size); + set_gdbarch_deprecated_register_virtual_type (gdbarch, rs6000_register_virtual_type); set_gdbarch_ptr_bit (gdbarch, wordsize * TARGET_CHAR_BIT); set_gdbarch_short_bit (gdbarch, 2 * TARGET_CHAR_BIT); @@ -2883,25 +2848,28 @@ rs6000_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches) set_gdbarch_long_long_bit (gdbarch, 8 * TARGET_CHAR_BIT); set_gdbarch_float_bit (gdbarch, 4 * TARGET_CHAR_BIT); set_gdbarch_double_bit (gdbarch, 8 * TARGET_CHAR_BIT); - set_gdbarch_long_double_bit (gdbarch, 8 * TARGET_CHAR_BIT); + if (sysv_abi) + set_gdbarch_long_double_bit (gdbarch, 16 * TARGET_CHAR_BIT); + else + set_gdbarch_long_double_bit (gdbarch, 8 * TARGET_CHAR_BIT); set_gdbarch_char_signed (gdbarch, 0); - set_gdbarch_call_dummy_length (gdbarch, 0); - set_gdbarch_call_dummy_address (gdbarch, entry_point_address); - set_gdbarch_call_dummy_breakpoint_offset_p (gdbarch, 1); - set_gdbarch_call_dummy_breakpoint_offset (gdbarch, 0); - set_gdbarch_call_dummy_start_offset (gdbarch, 0); - set_gdbarch_call_dummy_p (gdbarch, 1); - set_gdbarch_call_dummy_stack_adjust_p (gdbarch, 0); - set_gdbarch_fix_call_dummy (gdbarch, rs6000_fix_call_dummy); set_gdbarch_frame_align (gdbarch, rs6000_frame_align); - set_gdbarch_save_dummy_frame_tos (gdbarch, generic_save_dummy_frame_tos); - set_gdbarch_push_return_address (gdbarch, ppc_push_return_address); + if (sysv_abi && wordsize == 8) + /* PPC64 SYSV. */ + set_gdbarch_frame_red_zone_size (gdbarch, 288); + else if (!sysv_abi && wordsize == 4) + /* PowerOpen / AIX 32 bit. The saved area or red zone consists of + 19 4 byte GPRS + 18 8 byte FPRs giving a total of 220 bytes. + Problem is, 220 isn't frame (16 byte) aligned. Round it up to + 224. */ + set_gdbarch_frame_red_zone_size (gdbarch, 224); + set_gdbarch_deprecated_save_dummy_frame_tos (gdbarch, generic_save_dummy_frame_tos); set_gdbarch_believe_pcc_promotion (gdbarch, 1); - set_gdbarch_register_convertible (gdbarch, rs6000_register_convertible); - set_gdbarch_register_convert_to_virtual (gdbarch, rs6000_register_convert_to_virtual); - set_gdbarch_register_convert_to_raw (gdbarch, rs6000_register_convert_to_raw); + set_gdbarch_deprecated_register_convertible (gdbarch, rs6000_register_convertible); + set_gdbarch_deprecated_register_convert_to_virtual (gdbarch, rs6000_register_convert_to_virtual); + set_gdbarch_deprecated_register_convert_to_raw (gdbarch, rs6000_register_convert_to_raw); set_gdbarch_stab_reg_to_regnum (gdbarch, rs6000_stab_reg_to_regnum); /* Note: kevinb/2002-04-12: I'm not convinced that rs6000_push_arguments() is correct for the SysV ABI when the wordsize is 8, but I'm also @@ -2911,36 +2879,40 @@ rs6000_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches) 64-bit code. At some point in the future, this matter needs to be revisited. */ if (sysv_abi && wordsize == 4) - set_gdbarch_push_arguments (gdbarch, ppc_sysv_abi_push_arguments); + set_gdbarch_push_dummy_call (gdbarch, ppc_sysv_abi_push_dummy_call); + else if (sysv_abi && wordsize == 8) + set_gdbarch_push_dummy_call (gdbarch, ppc64_sysv_abi_push_dummy_call); else - set_gdbarch_push_arguments (gdbarch, rs6000_push_arguments); + set_gdbarch_push_dummy_call (gdbarch, rs6000_push_dummy_call); - set_gdbarch_store_struct_return (gdbarch, rs6000_store_struct_return); - set_gdbarch_extract_struct_value_address (gdbarch, rs6000_extract_struct_value_address); - set_gdbarch_pop_frame (gdbarch, rs6000_pop_frame); + set_gdbarch_deprecated_extract_struct_value_address (gdbarch, rs6000_extract_struct_value_address); + set_gdbarch_deprecated_pop_frame (gdbarch, rs6000_pop_frame); set_gdbarch_skip_prologue (gdbarch, rs6000_skip_prologue); set_gdbarch_inner_than (gdbarch, core_addr_lessthan); - set_gdbarch_decr_pc_after_break (gdbarch, 0); - set_gdbarch_function_start_offset (gdbarch, 0); set_gdbarch_breakpoint_from_pc (gdbarch, rs6000_breakpoint_from_pc); + /* Handle the 64-bit SVR4 minimal-symbol convention of using "FN" + for the descriptor and ".FN" for the entry-point -- a user + specifying "break FN" will unexpectedly end up with a breakpoint + on the descriptor and not the function. This architecture method + transforms any breakpoints on descriptors into breakpoints on the + corresponding entry point. */ + if (sysv_abi && wordsize == 8) + set_gdbarch_adjust_breakpoint_address (gdbarch, ppc64_sysv_abi_adjust_breakpoint_address); + /* Not sure on this. FIXMEmgo */ set_gdbarch_frame_args_skip (gdbarch, 8); - if (sysv_abi) - set_gdbarch_use_struct_convention (gdbarch, - ppc_sysv_abi_use_struct_convention); - else + if (!sysv_abi) set_gdbarch_use_struct_convention (gdbarch, - generic_use_struct_convention); + rs6000_use_struct_convention); - set_gdbarch_frameless_function_invocation (gdbarch, - rs6000_frameless_function_invocation); - set_gdbarch_frame_chain (gdbarch, rs6000_frame_chain); - set_gdbarch_frame_saved_pc (gdbarch, rs6000_frame_saved_pc); + set_gdbarch_deprecated_frameless_function_invocation (gdbarch, rs6000_frameless_function_invocation); + set_gdbarch_deprecated_frame_chain (gdbarch, rs6000_frame_chain); + set_gdbarch_deprecated_frame_saved_pc (gdbarch, rs6000_frame_saved_pc); - set_gdbarch_frame_init_saved_regs (gdbarch, rs6000_frame_init_saved_regs); + set_gdbarch_deprecated_frame_init_saved_regs (gdbarch, rs6000_frame_init_saved_regs); set_gdbarch_deprecated_init_extra_frame_info (gdbarch, rs6000_init_extra_frame_info); if (!sysv_abi) @@ -2950,17 +2922,26 @@ rs6000_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches) set_gdbarch_convert_from_func_ptr_addr (gdbarch, rs6000_convert_from_func_ptr_addr); } - set_gdbarch_frame_args_address (gdbarch, rs6000_frame_args_address); - set_gdbarch_frame_locals_address (gdbarch, rs6000_frame_args_address); - set_gdbarch_saved_pc_after_call (gdbarch, rs6000_saved_pc_after_call); + set_gdbarch_deprecated_frame_args_address (gdbarch, rs6000_frame_args_address); + set_gdbarch_deprecated_frame_locals_address (gdbarch, rs6000_frame_args_address); + set_gdbarch_deprecated_saved_pc_after_call (gdbarch, rs6000_saved_pc_after_call); - /* We can't tell how many args there are - now that the C compiler delays popping them. */ - set_gdbarch_frame_num_args (gdbarch, frame_num_args_unknown); + /* Helpers for function argument information. */ + set_gdbarch_fetch_pointer_argument (gdbarch, rs6000_fetch_pointer_argument); /* Hook in ABI-specific overrides, if they have been registered. */ gdbarch_init_osabi (info, gdbarch); + if (from_xcoff_exec) + { + /* NOTE: jimix/2003-06-09: This test should really check for + GDB_OSABI_AIX when that is defined and becomes + available. (Actually, once things are properly split apart, + the test goes away.) */ + /* RS6000/AIX does not support PT_STEP. Has to be simulated. */ + set_gdbarch_software_single_step (gdbarch, rs6000_software_single_step); + } + return gdbarch; } @@ -2985,6 +2966,8 @@ rs6000_info_powerpc_command (char *args, int from_tty) /* Initialization code. */ +extern initialize_file_ftype _initialize_rs6000_tdep; /* -Wmissing-prototypes */ + void _initialize_rs6000_tdep (void) {