diff options
Diffstat (limited to 'gdb/rs6000-xdep.c')
-rw-r--r-- | gdb/rs6000-xdep.c | 319 |
1 files changed, 28 insertions, 291 deletions
diff --git a/gdb/rs6000-xdep.c b/gdb/rs6000-xdep.c index b4a1851..a80ee14 100644 --- a/gdb/rs6000-xdep.c +++ b/gdb/rs6000-xdep.c @@ -1,5 +1,5 @@ /* IBM RS/6000 host-dependent code for GDB, the GNU debugger. - Copyright (C) 1986, 1987, 1989, 1991 Free Software Foundation, Inc. + Copyright 1986, 1987, 1989, 1991, 1992 Free Software Foundation, Inc. This file is part of GDB. @@ -23,6 +23,8 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #include "symtab.h" #include "target.h" +#ifdef RS6000_TARGET + #include <sys/param.h> #include <sys/dir.h> #include <sys/user.h> @@ -37,11 +39,11 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #include <sys/file.h> #include <sys/stat.h> #include <sys/core.h> -#include <sys/ldr.h> -#include <sys/utsname.h> extern int errno; -extern int attach_flag; + +static void +exec_one_dummy_insn PARAMS ((void)); /* Conversion from gdb-to-system special purpose register numbers.. */ @@ -54,13 +56,6 @@ static int special_regs[] = { XER, /* XER_REGNUM */ MQ /* MQ_REGNUM */ }; - - -/* Nonzero if we just simulated a single step break. */ -extern int one_stepped; - -extern struct obstack frame_cache_obstack; - void fetch_inferior_registers (regno) @@ -229,269 +224,10 @@ fetch_core_registers (core_reg_sect, core_reg_size, which, reg_addr) } -frameless_function_invocation (fi) -struct frame_info *fi; -{ - CORE_ADDR func_start; - struct aix_framedata fdata; - - 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 - to inspect the instructions. */ - - if (!func_start) - return 0; - - function_frame_info (func_start, &fdata); - return fdata.frameless; -} - - -/* If saved registers of frame FI are not known yet, read and cache them. - &FDATAP contains aix_framedata; TDATAP can be NULL, - in which case the framedata are read. - */ - -static void -frame_get_cache_fsr (fi, fdatap) - struct frame_info *fi; - struct aix_framedata *fdatap; -{ - int ii; - CORE_ADDR frame_addr; - struct aix_framedata work_fdata; - if (fi->cache_fsr) - return; - - if (fdatap == NULL) { - fdatap = &work_fdata; - function_frame_info (get_pc_function_start (fi->pc), fdatap); - } - - fi->cache_fsr = (struct frame_saved_regs *) - obstack_alloc (&frame_cache_obstack, sizeof (struct frame_saved_regs)); - bzero (fi->cache_fsr, sizeof (struct frame_saved_regs)); - - if (fi->prev && fi->prev->frame) - frame_addr = fi->prev->frame; - else - frame_addr = read_memory_integer (fi->frame, 4); - - /* if != -1, fdatap->saved_fpr is the smallest number of saved_fpr. - All fpr's from saved_fpr to fp31 are saved right underneath caller - stack pointer, starting from fp31 first. */ - - if (fdatap->saved_fpr >= 0) { - for (ii=31; ii >= fdatap->saved_fpr; --ii) - fi->cache_fsr->regs [FP0_REGNUM + ii] = frame_addr - ((32 - ii) * 8); - frame_addr -= (32 - fdatap->saved_fpr) * 8; - } - - /* if != -1, fdatap->saved_gpr is the smallest number of saved_gpr. - All gpr's from saved_gpr to gpr31 are saved right under saved fprs, - starting from r31 first. */ - - if (fdatap->saved_gpr >= 0) - for (ii=31; ii >= fdatap->saved_gpr; --ii) - fi->cache_fsr->regs [ii] = frame_addr - ((32 - ii) * 4); -} - -/* Return the address of a frame. This is the inital %sp value when the frame - was first allocated. For functions calling alloca(), it might be saved in - an alloca register. */ - -CORE_ADDR -frame_initial_stack_address (fi) - struct frame_info *fi; -{ - CORE_ADDR tmpaddr; - struct aix_framedata fdata; - struct frame_info *callee_fi; - - /* if the initial stack pointer (frame address) of this frame is known, - just return it. */ - - if (fi->initial_sp) - return fi->initial_sp; - - /* find out if this function is using an alloca register.. */ - - function_frame_info (get_pc_function_start (fi->pc), &fdata); - - /* if saved registers of this frame are not known yet, read and cache them. */ - - if (!fi->cache_fsr) - frame_get_cache_fsr (fi, &fdata); - - /* If no alloca register used, then fi->frame is the value of the %sp for - this frame, and it is good enough. */ - - if (fdata.alloca_reg < 0) { - fi->initial_sp = fi->frame; - return fi->initial_sp; - } - - /* This function has an alloca register. If this is the top-most frame - (with the lowest address), the value in alloca register is good. */ - - if (!fi->next) - return fi->initial_sp = read_register (fdata.alloca_reg); - - /* Otherwise, this is a caller frame. Callee has usually already saved - registers, but there are exceptions (such as when the callee - has no parameters). Find the address in which caller's alloca - register is saved. */ - - for (callee_fi = fi->next; callee_fi; callee_fi = callee_fi->next) { - - if (!callee_fi->cache_fsr) - frame_get_cache_fsr (fi, NULL); - - /* this is the address in which alloca register is saved. */ - - tmpaddr = callee_fi->cache_fsr->regs [fdata.alloca_reg]; - if (tmpaddr) { - fi->initial_sp = read_memory_integer (tmpaddr, 4); - return fi->initial_sp; - } - - /* Go look into deeper levels of the frame chain to see if any one of - the callees has saved alloca register. */ - } - - /* If alloca register was not saved, by the callee (or any of its callees) - then the value in the register is still good. */ - - return fi->initial_sp = read_register (fdata.alloca_reg); -} - - - -/* aixcoff_relocate_symtab - hook for symbol table relocation. - also reads shared libraries.. */ - -aixcoff_relocate_symtab (pid) -unsigned int pid; -{ -#define MAX_LOAD_SEGS 64 /* maximum number of load segments */ - - struct ld_info *ldi; - int temp; - - ldi = (void *) alloca(MAX_LOAD_SEGS * sizeof (*ldi)); - - /* According to my humble theory, aixcoff has some timing problems and - when the user stack grows, kernel doesn't update stack info in time - and ptrace calls step on user stack. That is why we sleep here a little, - and give kernel to update its internals. */ - - usleep (36000); - - errno = 0; - ptrace(PT_LDINFO, pid, (PTRACE_ARG3_TYPE) ldi, - MAX_LOAD_SEGS * sizeof(*ldi), ldi); - if (errno) { - perror_with_name ("ptrace ldinfo"); - return 0; - } - - vmap_ldinfo(ldi); - - do { - add_text_to_loadinfo (ldi->ldinfo_textorg, ldi->ldinfo_dataorg); - } while (ldi->ldinfo_next - && (ldi = (void *) (ldi->ldinfo_next + (char *) ldi))); - -#if 0 - /* Now that we've jumbled things around, re-sort them. */ - sort_minimal_symbols (); -#endif - - /* relocate the exec and core sections as well. */ - vmap_exec (); -} - - -/* 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. */ - -typedef struct { - unsigned long textorg, dataorg, toc_offset; -} LoadInfo; - -#define LOADINFOLEN 10 - -static LoadInfo *loadInfo = NULL; -static int loadInfoLen = 0; -static int loadInfoTocIndex = 0; -int aix_loadInfoTextIndex = 0; - - -xcoff_init_loadinfo () -{ - loadInfoTocIndex = 0; - aix_loadInfoTextIndex = 0; - - if (loadInfoLen == 0) { - loadInfo = (void*) xmalloc (sizeof (LoadInfo) * LOADINFOLEN); - loadInfoLen = LOADINFOLEN; - } -} - - -free_loadinfo () -{ - if (loadInfo) - free (loadInfo); - loadInfo = NULL; - loadInfoLen = 0; - loadInfoTocIndex = 0; - aix_loadInfoTextIndex = 0; -} - - -xcoff_add_toc_to_loadinfo (unsigned long tocaddr) -{ - while (loadInfoTocIndex >= loadInfoLen) { - loadInfoLen += LOADINFOLEN; - loadInfo = (void*) xrealloc (loadInfo, sizeof(LoadInfo) * loadInfoLen); - } - loadInfo [loadInfoTocIndex++].toc_offset = tocaddr; -} - - -add_text_to_loadinfo (unsigned long textaddr, unsigned long dataaddr) -{ - while (aix_loadInfoTextIndex >= loadInfoLen) { - loadInfoLen += LOADINFOLEN; - loadInfo = (void*) xrealloc (loadInfo, sizeof(LoadInfo) * loadInfoLen); - } - loadInfo [aix_loadInfoTextIndex].textorg = textaddr; - loadInfo [aix_loadInfoTextIndex].dataorg = dataaddr; - ++aix_loadInfoTextIndex; -} - - -unsigned long -find_toc_address (unsigned long pc) -{ - int ii, toc_entry, tocbase = 0; - - for (ii=0; ii < aix_loadInfoTextIndex; ++ii) - if (pc > loadInfo [ii].textorg && loadInfo [ii].textorg > tocbase) { - toc_entry = ii; - tocbase = loadInfo [ii].textorg; - } - - return loadInfo [toc_entry].dataorg + loadInfo [toc_entry].toc_offset; -} - - -/* execute one dummy breakpoint instruction. This way we give kernel +/* Execute one dummy breakpoint instruction. This way we give the kernel a chance to do some housekeeping and update inferior's internal data, including u_area. */ - +static void exec_one_dummy_insn () { #define DUMMY_INSN_ADDR (TEXT_SEGMENT_BASE)+0x200 @@ -517,28 +253,29 @@ exec_one_dummy_insn () } -#if 0 +#else /* RS6000_TARGET */ - *** not needed anymore *** +/* FIXME: Kludge this til we separate host vs. target vs. native code. */ -/* Return the number of initial trap signals we need to ignore once the inferior - process starts running. This will be `2' for aix-3.1, `3' for aix-3.2 */ - -int -aix_starting_inferior_traps () +void +fetch_inferior_registers (regno) + int regno; { - struct utsname unamebuf; +} - if (uname (&unamebuf) == -1) - fatal ("uname(3) failed."); +void +store_inferior_registers (regno) + int regno; +{ +} - /* Assume the future versions will behave like 3.2 and return '3' for - anything other than 3.1x. The extra trap in 3.2 is the "trap after the - program is loaded" signal. */ - - if (unamebuf.version[0] == '3' && unamebuf.release[0] == '1') - return 2; - else - return 3; +void +fetch_core_registers (core_reg_sect, core_reg_size, which, reg_addr) + char *core_reg_sect; + unsigned core_reg_size; + int which; + unsigned int reg_addr; /* Unused in this version */ +{ } -#endif + +#endif /* RS6000_TARGET */ |