/* Target-dependent code for GDB, the GNU debugger.
- Copyright 1986, 1987, 1989, 1991, 1992, 1993, 1994, 1995
+ Copyright 1986, 1987, 1989, 1991, 1992, 1993, 1994, 1995, 1996
Free Software Foundation, Inc.
This file is part of GDB.
#include "gdbcore.h"
#include "symfile.h"
#include "objfiles.h"
-
#include "xcoffsolib.h"
-#include <a.out.h>
-
extern struct obstack frame_cache_obstack;
extern int errno;
/* Static function prototypes */
-static CORE_ADDR
-find_toc_address PARAMS ((CORE_ADDR pc));
+static CORE_ADDR find_toc_address PARAMS ((CORE_ADDR pc));
-static CORE_ADDR
-branch_dest PARAMS ((int opcode, int instr, CORE_ADDR pc, CORE_ADDR safety));
+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 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. */
-/*
- * Calculate the destination of a branch/jump. Return -1 if not a branch.
- */
static CORE_ADDR
branch_dest (opcode, instr, pc, safety)
int opcode;
CORE_ADDR pc;
CORE_ADDR safety;
{
- register long offset;
CORE_ADDR dest;
int immediate;
int absolute;
void
single_step (signal)
- int signal;
+ enum target_signal signal;
{
#define INSNLEN(OPCODE) 4
/* 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 */
GDB process that keeps track of these dummy frames! -- gnu@cygnus.com Aug92
*/
+static void
pop_dummy_frame ()
{
CORE_ADDR sp, pc;
its argumets will be passed by gdb. */
void
-fix_call_dummy(dummyname, pc, fun, nargs, type)
- char *dummyname;
- CORE_ADDR pc;
- CORE_ADDR fun;
- int nargs; /* not used */
- int type; /* not used */
+fix_call_dummy (dummyname, pc, fun, nargs, type)
+ char *dummyname;
+ CORE_ADDR pc;
+ CORE_ADDR fun;
+ int nargs; /* not used */
+ int type; /* not used */
{
#define TOC_ADDR_OFFSET 20
#define TARGET_ADDR_OFFSET 28
*(int*)((char*)dummyname + TARGET_ADDR_OFFSET+4) = ii;
}
-/* Pass the arguments in either registers, or in the stack. In RS6000, the first
- eight words of the argument list (that might be less than eight parameters if
- some parameters occupy more than one word) are passed in r3..r11 registers.
- float and double parameters are passed in fpr's, in addition to that. Rest of
- the parameters if any are passed in user stack. There might be cases in which
- half of the parameter is copied into registers, the other half is pushed into
+/* Pass the arguments in either registers, or in the stack. In RS6000,
+ the first eight words of the argument list (that might be less than
+ eight parameters if some parameters occupy more than one word) are
+ passed in r3..r11 registers. float and double parameters are
+ passed in fpr's, in addition to that. Rest of the parameters if any
+ are passed in user stack. There might be cases in which half of the
+ parameter is copied into registers, the other half is pushed into
stack.
If the function is returning a structure, then the return address is passed
CORE_ADDR
push_arguments (nargs, args, sp, struct_return, struct_addr)
- int nargs;
- value_ptr *args;
- CORE_ADDR sp;
- int struct_return;
- CORE_ADDR struct_addr;
+ int nargs;
+ value_ptr *args;
+ CORE_ADDR sp;
+ 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];
- value_ptr arg;
int f_argno = 0; /* current floating point argno */
+ value_ptr arg = 0;
+ struct type *type;
- CORE_ADDR saved_sp, pc;
+ CORE_ADDR saved_sp;
if ( dummy_frame_count <= 0)
printf_unfiltered ("FATAL ERROR -push_arguments()! frame not found!!\n");
for (argno=0, argbytes=0; argno < nargs && ii<8; ++ii) {
arg = args[argno];
- len = TYPE_LENGTH (VALUE_TYPE (arg));
+ type = check_typedef (VALUE_TYPE (arg));
+ len = TYPE_LENGTH (type);
- if (TYPE_CODE (VALUE_TYPE (arg)) == TYPE_CODE_FLT) {
+ if (TYPE_CODE (type) == TYPE_CODE_FLT) {
/* floating point arguments are passed in fpr's, as well as gpr's.
There are 13 fpr's reserved for passing parameters. At this point
if ((argno < nargs) || argbytes) {
int space = 0, jj;
- value_ptr val;
if (argbytes) {
space += ((len - argbytes + 3) & -4);
jj = argno;
for (; jj < nargs; ++jj) {
- val = args[jj];
+ value_ptr val = args[jj];
space += ((TYPE_LENGTH (VALUE_TYPE (val))) + 3) & -4;
}
for (; argno < nargs; ++argno) {
arg = args[argno];
- len = TYPE_LENGTH (VALUE_TYPE (arg));
+ type = check_typedef (VALUE_TYPE (arg));
+ len = TYPE_LENGTH (type);
/* float types should be passed in fpr's, as well as in the stack. */
- if (TYPE_CODE (VALUE_TYPE (arg)) == TYPE_CODE_FLT && f_argno < 13) {
+ if (TYPE_CODE (type) == TYPE_CODE_FLT && f_argno < 13) {
if (len > 8)
printf_unfiltered (
void
extract_return_value (valtype, regbuf, valbuf)
- struct type *valtype;
- char regbuf[REGISTER_BYTES];
- char *valbuf;
+ struct type *valtype;
+ char regbuf[REGISTER_BYTES];
+ char *valbuf;
{
int offset = 0;
CORE_ADDR
skip_trampoline_code (pc)
-CORE_ADDR pc;
+ CORE_ADDR pc;
{
register unsigned int ii, op;
CORE_ADDR solib_target_pc;
return pc;
}
-
/* Determines whether the function FI has a frame on the stack or not. */
+
int
frameless_function_invocation (fi)
struct frame_info *fi;
}
/* Return the PC saved in a frame */
+
unsigned long
frame_saved_pc (fi)
struct frame_info *fi;
{
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);
/* FIXME -- this is never called! */
+#if 0
void
free_loadinfo ()
{
loadinfotocindex = 0;
loadinfotextindex = 0;
}
+#endif
/* this is called from xcoffread.c */
}
-/* 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. */
+/* 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)
void
_initialize_rs6000_tdep ()
{
+#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;
+
+ /* 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 */
+
/* FIXME, this should not be decided via ifdef. */
#ifdef GDB_TARGET_POWERPC
tm_print_insn = gdb_print_insn_powerpc;