aboutsummaryrefslogtreecommitdiff
path: root/gdb/config/rs6000
diff options
context:
space:
mode:
authorMichael Meissner <gnu@the-meissners.org>1995-07-27 03:50:05 +0000
committerMichael Meissner <gnu@the-meissners.org>1995-07-27 03:50:05 +0000
commit068c9fd63f9a7ca5ec8ebc5aa1f758a4ea9f0405 (patch)
tree4ea09c249b72fefff8e3c3cea37a7b462f2b942e /gdb/config/rs6000
parentddb97850d08a3e6ee06edf061a82bce2b9b26e87 (diff)
downloadfsf-binutils-gdb-068c9fd63f9a7ca5ec8ebc5aa1f758a4ea9f0405.zip
fsf-binutils-gdb-068c9fd63f9a7ca5ec8ebc5aa1f758a4ea9f0405.tar.gz
fsf-binutils-gdb-068c9fd63f9a7ca5ec8ebc5aa1f758a4ea9f0405.tar.bz2
Better support V.4 calling sequences.
Diffstat (limited to 'gdb/config/rs6000')
-rw-r--r--gdb/config/rs6000/tm-rs6000.h96
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; \
+ } \
}