aboutsummaryrefslogtreecommitdiffstats
path: root/recipes-microblaze/gdb/files/0008-Patch-microblaze-Added-Backtrace-support-to-GDB.patch
blob: 7f075d55e3a149ba0eb8051be449e7ce77ce721c (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
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