diff options
author | Michael Meissner <gnu@the-meissners.org> | 1995-07-27 03:50:05 +0000 |
---|---|---|
committer | Michael Meissner <gnu@the-meissners.org> | 1995-07-27 03:50:05 +0000 |
commit | 068c9fd63f9a7ca5ec8ebc5aa1f758a4ea9f0405 (patch) | |
tree | 4ea09c249b72fefff8e3c3cea37a7b462f2b942e /gdb/config/rs6000 | |
parent | ddb97850d08a3e6ee06edf061a82bce2b9b26e87 (diff) | |
download | gdb-068c9fd63f9a7ca5ec8ebc5aa1f758a4ea9f0405.zip gdb-068c9fd63f9a7ca5ec8ebc5aa1f758a4ea9f0405.tar.gz gdb-068c9fd63f9a7ca5ec8ebc5aa1f758a4ea9f0405.tar.bz2 |
Better support V.4 calling sequences.
Diffstat (limited to 'gdb/config/rs6000')
-rw-r--r-- | gdb/config/rs6000/tm-rs6000.h | 96 |
1 files changed, 58 insertions, 38 deletions
diff --git a/gdb/config/rs6000/tm-rs6000.h b/gdb/config/rs6000/tm-rs6000.h index 31a49ef..8995d73 100644 --- a/gdb/config/rs6000/tm-rs6000.h +++ b/gdb/config/rs6000/tm-rs6000.h @@ -56,7 +56,7 @@ struct fp_status { }; -/* To be used by function_frame_info. */ +/* To be used by skip_prologue. */ struct rs6000_framedata { int offset; /* # of bytes in gpr's and fpr's are saved */ @@ -65,11 +65,12 @@ struct rs6000_framedata { int alloca_reg; /* alloca register number (frame ptr) */ char frameless; /* true if frameless functions. */ char nosavedpc; /* true if pc not saved. */ + int gpr_offset; /* offset of saved gprs */ + int fpr_offset; /* offset of saved fprs */ + int lr_offset; /* offset of saved lr */ + int cr_offset; /* offset of saved cr */ }; -void -function_frame_info PARAMS ((CORE_ADDR, struct rs6000_framedata *)); - /* Define the byte order of the machine. */ #define TARGET_BYTE_ORDER BIG_ENDIAN @@ -87,7 +88,14 @@ function_frame_info PARAMS ((CORE_ADDR, struct rs6000_framedata *)); /* Advance PC across any function entry prologue instructions to reach some "real" code. */ -#define SKIP_PROLOGUE(pc) pc = skip_prologue (pc) +#define SKIP_PROLOGUE(pc) \ +do { \ + struct rs6000_framedata _frame; \ + pc = skip_prologue (pc, &_frame); \ +} while (0) + +extern CORE_ADDR skip_prologue PARAMS((CORE_ADDR, struct rs6000_framedata *)); + /* If PC is in some function-call trampoline code, return the PC where the function itself actually starts. If not, return NULL. */ @@ -386,7 +394,9 @@ CORE_ADDR rs6000_frame_chain PARAMS ((struct frame_info *)); does not, FRAMELESS is set to 1, else 0. */ #define FRAMELESS_FUNCTION_INVOCATION(FI, FRAMELESS) \ - FRAMELESS = frameless_function_invocation (FI, 0) + FRAMELESS = frameless_function_invocation (FI) + +extern int frameless_function_invocation PARAMS((struct frame_info *)); /* Functions calling alloca() change the value of the stack pointer. We need to use initial stack pointer (which is saved in r31 by gcc) in @@ -424,17 +434,10 @@ CORE_ADDR rs6000_frame_chain PARAMS ((struct frame_info *)); #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 - frameless_function_invocation to tell us how to get the %pc. */ +/* Return saved PC from a frame */ +#define FRAME_SAVED_PC(FRAME) frame_saved_pc (FRAME) -#define FRAME_SAVED_PC(FRAME) \ - (frameless_function_invocation (FRAME, 1) \ - ? SAVED_PC_AFTER_CALL (FRAME) \ - : (FRAME)->signal_handler_caller \ - ? read_memory_integer ((FRAME)->frame + SIG_FRAME_PC_OFFSET, 4) \ - : read_memory_integer (rs6000_frame_chain (FRAME) + 8, 4)) +extern unsigned long frame_saved_pc PARAMS ((struct frame_info *)); #define FRAME_ARGS_ADDRESS(FI) \ (((struct frame_info*)(FI))->initial_sp ? \ @@ -471,40 +474,57 @@ CORE_ADDR rs6000_frame_chain PARAMS ((struct frame_info *)); CORE_ADDR frame_addr, func_start; \ struct rs6000_framedata fdata; \ \ - /* find the start of the function and collect info about its frame. */\ + /* find the start of the function and collect info about its frame. */ \ \ func_start = get_pc_function_start ((FRAME_INFO)->pc) + FUNCTION_START_OFFSET; \ - function_frame_info (func_start, &fdata); \ - memset (&(FRAME_SAVED_REGS), '\0', sizeof (FRAME_SAVED_REGS)); \ + (void) skip_prologue (func_start, &fdata); \ + memset (&(FRAME_SAVED_REGS), '\0', sizeof (FRAME_SAVED_REGS)); \ \ /* if there were any saved registers, figure out parent's stack pointer. */ \ - frame_addr = 0; \ /* the following is true only if the frame doesn't have a call to alloca(), \ FIXME. */ \ - if (fdata.saved_fpr >= 0 || fdata.saved_gpr >= 0) { \ - if ((FRAME_INFO)->prev && (FRAME_INFO)->prev->frame) \ - frame_addr = (FRAME_INFO)->prev->frame; \ - else \ - frame_addr = read_memory_integer ((FRAME_INFO)->frame, 4); \ - } \ + if (fdata.saved_fpr == 0 && fdata.saved_gpr == 0 && \ + fdata.lr_offset == 0 && fdata.cr_offset == 0) { \ + frame_addr = 0; \ \ - /* if != -1, fdata.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. */ \ + } else if ((FRAME_INFO)->prev && (FRAME_INFO)->prev->frame) { \ + frame_addr = (FRAME_INFO)->prev->frame; \ \ + } else { \ + frame_addr = read_memory_integer ((FRAME_INFO)->frame, 4); \ + } \ + \ + /* if != -1, fdata.saved_fpr is the smallest number of saved_fpr. All \ + fpr's from saved_fpr to f31 are saved. */ \ if (fdata.saved_fpr >= 0) { \ - for (ii=31; ii >= fdata.saved_fpr; --ii) \ - (FRAME_SAVED_REGS).regs [FP0_REGNUM + ii] = frame_addr - ((32 - ii) * 8); \ - frame_addr -= (32 - fdata.saved_fpr) * 8; \ + int fpr_offset = frame_addr + fdata.fpr_offset; \ + for (ii = fdata.saved_fpr; ii < 32; ii++) { \ + (FRAME_SAVED_REGS).regs [FP0_REGNUM + ii] = fpr_offset; \ + fpr_offset += 8; \ + } \ + } \ + \ + /* if != -1, fdata.saved_gpr is the smallest number of saved_gpr. All \ + gpr's from saved_gpr to r31 are saved. */ \ + if (fdata.saved_gpr >= 0) { \ + int gpr_offset = frame_addr + fdata.gpr_offset; \ + for (ii = fdata.saved_gpr; ii < 32; ii++) { \ + (FRAME_SAVED_REGS).regs [ii] = gpr_offset; \ + gpr_offset += 4; \ + } \ } \ \ - /* if != -1, fdata.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 != 0, fdata.cr_offset is the offset from the frame that holds \ + the CR */ \ + if (fdata.cr_offset != 0) { \ + (FRAME_SAVED_REGS).regs [CR_REGNUM] = frame_addr + fdata.cr_offset; \ + } \ \ - if (fdata.saved_gpr >= 0) \ - for (ii=31; ii >= fdata.saved_gpr; --ii) \ - (FRAME_SAVED_REGS).regs [ii] = frame_addr - ((32 - ii) * 4); \ + /* If != 0, fdata.cr_offset is the offset from the frame that holds \ + the LR */ \ + if (fdata.lr_offset != 0) { \ + (FRAME_SAVED_REGS).regs [LR_REGNUM] = frame_addr + fdata.lr_offset; \ + } \ } |