blob: bf71b008bd5c7318e7e5981231db26dfa98ba73f [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
45 ABI *abi = m_thread.GetProcess().GetABI().get();
46
47 while (AddOneMoreFrame (abi))
Greg Claytonfd119992011-01-07 06:08:19 +000048 {
49#if DEBUG_FRAME_SPEED
Greg Claytona875b642011-01-09 21:07:35 +000050 if ((m_frames.size() % FRAME_COUNT) == 0)
Greg Claytonfd119992011-01-07 06:08:19 +000051 {
52 TimeValue now(TimeValue::Now());
53 uint64_t delta_t = now - time_value;
Greg Claytona875b642011-01-09 21:07:35 +000054 printf ("%u frames in %llu.%09llu ms (%g frames/sec)\n",
55 FRAME_COUNT,
Peter Collingbourne20fe30c2011-06-18 23:52:14 +000056 delta_t / TimeValue::NanoSecPerSec,
57 delta_t % TimeValue::NanoSecPerSec,
58 (float)FRAME_COUNT / ((float)delta_t / (float)TimeValue::NanoSecPerSec));
Greg Claytonfd119992011-01-07 06:08:19 +000059 time_value = now;
60 }
61#endif
62 }
Jason Molenda8280cbe2010-10-25 11:12:07 +000063 }
64 return m_frames.size ();
65}
66
67bool
Jason Molenda1da513b2010-11-09 02:31:21 +000068UnwindLLDB::AddFirstFrame ()
69{
70 // First, set up the 0th (initial) frame
71 CursorSP first_cursor_sp(new Cursor ());
Greg Clayton13d24fb2012-01-29 20:56:30 +000072 RegisterContextLLDBSP reg_ctx_sp (new RegisterContextLLDB (m_thread,
73 RegisterContextLLDBSP(),
74 first_cursor_sp->sctx,
75 0, *this));
Greg Clayton54b38412011-05-24 23:06:02 +000076 if (reg_ctx_sp.get() == NULL)
Jason Molenda1da513b2010-11-09 02:31:21 +000077 return false;
Greg Clayton08d7d3a2011-01-06 22:15:06 +000078
Greg Clayton54b38412011-05-24 23:06:02 +000079 if (!reg_ctx_sp->IsValid())
Jason Molenda1da513b2010-11-09 02:31:21 +000080 return false;
Greg Clayton08d7d3a2011-01-06 22:15:06 +000081
Greg Clayton54b38412011-05-24 23:06:02 +000082 if (!reg_ctx_sp->GetCFA (first_cursor_sp->cfa))
Jason Molenda1da513b2010-11-09 02:31:21 +000083 return false;
Greg Clayton08d7d3a2011-01-06 22:15:06 +000084
Greg Clayton54b38412011-05-24 23:06:02 +000085 if (!reg_ctx_sp->ReadPC (first_cursor_sp->start_pc))
Greg Clayton08d7d3a2011-01-06 22:15:06 +000086 return false;
87
88 // Everything checks out, so release the auto pointer value and let the
89 // cursor own it in its shared pointer
Greg Clayton13d24fb2012-01-29 20:56:30 +000090 first_cursor_sp->reg_ctx_lldb_sp = reg_ctx_sp;
Jason Molenda1da513b2010-11-09 02:31:21 +000091 m_frames.push_back (first_cursor_sp);
92 return true;
93}
94
95// For adding a non-zero stack frame to m_frames.
96bool
Greg Clayton54b38412011-05-24 23:06:02 +000097UnwindLLDB::AddOneMoreFrame (ABI *abi)
Jason Molenda1da513b2010-11-09 02:31:21 +000098{
99 LogSP log(GetLogIfAllCategoriesSet (LIBLLDB_LOG_UNWIND));
100 CursorSP cursor_sp(new Cursor ());
Jason Molenda1da513b2010-11-09 02:31:21 +0000101
102 // Frame zero is a little different
103 if (m_frames.size() == 0)
104 return false;
105
106 uint32_t cur_idx = m_frames.size ();
Greg Clayton13d24fb2012-01-29 20:56:30 +0000107 RegisterContextLLDBSP reg_ctx_sp(new RegisterContextLLDB (m_thread,
108 m_frames[cur_idx - 1]->reg_ctx_lldb_sp,
109 cursor_sp->sctx,
110 cur_idx,
111 *this));
Greg Clayton54b38412011-05-24 23:06:02 +0000112 if (reg_ctx_sp.get() == NULL)
Greg Clayton08d7d3a2011-01-06 22:15:06 +0000113 return false;
Jason Molenda1da513b2010-11-09 02:31:21 +0000114
Greg Clayton54b38412011-05-24 23:06:02 +0000115 if (!reg_ctx_sp->IsValid())
Jason Molenda1da513b2010-11-09 02:31:21 +0000116 {
Jason Molenda1da513b2010-11-09 02:31:21 +0000117 if (log)
118 {
119 log->Printf("%*sFrame %d invalid RegisterContext for this frame, stopping stack walk",
120 cur_idx < 100 ? cur_idx : 100, "", cur_idx);
121 }
122 return false;
123 }
Greg Clayton54b38412011-05-24 23:06:02 +0000124 if (!reg_ctx_sp->GetCFA (cursor_sp->cfa))
Jason Molenda1da513b2010-11-09 02:31:21 +0000125 {
Jason Molenda1da513b2010-11-09 02:31:21 +0000126 if (log)
127 {
128 log->Printf("%*sFrame %d did not get CFA for this frame, stopping stack walk",
129 cur_idx < 100 ? cur_idx : 100, "", cur_idx);
130 }
131 return false;
132 }
Greg Clayton54b38412011-05-24 23:06:02 +0000133 if (abi && !abi->CallFrameAddressIsValid(cursor_sp->cfa))
Jason Molenda1da513b2010-11-09 02:31:21 +0000134 {
Jason Molenda1da513b2010-11-09 02:31:21 +0000135 if (log)
136 {
137 log->Printf("%*sFrame %d did not get a valid CFA for this frame, stopping stack walk",
138 cur_idx < 100 ? cur_idx : 100, "", cur_idx);
139 }
140 return false;
141 }
Greg Clayton54b38412011-05-24 23:06:02 +0000142 if (!reg_ctx_sp->ReadPC (cursor_sp->start_pc))
Jason Molenda1da513b2010-11-09 02:31:21 +0000143 {
Jason Molenda1da513b2010-11-09 02:31:21 +0000144 if (log)
145 {
146 log->Printf("%*sFrame %d did not get PC for this frame, stopping stack walk",
147 cur_idx < 100 ? cur_idx : 100, "", cur_idx);
148 }
149 return false;
150 }
Greg Clayton54b38412011-05-24 23:06:02 +0000151 if (abi && !abi->CodeAddressIsValid (cursor_sp->start_pc))
152 {
153 if (log)
154 {
155 log->Printf("%*sFrame %d did not get a valid PC, stopping stack walk",
156 cur_idx < 100 ? cur_idx : 100, "", cur_idx);
157 }
158 return false;
159 }
Greg Clayton1724dec2011-01-17 21:03:33 +0000160 if (!m_frames.empty())
161 {
Greg Clayton54b38412011-05-24 23:06:02 +0000162 if (m_frames.back()->start_pc == cursor_sp->start_pc)
Greg Clayton1724dec2011-01-17 21:03:33 +0000163 {
Greg Clayton54b38412011-05-24 23:06:02 +0000164 if (m_frames.back()->cfa == cursor_sp->cfa)
165 return false; // Infinite loop where the current cursor is the same as the previous one...
166 else if (abi->StackUsesFrames())
167 {
Greg Clayton19552cb2011-05-25 17:56:20 +0000168 // We might have a CFA that is not using the frame pointer and
169 // we want to validate that the frame pointer is valid.
Greg Clayton54b38412011-05-24 23:06:02 +0000170 if (reg_ctx_sp->GetFP() == 0)
171 return false;
172 }
Greg Clayton1724dec2011-01-17 21:03:33 +0000173 }
174 }
Greg Clayton13d24fb2012-01-29 20:56:30 +0000175 cursor_sp->reg_ctx_lldb_sp = reg_ctx_sp;
Jason Molenda1da513b2010-11-09 02:31:21 +0000176 m_frames.push_back (cursor_sp);
177 return true;
178}
179
180bool
Jim Ingham591cf152011-10-21 01:49:48 +0000181UnwindLLDB::DoGetFrameInfoAtIndex (uint32_t idx, addr_t& cfa, addr_t& pc)
Jason Molenda8280cbe2010-10-25 11:12:07 +0000182{
Jason Molenda8280cbe2010-10-25 11:12:07 +0000183 if (m_frames.size() == 0)
Jason Molenda1da513b2010-11-09 02:31:21 +0000184 {
185 if (!AddFirstFrame())
186 return false;
187 }
188
Greg Clayton54b38412011-05-24 23:06:02 +0000189 ABI *abi = m_thread.GetProcess().GetABI().get();
190
191 while (idx >= m_frames.size() && AddOneMoreFrame (abi))
Jason Molenda1da513b2010-11-09 02:31:21 +0000192 ;
Jason Molenda8280cbe2010-10-25 11:12:07 +0000193
194 if (idx < m_frames.size ())
195 {
Jason Molenda800d11d2010-11-04 00:53:20 +0000196 cfa = m_frames[idx]->cfa;
197 pc = m_frames[idx]->start_pc;
Jason Molenda8280cbe2010-10-25 11:12:07 +0000198 return true;
199 }
200 return false;
201}
202
Greg Clayton08d7d3a2011-01-06 22:15:06 +0000203lldb::RegisterContextSP
Jim Ingham591cf152011-10-21 01:49:48 +0000204UnwindLLDB::DoCreateRegisterContextForFrame (StackFrame *frame)
Jason Molenda8280cbe2010-10-25 11:12:07 +0000205{
Greg Clayton08d7d3a2011-01-06 22:15:06 +0000206 lldb::RegisterContextSP reg_ctx_sp;
Greg Clayton869efc22011-01-08 01:53:06 +0000207 uint32_t idx = frame->GetConcreteFrameIndex ();
Jason Molenda1da513b2010-11-09 02:31:21 +0000208
Jason Molenda8280cbe2010-10-25 11:12:07 +0000209 if (idx == 0)
210 {
211 return m_thread.GetRegisterContext();
212 }
Jason Molenda1da513b2010-11-09 02:31:21 +0000213
214 if (m_frames.size() == 0)
215 {
216 if (!AddFirstFrame())
Greg Clayton08d7d3a2011-01-06 22:15:06 +0000217 return reg_ctx_sp;
Jason Molenda1da513b2010-11-09 02:31:21 +0000218 }
219
Greg Clayton54b38412011-05-24 23:06:02 +0000220 ABI *abi = m_thread.GetProcess().GetABI().get();
221
Greg Clayton13d24fb2012-01-29 20:56:30 +0000222 while (idx >= m_frames.size())
223 {
224 if (!AddOneMoreFrame (abi))
225 break;
226 }
Jason Molenda1da513b2010-11-09 02:31:21 +0000227
Greg Clayton13d24fb2012-01-29 20:56:30 +0000228 const uint32_t num_frames = m_frames.size();
229 if (idx < num_frames)
230 {
231 Cursor *frame_cursor = m_frames[idx].get();
232 reg_ctx_sp = frame_cursor->reg_ctx_lldb_sp->shared_from_this();
233 }
Greg Clayton08d7d3a2011-01-06 22:15:06 +0000234 return reg_ctx_sp;
Jason Molenda8280cbe2010-10-25 11:12:07 +0000235}
Jason Molendaabe2d362011-11-01 03:21:25 +0000236
Greg Clayton13d24fb2012-01-29 20:56:30 +0000237UnwindLLDB::RegisterContextLLDBSP
Jason Molendaabe2d362011-11-01 03:21:25 +0000238UnwindLLDB::GetRegisterContextForFrameNum (uint32_t frame_num)
239{
Greg Clayton13d24fb2012-01-29 20:56:30 +0000240 RegisterContextLLDBSP reg_ctx_sp;
241 if (frame_num < m_frames.size())
242 reg_ctx_sp = m_frames[frame_num]->reg_ctx_lldb_sp;
Jason Molendaabe2d362011-11-01 03:21:25 +0000243 return reg_ctx_sp;
244}
245
246bool
247UnwindLLDB::SearchForSavedLocationForRegister (uint32_t lldb_regnum, lldb_private::UnwindLLDB::RegisterLocation &regloc, uint32_t starting_frame_num)
248{
249 int64_t frame_num = starting_frame_num;
250 if (frame_num >= m_frames.size())
251 return false;
252 while (frame_num >= 0)
253 {
Greg Clayton13d24fb2012-01-29 20:56:30 +0000254 if (m_frames[frame_num]->reg_ctx_lldb_sp->SavedLocationForRegister (lldb_regnum, regloc, false))
Jason Molendaabe2d362011-11-01 03:21:25 +0000255 return true;
256 frame_num--;
257 }
258 return false;
259}