/* Target-dependent code for GDB, the GNU debugger.
- Copyright 1986, 1987, 1989, 1991, 1992, 1993, 1994, 1995, 1996
+ Copyright 1986, 1987, 1989, 1991, 1992, 1993, 1994, 1995, 1996, 1997
Free Software Foundation, Inc.
This file is part of GDB.
extern int errno;
-/* Nonzero if we just simulated a single step break. */
-int one_stepped;
-
/* Breakpoint shadows for the single step instructions will be kept here. */
static struct sstep_breaks {
char data[4];
} stepBreaks[2];
-/* Static function prototypes */
+/* Hook for determining the TOC address when calling functions in the
+ inferior under AIX. The initialization code in rs6000-nat.c sets
+ this hook to point to find_toc_address. */
-static CORE_ADDR find_toc_address PARAMS ((CORE_ADDR pc));
+CORE_ADDR (*find_toc_address_hook) PARAMS ((CORE_ADDR)) = NULL;
+
+/* Static function prototypes */
static CORE_ADDR branch_dest PARAMS ((int opcode, int instr, CORE_ADDR pc,
CORE_ADDR safety));
static void frame_get_cache_fsr PARAMS ((struct frame_info *fi,
struct rs6000_framedata *fdatap));
+static void pop_dummy_frame PARAMS ((void));
+
/* Calculate the destination of a branch/jump. Return -1 if not a branch. */
static CORE_ADDR
CORE_ADDR pc;
CORE_ADDR safety;
{
- register long offset;
CORE_ADDR dest;
int immediate;
int absolute;
ext_op = (instr>>1) & 0x3ff;
if (ext_op == 16) /* br conditional register */
- dest = read_register (LR_REGNUM) & ~3;
+ {
+ dest = read_register (LR_REGNUM) & ~3;
+
+ /* If we are about to return from a signal handler, dest is
+ something like 0x3c90. The current frame is a signal handler
+ caller frame, upon completion of the sigreturn system call
+ execution will return to the saved PC in the frame. */
+ if (dest < TEXT_SEGMENT_BASE)
+ {
+ struct frame_info *fi;
+
+ fi = get_current_frame ();
+ if (fi != NULL)
+ dest = read_memory_integer (fi->frame + SIG_FRAME_PC_OFFSET,
+ 4);
+ }
+ }
else if (ext_op == 528) /* br cond to count reg */
{
}
+/* Sequence of bytes for breakpoint instruction. */
+
+#define BIG_BREAKPOINT { 0x7d, 0x82, 0x10, 0x08 }
+#define LITTLE_BREAKPOINT { 0x08, 0x10, 0x82, 0x7d }
+
+unsigned char *
+rs6000_breakpoint_from_pc (bp_addr, bp_size)
+ CORE_ADDR *bp_addr;
+ int *bp_size;
+{
+ static unsigned char big_breakpoint[] = BIG_BREAKPOINT;
+ static unsigned char little_breakpoint[] = LITTLE_BREAKPOINT;
+ *bp_size = 4;
+ if (TARGET_BYTE_ORDER == BIG_ENDIAN)
+ return big_breakpoint;
+ else
+ return little_breakpoint;
+}
+
/* AIX does not support PT_STEP. Simulate it. */
void
-single_step (signal)
- int signal;
+rs6000_software_single_step (signal, insert_breakpoints_p)
+ enum target_signal signal;
+ int insert_breakpoints_p;
{
#define INSNLEN(OPCODE) 4
CORE_ADDR breaks[2];
int opcode;
- if (!one_stepped) {
+ if (insert_breakpoints_p) {
+
loc = read_pc ();
insn = read_memory_integer (loc, 4);
stepBreaks[ii].address = breaks[ii];
}
- one_stepped = 1;
} else {
/* remove step breakpoints. */
write_memory
(stepBreaks[ii].address, stepBreaks[ii].data, 4);
- one_stepped = 0;
}
errno = 0; /* FIXME, don't ignore errors! */
/* What errors? {read,write}_memory call error(). */
continue;
} else if (((op & 0xfc1f0000) == 0xbc010000) || /* stm Rx, NUM(r1) */
- ((op & 0xfc1f0000) == 0x90010000 && /* st rx,NUM(r1), rx >= r13 */
+ ((op & 0xfc1f0000) == 0x90010000 && /* st rx,NUM(r1),
+ rx >= r13 */
(op & 0x03e00000) >= 0x01a00000)) {
reg = GET_SRC_REG (op);
}
continue;
- } else if ((op & 0xffff0000) == 0x3c000000) { /* addis 0,0,NUM, used for >= 32k frames */
+ } else if ((op & 0xffff0000) == 0x3c000000) { /* addis 0,0,NUM, used
+ for >= 32k frames */
fdata->offset = (op & 0x0000ffff) << 16;
fdata->frameless = 0;
continue;
- } else if ((op & 0xffff0000) == 0x60000000) { /* ori 0,0,NUM, 2nd half of >= 32k frames */
+ } else if ((op & 0xffff0000) == 0x60000000) { /* ori 0,0,NUM, 2nd ha
+ lf of >= 32k frames */
fdata->offset |= (op & 0x0000ffff);
fdata->frameless = 0;
continue;
- } else if ((op & 0xffff0000) == lr_reg) { /* st Rx,NUM(r1) where Rx == lr */
+ } else if ((op & 0xffff0000) == lr_reg) { /* st Rx,NUM(r1)
+ where Rx == lr */
fdata->lr_offset = SIGNED_SHORT (op) + offset;
fdata->nosavedpc = 0;
lr_reg = 0;
continue;
- } else if ((op & 0xffff0000) == cr_reg) { /* st Rx,NUM(r1) where Rx == cr */
+ } else if ((op & 0xffff0000) == cr_reg) { /* st Rx,NUM(r1)
+ where Rx == cr */
fdata->cr_offset = SIGNED_SHORT (op) + offset;
cr_reg = 0;
continue;
- } else if (op == 0x48000005) { /* bl .+4 used in -mrelocatable */
+ } else if (op == 0x48000005) { /* bl .+4 used in
+ -mrelocatable */
continue;
} else if (op == 0x48000004) { /* b .+4 (xlc) */
break;
- } else if (((op & 0xffff0000) == 0x801e0000 || /* lwz 0,NUM(r30), used in V.4 -mrelocatable */
- op == 0x7fc0f214) && /* add r30,r0,r30, used in V.4 -mrelocatable */
+ } else if (((op & 0xffff0000) == 0x801e0000 || /* lwz 0,NUM(r30), used
+ in V.4 -mrelocatable */
+ op == 0x7fc0f214) && /* add r30,r0,r30, used
+ in V.4 -mrelocatable */
lr_reg == 0x901e0000) {
continue;
- } else if ((op & 0xffff0000) == 0x3fc00000 || /* addis 30,0,foo@ha, used in V.4 -mminimal-toc */
+ } else if ((op & 0xffff0000) == 0x3fc00000 || /* addis 30,0,foo@ha, used
+ in V.4 -mminimal-toc */
(op & 0xffff0000) == 0x3bde0000) { /* addi 30,30,foo@l */
continue;
- } else if ((op & 0xfc000000) == 0x48000000) { /* bl foo, to save fprs??? */
+ } else if ((op & 0xfc000000) == 0x48000000) { /* bl foo,
+ to save fprs??? */
fdata->frameless = 0;
/* Don't skip over the subroutine call if it is not within the first
prologue. */
if (op == 0x4def7b82 || op == 0) /* crorc 15, 15, 15 */
- break; /* don't skip over this branch */
-
+ break; /* don't skip over
+ this branch */
continue;
/* update stack pointer */
/* store parameters in stack via frame pointer */
} else if (framep &&
- (op & 0xfc1f0000) == 0x901f0000 || /* st rx,NUM(r1) */
+ ((op & 0xfc1f0000) == 0x901f0000 || /* st rx,NUM(r1) */
(op & 0xfc1f0000) == 0xd81f0000 || /* stfd Rx,NUM(r1) */
- (op & 0xfc1f0000) == 0xfc1f0000) { /* frsp, fp?,NUM(r1) */
+ (op & 0xfc1f0000) == 0xfc1f0000)) { /* frsp, fp?,NUM(r1) */
continue;
/* Set up frame pointer */
pc = read_register(PC_REGNUM);
store_address (pc_targ, 4, pc);
- (void) skip_prologue (get_pc_function_start (pc) + FUNCTION_START_OFFSET, &fdata);
+ skip_prologue (get_pc_function_start (pc) + FUNCTION_START_OFFSET, &fdata);
dummy_frame_addr [dummy_frame_count++] = sp;
for (ii=1; ii <= (LAST_SP_REGNUM-FIRST_SP_REGNUM+1); ++ii) {
write_memory (sp-384-(ii*4),
- ®isters[REGISTER_BYTE (FPLAST_REGNUM + ii)], 4);
+ ®isters[REGISTER_BYTE (FPLAST_REGNUM + ii)], 4);
}
/* Save sp or so called back chain right here. */
GDB process that keeps track of these dummy frames! -- gnu@cygnus.com Aug92
*/
+static void
pop_dummy_frame ()
{
CORE_ADDR sp, pc;
order to secure astack space. Thus, saved %sp (or %r1) value, is not the
one we should restore. Change it with the one we need. */
- *(int*)®isters [REGISTER_BYTE(FP_REGNUM)] = sp;
+ memcpy (®isters [REGISTER_BYTE(FP_REGNUM)], (char *) &sp, sizeof (int));
/* Now we can restore all registers. */
pc = read_pc ();
sp = FRAME_FP (frame);
- if (stop_stack_dummy && dummy_frame_count) {
- pop_dummy_frame ();
- return;
- }
+ if (stop_stack_dummy)
+ {
+#ifdef USE_GENERIC_DUMMY_FRAMES
+ generic_pop_dummy_frame ();
+ flush_cached_frames ();
+ return;
+#else
+ if (dummy_frame_count)
+ pop_dummy_frame ();
+ return;
+#endif
+ }
/* Make sure that all registers are valid. */
read_register_bytes (0, NULL, REGISTER_BYTES);
its argumets will be passed by gdb. */
void
-fix_call_dummy (dummyname, pc, fun, nargs, type)
+rs6000_fix_call_dummy (dummyname, pc, fun, nargs, args, type, gcc_p)
char *dummyname;
CORE_ADDR pc;
CORE_ADDR fun;
- int nargs; /* not used */
- int type; /* not used */
+ int nargs;
+ value_ptr *args;
+ struct type *type;
+ int gcc_p;
{
#define TOC_ADDR_OFFSET 20
#define TARGET_ADDR_OFFSET 28
int ii;
CORE_ADDR target_addr;
- CORE_ADDR tocvalue;
- target_addr = fun;
- tocvalue = find_toc_address (target_addr);
+ if (find_toc_address_hook != NULL)
+ {
+ CORE_ADDR tocvalue;
- 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;
stack.
If the function is returning a structure, then the return address is passed
- in r3, then the first 7 words of the parametes can be passed in registers,
+ in r3, then the first 7 words of the parameters can be passed in registers,
starting from r4. */
CORE_ADDR
int struct_return;
CORE_ADDR struct_addr;
{
- int ii, len;
+ int ii;
+ int len = 0;
int argno; /* current argument number */
int argbytes; /* current argument byte */
char tmp_buffer [50];
int f_argno = 0; /* current floating point argno */
- value_ptr arg;
+
+ value_ptr arg = 0;
struct type *type;
- CORE_ADDR saved_sp, pc;
+ CORE_ADDR saved_sp;
+#ifndef USE_GENERIC_DUMMY_FRAMES
if ( dummy_frame_count <= 0)
printf_unfiltered ("FATAL ERROR -push_arguments()! frame not found!!\n");
+#endif /* GENERIC_DUMMY_FRAMES */
/* The first eight words of ther arguments are passed in registers. Copy
them appropriately.
ii = struct_return ? 1 : 0;
+/*
+effectively indirect call... gcc does...
+
+return_val example( float, int);
+
+eabi:
+ float in fp0, int in r3
+ offset of stack on overflow 8/16
+ for varargs, must go by type.
+power open:
+ float in r3&r4, int in r5
+ offset of stack on overflow different
+both:
+ return in r3 or f0. If no float, must study how gcc emulates floats;
+ pay attention to arg promotion.
+ User may have to cast\args to handle promotion correctly
+ since gdb won't know if prototype supplied or not.
+*/
+
for (argno=0, argbytes=0; argno < nargs && ii<8; ++ii) {
arg = args[argno];
printf_unfiltered (
"Fatal Error: a floating point parameter #%d with a size > 8 is found!\n", argno);
- memcpy (®isters[REGISTER_BYTE(FP0_REGNUM + 1 + f_argno)], VALUE_CONTENTS (arg),
- len);
+ memcpy (®isters[REGISTER_BYTE(FP0_REGNUM + 1 + f_argno)],
+ VALUE_CONTENTS (arg),
+ len);
++f_argno;
}
/* Argument takes more than one register. */
while (argbytes < len) {
-
- *(int*)®isters[REGISTER_BYTE(ii+3)] = 0;
+ memset (®isters[REGISTER_BYTE(ii+3)], 0, sizeof(int));
memcpy (®isters[REGISTER_BYTE(ii+3)],
- ((char*)VALUE_CONTENTS (arg))+argbytes,
- (len - argbytes) > 4 ? 4 : len - argbytes);
+ ((char*)VALUE_CONTENTS (arg))+argbytes,
+ (len - argbytes) > 4 ? 4 : len - argbytes);
++ii, argbytes += 4;
if (ii >= 8)
--ii;
}
else { /* Argument can fit in one register. No problem. */
- *(int*)®isters[REGISTER_BYTE(ii+3)] = 0;
+ memset (®isters[REGISTER_BYTE(ii+3)], 0, sizeof(int));
memcpy (®isters[REGISTER_BYTE(ii+3)], VALUE_CONTENTS (arg), len);
}
++argno;
ran_out_of_registers_for_arguments:
+#ifdef USE_GENERIC_DUMMY_FRAMES
+ saved_sp = read_sp ();
+#else
/* location for 8 parameters are always reserved. */
sp -= 4 * 8;
/* another six words for back chain, TOC register, link register, etc. */
sp -= 24;
-
+#endif /* GENERIC_DUMMY_FRAMES */
/* if there are more arguments, allocate space for them in
the stack, then push them starting from the ninth one. */
completely, push the rest of it into stack. */
if (argbytes) {
- write_memory (
- sp+24+(ii*4), ((char*)VALUE_CONTENTS (arg))+argbytes, len - argbytes);
+ write_memory (sp+24+(ii*4),
+ ((char*)VALUE_CONTENTS (arg))+argbytes,
+ len - argbytes);
++argno;
ii += ((len - argbytes + 3) & -4) / 4;
}
printf_unfiltered (
"Fatal Error: a floating point parameter #%d with a size > 8 is found!\n", argno);
- memcpy (®isters[REGISTER_BYTE(FP0_REGNUM + 1 + f_argno)], VALUE_CONTENTS (arg),
- len);
+ memcpy (®isters[REGISTER_BYTE(FP0_REGNUM + 1 + f_argno)],
+ VALUE_CONTENTS (arg),
+ len);
++f_argno;
}
/* Secure stack areas first, before doing anything else. */
write_register (SP_REGNUM, sp);
+#ifndef USE_GENERIC_DUMMY_FRAMES
+/* we want to copy 24 bytes of target's frame to dummy's frame,
+ then set back chain to point to new frame. */
+
saved_sp = dummy_frame_addr [dummy_frame_count - 1];
read_memory (saved_sp, tmp_buffer, 24);
write_memory (sp, tmp_buffer, 24);
+#endif /* GENERIC_DUMMY_FRAMES */
/* set back chain properly */
store_address (tmp_buffer, 4, saved_sp);
target_store_registers (-1);
return sp;
}
+#ifdef ELF_OBJECT_FORMAT
+
+/* Function: ppc_push_return_address (pc, sp)
+ Set up the return address for the inferior function call. */
+
+CORE_ADDR
+ppc_push_return_address (pc, sp)
+ CORE_ADDR pc;
+ CORE_ADDR sp;
+{
+ write_register (LR_REGNUM, CALL_DUMMY_ADDRESS ());
+ return sp;
+}
+
+#endif
/* a given return value in `regbuf' with a type `valtype', extract and copy its
value into `valbuf' */
necessary. */
if (TYPE_LENGTH (valtype) > 4) /* this is a double */
- memcpy (valbuf, ®buf[REGISTER_BYTE (FP0_REGNUM + 1)],
- TYPE_LENGTH (valtype));
+ memcpy (valbuf,
+ ®buf[REGISTER_BYTE (FP0_REGNUM + 1)],
+ TYPE_LENGTH (valtype));
else { /* float */
memcpy (&dd, ®buf[REGISTER_BYTE (FP0_REGNUM + 1)], 8);
ff = (float)dd;
&& TYPE_LENGTH (valtype) < REGISTER_RAW_SIZE (3))
offset = REGISTER_RAW_SIZE (3) - TYPE_LENGTH (valtype);
- memcpy (valbuf, regbuf + REGISTER_BYTE (3) + offset,
+ memcpy (valbuf,
+ regbuf + REGISTER_BYTE (3) + offset,
TYPE_LENGTH (valtype));
}
}
CORE_ADDR func_start;
struct rs6000_framedata fdata;
- if (fi->next != NULL)
- /* Don't even think about framelessness except on the innermost frame. */
- /* FIXME: Can also be frameless if fi->next->signal_handler_caller (if
- a signal happens while executing in a frameless function). */
+ /* Don't even think about framelessness except on the innermost frame
+ or if the function was interrupted by a signal. */
+ if (fi->next != NULL && !fi->next->signal_handler_caller)
return 0;
- func_start = get_pc_function_start (fi->pc) + FUNCTION_START_OFFSET;
+ func_start = get_pc_function_start (fi->pc);
/* If we failed to find the start of the function, it is a mistake
to inspect the instructions. */
if (!func_start)
- return 0;
+ {
+ /* A frame with a zero PC is usually created by dereferencing a NULL
+ function pointer, normally causing an immediate core dump of the
+ inferior. Mark function as frameless, as the inferior has no chance
+ of setting up a stack frame. */
+ if (fi->pc == 0)
+ return 1;
+ else
+ return 0;
+ }
+ func_start += FUNCTION_START_OFFSET;
(void) skip_prologue (func_start, &fdata);
return fdata.frameless;
}
{
CORE_ADDR func_start;
struct rs6000_framedata fdata;
- int frameless;
if (fi->signal_handler_caller)
return read_memory_integer (fi->frame + SIG_FRAME_PC_OFFSET, 4);
+#ifdef USE_GENERIC_DUMMY_FRAMES
+ if (PC_IN_CALL_DUMMY (fi->pc, fi->frame, fi->frame))
+ return generic_read_register_dummy(fi->pc, fi->frame, PC_REGNUM);
+#endif /* GENERIC_DUMMY_FRAMES */
+
func_start = get_pc_function_start (fi->pc) + FUNCTION_START_OFFSET;
/* If we failed to find the start of the function, it is a mistake
(void) skip_prologue (func_start, &fdata);
if (fdata.lr_offset == 0 && fi->next != NULL)
- return read_memory_integer (rs6000_frame_chain (fi) + DEFAULT_LR_SAVE, 4);
+ {
+ if (fi->next->signal_handler_caller)
+ return read_memory_integer (fi->next->frame + SIG_FRAME_LR_OFFSET, 4);
+ else
+ return read_memory_integer (rs6000_frame_chain (fi) + DEFAULT_LR_SAVE,
+ 4);
+ }
if (fdata.lr_offset == 0)
return read_register (LR_REGNUM);
struct frame_info *thisframe;
{
CORE_ADDR fp;
- if (inside_entry_file ((thisframe)->pc))
+
+#ifdef USE_GENERIC_DUMMY_FRAMES
+ if (PC_IN_CALL_DUMMY (thisframe->pc, thisframe->frame, thisframe->frame))
+ return thisframe->frame; /* dummy frame same as caller's frame */
+#endif /* GENERIC_DUMMY_FRAMES */
+
+ if (inside_entry_file (thisframe->pc) ||
+ thisframe->pc == entry_point_address ())
return 0;
+
if (thisframe->signal_handler_caller)
fp = read_memory_integer (thisframe->frame + SIG_FRAME_FP_OFFSET, 4);
+ else if (thisframe->next != NULL
+ && thisframe->next->signal_handler_caller
+ && frameless_function_invocation (thisframe))
+ /* A frameless function interrupted by a signal did not change the
+ frame pointer. */
+ fp = FRAME_FP (thisframe);
else
fp = read_memory_integer ((thisframe)->frame, 4);
- return fp;
-}
-\f
-/* Keep an array of load segment information and their TOC table addresses.
- This info will be useful when calling a shared library function by hand. */
-
-struct loadinfo {
- CORE_ADDR textorg, dataorg;
- unsigned long toc_offset;
-};
-
-#define LOADINFOLEN 10
-
-static struct loadinfo *loadinfo = NULL;
-static int loadinfolen = 0;
-static int loadinfotocindex = 0;
-static int loadinfotextindex = 0;
-
-
-void
-xcoff_init_loadinfo ()
-{
- loadinfotocindex = 0;
- loadinfotextindex = 0;
-
- if (loadinfolen == 0) {
- loadinfo = (struct loadinfo *)
- xmalloc (sizeof (struct loadinfo) * LOADINFOLEN);
- loadinfolen = LOADINFOLEN;
- }
-}
-
-
-/* FIXME -- this is never called! */
-void
-free_loadinfo ()
-{
- if (loadinfo)
- free (loadinfo);
- loadinfo = NULL;
- loadinfolen = 0;
- loadinfotocindex = 0;
- loadinfotextindex = 0;
-}
-
-/* this is called from xcoffread.c */
-
-void
-xcoff_add_toc_to_loadinfo (tocoff)
- unsigned long tocoff;
-{
- while (loadinfotocindex >= loadinfolen) {
- loadinfolen += LOADINFOLEN;
- loadinfo = (struct loadinfo *)
- xrealloc (loadinfo, sizeof(struct loadinfo) * loadinfolen);
- }
- loadinfo [loadinfotocindex++].toc_offset = tocoff;
-}
+#ifdef USE_GENERIC_DUMMY_FRAMES
+ {
+ CORE_ADDR fpp, lr;
-void
-add_text_to_loadinfo (textaddr, dataaddr)
- CORE_ADDR textaddr;
- CORE_ADDR dataaddr;
-{
- while (loadinfotextindex >= loadinfolen) {
- loadinfolen += LOADINFOLEN;
- loadinfo = (struct loadinfo *)
- xrealloc (loadinfo, sizeof(struct loadinfo) * loadinfolen);
+ lr = read_register (LR_REGNUM);
+ if (lr == entry_point_address ())
+ if (fp != 0 && (fpp = read_memory_integer (fp, 4)) != 0)
+ if (PC_IN_CALL_DUMMY (lr, fpp, fpp))
+ return fpp;
}
- loadinfo [loadinfotextindex].textorg = textaddr;
- loadinfo [loadinfotextindex].dataorg = dataaddr;
- ++loadinfotextindex;
-}
-
-
-/* Note that this assumes that the "textorg" and "dataorg" elements of
- a member of this array are correlated with the "toc_offset" element
- of the same member. This is taken care of because the loops which
- assign the former (in xcoff_relocate_symtab or xcoff_relocate_core)
- and the latter (in scan_xcoff_symtab, via vmap_symtab, in
- vmap_ldinfo or xcoff_relocate_core) traverse the same objfiles in
- the same order. */
-
-static CORE_ADDR
-find_toc_address (pc)
- CORE_ADDR pc;
-{
- int ii, toc_entry, tocbase = 0;
-
- toc_entry = -1;
- for (ii=0; ii < loadinfotextindex; ++ii)
- if (pc > loadinfo[ii].textorg && loadinfo[ii].textorg > tocbase) {
- toc_entry = ii;
- tocbase = loadinfo[ii].textorg;
- }
-
- if (toc_entry == -1)
- error ("Unable to find TOC entry for pc 0x%x\n", pc);
- return loadinfo[toc_entry].dataorg + loadinfo[toc_entry].toc_offset;
+#endif /* GENERIC_DUMMY_FRAMES */
+ return fp;
}
-
+\f
/* Return nonzero if ADDR (a function pointer) is in the data space and
is therefore a special function pointer. */
}
#endif
+/* Function: get_saved_register
+ Just call the generic_get_saved_register function. */
+
+#ifdef USE_GENERIC_DUMMY_FRAMES
void
-_initialize_rs6000_tdep ()
+get_saved_register (raw_buffer, optimized, addrp, frame, regnum, lval)
+ char *raw_buffer;
+ int *optimized;
+ CORE_ADDR *addrp;
+ struct frame_info *frame;
+ int regnum;
+ enum lval_type *lval;
{
-#ifndef ELF_OBJECT_FORMAT
- {
- extern void (*xcoff_add_toc_to_loadinfo_hook) PARAMS ((unsigned long));
- extern void (*xcoff_init_loadinfo_hook) PARAMS ((void));
-
- /* Initialize hook in xcoffread for recording the toc offset value
- of a symbol table into the ldinfo structure, for native rs6000
- config. */
- xcoff_add_toc_to_loadinfo_hook = &xcoff_add_toc_to_loadinfo;
+ generic_get_saved_register (raw_buffer, optimized, addrp,
+ frame, regnum, lval);
+}
+#endif
- /* Initialize hook in xcoffread for calling xcoff_init_loadinfo in
- a native rs6000 config. */
- xcoff_init_loadinfo_hook = &xcoff_init_loadinfo;
- }
-#endif /* ELF_OBJECT_FORMAT */
+void
+_initialize_rs6000_tdep ()
+{
/* FIXME, this should not be decided via ifdef. */
#ifdef GDB_TARGET_POWERPC
tm_print_insn = gdb_print_insn_powerpc;