UnwindLLDB.cpp revision 321369
1254721Semaste//===-- UnwindLLDB.cpp -------------------------------------*- C++ -*-===//
2254721Semaste//
3254721Semaste//                     The LLVM Compiler Infrastructure
4254721Semaste//
5254721Semaste// This file is distributed under the University of Illinois Open Source
6254721Semaste// License. See LICENSE.TXT for details.
7254721Semaste//
8254721Semaste//===----------------------------------------------------------------------===//
9254721Semaste
10254721Semaste#include "lldb/Core/Module.h"
11254721Semaste#include "lldb/Symbol/FuncUnwinders.h"
12254721Semaste#include "lldb/Symbol/Function.h"
13254721Semaste#include "lldb/Symbol/UnwindPlan.h"
14288943Sdim#include "lldb/Target/ABI.h"
15254721Semaste#include "lldb/Target/Process.h"
16254721Semaste#include "lldb/Target/RegisterContext.h"
17314564Sdim#include "lldb/Target/Target.h"
18314564Sdim#include "lldb/Target/Thread.h"
19321369Sdim#include "lldb/Utility/Log.h"
20254721Semaste
21314564Sdim#include "RegisterContextLLDB.h"
22254721Semaste#include "UnwindLLDB.h"
23254721Semaste
24254721Semasteusing namespace lldb;
25254721Semasteusing namespace lldb_private;
26254721Semaste
27314564SdimUnwindLLDB::UnwindLLDB(Thread &thread)
28314564Sdim    : Unwind(thread), m_frames(), m_unwind_complete(false),
29314564Sdim      m_user_supplied_trap_handler_functions() {
30314564Sdim  ProcessSP process_sp(thread.GetProcess());
31314564Sdim  if (process_sp) {
32314564Sdim    Args args;
33314564Sdim    process_sp->GetTarget().GetUserSpecifiedTrapHandlerNames(args);
34314564Sdim    size_t count = args.GetArgumentCount();
35314564Sdim    for (size_t i = 0; i < count; i++) {
36314564Sdim      const char *func_name = args.GetArgumentAtIndex(i);
37314564Sdim      m_user_supplied_trap_handler_functions.push_back(ConstString(func_name));
38262528Semaste    }
39314564Sdim  }
40254721Semaste}
41254721Semaste
42314564Sdimuint32_t UnwindLLDB::DoGetFrameCount() {
43314564Sdim  if (!m_unwind_complete) {
44254721Semaste//#define DEBUG_FRAME_SPEED 1
45254721Semaste#if DEBUG_FRAME_SPEED
46254721Semaste#define FRAME_COUNT 10000
47314564Sdim    using namespace std::chrono;
48314564Sdim    auto time_value = steady_clock::now();
49254721Semaste#endif
50314564Sdim    if (!AddFirstFrame())
51314564Sdim      return 0;
52254721Semaste
53314564Sdim    ProcessSP process_sp(m_thread.GetProcess());
54314564Sdim    ABI *abi = process_sp ? process_sp->GetABI().get() : NULL;
55254721Semaste
56314564Sdim    while (AddOneMoreFrame(abi)) {
57254721Semaste#if DEBUG_FRAME_SPEED
58314564Sdim      if ((m_frames.size() % FRAME_COUNT) == 0) {
59314564Sdim        const auto now = steady_clock::now();
60314564Sdim        const auto delta_t = now - time_value;
61314564Sdim        printf("%u frames in %.9f ms (%g frames/sec)\n", FRAME_COUNT,
62314564Sdim               duration<double, std::milli>(delta_t).count(),
63314564Sdim               (float)FRAME_COUNT / duration<double>(delta_t).count());
64314564Sdim        time_value = now;
65314564Sdim      }
66254721Semaste#endif
67254721Semaste    }
68314564Sdim  }
69314564Sdim  return m_frames.size();
70254721Semaste}
71254721Semaste
72314564Sdimbool UnwindLLDB::AddFirstFrame() {
73314564Sdim  if (m_frames.size() > 0)
74314564Sdim    return true;
75296417Sdim
76314564Sdim  ProcessSP process_sp(m_thread.GetProcess());
77314564Sdim  ABI *abi = process_sp ? process_sp->GetABI().get() : NULL;
78254721Semaste
79314564Sdim  // First, set up the 0th (initial) frame
80314564Sdim  CursorSP first_cursor_sp(new Cursor());
81314564Sdim  RegisterContextLLDBSP reg_ctx_sp(new RegisterContextLLDB(
82314564Sdim      m_thread, RegisterContextLLDBSP(), first_cursor_sp->sctx, 0, *this));
83314564Sdim  if (reg_ctx_sp.get() == NULL)
84314564Sdim    goto unwind_done;
85254721Semaste
86314564Sdim  if (!reg_ctx_sp->IsValid())
87314564Sdim    goto unwind_done;
88254721Semaste
89314564Sdim  if (!reg_ctx_sp->GetCFA(first_cursor_sp->cfa))
90314564Sdim    goto unwind_done;
91296417Sdim
92314564Sdim  if (!reg_ctx_sp->ReadPC(first_cursor_sp->start_pc))
93314564Sdim    goto unwind_done;
94296417Sdim
95314564Sdim  // Everything checks out, so release the auto pointer value and let the
96314564Sdim  // cursor own it in its shared pointer
97314564Sdim  first_cursor_sp->reg_ctx_lldb_sp = reg_ctx_sp;
98314564Sdim  m_frames.push_back(first_cursor_sp);
99262528Semaste
100314564Sdim  // Update the Full Unwind Plan for this frame if not valid
101314564Sdim  UpdateUnwindPlanForFirstFrameIfInvalid(abi);
102314564Sdim
103314564Sdim  return true;
104314564Sdim
105254721Semasteunwind_done:
106314564Sdim  Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_UNWIND));
107314564Sdim  if (log) {
108314564Sdim    log->Printf("th%d Unwind of this thread is complete.",
109314564Sdim                m_thread.GetIndexID());
110314564Sdim  }
111314564Sdim  m_unwind_complete = true;
112314564Sdim  return false;
113254721Semaste}
114254721Semaste
115314564SdimUnwindLLDB::CursorSP UnwindLLDB::GetOneMoreFrame(ABI *abi) {
116314564Sdim  assert(m_frames.size() != 0 &&
117314564Sdim         "Get one more frame called with empty frame list");
118288943Sdim
119314564Sdim  // If we've already gotten to the end of the stack, don't bother to try
120314564Sdim  // again...
121314564Sdim  if (m_unwind_complete)
122314564Sdim    return nullptr;
123254721Semaste
124314564Sdim  Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_UNWIND));
125254721Semaste
126314564Sdim  CursorSP prev_frame = m_frames.back();
127314564Sdim  uint32_t cur_idx = m_frames.size();
128254721Semaste
129314564Sdim  CursorSP cursor_sp(new Cursor());
130314564Sdim  RegisterContextLLDBSP reg_ctx_sp(new RegisterContextLLDB(
131314564Sdim      m_thread, prev_frame->reg_ctx_lldb_sp, cursor_sp->sctx, cur_idx, *this));
132254721Semaste
133314564Sdim  // We want to detect an unwind that cycles erroneously and stop backtracing.
134314564Sdim  // Don't want this maximum unwind limit to be too low -- if you have a
135314564Sdim  // backtrace
136314564Sdim  // with an "infinitely recursing" bug, it will crash when the stack blows out
137314564Sdim  // and the first 35,000 frames are uninteresting - it's the top most 5 frames
138314564Sdim  // that
139314564Sdim  // you actually care about.  So you can't just cap the unwind at 10,000 or
140314564Sdim  // something.
141314564Sdim  // Realistically anything over around 200,000 is going to blow out the stack
142314564Sdim  // space.
143314564Sdim  // If we're still unwinding at that point, we're probably never going to
144314564Sdim  // finish.
145314564Sdim  if (cur_idx > 300000) {
146314564Sdim    if (log)
147314564Sdim      log->Printf("%*sFrame %d unwound too many frames, assuming unwind has "
148314564Sdim                  "gone astray, stopping.",
149314564Sdim                  cur_idx < 100 ? cur_idx : 100, "", cur_idx);
150314564Sdim    return nullptr;
151314564Sdim  }
152296417Sdim
153314564Sdim  if (reg_ctx_sp.get() == NULL) {
154314564Sdim    // If the RegisterContextLLDB has a fallback UnwindPlan, it will switch to
155314564Sdim    // that and return
156314564Sdim    // true.  Subsequent calls to TryFallbackUnwindPlan() will return false.
157314564Sdim    if (prev_frame->reg_ctx_lldb_sp->TryFallbackUnwindPlan()) {
158314564Sdim      // TryFallbackUnwindPlan for prev_frame succeeded and updated
159314564Sdim      // reg_ctx_lldb_sp field of
160314564Sdim      // prev_frame. However, cfa field of prev_frame still needs to be updated.
161314564Sdim      // Hence updating it.
162314564Sdim      if (!(prev_frame->reg_ctx_lldb_sp->GetCFA(prev_frame->cfa)))
163314564Sdim        return nullptr;
164288943Sdim
165314564Sdim      return GetOneMoreFrame(abi);
166262528Semaste    }
167254721Semaste
168314564Sdim    if (log)
169314564Sdim      log->Printf("%*sFrame %d did not get a RegisterContext, stopping.",
170314564Sdim                  cur_idx < 100 ? cur_idx : 100, "", cur_idx);
171314564Sdim    return nullptr;
172314564Sdim  }
173296417Sdim
174314564Sdim  if (!reg_ctx_sp->IsValid()) {
175314564Sdim    // We failed to get a valid RegisterContext.
176314564Sdim    // See if the regctx below this on the stack has a fallback unwind plan it
177314564Sdim    // can use.
178314564Sdim    // Subsequent calls to TryFallbackUnwindPlan() will return false.
179314564Sdim    if (prev_frame->reg_ctx_lldb_sp->TryFallbackUnwindPlan()) {
180314564Sdim      // TryFallbackUnwindPlan for prev_frame succeeded and updated
181314564Sdim      // reg_ctx_lldb_sp field of
182314564Sdim      // prev_frame. However, cfa field of prev_frame still needs to be updated.
183314564Sdim      // Hence updating it.
184314564Sdim      if (!(prev_frame->reg_ctx_lldb_sp->GetCFA(prev_frame->cfa)))
185314564Sdim        return nullptr;
186288943Sdim
187314564Sdim      return GetOneMoreFrame(abi);
188254721Semaste    }
189296417Sdim
190314564Sdim    if (log)
191314564Sdim      log->Printf("%*sFrame %d invalid RegisterContext for this frame, "
192314564Sdim                  "stopping stack walk",
193314564Sdim                  cur_idx < 100 ? cur_idx : 100, "", cur_idx);
194314564Sdim    return nullptr;
195314564Sdim  }
196314564Sdim  if (!reg_ctx_sp->GetCFA(cursor_sp->cfa)) {
197314564Sdim    // If the RegisterContextLLDB has a fallback UnwindPlan, it will switch to
198314564Sdim    // that and return
199314564Sdim    // true.  Subsequent calls to TryFallbackUnwindPlan() will return false.
200314564Sdim    if (prev_frame->reg_ctx_lldb_sp->TryFallbackUnwindPlan()) {
201314564Sdim      // TryFallbackUnwindPlan for prev_frame succeeded and updated
202314564Sdim      // reg_ctx_lldb_sp field of
203314564Sdim      // prev_frame. However, cfa field of prev_frame still needs to be updated.
204314564Sdim      // Hence updating it.
205314564Sdim      if (!(prev_frame->reg_ctx_lldb_sp->GetCFA(prev_frame->cfa)))
206314564Sdim        return nullptr;
207288943Sdim
208314564Sdim      return GetOneMoreFrame(abi);
209254721Semaste    }
210296417Sdim
211314564Sdim    if (log)
212314564Sdim      log->Printf(
213314564Sdim          "%*sFrame %d did not get CFA for this frame, stopping stack walk",
214314564Sdim          cur_idx < 100 ? cur_idx : 100, "", cur_idx);
215314564Sdim    return nullptr;
216314564Sdim  }
217314564Sdim  if (abi && !abi->CallFrameAddressIsValid(cursor_sp->cfa)) {
218314564Sdim    // On Mac OS X, the _sigtramp asynchronous signal trampoline frame may not
219314564Sdim    // have
220314564Sdim    // its (constructed) CFA aligned correctly -- don't do the abi alignment
221314564Sdim    // check for
222314564Sdim    // these.
223314564Sdim    if (reg_ctx_sp->IsTrapHandlerFrame() == false) {
224314564Sdim      // See if we can find a fallback unwind plan for THIS frame.  It may be
225314564Sdim      // that the UnwindPlan we're using for THIS frame was bad and gave us a
226314564Sdim      // bad CFA.
227314564Sdim      // If that's not it, then see if we can change the UnwindPlan for the
228314564Sdim      // frame
229314564Sdim      // below us ("NEXT") -- see if using that other UnwindPlan gets us a
230314564Sdim      // better
231314564Sdim      // unwind state.
232314564Sdim      if (reg_ctx_sp->TryFallbackUnwindPlan() == false ||
233314564Sdim          reg_ctx_sp->GetCFA(cursor_sp->cfa) == false ||
234314564Sdim          abi->CallFrameAddressIsValid(cursor_sp->cfa) == false) {
235314564Sdim        if (prev_frame->reg_ctx_lldb_sp->TryFallbackUnwindPlan()) {
236314564Sdim          // TryFallbackUnwindPlan for prev_frame succeeded and updated
237314564Sdim          // reg_ctx_lldb_sp field of
238314564Sdim          // prev_frame. However, cfa field of prev_frame still needs to be
239314564Sdim          // updated. Hence updating it.
240314564Sdim          if (!(prev_frame->reg_ctx_lldb_sp->GetCFA(prev_frame->cfa)))
241314564Sdim            return nullptr;
242288943Sdim
243314564Sdim          return GetOneMoreFrame(abi);
244254721Semaste        }
245296417Sdim
246254721Semaste        if (log)
247314564Sdim          log->Printf("%*sFrame %d did not get a valid CFA for this frame, "
248314564Sdim                      "stopping stack walk",
249314564Sdim                      cur_idx < 100 ? cur_idx : 100, "", cur_idx);
250288943Sdim        return nullptr;
251314564Sdim      } else {
252314564Sdim        if (log)
253314564Sdim          log->Printf("%*sFrame %d had a bad CFA value but we switched the "
254314564Sdim                      "UnwindPlan being used and got one that looks more "
255314564Sdim                      "realistic.",
256314564Sdim                      cur_idx < 100 ? cur_idx : 100, "", cur_idx);
257314564Sdim      }
258254721Semaste    }
259314564Sdim  }
260314564Sdim  if (!reg_ctx_sp->ReadPC(cursor_sp->start_pc)) {
261314564Sdim    // If the RegisterContextLLDB has a fallback UnwindPlan, it will switch to
262314564Sdim    // that and return
263314564Sdim    // true.  Subsequent calls to TryFallbackUnwindPlan() will return false.
264314564Sdim    if (prev_frame->reg_ctx_lldb_sp->TryFallbackUnwindPlan()) {
265314564Sdim      // TryFallbackUnwindPlan for prev_frame succeeded and updated
266314564Sdim      // reg_ctx_lldb_sp field of
267314564Sdim      // prev_frame. However, cfa field of prev_frame still needs to be updated.
268314564Sdim      // Hence updating it.
269314564Sdim      if (!(prev_frame->reg_ctx_lldb_sp->GetCFA(prev_frame->cfa)))
270314564Sdim        return nullptr;
271296417Sdim
272314564Sdim      return GetOneMoreFrame(abi);
273314564Sdim    }
274288943Sdim
275314564Sdim    if (log)
276314564Sdim      log->Printf(
277314564Sdim          "%*sFrame %d did not get PC for this frame, stopping stack walk",
278314564Sdim          cur_idx < 100 ? cur_idx : 100, "", cur_idx);
279314564Sdim    return nullptr;
280314564Sdim  }
281314564Sdim  if (abi && !abi->CodeAddressIsValid(cursor_sp->start_pc)) {
282314564Sdim    // If the RegisterContextLLDB has a fallback UnwindPlan, it will switch to
283314564Sdim    // that and return
284314564Sdim    // true.  Subsequent calls to TryFallbackUnwindPlan() will return false.
285314564Sdim    if (prev_frame->reg_ctx_lldb_sp->TryFallbackUnwindPlan()) {
286314564Sdim      // TryFallbackUnwindPlan for prev_frame succeeded and updated
287314564Sdim      // reg_ctx_lldb_sp field of
288314564Sdim      // prev_frame. However, cfa field of prev_frame still needs to be updated.
289314564Sdim      // Hence updating it.
290314564Sdim      if (!(prev_frame->reg_ctx_lldb_sp->GetCFA(prev_frame->cfa)))
291288943Sdim        return nullptr;
292314564Sdim
293314564Sdim      return GetOneMoreFrame(abi);
294254721Semaste    }
295258054Semaste
296314564Sdim    if (log)
297314564Sdim      log->Printf("%*sFrame %d did not get a valid PC, stopping stack walk",
298314564Sdim                  cur_idx < 100 ? cur_idx : 100, "", cur_idx);
299314564Sdim    return nullptr;
300314564Sdim  }
301314564Sdim  // Infinite loop where the current cursor is the same as the previous one...
302314564Sdim  if (prev_frame->start_pc == cursor_sp->start_pc &&
303314564Sdim      prev_frame->cfa == cursor_sp->cfa) {
304314564Sdim    if (log)
305314564Sdim      log->Printf("th%d pc of this frame is the same as the previous frame and "
306314564Sdim                  "CFAs for both frames are identical -- stopping unwind",
307314564Sdim                  m_thread.GetIndexID());
308314564Sdim    return nullptr;
309314564Sdim  }
310314564Sdim
311314564Sdim  cursor_sp->reg_ctx_lldb_sp = reg_ctx_sp;
312314564Sdim  return cursor_sp;
313288943Sdim}
314288943Sdim
315314564Sdimvoid UnwindLLDB::UpdateUnwindPlanForFirstFrameIfInvalid(ABI *abi) {
316314564Sdim  // This function is called for First Frame only.
317314564Sdim  assert(m_frames.size() == 1 && "No. of cursor frames are not 1");
318296417Sdim
319314564Sdim  bool old_m_unwind_complete = m_unwind_complete;
320314564Sdim  CursorSP old_m_candidate_frame = m_candidate_frame;
321296417Sdim
322314564Sdim  // Try to unwind 2 more frames using the Unwinder. It uses Full UnwindPlan
323314564Sdim  // and if Full UnwindPlan fails, then uses FallBack UnwindPlan. Also
324314564Sdim  // update the cfa of Frame 0 (if required).
325314564Sdim  AddOneMoreFrame(abi);
326296417Sdim
327314564Sdim  // Remove all the frames added by above function as the purpose of
328314564Sdim  // using above function was just to check whether Unwinder of Frame 0
329314564Sdim  // works or not.
330314564Sdim  for (uint32_t i = 1; i < m_frames.size(); i++)
331314564Sdim    m_frames.pop_back();
332296417Sdim
333314564Sdim  // Restore status after calling AddOneMoreFrame
334314564Sdim  m_unwind_complete = old_m_unwind_complete;
335314564Sdim  m_candidate_frame = old_m_candidate_frame;
336314564Sdim  return;
337296417Sdim}
338296417Sdim
339314564Sdimbool UnwindLLDB::AddOneMoreFrame(ABI *abi) {
340314564Sdim  Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_UNWIND));
341296417Sdim
342314564Sdim  // Frame zero is a little different
343314564Sdim  if (m_frames.empty())
344314564Sdim    return false;
345288943Sdim
346314564Sdim  // If we've already gotten to the end of the stack, don't bother to try
347314564Sdim  // again...
348314564Sdim  if (m_unwind_complete)
349314564Sdim    return false;
350288943Sdim
351314564Sdim  CursorSP new_frame = m_candidate_frame;
352314564Sdim  if (new_frame == nullptr)
353314564Sdim    new_frame = GetOneMoreFrame(abi);
354288943Sdim
355314564Sdim  if (new_frame == nullptr) {
356314564Sdim    if (log)
357314564Sdim      log->Printf("th%d Unwind of this thread is complete.",
358314564Sdim                  m_thread.GetIndexID());
359314564Sdim    m_unwind_complete = true;
360314564Sdim    return false;
361314564Sdim  }
362288943Sdim
363314564Sdim  m_frames.push_back(new_frame);
364288943Sdim
365314564Sdim  // If we can get one more frame further then accept that we get back a correct
366314564Sdim  // frame.
367314564Sdim  m_candidate_frame = GetOneMoreFrame(abi);
368314564Sdim  if (m_candidate_frame)
369314564Sdim    return true;
370288943Sdim
371314564Sdim  // We can't go further from the frame returned by GetOneMore frame. Lets try
372314564Sdim  // to get a
373314564Sdim  // different frame with using the fallback unwind plan.
374314564Sdim  if (!m_frames[m_frames.size() - 2]
375314564Sdim           ->reg_ctx_lldb_sp->TryFallbackUnwindPlan()) {
376314564Sdim    // We don't have a valid fallback unwind plan. Accept the frame as it is.
377314564Sdim    // This is a
378314564Sdim    // valid situation when we are at the bottom of the stack.
379314564Sdim    return true;
380314564Sdim  }
381288943Sdim
382314564Sdim  // Remove the possibly incorrect frame from the frame list and try to add a
383314564Sdim  // different one with
384314564Sdim  // the newly selected fallback unwind plan.
385314564Sdim  m_frames.pop_back();
386314564Sdim  CursorSP new_frame_v2 = GetOneMoreFrame(abi);
387314564Sdim  if (new_frame_v2 == nullptr) {
388314564Sdim    // We haven't got a new frame from the fallback unwind plan. Accept the
389314564Sdim    // frame from the
390314564Sdim    // original unwind plan. This is a valid situation when we are at the bottom
391314564Sdim    // of the stack.
392314564Sdim    m_frames.push_back(new_frame);
393314564Sdim    return true;
394314564Sdim  }
395288943Sdim
396314564Sdim  // Push the new frame to the list and try to continue from this frame. If we
397314564Sdim  // can get a new frame
398314564Sdim  // then accept it as the correct one.
399314564Sdim  m_frames.push_back(new_frame_v2);
400314564Sdim  m_candidate_frame = GetOneMoreFrame(abi);
401314564Sdim  if (m_candidate_frame) {
402314564Sdim    // If control reached here then TryFallbackUnwindPlan had succeeded for
403314564Sdim    // Cursor::m_frames[m_frames.size() - 2].
404314564Sdim    // It also succeeded to Unwind next 2 frames i.e. m_frames[m_frames.size() -
405314564Sdim    // 1] and a frame after that.
406314564Sdim    // For Cursor::m_frames[m_frames.size() - 2], reg_ctx_lldb_sp field was
407314564Sdim    // already updated during TryFallbackUnwindPlan
408314564Sdim    // call above. However, cfa field still needs to be updated. Hence updating
409314564Sdim    // it here and then returning.
410314564Sdim    if (!(m_frames[m_frames.size() - 2]->reg_ctx_lldb_sp->GetCFA(
411314564Sdim            m_frames[m_frames.size() - 2]->cfa)))
412314564Sdim      return false;
413314564Sdim    return true;
414314564Sdim  }
415288943Sdim
416314564Sdim  // The new frame hasn't helped in unwinding. Fall back to the original one as
417314564Sdim  // the default unwind
418314564Sdim  // plan is usually more reliable then the fallback one.
419314564Sdim  m_frames.pop_back();
420314564Sdim  m_frames.push_back(new_frame);
421314564Sdim  return true;
422254721Semaste}
423254721Semaste
424314564Sdimbool UnwindLLDB::DoGetFrameInfoAtIndex(uint32_t idx, addr_t &cfa, addr_t &pc) {
425314564Sdim  if (m_frames.size() == 0) {
426314564Sdim    if (!AddFirstFrame())
427314564Sdim      return false;
428314564Sdim  }
429254721Semaste
430314564Sdim  ProcessSP process_sp(m_thread.GetProcess());
431314564Sdim  ABI *abi = process_sp ? process_sp->GetABI().get() : NULL;
432254721Semaste
433314564Sdim  while (idx >= m_frames.size() && AddOneMoreFrame(abi))
434314564Sdim    ;
435254721Semaste
436314564Sdim  if (idx < m_frames.size()) {
437314564Sdim    cfa = m_frames[idx]->cfa;
438314564Sdim    pc = m_frames[idx]->start_pc;
439314564Sdim    return true;
440314564Sdim  }
441314564Sdim  return false;
442254721Semaste}
443254721Semaste
444254721Semastelldb::RegisterContextSP
445314564SdimUnwindLLDB::DoCreateRegisterContextForFrame(StackFrame *frame) {
446314564Sdim  lldb::RegisterContextSP reg_ctx_sp;
447314564Sdim  uint32_t idx = frame->GetConcreteFrameIndex();
448254721Semaste
449314564Sdim  if (idx == 0) {
450314564Sdim    return m_thread.GetRegisterContext();
451314564Sdim  }
452254721Semaste
453314564Sdim  if (m_frames.size() == 0) {
454314564Sdim    if (!AddFirstFrame())
455314564Sdim      return reg_ctx_sp;
456314564Sdim  }
457254721Semaste
458314564Sdim  ProcessSP process_sp(m_thread.GetProcess());
459314564Sdim  ABI *abi = process_sp ? process_sp->GetABI().get() : NULL;
460254721Semaste
461314564Sdim  while (idx >= m_frames.size()) {
462314564Sdim    if (!AddOneMoreFrame(abi))
463314564Sdim      break;
464314564Sdim  }
465254721Semaste
466314564Sdim  const uint32_t num_frames = m_frames.size();
467314564Sdim  if (idx < num_frames) {
468314564Sdim    Cursor *frame_cursor = m_frames[idx].get();
469314564Sdim    reg_ctx_sp = frame_cursor->reg_ctx_lldb_sp;
470314564Sdim  }
471314564Sdim  return reg_ctx_sp;
472254721Semaste}
473254721Semaste
474254721SemasteUnwindLLDB::RegisterContextLLDBSP
475314564SdimUnwindLLDB::GetRegisterContextForFrameNum(uint32_t frame_num) {
476314564Sdim  RegisterContextLLDBSP reg_ctx_sp;
477314564Sdim  if (frame_num < m_frames.size())
478314564Sdim    reg_ctx_sp = m_frames[frame_num]->reg_ctx_lldb_sp;
479314564Sdim  return reg_ctx_sp;
480254721Semaste}
481254721Semaste
482314564Sdimbool UnwindLLDB::SearchForSavedLocationForRegister(
483314564Sdim    uint32_t lldb_regnum, lldb_private::UnwindLLDB::RegisterLocation &regloc,
484314564Sdim    uint32_t starting_frame_num, bool pc_reg) {
485314564Sdim  int64_t frame_num = starting_frame_num;
486314564Sdim  if (static_cast<size_t>(frame_num) >= m_frames.size())
487314564Sdim    return false;
488254721Semaste
489314564Sdim  // Never interrogate more than one level while looking for the saved pc value.
490314564Sdim  // If the value
491314564Sdim  // isn't saved by frame_num, none of the frames lower on the stack will have a
492314564Sdim  // useful value.
493314564Sdim  if (pc_reg) {
494314564Sdim    UnwindLLDB::RegisterSearchResult result;
495314564Sdim    result = m_frames[frame_num]->reg_ctx_lldb_sp->SavedLocationForRegister(
496314564Sdim        lldb_regnum, regloc);
497314564Sdim    if (result == UnwindLLDB::RegisterSearchResult::eRegisterFound)
498314564Sdim      return true;
499314564Sdim    else
500314564Sdim      return false;
501314564Sdim  }
502314564Sdim  while (frame_num >= 0) {
503314564Sdim    UnwindLLDB::RegisterSearchResult result;
504314564Sdim    result = m_frames[frame_num]->reg_ctx_lldb_sp->SavedLocationForRegister(
505314564Sdim        lldb_regnum, regloc);
506314564Sdim
507314564Sdim    // We descended down to the live register context aka stack frame 0 and are
508314564Sdim    // reading the value
509314564Sdim    // out of a live register.
510314564Sdim    if (result == UnwindLLDB::RegisterSearchResult::eRegisterFound &&
511314564Sdim        regloc.type ==
512314564Sdim            UnwindLLDB::RegisterLocation::eRegisterInLiveRegisterContext) {
513314564Sdim      return true;
514254721Semaste    }
515254721Semaste
516314564Sdim    // If we have unwind instructions saying that register N is saved in
517314564Sdim    // register M in the middle of
518314564Sdim    // the stack (and N can equal M here, meaning the register was not used in
519314564Sdim    // this function), then
520314564Sdim    // change the register number we're looking for to M and keep looking for a
521314564Sdim    // concrete  location
522314564Sdim    // down the stack, or an actual value from a live RegisterContext at frame
523314564Sdim    // 0.
524314564Sdim    if (result == UnwindLLDB::RegisterSearchResult::eRegisterFound &&
525314564Sdim        regloc.type == UnwindLLDB::RegisterLocation::eRegisterInRegister &&
526314564Sdim        frame_num > 0) {
527314564Sdim      result = UnwindLLDB::RegisterSearchResult::eRegisterNotFound;
528314564Sdim      lldb_regnum = regloc.location.register_number;
529314564Sdim    }
530280031Sdim
531314564Sdim    if (result == UnwindLLDB::RegisterSearchResult::eRegisterFound)
532314564Sdim      return true;
533314564Sdim    if (result == UnwindLLDB::RegisterSearchResult::eRegisterIsVolatile)
534314564Sdim      return false;
535314564Sdim    frame_num--;
536314564Sdim  }
537314564Sdim  return false;
538254721Semaste}
539