From 44761ac746ef5b67b9aec11f633abffe052bcbcd Mon Sep 17 00:00:00 2001 From: Peter Schauer Date: Sat, 29 Oct 1994 09:56:38 +0000 Subject: [PATCH] * config/rs6000/tm-rs6000.h (INIT_EXTRA_FRAME_INFO): Don't test for zero backchain pointer to recognize a signal handler frame, if read() gets interrupted by a signal, the backchain will be non zero. (SIG_FRAME_FP_OFFSET): Move to here from rs6000-tdep.c, improve comment. (SIG_FRAME_PC_OFFSET): New definition. (FRAME_SAVED_PC): Return saved pc from sigcontext if this is a signal handler frame. * rs6000-tdep.c (function_frame_info): Do not error out if we can't access the instructions. * config/rs6000/tm-rs6000.h (CONVERT_FROM_FUNC_PTR_ADDR): New definition to get the function address from a function pointer. * valops.c (find_function_addr): Use it when calling a user function through a function pointer. --- gdb/config/rs6000/tm-rs6000.h | 60 ++++++++++++++++++----------------- 1 file changed, 31 insertions(+), 29 deletions(-) diff --git a/gdb/config/rs6000/tm-rs6000.h b/gdb/config/rs6000/tm-rs6000.h index 08e5221f082..5e63f826988 100644 --- a/gdb/config/rs6000/tm-rs6000.h +++ b/gdb/config/rs6000/tm-rs6000.h @@ -98,15 +98,6 @@ function_frame_info PARAMS ((CORE_ADDR, struct aix_framedata *)); #define SKIP_TRAMPOLINE_CODE(pc) skip_trampoline_code (pc) -/* When a child process is just starting, we sneak in and relocate - the symbol table (and other stuff) after the dynamic linker has - figured out where they go. */ - -#define SOLIB_CREATE_INFERIOR_HOOK(PID) \ - do { \ - xcoff_relocate_symtab (PID); \ - } while (0) - /* Number of trap signals we need to skip over, once the inferior process starts running. */ @@ -132,18 +123,6 @@ function_frame_info PARAMS ((CORE_ADDR, struct aix_framedata *)); #define PROCESS_LINENUMBER_HOOK() aix_process_linenos () -/* When a target process or core-file has been attached, we sneak in - and figure out where the shared libraries have got to. */ - -#define SOLIB_ADD(a, b, c) \ - if (inferior_pid) \ - /* Attach to process. */ \ - xcoff_relocate_symtab (inferior_pid); \ - else \ - /* Core file. */ \ - xcoff_relocate_core (); -extern void xcoff_relocate_core PARAMS ((void)); - /* Immediately after a function call, return the saved pc. Can't go through the frames for this because on some machines the new frame is not set up until the new function executes @@ -189,10 +168,6 @@ extern void xcoff_relocate_core PARAMS ((void)); #define ABOUT_TO_RETURN(pc) \ ((read_memory_integer (pc, 4) & 0xfe8007ff) == 0x4e800020) -/* Return 1 if P points to an invalid floating point value. */ - -#define INVALID_FLOAT(p, len) 0 /* Just a first guess; not checked */ - /* Say how long (ordinary) registers are. This is a piece of bogosity used in push_word and a few other places; REGISTER_RAW_SIZE is the real way to know how big a register is. */ @@ -345,7 +320,7 @@ extern CORE_ADDR rs6000_struct_return_address; #define STORE_STRUCT_RETURN(ADDR, SP) \ { write_register (3, (ADDR)); \ - rs6000_struct_return_address = (unsigned int)(ADDR); } + rs6000_struct_return_address = (ADDR); } /* Extract from an array REGBUF containing the (raw) register state a function return value of type TYPE, and copy that, in virtual format, @@ -426,13 +401,23 @@ CORE_ADDR rs6000_frame_chain PARAMS ((struct frame_info *)); fi->initial_sp = 0; \ fi->cache_fsr = 0; \ if (fi->next != (CORE_ADDR)0 \ - && read_memory_integer (fi->frame, 4) == 0 \ && fi->pc < TEXT_SEGMENT_BASE) \ /* We're in get_prev_frame_info */ \ /* and this is a special signal frame. */ \ - /* (fi->pc will be something like 0x3f88 or 0x2790). */ \ + /* (fi->pc will be some low address in the kernel, */ \ + /* to which the signal handler returns). */ fi->signal_handler_caller = 1; +/* If the kernel has to deliver a signal, it pushes a sigcontext + structure on the stack and then calls the signal handler, passing + the address of the sigcontext in an argument register. Usually + the signal handler doesn't save this register, so we have to + access the sigcontext structure via an offset from the signal handler + frame. + The following constants were determined by experimentation on AIX 3.2. */ +#define SIG_FRAME_PC_OFFSET 96 +#define SIG_FRAME_FP_OFFSET 284 + /* Frameless function invocation in IBM RS/6000 is sometimes half-done. It perfectly sets up a new frame, e.g. a new frame (in fact stack) pointer, etc, but it doesn't save the %pc. We call @@ -441,7 +426,9 @@ CORE_ADDR rs6000_frame_chain PARAMS ((struct frame_info *)); #define FRAME_SAVED_PC(FRAME) \ (frameless_function_invocation (FRAME, 1) \ ? SAVED_PC_AFTER_CALL (FRAME) \ - : read_memory_integer (rs6000_frame_chain (FRAME)+8, 4)) + : (FRAME)->signal_handler_caller \ + ? read_memory_integer ((FRAME)->frame + SIG_FRAME_PC_OFFSET, 4) \ + : read_memory_integer (rs6000_frame_chain (FRAME) + 8, 4)) #define FRAME_ARGS_ADDRESS(FI) \ (((struct frame_info*)(FI))->initial_sp ? \ @@ -579,6 +566,21 @@ CORE_ADDR rs6000_frame_chain PARAMS ((struct frame_info *)); #define FIX_CALL_DUMMY(dummyname, pc, fun, nargs, args, type, using_gcc) \ fix_call_dummy(dummyname, pc, fun, nargs, type) +/* Usually a function pointer's representation is simply the address of + the function. On the RS/6000 however, a function pointer is represented + by a pointer to a TOC entry. This TOC entry contains three words, + the first word is the address of the function, the second word is the + TOC pointer (r2), and the third word is the static chain value. + Throughout GDB it is currently assumed that a function pointer contains + the address of the function, which is not easy to fix. + In addition, the conversion of a function address to a function + pointer would require allocation of a TOC entry in the inferior's + memory space, with all its drawbacks. + To be able to call C++ virtual methods in the inferior (which are called + via function pointers), find_function_addr uses this macro to + get the function address from a function pointer. */ +#define CONVERT_FROM_FUNC_PTR_ADDR(ADDR) read_memory_integer (ADDR, 4) + /* Flag for machine-specific stuff in shared files. FIXME */ #define IBM6000_TARGET -- 2.30.2