blob: 1ba3f0f419f39a4035fb6df75c58a96eca513e57 [file] [log] [blame]
Jason Molenda8280cbe2010-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 Clayton97eecb12011-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 Molenda8280cbe2010-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 Molenda8280cbe2010-10-25 11:12:07 +000019
Greg Claytonc3c46612011-02-15 00:19:15 +000020#include "UnwindLLDB.h"
21#include "RegisterContextLLDB.h"
22
Jason Molenda8280cbe2010-10-25 11:12:07 +000023using namespace lldb;
24using namespace lldb_private;
25
26UnwindLLDB::UnwindLLDB (Thread &thread) :
27 Unwind (thread),
28 m_frames()
29{
30}
31
32uint32_t
Jim Ingham591cf152011-10-21 01:49:48 +000033UnwindLLDB::DoGetFrameCount()
Jason Molenda8280cbe2010-10-25 11:12:07 +000034{
Jason Molenda8280cbe2010-10-25 11:12:07 +000035 if (m_frames.empty())
36 {
Greg Claytonfd119992011-01-07 06:08:19 +000037//#define DEBUG_FRAME_SPEED 1
38#if DEBUG_FRAME_SPEED
Greg Claytona875b642011-01-09 21:07:35 +000039#define FRAME_COUNT 10000
Greg Claytonfd119992011-01-07 06:08:19 +000040 TimeValue time_value (TimeValue::Now());
41#endif
Jason Molenda1da513b2010-11-09 02:31:21 +000042 if (!AddFirstFrame ())
Jason Molenda8280cbe2010-10-25 11:12:07 +000043 return 0;
Greg Clayton54b38412011-05-24 23:06:02 +000044
Greg Claytonf4124de2012-02-21 00:09:25 +000045 ProcessSP process_sp (m_thread.GetProcess());
46 ABI *abi = process_sp ? process_sp->GetABI().get() : NULL;
Greg Clayton54b38412011-05-24 23:06:02 +000047
48 while (AddOneMoreFrame (abi))
Greg Claytonfd119992011-01-07 06:08:19 +000049 {
50#if DEBUG_FRAME_SPEED
Greg Claytona875b642011-01-09 21:07:35 +000051 if ((m_frames.size() % FRAME_COUNT) == 0)
Greg Claytonfd119992011-01-07 06:08:19 +000052 {
53 TimeValue now(TimeValue::Now());
54 uint64_t delta_t = now - time_value;
Greg Claytona875b642011-01-09 21:07:35 +000055 printf ("%u frames in %llu.%09llu ms (%g frames/sec)\n",
56 FRAME_COUNT,
Peter Collingbourne20fe30c2011-06-18 23:52:14 +000057 delta_t / TimeValue::NanoSecPerSec,
58 delta_t % TimeValue::NanoSecPerSec,
59 (float)FRAME_COUNT / ((float)delta_t / (float)TimeValue::NanoSecPerSec));
Greg Claytonfd119992011-01-07 06:08:19 +000060 time_value = now;
61 }
62#endif
63 }
Jason Molenda8280cbe2010-10-25 11:12:07 +000064 }
65 return m_frames.size ();
66}
67
68bool
Jason Molenda1da513b2010-11-09 02:31:21 +000069UnwindLLDB::AddFirstFrame ()
70{
71 // First, set up the 0th (initial) frame
72 CursorSP first_cursor_sp(new Cursor ());
Greg Clayton13d24fb2012-01-29 20:56:30 +000073 RegisterContextLLDBSP reg_ctx_sp (new RegisterContextLLDB (m_thread,
74 RegisterContextLLDBSP(),
75 first_cursor_sp->sctx,
76 0, *this));
Greg Clayton54b38412011-05-24 23:06:02 +000077 if (reg_ctx_sp.get() == NULL)
Jason Molenda1da513b2010-11-09 02:31:21 +000078 return false;
Greg Clayton08d7d3a2011-01-06 22:15:06 +000079
Greg Clayton54b38412011-05-24 23:06:02 +000080 if (!reg_ctx_sp->IsValid())
Jason Molenda1da513b2010-11-09 02:31:21 +000081 return false;
Greg Clayton08d7d3a2011-01-06 22:15:06 +000082
Greg Clayton54b38412011-05-24 23:06:02 +000083 if (!reg_ctx_sp->GetCFA (first_cursor_sp->cfa))
Jason Molenda1da513b2010-11-09 02:31:21 +000084 return false;
Greg Clayton08d7d3a2011-01-06 22:15:06 +000085
Greg Clayton54b38412011-05-24 23:06:02 +000086 if (!reg_ctx_sp->ReadPC (first_cursor_sp->start_pc))
Greg Clayton08d7d3a2011-01-06 22:15:06 +000087 return false;
88
89 // Everything checks out, so release the auto pointer value and let the
90 // cursor own it in its shared pointer
Greg Clayton13d24fb2012-01-29 20:56:30 +000091 first_cursor_sp->reg_ctx_lldb_sp = reg_ctx_sp;
Jason Molenda1da513b2010-11-09 02:31:21 +000092 m_frames.push_back (first_cursor_sp);
93 return true;
94}
95
96// For adding a non-zero stack frame to m_frames.
97bool
Greg Clayton54b38412011-05-24 23:06:02 +000098UnwindLLDB::AddOneMoreFrame (ABI *abi)
Jason Molenda1da513b2010-11-09 02:31:21 +000099{
100 LogSP log(GetLogIfAllCategoriesSet (LIBLLDB_LOG_UNWIND));
101 CursorSP cursor_sp(new Cursor ());
Jason Molenda1da513b2010-11-09 02:31:21 +0000102
103 // Frame zero is a little different
104 if (m_frames.size() == 0)
105 return false;
106
107 uint32_t cur_idx = m_frames.size ();
Greg Clayton13d24fb2012-01-29 20:56:30 +0000108 RegisterContextLLDBSP reg_ctx_sp(new RegisterContextLLDB (m_thread,
109 m_frames[cur_idx - 1]->reg_ctx_lldb_sp,
110 cursor_sp->sctx,
111 cur_idx,
112 *this));
Greg Clayton54b38412011-05-24 23:06:02 +0000113 if (reg_ctx_sp.get() == NULL)
Greg Clayton08d7d3a2011-01-06 22:15:06 +0000114 return false;
Jason Molenda1da513b2010-11-09 02:31:21 +0000115
Greg Clayton54b38412011-05-24 23:06:02 +0000116 if (!reg_ctx_sp->IsValid())
Jason Molenda1da513b2010-11-09 02:31:21 +0000117 {
Jason Molenda1da513b2010-11-09 02:31:21 +0000118 if (log)
119 {
120 log->Printf("%*sFrame %d invalid RegisterContext for this frame, stopping stack walk",
121 cur_idx < 100 ? cur_idx : 100, "", cur_idx);
122 }
123 return false;
124 }
Greg Clayton54b38412011-05-24 23:06:02 +0000125 if (!reg_ctx_sp->GetCFA (cursor_sp->cfa))
Jason Molenda1da513b2010-11-09 02:31:21 +0000126 {
Jason Molenda1da513b2010-11-09 02:31:21 +0000127 if (log)
128 {
129 log->Printf("%*sFrame %d did not get CFA for this frame, stopping stack walk",
130 cur_idx < 100 ? cur_idx : 100, "", cur_idx);
131 }
132 return false;
133 }
Greg Clayton54b38412011-05-24 23:06:02 +0000134 if (abi && !abi->CallFrameAddressIsValid(cursor_sp->cfa))
Jason Molenda1da513b2010-11-09 02:31:21 +0000135 {
Jason Molenda1da513b2010-11-09 02:31:21 +0000136 if (log)
137 {
138 log->Printf("%*sFrame %d did not get a valid CFA for this frame, stopping stack walk",
139 cur_idx < 100 ? cur_idx : 100, "", cur_idx);
140 }
141 return false;
142 }
Greg Clayton54b38412011-05-24 23:06:02 +0000143 if (!reg_ctx_sp->ReadPC (cursor_sp->start_pc))
Jason Molenda1da513b2010-11-09 02:31:21 +0000144 {
Jason Molenda1da513b2010-11-09 02:31:21 +0000145 if (log)
146 {
147 log->Printf("%*sFrame %d did not get PC for this frame, stopping stack walk",
148 cur_idx < 100 ? cur_idx : 100, "", cur_idx);
149 }
150 return false;
151 }
Greg Clayton54b38412011-05-24 23:06:02 +0000152 if (abi && !abi->CodeAddressIsValid (cursor_sp->start_pc))
153 {
154 if (log)
155 {
156 log->Printf("%*sFrame %d did not get a valid PC, stopping stack walk",
157 cur_idx < 100 ? cur_idx : 100, "", cur_idx);
158 }
159 return false;
160 }
Greg Clayton1724dec2011-01-17 21:03:33 +0000161 if (!m_frames.empty())
162 {
Greg Clayton54b38412011-05-24 23:06:02 +0000163 if (m_frames.back()->start_pc == cursor_sp->start_pc)
Greg Clayton1724dec2011-01-17 21:03:33 +0000164 {
Greg Clayton54b38412011-05-24 23:06:02 +0000165 if (m_frames.back()->cfa == cursor_sp->cfa)
166 return false; // Infinite loop where the current cursor is the same as the previous one...
167 else if (abi->StackUsesFrames())
168 {
Greg Clayton19552cb2011-05-25 17:56:20 +0000169 // We might have a CFA that is not using the frame pointer and
170 // we want to validate that the frame pointer is valid.
Greg Clayton54b38412011-05-24 23:06:02 +0000171 if (reg_ctx_sp->GetFP() == 0)
172 return false;
173 }
Greg Clayton1724dec2011-01-17 21:03:33 +0000174 }
175 }
Greg Clayton13d24fb2012-01-29 20:56:30 +0000176 cursor_sp->reg_ctx_lldb_sp = reg_ctx_sp;
Jason Molenda1da513b2010-11-09 02:31:21 +0000177 m_frames.push_back (cursor_sp);
178 return true;
179}
180
181bool
Jim Ingham591cf152011-10-21 01:49:48 +0000182UnwindLLDB::DoGetFrameInfoAtIndex (uint32_t idx, addr_t& cfa, addr_t& pc)
Jason Molenda8280cbe2010-10-25 11:12:07 +0000183{
Jason Molenda8280cbe2010-10-25 11:12:07 +0000184 if (m_frames.size() == 0)
Jason Molenda1da513b2010-11-09 02:31:21 +0000185 {
186 if (!AddFirstFrame())
187 return false;
188 }
189
Greg Claytonf4124de2012-02-21 00:09:25 +0000190 ProcessSP process_sp (m_thread.GetProcess());
191 ABI *abi = process_sp ? process_sp->GetABI().get() : NULL;
Greg Clayton54b38412011-05-24 23:06:02 +0000192
193 while (idx >= m_frames.size() && AddOneMoreFrame (abi))
Jason Molenda1da513b2010-11-09 02:31:21 +0000194 ;
Jason Molenda8280cbe2010-10-25 11:12:07 +0000195
196 if (idx < m_frames.size ())
197 {
Jason Molenda800d11d2010-11-04 00:53:20 +0000198 cfa = m_frames[idx]->cfa;
199 pc = m_frames[idx]->start_pc;
Jason Molenda8280cbe2010-10-25 11:12:07 +0000200 return true;
201 }
202 return false;
203}
204
Greg Clayton08d7d3a2011-01-06 22:15:06 +0000205lldb::RegisterContextSP
Jim Ingham591cf152011-10-21 01:49:48 +0000206UnwindLLDB::DoCreateRegisterContextForFrame (StackFrame *frame)
Jason Molenda8280cbe2010-10-25 11:12:07 +0000207{
Greg Clayton08d7d3a2011-01-06 22:15:06 +0000208 lldb::RegisterContextSP reg_ctx_sp;
Greg Clayton869efc22011-01-08 01:53:06 +0000209 uint32_t idx = frame->GetConcreteFrameIndex ();
Jason Molenda1da513b2010-11-09 02:31:21 +0000210
Jason Molenda8280cbe2010-10-25 11:12:07 +0000211 if (idx == 0)
212 {
213 return m_thread.GetRegisterContext();
214 }
Jason Molenda1da513b2010-11-09 02:31:21 +0000215
216 if (m_frames.size() == 0)
217 {
218 if (!AddFirstFrame())
Greg Clayton08d7d3a2011-01-06 22:15:06 +0000219 return reg_ctx_sp;
Jason Molenda1da513b2010-11-09 02:31:21 +0000220 }
221
Greg Claytonf4124de2012-02-21 00:09:25 +0000222 ProcessSP process_sp (m_thread.GetProcess());
223 ABI *abi = process_sp ? process_sp->GetABI().get() : NULL;
Greg Clayton54b38412011-05-24 23:06:02 +0000224
Greg Clayton13d24fb2012-01-29 20:56:30 +0000225 while (idx >= m_frames.size())
226 {
227 if (!AddOneMoreFrame (abi))
228 break;
229 }
Jason Molenda1da513b2010-11-09 02:31:21 +0000230
Greg Clayton13d24fb2012-01-29 20:56:30 +0000231 const uint32_t num_frames = m_frames.size();
232 if (idx < num_frames)
233 {
234 Cursor *frame_cursor = m_frames[idx].get();
235 reg_ctx_sp = frame_cursor->reg_ctx_lldb_sp->shared_from_this();
236 }
Greg Clayton08d7d3a2011-01-06 22:15:06 +0000237 return reg_ctx_sp;
Jason Molenda8280cbe2010-10-25 11:12:07 +0000238}
Jason Molendaabe2d362011-11-01 03:21:25 +0000239
Greg Clayton13d24fb2012-01-29 20:56:30 +0000240UnwindLLDB::RegisterContextLLDBSP
Jason Molendaabe2d362011-11-01 03:21:25 +0000241UnwindLLDB::GetRegisterContextForFrameNum (uint32_t frame_num)
242{
Greg Clayton13d24fb2012-01-29 20:56:30 +0000243 RegisterContextLLDBSP reg_ctx_sp;
244 if (frame_num < m_frames.size())
245 reg_ctx_sp = m_frames[frame_num]->reg_ctx_lldb_sp;
Jason Molendaabe2d362011-11-01 03:21:25 +0000246 return reg_ctx_sp;
247}
248
249bool
250UnwindLLDB::SearchForSavedLocationForRegister (uint32_t lldb_regnum, lldb_private::UnwindLLDB::RegisterLocation &regloc, uint32_t starting_frame_num)
251{
252 int64_t frame_num = starting_frame_num;
253 if (frame_num >= m_frames.size())
254 return false;
255 while (frame_num >= 0)
256 {
Greg Clayton13d24fb2012-01-29 20:56:30 +0000257 if (m_frames[frame_num]->reg_ctx_lldb_sp->SavedLocationForRegister (lldb_regnum, regloc, false))
Jason Molendaabe2d362011-11-01 03:21:25 +0000258 return true;
259 frame_num--;
260 }
261 return false;
262}