blob: 7f075d55e3a149ba0eb8051be449e7ce77ce721c [file] [log] [blame]
From 7944750e435100e72913f01aa0a43b7d7cffd421 Mon Sep 17 00:00:00 2001
From: nagaraju <nmekala@xilix.com>
Date: Tue, 3 Sep 2013 12:09:47 +0530
Subject: [PATCH 08/16] [Patch, microblaze]: Added Backtrace support to GDB
Added backtrace support without debugging information.
Earlier backtrace used to work only when debug information is available.
Previous pc & sp values are calculated incorrectly due to which backtrace
was failing.
In this patch, previous frame sp & pc values are calculated correctly
in microblaze_frame_cache function and supplied them to
microblaze_frame_prev_register function
Signed-off-by:nagaraju <nmekala@xilix.com>
Upstream-Status: Pending
---
gdb/microblaze-tdep.c | 42 ++++++++++++++++++++++++++++++++++--------
gdb/microblaze-tdep.h | 5 +++--
2 files changed, 37 insertions(+), 10 deletions(-)
diff --git a/gdb/microblaze-tdep.c b/gdb/microblaze-tdep.c
index 0ce4947..247740e 100644
--- a/gdb/microblaze-tdep.c
+++ b/gdb/microblaze-tdep.c
@@ -225,6 +225,7 @@ microblaze_alloc_frame_cache (void)
/* Base address. */
cache->base = 0;
cache->pc = 0;
+ cache->saved_sp = 0;
/* Frameless until proven otherwise. */
cache->frameless_p = 1;
@@ -347,6 +348,7 @@ microblaze_analyze_prologue (struct gdbarch *gdbarch, CORE_ADDR pc,
cache->frameless_p = 0; /* Frame found. */
save_hidden_pointer_found = 0;
non_stack_instruction_found = 0;
+ cache->register_offsets[rd] = -imm;
continue;
}
else if (IS_SPILL_SP(op, rd, ra))
@@ -508,6 +510,7 @@ microblaze_skip_prologue (struct gdbarch *gdbarch, CORE_ADDR start_pc)
return start_pc;
}
+enum { REG_UNAVAIL = (CORE_ADDR) -1 };
/* Normal frames. */
static struct microblaze_frame_cache *
@@ -515,7 +518,7 @@ microblaze_frame_cache (struct frame_info *next_frame, void **this_cache)
{
struct microblaze_frame_cache *cache;
struct gdbarch *gdbarch = get_frame_arch (next_frame);
- CORE_ADDR func;
+ CORE_ADDR current_pc;
int rn;
if (*this_cache)
@@ -529,10 +532,18 @@ microblaze_frame_cache (struct frame_info *next_frame, void **this_cache)
for (rn = 0; rn < gdbarch_num_regs (gdbarch); rn++)
cache->register_offsets[rn] = -1;
- func = get_frame_func (next_frame);
+ cache->pc = get_frame_func (next_frame);
+ current_pc = get_frame_pc (next_frame);
+
+ if (cache->pc)
+ microblaze_analyze_prologue (gdbarch, cache->pc, current_pc,
+ cache);
cache->base = get_frame_register_unsigned (next_frame, gdbarch_sp_regnum (gdbarch));
- cache->pc = get_frame_address_in_block (next_frame);
+ cache->saved_sp = cache->base + cache->framesize;
+
+ cache->register_offsets[MICROBLAZE_PREV_PC_REGNUM] = cache->base;
+ cache->register_offsets[MICROBLAZE_SP_REGNUM] = cache->saved_sp;
return cache;
}
@@ -548,7 +559,7 @@ microblaze_frame_this_id (struct frame_info *next_frame, void **this_cache,
if (cache->base == 0)
return;
- (*this_id) = frame_id_build (cache->base, get_frame_pc (next_frame));
+ (*this_id) = frame_id_build (cache->base, cache->pc);
}
static struct value *
@@ -558,6 +569,14 @@ microblaze_frame_prev_register (struct frame_info *this_frame,
struct microblaze_frame_cache *cache =
microblaze_frame_cache (this_frame, this_cache);
+ if ((regnum == MICROBLAZE_SP_REGNUM &&
+ cache->register_offsets[MICROBLAZE_SP_REGNUM])
+ || (regnum == MICROBLAZE_FP_REGNUM &&
+ cache->register_offsets[MICROBLAZE_SP_REGNUM]))
+
+ return frame_unwind_got_constant (this_frame, regnum,
+ cache->register_offsets[MICROBLAZE_SP_REGNUM]);
+
if (cache->frameless_p)
{
if (regnum == MICROBLAZE_PC_REGNUM)
@@ -565,11 +584,18 @@ microblaze_frame_prev_register (struct frame_info *this_frame,
if (regnum == MICROBLAZE_SP_REGNUM)
regnum = 1;
return trad_frame_get_prev_register (this_frame,
- cache->saved_regs, regnum);
+ cache->saved_regs, regnum);
}
- else
- return trad_frame_get_prev_register (this_frame, cache->saved_regs,
- regnum);
+
+ if (regnum == MICROBLAZE_PC_REGNUM)
+ {
+ regnum = 15;
+ return frame_unwind_got_memory (this_frame, regnum,
+ cache->register_offsets[MICROBLAZE_PREV_PC_REGNUM]);
+ }
+
+ return trad_frame_get_prev_register (this_frame, cache->saved_regs,
+ regnum);
}
diff --git a/gdb/microblaze-tdep.h b/gdb/microblaze-tdep.h
index cd32e9f..14eb3ab 100644
--- a/gdb/microblaze-tdep.h
+++ b/gdb/microblaze-tdep.h
@@ -57,6 +57,7 @@ struct microblaze_frame_cache
/* Offsets to saved registers. */
int register_offsets[59]; /* Must match MICROBLAZE_NUM_REGS. */
+ CORE_ADDR saved_sp;
/* Table of saved registers. */
struct trad_frame_saved_reg *saved_regs;
@@ -80,11 +81,11 @@ enum microblaze_regnum
MICROBLAZE_R12_REGNUM,
MICROBLAZE_R13_REGNUM,
MICROBLAZE_R14_REGNUM,
- MICROBLAZE_R15_REGNUM,
+ MICROBLAZE_R15_REGNUM, MICROBLAZE_PREV_PC_REGNUM = MICROBLAZE_R15_REGNUM,
MICROBLAZE_R16_REGNUM,
MICROBLAZE_R17_REGNUM,
MICROBLAZE_R18_REGNUM,
- MICROBLAZE_R19_REGNUM,
+ MICROBLAZE_R19_REGNUM, MICROBLAZE_FP_REGNUM = MICROBLAZE_R19_REGNUM,
MICROBLAZE_R20_REGNUM,
MICROBLAZE_R21_REGNUM,
MICROBLAZE_R22_REGNUM,
--
1.9.0