aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gdb/rs6000-tdep.c49
1 files changed, 35 insertions, 14 deletions
diff --git a/gdb/rs6000-tdep.c b/gdb/rs6000-tdep.c
index 4c41808..c53e542 100644
--- a/gdb/rs6000-tdep.c
+++ b/gdb/rs6000-tdep.c
@@ -292,6 +292,12 @@ skip_prologue (pc, fdata)
continue;
} else if ((op & 0xfc000000) == 0x48000000) { /* bl foo, to save fprs??? */
+
+ /* Don't skip over the subroutine call if it is not within the first
+ three instructions of the prologue. */
+ if ((pc - orig_pc) > 8)
+ break;
+
op = read_memory_integer (pc+4, 4);
/* At this point, make sure this is not a trampoline function
@@ -300,7 +306,7 @@ skip_prologue (pc, fdata)
prologue. */
if (op == 0x4def7b82 || op == 0) /* crorc 15, 15, 15 */
- return pc; /* don't skip over this branch */
+ break; /* don't skip over this branch */
continue;
@@ -335,6 +341,7 @@ skip_prologue (pc, fdata)
} else if (op == 0x603f0000 /* oril r31, r1, 0x0 */
|| op == 0x7c3f0b78) { /* mr r31, r1 */
framep = 1;
+ fdata->alloca_reg = 31;
continue;
} else {
@@ -927,6 +934,9 @@ frame_saved_pc (fi)
struct rs6000_framedata fdata;
int frameless;
+ if (fi->signal_handler_caller)
+ return read_memory_integer (fi->frame + SIG_FRAME_PC_OFFSET, 4);
+
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
@@ -936,9 +946,6 @@ frame_saved_pc (fi)
(void) skip_prologue (func_start, &fdata);
- if (fi->signal_handler_caller)
- return read_memory_integer (fi->frame + SIG_FRAME_PC_OFFSET, 4);
-
if (fdata.lr_offset == 0 && fi->next != NULL)
return read_memory_integer (rs6000_frame_chain (fi) + DEFAULT_LR_SAVE, 4);
@@ -979,22 +986,36 @@ frame_get_cache_fsr (fi, fdatap)
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. */
+ All fpr's from saved_fpr to fp31 are saved. */
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;
+ int fpr_offset = frame_addr + fdatap->fpr_offset;
+ for (ii = fdatap->saved_fpr; ii < 32; ii++) {
+ fi->cache_fsr->regs [FP0_REGNUM + ii] = fpr_offset;
+ fpr_offset += 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. */
+ All gpr's from saved_gpr to gpr31 are saved. */
- if (fdatap->saved_gpr >= 0)
- for (ii=31; ii >= fdatap->saved_gpr; --ii)
- fi->cache_fsr->regs [ii] = frame_addr - ((32 - ii) * 4);
+ if (fdatap->saved_gpr >= 0) {
+ int gpr_offset = frame_addr + fdatap->gpr_offset;
+ for (ii = fdatap->saved_gpr; ii < 32; ii++) {
+ fi->cache_fsr->regs [ii] = gpr_offset;
+ gpr_offset += 4;
+ }
+ }
+
+ /* If != 0, fdatap->cr_offset is the offset from the frame that holds
+ the CR. */
+ if (fdatap->cr_offset != 0)
+ fi->cache_fsr->regs [CR_REGNUM] = frame_addr + fdatap->cr_offset;
+
+ /* If != 0, fdatap->lr_offset is the offset from the frame that holds
+ the LR. */
+ if (fdatap->lr_offset != 0)
+ fi->cache_fsr->regs [LR_REGNUM] = frame_addr + fdatap->lr_offset;
}
/* Return the address of a frame. This is the inital %sp value when the frame