blob: 4f4d2182f25901b1b978ad5fa58faba856771a14 [file] [log] [blame]
Jason Molendaab4f1922010-10-25 11:12:07 +00001//===-- UnwindLLDB.cpp -------------------------------------*- C++ -*-===//
2//
3// The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9
Greg Claytondc5eb692011-04-25 18:36:36 +000010#include "lldb/Core/Module.h"
11#include "lldb/Core/Log.h"
12#include "lldb/Symbol/FuncUnwinders.h"
13#include "lldb/Symbol/Function.h"
14#include "lldb/Symbol/UnwindPlan.h"
Jason Molendaab4f1922010-10-25 11:12:07 +000015#include "lldb/Target/Thread.h"
16#include "lldb/Target/Target.h"
17#include "lldb/Target/Process.h"
18#include "lldb/Target/RegisterContext.h"
Jason Molendaab4f1922010-10-25 11:12:07 +000019
Greg Claytone576ab22011-02-15 00:19:15 +000020#include "UnwindLLDB.h"
21#include "RegisterContextLLDB.h"
22
Jason Molendaab4f1922010-10-25 11:12:07 +000023using namespace lldb;
24using namespace lldb_private;
25
26UnwindLLDB::UnwindLLDB (Thread &thread) :
27 Unwind (thread),
Jim Inghamb0c72a52012-02-29 03:40:22 +000028 m_frames(),
29 m_unwind_complete(false)
Jason Molendaab4f1922010-10-25 11:12:07 +000030{
31}
32
33uint32_t
Jim Ingham8f077162011-10-21 01:49:48 +000034UnwindLLDB::DoGetFrameCount()
Jason Molendaab4f1922010-10-25 11:12:07 +000035{
Jim Inghamb0c72a52012-02-29 03:40:22 +000036 if (!m_unwind_complete)
Jason Molendaab4f1922010-10-25 11:12:07 +000037 {
Greg Clayton58be07b2011-01-07 06:08:19 +000038//#define DEBUG_FRAME_SPEED 1
39#if DEBUG_FRAME_SPEED
Greg Clayton3e06bd92011-01-09 21:07:35 +000040#define FRAME_COUNT 10000
Greg Clayton58be07b2011-01-07 06:08:19 +000041 TimeValue time_value (TimeValue::Now());
42#endif
Jason Molenda8fed2952010-11-09 02:31:21 +000043 if (!AddFirstFrame ())
Jason Molendaab4f1922010-10-25 11:12:07 +000044 return 0;
Greg Clayton9b72eb72011-05-24 23:06:02 +000045
Greg Clayton1ac04c32012-02-21 00:09:25 +000046 ProcessSP process_sp (m_thread.GetProcess());
47 ABI *abi = process_sp ? process_sp->GetABI().get() : NULL;
Greg Clayton9b72eb72011-05-24 23:06:02 +000048
49 while (AddOneMoreFrame (abi))
Greg Clayton58be07b2011-01-07 06:08:19 +000050 {
51#if DEBUG_FRAME_SPEED
Greg Clayton3e06bd92011-01-09 21:07:35 +000052 if ((m_frames.size() % FRAME_COUNT) == 0)
Greg Clayton58be07b2011-01-07 06:08:19 +000053 {
54 TimeValue now(TimeValue::Now());
55 uint64_t delta_t = now - time_value;
Daniel Malead01b2952012-11-29 21:49:15 +000056 printf ("%u frames in %" PRIu64 ".%09llu ms (%g frames/sec)\n",
Greg Clayton3e06bd92011-01-09 21:07:35 +000057 FRAME_COUNT,
Peter Collingbourneba23ca02011-06-18 23:52:14 +000058 delta_t / TimeValue::NanoSecPerSec,
59 delta_t % TimeValue::NanoSecPerSec,
60 (float)FRAME_COUNT / ((float)delta_t / (float)TimeValue::NanoSecPerSec));
Greg Clayton58be07b2011-01-07 06:08:19 +000061 time_value = now;
62 }
63#endif
64 }
Jason Molendaab4f1922010-10-25 11:12:07 +000065 }
66 return m_frames.size ();
67}
68
69bool
Jason Molenda8fed2952010-11-09 02:31:21 +000070UnwindLLDB::AddFirstFrame ()
71{
Jim Inghamb0c72a52012-02-29 03:40:22 +000072 if (m_frames.size() > 0)
73 return true;
74
Jason Molenda8fed2952010-11-09 02:31:21 +000075 // First, set up the 0th (initial) frame
76 CursorSP first_cursor_sp(new Cursor ());
Greg Claytone1cd1be2012-01-29 20:56:30 +000077 RegisterContextLLDBSP reg_ctx_sp (new RegisterContextLLDB (m_thread,
78 RegisterContextLLDBSP(),
79 first_cursor_sp->sctx,
80 0, *this));
Greg Clayton9b72eb72011-05-24 23:06:02 +000081 if (reg_ctx_sp.get() == NULL)
Jim Inghamb0c72a52012-02-29 03:40:22 +000082 goto unwind_done;
Greg Clayton5ccbd292011-01-06 22:15:06 +000083
Greg Clayton9b72eb72011-05-24 23:06:02 +000084 if (!reg_ctx_sp->IsValid())
Jim Inghamb0c72a52012-02-29 03:40:22 +000085 goto unwind_done;
Greg Clayton5ccbd292011-01-06 22:15:06 +000086
Greg Clayton9b72eb72011-05-24 23:06:02 +000087 if (!reg_ctx_sp->GetCFA (first_cursor_sp->cfa))
Jim Inghamb0c72a52012-02-29 03:40:22 +000088 goto unwind_done;
Greg Clayton5ccbd292011-01-06 22:15:06 +000089
Greg Clayton9b72eb72011-05-24 23:06:02 +000090 if (!reg_ctx_sp->ReadPC (first_cursor_sp->start_pc))
Jim Inghamb0c72a52012-02-29 03:40:22 +000091 goto unwind_done;
Greg Clayton5ccbd292011-01-06 22:15:06 +000092
93 // Everything checks out, so release the auto pointer value and let the
94 // cursor own it in its shared pointer
Greg Claytone1cd1be2012-01-29 20:56:30 +000095 first_cursor_sp->reg_ctx_lldb_sp = reg_ctx_sp;
Jason Molenda8fed2952010-11-09 02:31:21 +000096 m_frames.push_back (first_cursor_sp);
97 return true;
Jim Inghamb0c72a52012-02-29 03:40:22 +000098unwind_done:
99 m_unwind_complete = true;
100 return false;
Jason Molenda8fed2952010-11-09 02:31:21 +0000101}
102
103// For adding a non-zero stack frame to m_frames.
104bool
Greg Clayton9b72eb72011-05-24 23:06:02 +0000105UnwindLLDB::AddOneMoreFrame (ABI *abi)
Jason Molenda8fed2952010-11-09 02:31:21 +0000106{
Jim Inghamb0c72a52012-02-29 03:40:22 +0000107 // If we've already gotten to the end of the stack, don't bother to try again...
108 if (m_unwind_complete)
109 return false;
110
Jason Molenda8fed2952010-11-09 02:31:21 +0000111 LogSP log(GetLogIfAllCategoriesSet (LIBLLDB_LOG_UNWIND));
112 CursorSP cursor_sp(new Cursor ());
Jason Molenda8fed2952010-11-09 02:31:21 +0000113
114 // Frame zero is a little different
115 if (m_frames.size() == 0)
116 return false;
117
118 uint32_t cur_idx = m_frames.size ();
Greg Claytone1cd1be2012-01-29 20:56:30 +0000119 RegisterContextLLDBSP reg_ctx_sp(new RegisterContextLLDB (m_thread,
120 m_frames[cur_idx - 1]->reg_ctx_lldb_sp,
121 cursor_sp->sctx,
122 cur_idx,
123 *this));
Greg Clayton9b72eb72011-05-24 23:06:02 +0000124 if (reg_ctx_sp.get() == NULL)
Jim Inghamb0c72a52012-02-29 03:40:22 +0000125 goto unwind_done;
Jason Molenda8fed2952010-11-09 02:31:21 +0000126
Greg Clayton9b72eb72011-05-24 23:06:02 +0000127 if (!reg_ctx_sp->IsValid())
Jason Molenda8fed2952010-11-09 02:31:21 +0000128 {
Jason Molenda8fed2952010-11-09 02:31:21 +0000129 if (log)
130 {
131 log->Printf("%*sFrame %d invalid RegisterContext for this frame, stopping stack walk",
132 cur_idx < 100 ? cur_idx : 100, "", cur_idx);
133 }
Jim Inghamb0c72a52012-02-29 03:40:22 +0000134 goto unwind_done;
Jason Molenda8fed2952010-11-09 02:31:21 +0000135 }
Greg Clayton9b72eb72011-05-24 23:06:02 +0000136 if (!reg_ctx_sp->GetCFA (cursor_sp->cfa))
Jason Molenda8fed2952010-11-09 02:31:21 +0000137 {
Jason Molenda8fed2952010-11-09 02:31:21 +0000138 if (log)
139 {
140 log->Printf("%*sFrame %d did not get CFA for this frame, stopping stack walk",
141 cur_idx < 100 ? cur_idx : 100, "", cur_idx);
142 }
Jim Inghamb0c72a52012-02-29 03:40:22 +0000143 goto unwind_done;
Jason Molenda8fed2952010-11-09 02:31:21 +0000144 }
Greg Clayton9b72eb72011-05-24 23:06:02 +0000145 if (abi && !abi->CallFrameAddressIsValid(cursor_sp->cfa))
Jason Molenda8fed2952010-11-09 02:31:21 +0000146 {
Jason Molenda8fed2952010-11-09 02:31:21 +0000147 if (log)
148 {
149 log->Printf("%*sFrame %d did not get a valid CFA for this frame, stopping stack walk",
150 cur_idx < 100 ? cur_idx : 100, "", cur_idx);
151 }
Jim Inghamb0c72a52012-02-29 03:40:22 +0000152 goto unwind_done;
Jason Molenda8fed2952010-11-09 02:31:21 +0000153 }
Greg Clayton9b72eb72011-05-24 23:06:02 +0000154 if (!reg_ctx_sp->ReadPC (cursor_sp->start_pc))
Jason Molenda8fed2952010-11-09 02:31:21 +0000155 {
Jason Molenda8fed2952010-11-09 02:31:21 +0000156 if (log)
157 {
158 log->Printf("%*sFrame %d did not get PC for this frame, stopping stack walk",
159 cur_idx < 100 ? cur_idx : 100, "", cur_idx);
160 }
Jim Inghamb0c72a52012-02-29 03:40:22 +0000161 goto unwind_done;
Jason Molenda8fed2952010-11-09 02:31:21 +0000162 }
Greg Clayton9b72eb72011-05-24 23:06:02 +0000163 if (abi && !abi->CodeAddressIsValid (cursor_sp->start_pc))
164 {
165 if (log)
166 {
167 log->Printf("%*sFrame %d did not get a valid PC, stopping stack walk",
168 cur_idx < 100 ? cur_idx : 100, "", cur_idx);
169 }
Jim Inghamb0c72a52012-02-29 03:40:22 +0000170 goto unwind_done;
Greg Clayton9b72eb72011-05-24 23:06:02 +0000171 }
Greg Claytonfc753032011-01-17 21:03:33 +0000172 if (!m_frames.empty())
173 {
Greg Clayton9b72eb72011-05-24 23:06:02 +0000174 if (m_frames.back()->start_pc == cursor_sp->start_pc)
Greg Claytonfc753032011-01-17 21:03:33 +0000175 {
Greg Clayton9b72eb72011-05-24 23:06:02 +0000176 if (m_frames.back()->cfa == cursor_sp->cfa)
Jim Inghamb0c72a52012-02-29 03:40:22 +0000177 goto unwind_done; // Infinite loop where the current cursor is the same as the previous one...
Jim Ingham28eb5712012-10-12 17:34:26 +0000178 else if (abi && abi->StackUsesFrames())
Greg Clayton9b72eb72011-05-24 23:06:02 +0000179 {
Greg Clayton1cbc52c2011-05-25 17:56:20 +0000180 // We might have a CFA that is not using the frame pointer and
181 // we want to validate that the frame pointer is valid.
Greg Clayton9b72eb72011-05-24 23:06:02 +0000182 if (reg_ctx_sp->GetFP() == 0)
Jim Inghamb0c72a52012-02-29 03:40:22 +0000183 goto unwind_done;
Greg Clayton9b72eb72011-05-24 23:06:02 +0000184 }
Greg Claytonfc753032011-01-17 21:03:33 +0000185 }
186 }
Greg Claytone1cd1be2012-01-29 20:56:30 +0000187 cursor_sp->reg_ctx_lldb_sp = reg_ctx_sp;
Jason Molenda8fed2952010-11-09 02:31:21 +0000188 m_frames.push_back (cursor_sp);
189 return true;
Jim Inghamb0c72a52012-02-29 03:40:22 +0000190
191unwind_done:
192 m_unwind_complete = true;
193 return false;
Jason Molenda8fed2952010-11-09 02:31:21 +0000194}
195
196bool
Jim Ingham8f077162011-10-21 01:49:48 +0000197UnwindLLDB::DoGetFrameInfoAtIndex (uint32_t idx, addr_t& cfa, addr_t& pc)
Jason Molendaab4f1922010-10-25 11:12:07 +0000198{
Jason Molendaab4f1922010-10-25 11:12:07 +0000199 if (m_frames.size() == 0)
Jason Molenda8fed2952010-11-09 02:31:21 +0000200 {
201 if (!AddFirstFrame())
202 return false;
203 }
204
Greg Clayton1ac04c32012-02-21 00:09:25 +0000205 ProcessSP process_sp (m_thread.GetProcess());
206 ABI *abi = process_sp ? process_sp->GetABI().get() : NULL;
Greg Clayton9b72eb72011-05-24 23:06:02 +0000207
208 while (idx >= m_frames.size() && AddOneMoreFrame (abi))
Jason Molenda8fed2952010-11-09 02:31:21 +0000209 ;
Jason Molendaab4f1922010-10-25 11:12:07 +0000210
211 if (idx < m_frames.size ())
212 {
Jason Molenda59762002010-11-04 00:53:20 +0000213 cfa = m_frames[idx]->cfa;
214 pc = m_frames[idx]->start_pc;
Jason Molendaab4f1922010-10-25 11:12:07 +0000215 return true;
216 }
217 return false;
218}
219
Greg Clayton5ccbd292011-01-06 22:15:06 +0000220lldb::RegisterContextSP
Jim Ingham8f077162011-10-21 01:49:48 +0000221UnwindLLDB::DoCreateRegisterContextForFrame (StackFrame *frame)
Jason Molendaab4f1922010-10-25 11:12:07 +0000222{
Greg Clayton5ccbd292011-01-06 22:15:06 +0000223 lldb::RegisterContextSP reg_ctx_sp;
Greg Clayton671cabe2011-01-08 01:53:06 +0000224 uint32_t idx = frame->GetConcreteFrameIndex ();
Jason Molenda8fed2952010-11-09 02:31:21 +0000225
Jason Molendaab4f1922010-10-25 11:12:07 +0000226 if (idx == 0)
227 {
228 return m_thread.GetRegisterContext();
229 }
Jason Molenda8fed2952010-11-09 02:31:21 +0000230
231 if (m_frames.size() == 0)
232 {
233 if (!AddFirstFrame())
Greg Clayton5ccbd292011-01-06 22:15:06 +0000234 return reg_ctx_sp;
Jason Molenda8fed2952010-11-09 02:31:21 +0000235 }
236
Greg Clayton1ac04c32012-02-21 00:09:25 +0000237 ProcessSP process_sp (m_thread.GetProcess());
238 ABI *abi = process_sp ? process_sp->GetABI().get() : NULL;
Greg Clayton9b72eb72011-05-24 23:06:02 +0000239
Greg Claytone1cd1be2012-01-29 20:56:30 +0000240 while (idx >= m_frames.size())
241 {
242 if (!AddOneMoreFrame (abi))
243 break;
244 }
Jason Molenda8fed2952010-11-09 02:31:21 +0000245
Greg Claytone1cd1be2012-01-29 20:56:30 +0000246 const uint32_t num_frames = m_frames.size();
247 if (idx < num_frames)
248 {
249 Cursor *frame_cursor = m_frames[idx].get();
Greg Claytone72dfb32012-02-24 01:59:29 +0000250 reg_ctx_sp = frame_cursor->reg_ctx_lldb_sp;
Greg Claytone1cd1be2012-01-29 20:56:30 +0000251 }
Greg Clayton5ccbd292011-01-06 22:15:06 +0000252 return reg_ctx_sp;
Jason Molendaab4f1922010-10-25 11:12:07 +0000253}
Jason Molenda707fec42011-11-01 03:21:25 +0000254
Greg Claytone1cd1be2012-01-29 20:56:30 +0000255UnwindLLDB::RegisterContextLLDBSP
Jason Molenda707fec42011-11-01 03:21:25 +0000256UnwindLLDB::GetRegisterContextForFrameNum (uint32_t frame_num)
257{
Greg Claytone1cd1be2012-01-29 20:56:30 +0000258 RegisterContextLLDBSP reg_ctx_sp;
259 if (frame_num < m_frames.size())
260 reg_ctx_sp = m_frames[frame_num]->reg_ctx_lldb_sp;
Jason Molenda707fec42011-11-01 03:21:25 +0000261 return reg_ctx_sp;
262}
263
264bool
Jason Molenda60f0bd42012-10-26 06:08:58 +0000265UnwindLLDB::SearchForSavedLocationForRegister (uint32_t lldb_regnum, lldb_private::UnwindLLDB::RegisterLocation &regloc, uint32_t starting_frame_num, bool pc_or_return_address_reg)
Jason Molenda707fec42011-11-01 03:21:25 +0000266{
267 int64_t frame_num = starting_frame_num;
268 if (frame_num >= m_frames.size())
269 return false;
Jason Molenda60f0bd42012-10-26 06:08:58 +0000270
271 // Never interrogate more than one level while looking for the saved pc value. If the value
272 // isn't saved by frame_num, none of the frames lower on the stack will have a useful value.
273 if (pc_or_return_address_reg)
274 {
Jason Molendaaff2a262012-11-16 01:03:31 +0000275 UnwindLLDB::RegisterSearchResult result;
276 result = m_frames[frame_num]->reg_ctx_lldb_sp->SavedLocationForRegister (lldb_regnum, regloc);
277 if (result == UnwindLLDB::RegisterSearchResult::eRegisterFound)
Jason Molenda60f0bd42012-10-26 06:08:58 +0000278 return true;
279 else
280 return false;
281 }
Jason Molenda707fec42011-11-01 03:21:25 +0000282 while (frame_num >= 0)
283 {
Jason Molendaaff2a262012-11-16 01:03:31 +0000284 UnwindLLDB::RegisterSearchResult result;
285 result = m_frames[frame_num]->reg_ctx_lldb_sp->SavedLocationForRegister (lldb_regnum, regloc);
Jason Molenda4c781fd72013-01-19 03:53:42 +0000286
287 // If we have unwind instructions saying that register N is saved in register M in the middle of
288 // the stack (and N can equal M here, meaning the register was not used in this function), then
289 // change the register number we're looking for to M and keep looking for a concrete location
290 // down the stack, or an actual value from a live RegisterContext at frame 0.
291 if (result == UnwindLLDB::RegisterSearchResult::eRegisterFound
292 && regloc.type == UnwindLLDB::RegisterLocation::eRegisterInRegister
293 && frame_num > 0)
294 {
295 result = UnwindLLDB::RegisterSearchResult::eRegisterNotFound;
296 lldb_regnum = regloc.location.register_number;
297 }
298
Jason Molendaaff2a262012-11-16 01:03:31 +0000299 if (result == UnwindLLDB::RegisterSearchResult::eRegisterFound)
Jason Molenda707fec42011-11-01 03:21:25 +0000300 return true;
Jason Molendaaff2a262012-11-16 01:03:31 +0000301 if (result == UnwindLLDB::RegisterSearchResult::eRegisterIsVolatile)
302 return false;
Jason Molenda707fec42011-11-01 03:21:25 +0000303 frame_num--;
304 }
305 return false;
306}