X-Git-Url: http://git.efficios.com/?a=blobdiff_plain;f=gdb%2Frs6000-tdep.c;h=9cd6120080d31035e51586ff7ba4b573c8710da5;hb=e2d0e7eb0476ade97ed7c00e7a3838609d52d084;hp=98e1a0ca088ee69f5975627d5dbb4ebe0dfd9f2c;hpb=143985b7f3c98d0644b2eef50059f14974fe9d64;p=deliverable%2Fbinutils-gdb.git diff --git a/gdb/rs6000-tdep.c b/gdb/rs6000-tdep.c index 98e1a0ca08..9cd6120080 100644 --- a/gdb/rs6000-tdep.c +++ b/gdb/rs6000-tdep.c @@ -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 @@ -231,12 +232,12 @@ rs6000_saved_pc_after_call (struct frame_info *fi) } /* Get the ith function argument for the current function. */ -CORE_ADDR +static CORE_ADDR rs6000_fetch_pointer_argument (struct frame_info *frame, int argi, struct type *type) { CORE_ADDR addr; - frame_read_register (frame, 3 + argi, &addr); + get_frame_register (frame, 3 + argi, &addr); return addr; } @@ -1053,7 +1054,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; } @@ -1064,7 +1065,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; } } @@ -1074,25 +1075,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) @@ -1117,9 +1099,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 */ @@ -1134,14 +1119,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... @@ -1164,7 +1154,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)); @@ -1181,7 +1171,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; @@ -1193,9 +1183,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); @@ -1211,8 +1201,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; @@ -1256,14 +1246,6 @@ ran_out_of_registers_for_arguments: space = (space + 15) & -16; sp -= space; - /* 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 - else. */ - - write_register (SP_REGNUM, sp); - /* If the last argument copied into the registers didn't fit there completely, push the rest of it into stack. */ @@ -1294,7 +1276,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; @@ -1304,86 +1286,43 @@ 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_unsigned_integer (tmp_buffer, 4, saved_sp); write_memory (sp, tmp_buffer, 4); - target_store_registers (-1); - return sp; -} - -/* Function: ppc_push_return_address (pc, sp) - Set up the return address for the inferior function call. */ - -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 ()); - return sp; -} + /* Set the stack pointer. According to the ABI, the SP is meant to + be set _before_ the corresponding stack space is used. No need + for that here though - the target has been completely stopped - + it isn't possible for an exception handler to stomp on the stack. */ + regcache_raw_write_signed (regcache, SP_REGNUM, 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); + /* Point the inferior function call's return address at the dummy's + breakpoint. */ + regcache_raw_write_signed (regcache, tdep->ppc_lr_regnum, bp_addr); - if (TYPE_CODE (valtype) == TYPE_CODE_ARRAY - && vallen == 8 - && TYPE_VECTOR (valtype)) + /* 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) { - regcache_raw_read (regbuf, tdep->ppc_ev0_regnum + 3, valbuf); + CORE_ADDR tocvalue = (*rs6000_find_toc_address_hook) (func_addr); + regcache_raw_write_signed (regcache, tdep->ppc_toc_regnum, tocvalue); } - 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); + target_store_registers (-1); + return sp; +} - /* 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); - } +/* PowerOpen always puts structures in memory. Vectors, which were + added later, do get returned in a register though. */ + +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 @@ -1403,11 +1342,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)); } @@ -1416,18 +1355,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)); } } @@ -1477,7 +1416,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; @@ -1630,7 +1569,7 @@ 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) @@ -1672,7 +1611,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; } } @@ -1686,7 +1625,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)[tdep->ppc_gp0_regnum + i] = gpr_addr; + deprecated_get_frame_saved_regs (fi)[tdep->ppc_gp0_regnum + i] = gpr_addr; gpr_addr += wordsize; } } @@ -1701,8 +1640,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); } } } @@ -1717,9 +1656,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); } } } @@ -1727,17 +1666,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 @@ -1764,7 +1703,7 @@ frame_initial_stack_address (struct frame_info *fi) /* 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 @@ -1784,7 +1723,7 @@ frame_initial_stack_address (struct frame_info *fi) { 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 @@ -1817,7 +1756,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; @@ -1894,6 +1833,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; @@ -1904,8 +1847,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); } } } @@ -1930,13 +1873,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 = deprecated_extract_floating (from, REGISTER_RAW_SIZE (n)); + 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 @@ -1944,15 +1887,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 = deprecated_extract_floating (from, TYPE_LENGTH (type)); - deprecated_store_floating (to, REGISTER_RAW_SIZE (n), val); + 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 @@ -2044,40 +1987,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) { @@ -2089,18 +1998,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)); } @@ -2145,7 +2054,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 @@ -2164,8 +2073,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; @@ -2838,9 +2749,21 @@ 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_deprecated_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); + if (sysv_abi && wordsize == 8) + { + set_gdbarch_extract_return_value (gdbarch, ppc64_sysv_abi_extract_return_value); + set_gdbarch_store_return_value (gdbarch, ppc64_sysv_abi_store_return_value); + } + else if (sysv_abi && wordsize == 4) + { + set_gdbarch_extract_return_value (gdbarch, ppc_sysv_abi_extract_return_value); + set_gdbarch_store_return_value (gdbarch, ppc_sysv_abi_store_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) @@ -2874,8 +2797,6 @@ rs6000_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches) 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; @@ -2910,22 +2831,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_sp (gdbarch, generic_target_read_sp); - set_gdbarch_deprecated_dummy_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_deprecated_register_size (gdbarch, wordsize); set_gdbarch_deprecated_register_bytes (gdbarch, off); - set_gdbarch_register_byte (gdbarch, rs6000_register_byte); - set_gdbarch_register_raw_size (gdbarch, rs6000_register_raw_size); - set_gdbarch_deprecated_max_register_raw_size (gdbarch, 16); - set_gdbarch_register_virtual_size (gdbarch, generic_register_size); - set_gdbarch_deprecated_max_register_virtual_size (gdbarch, 16); - set_gdbarch_register_virtual_type (gdbarch, rs6000_register_virtual_type); + 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); @@ -2940,15 +2855,22 @@ rs6000_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches) set_gdbarch_long_double_bit (gdbarch, 8 * TARGET_CHAR_BIT); set_gdbarch_char_signed (gdbarch, 0); - set_gdbarch_deprecated_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_deprecated_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 @@ -2958,11 +2880,12 @@ 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_deprecated_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_deprecated_push_arguments (gdbarch, rs6000_push_arguments); + set_gdbarch_push_dummy_call (gdbarch, rs6000_push_dummy_call); - set_gdbarch_deprecated_store_struct_return (gdbarch, rs6000_store_struct_return); set_gdbarch_extract_struct_value_address (gdbarch, rs6000_extract_struct_value_address); set_gdbarch_deprecated_pop_frame (gdbarch, rs6000_pop_frame); @@ -2975,12 +2898,14 @@ rs6000_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches) /* Not sure on this. FIXMEmgo */ set_gdbarch_frame_args_skip (gdbarch, 8); - if (sysv_abi) + if (sysv_abi && wordsize == 4) set_gdbarch_use_struct_convention (gdbarch, ppc_sysv_abi_use_struct_convention); + else if (sysv_abi && wordsize == 8) + set_gdbarch_use_struct_convention (gdbarch, ppc64_sysv_abi_use_struct_convention); else set_gdbarch_use_struct_convention (gdbarch, - generic_use_struct_convention); + rs6000_use_struct_convention); set_gdbarch_frameless_function_invocation (gdbarch, rs6000_frameless_function_invocation); @@ -2997,20 +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_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); /* Helpers for function argument information. */ set_gdbarch_fetch_pointer_argument (gdbarch, rs6000_fetch_pointer_argument); - /* 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); - /* 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; } @@ -3035,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) {