blob: 7f075d55e3a149ba0eb8051be449e7ce77ce721c [file] [log] [blame]
Brad Bishop286d45c2018-10-02 15:21:57 -04001From 7944750e435100e72913f01aa0a43b7d7cffd421 Mon Sep 17 00:00:00 2001
2From: nagaraju <nmekala@xilix.com>
3Date: Tue, 3 Sep 2013 12:09:47 +0530
4Subject: [PATCH 08/16] [Patch, microblaze]: Added Backtrace support to GDB
5
6Added backtrace support without debugging information.
7
8Earlier backtrace used to work only when debug information is available.
9Previous pc & sp values are calculated incorrectly due to which backtrace
10was failing.
11
12In this patch, previous frame sp & pc values are calculated correctly
13in microblaze_frame_cache function and supplied them to
14microblaze_frame_prev_register function
15
16Signed-off-by:nagaraju <nmekala@xilix.com>
17Upstream-Status: Pending
18---
19 gdb/microblaze-tdep.c | 42 ++++++++++++++++++++++++++++++++++--------
20 gdb/microblaze-tdep.h | 5 +++--
21 2 files changed, 37 insertions(+), 10 deletions(-)
22
23diff --git a/gdb/microblaze-tdep.c b/gdb/microblaze-tdep.c
24index 0ce4947..247740e 100644
25--- a/gdb/microblaze-tdep.c
26+++ b/gdb/microblaze-tdep.c
27@@ -225,6 +225,7 @@ microblaze_alloc_frame_cache (void)
28 /* Base address. */
29 cache->base = 0;
30 cache->pc = 0;
31+ cache->saved_sp = 0;
32
33 /* Frameless until proven otherwise. */
34 cache->frameless_p = 1;
35@@ -347,6 +348,7 @@ microblaze_analyze_prologue (struct gdbarch *gdbarch, CORE_ADDR pc,
36 cache->frameless_p = 0; /* Frame found. */
37 save_hidden_pointer_found = 0;
38 non_stack_instruction_found = 0;
39+ cache->register_offsets[rd] = -imm;
40 continue;
41 }
42 else if (IS_SPILL_SP(op, rd, ra))
43@@ -508,6 +510,7 @@ microblaze_skip_prologue (struct gdbarch *gdbarch, CORE_ADDR start_pc)
44 return start_pc;
45 }
46
47+enum { REG_UNAVAIL = (CORE_ADDR) -1 };
48 /* Normal frames. */
49
50 static struct microblaze_frame_cache *
51@@ -515,7 +518,7 @@ microblaze_frame_cache (struct frame_info *next_frame, void **this_cache)
52 {
53 struct microblaze_frame_cache *cache;
54 struct gdbarch *gdbarch = get_frame_arch (next_frame);
55- CORE_ADDR func;
56+ CORE_ADDR current_pc;
57 int rn;
58
59 if (*this_cache)
60@@ -529,10 +532,18 @@ microblaze_frame_cache (struct frame_info *next_frame, void **this_cache)
61 for (rn = 0; rn < gdbarch_num_regs (gdbarch); rn++)
62 cache->register_offsets[rn] = -1;
63
64- func = get_frame_func (next_frame);
65+ cache->pc = get_frame_func (next_frame);
66+ current_pc = get_frame_pc (next_frame);
67+
68+ if (cache->pc)
69+ microblaze_analyze_prologue (gdbarch, cache->pc, current_pc,
70+ cache);
71
72 cache->base = get_frame_register_unsigned (next_frame, gdbarch_sp_regnum (gdbarch));
73- cache->pc = get_frame_address_in_block (next_frame);
74+ cache->saved_sp = cache->base + cache->framesize;
75+
76+ cache->register_offsets[MICROBLAZE_PREV_PC_REGNUM] = cache->base;
77+ cache->register_offsets[MICROBLAZE_SP_REGNUM] = cache->saved_sp;
78
79 return cache;
80 }
81@@ -548,7 +559,7 @@ microblaze_frame_this_id (struct frame_info *next_frame, void **this_cache,
82 if (cache->base == 0)
83 return;
84
85- (*this_id) = frame_id_build (cache->base, get_frame_pc (next_frame));
86+ (*this_id) = frame_id_build (cache->base, cache->pc);
87 }
88
89 static struct value *
90@@ -558,6 +569,14 @@ microblaze_frame_prev_register (struct frame_info *this_frame,
91 struct microblaze_frame_cache *cache =
92 microblaze_frame_cache (this_frame, this_cache);
93
94+ if ((regnum == MICROBLAZE_SP_REGNUM &&
95+ cache->register_offsets[MICROBLAZE_SP_REGNUM])
96+ || (regnum == MICROBLAZE_FP_REGNUM &&
97+ cache->register_offsets[MICROBLAZE_SP_REGNUM]))
98+
99+ return frame_unwind_got_constant (this_frame, regnum,
100+ cache->register_offsets[MICROBLAZE_SP_REGNUM]);
101+
102 if (cache->frameless_p)
103 {
104 if (regnum == MICROBLAZE_PC_REGNUM)
105@@ -565,11 +584,18 @@ microblaze_frame_prev_register (struct frame_info *this_frame,
106 if (regnum == MICROBLAZE_SP_REGNUM)
107 regnum = 1;
108 return trad_frame_get_prev_register (this_frame,
109- cache->saved_regs, regnum);
110+ cache->saved_regs, regnum);
111 }
112- else
113- return trad_frame_get_prev_register (this_frame, cache->saved_regs,
114- regnum);
115+
116+ if (regnum == MICROBLAZE_PC_REGNUM)
117+ {
118+ regnum = 15;
119+ return frame_unwind_got_memory (this_frame, regnum,
120+ cache->register_offsets[MICROBLAZE_PREV_PC_REGNUM]);
121+ }
122+
123+ return trad_frame_get_prev_register (this_frame, cache->saved_regs,
124+ regnum);
125
126 }
127
128diff --git a/gdb/microblaze-tdep.h b/gdb/microblaze-tdep.h
129index cd32e9f..14eb3ab 100644
130--- a/gdb/microblaze-tdep.h
131+++ b/gdb/microblaze-tdep.h
132@@ -57,6 +57,7 @@ struct microblaze_frame_cache
133
134 /* Offsets to saved registers. */
135 int register_offsets[59]; /* Must match MICROBLAZE_NUM_REGS. */
136+ CORE_ADDR saved_sp;
137
138 /* Table of saved registers. */
139 struct trad_frame_saved_reg *saved_regs;
140@@ -80,11 +81,11 @@ enum microblaze_regnum
141 MICROBLAZE_R12_REGNUM,
142 MICROBLAZE_R13_REGNUM,
143 MICROBLAZE_R14_REGNUM,
144- MICROBLAZE_R15_REGNUM,
145+ MICROBLAZE_R15_REGNUM, MICROBLAZE_PREV_PC_REGNUM = MICROBLAZE_R15_REGNUM,
146 MICROBLAZE_R16_REGNUM,
147 MICROBLAZE_R17_REGNUM,
148 MICROBLAZE_R18_REGNUM,
149- MICROBLAZE_R19_REGNUM,
150+ MICROBLAZE_R19_REGNUM, MICROBLAZE_FP_REGNUM = MICROBLAZE_R19_REGNUM,
151 MICROBLAZE_R20_REGNUM,
152 MICROBLAZE_R21_REGNUM,
153 MICROBLAZE_R22_REGNUM,
154--
1551.9.0
156