blob: 87d0f49421c5fd1d29369b16bb8d2fcd8d88c469 [file] [log] [blame]
Jason Molendafbcb7f22010-09-10 07:49:16 +00001//===-- UnwindPlan.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
10#include "lldb/Symbol/UnwindPlan.h"
Greg Clayton79ea8782011-04-26 23:48:45 +000011
12#include "lldb/Core/ConstString.h"
Jason Molenda61cd0722013-12-03 04:46:27 +000013#include "lldb/Core/Log.h"
Greg Claytonf5e56de2010-09-14 23:36:40 +000014#include "lldb/Target/Process.h"
Jason Molendafbcb7f22010-09-10 07:49:16 +000015#include "lldb/Target/RegisterContext.h"
Greg Claytonf5e56de2010-09-14 23:36:40 +000016#include "lldb/Target/Thread.h"
Jason Molendafbcb7f22010-09-10 07:49:16 +000017
18using namespace lldb;
19using namespace lldb_private;
20
21bool
22UnwindPlan::Row::RegisterLocation::operator == (const UnwindPlan::Row::RegisterLocation& rhs) const
23{
Greg Clayton31f1d2f2011-05-11 18:39:18 +000024 if (m_type == rhs.m_type)
25 {
26 switch (m_type)
27 {
28 case unspecified:
29 case undefined:
30 case same:
31 return true;
32
33 case atCFAPlusOffset:
34 case isCFAPlusOffset:
35 return m_location.offset == rhs.m_location.offset;
36
37 case inOtherRegister:
38 return m_location.reg_num == rhs.m_location.reg_num;
39
40 case atDWARFExpression:
41 case isDWARFExpression:
42 if (m_location.expr.length == rhs.m_location.expr.length)
43 return !memcmp (m_location.expr.opcodes, rhs.m_location.expr.opcodes, m_location.expr.length);
44 break;
45 }
46 }
Jason Molendafbcb7f22010-09-10 07:49:16 +000047 return false;
48}
49
50// This function doesn't copy the dwarf expression bytes; they must remain in allocated
51// memory for the lifespan of this UnwindPlan object.
52void
53UnwindPlan::Row::RegisterLocation::SetAtDWARFExpression (const uint8_t *opcodes, uint32_t len)
54{
55 m_type = atDWARFExpression;
56 m_location.expr.opcodes = opcodes;
57 m_location.expr.length = len;
58}
59
60// This function doesn't copy the dwarf expression bytes; they must remain in allocated
61// memory for the lifespan of this UnwindPlan object.
62void
63UnwindPlan::Row::RegisterLocation::SetIsDWARFExpression (const uint8_t *opcodes, uint32_t len)
64{
65 m_type = isDWARFExpression;
66 m_location.expr.opcodes = opcodes;
67 m_location.expr.length = len;
68}
69
70void
Greg Clayton31f1d2f2011-05-11 18:39:18 +000071UnwindPlan::Row::RegisterLocation::Dump (Stream &s, const UnwindPlan* unwind_plan, const UnwindPlan::Row* row, Thread* thread, bool verbose) const
Jason Molendafbcb7f22010-09-10 07:49:16 +000072{
73 switch (m_type)
74 {
75 case unspecified:
Greg Clayton31f1d2f2011-05-11 18:39:18 +000076 if (verbose)
77 s.PutCString ("=<unspec>");
78 else
79 s.PutCString ("=!");
Jason Molendafbcb7f22010-09-10 07:49:16 +000080 break;
Greg Clayton31f1d2f2011-05-11 18:39:18 +000081 case undefined:
82 if (verbose)
83 s.PutCString ("=<undef>");
84 else
85 s.PutCString ("=?");
Jason Molendafbcb7f22010-09-10 07:49:16 +000086 break;
Greg Clayton31f1d2f2011-05-11 18:39:18 +000087 case same:
88 s.PutCString ("= <same>");
Jason Molendafbcb7f22010-09-10 07:49:16 +000089 break;
Greg Clayton31f1d2f2011-05-11 18:39:18 +000090
Jason Molendafbcb7f22010-09-10 07:49:16 +000091 case atCFAPlusOffset:
Jason Molendafbcb7f22010-09-10 07:49:16 +000092 case isCFAPlusOffset:
Greg Clayton31f1d2f2011-05-11 18:39:18 +000093 {
94 s.PutChar('=');
95 if (m_type == atCFAPlusOffset)
96 s.PutChar('[');
97 if (verbose)
98 s.Printf ("CFA%+d", m_location.offset);
99
100 if (unwind_plan && row)
101 {
102 const uint32_t cfa_reg = row->GetCFARegister();
103 const RegisterInfo *cfa_reg_info = unwind_plan->GetRegisterInfo (thread, cfa_reg);
104 const int32_t offset = row->GetCFAOffset() + m_location.offset;
105 if (verbose)
106 {
107 if (cfa_reg_info)
108 s.Printf (" (%s%+d)", cfa_reg_info->name, offset);
109 else
Johnny Chend397dc82011-08-12 00:02:24 +0000110 s.Printf (" (reg(%u)%+d)", cfa_reg, offset);
Greg Clayton31f1d2f2011-05-11 18:39:18 +0000111 }
112 else
113 {
114 if (cfa_reg_info)
115 s.Printf ("%s", cfa_reg_info->name);
116 else
Johnny Chend397dc82011-08-12 00:02:24 +0000117 s.Printf ("reg(%u)", cfa_reg);
Greg Clayton31f1d2f2011-05-11 18:39:18 +0000118 if (offset != 0)
119 s.Printf ("%+d", offset);
120 }
121 }
122 if (m_type == atCFAPlusOffset)
123 s.PutChar(']');
124 }
Jason Molendafbcb7f22010-09-10 07:49:16 +0000125 break;
Greg Clayton31f1d2f2011-05-11 18:39:18 +0000126
Jason Molendafbcb7f22010-09-10 07:49:16 +0000127 case inOtherRegister:
Greg Clayton31f1d2f2011-05-11 18:39:18 +0000128 {
Ed Masted4612ad2014-04-20 13:17:36 +0000129 const RegisterInfo *other_reg_info = nullptr;
Greg Clayton31f1d2f2011-05-11 18:39:18 +0000130 if (unwind_plan)
131 other_reg_info = unwind_plan->GetRegisterInfo (thread, m_location.reg_num);
132 if (other_reg_info)
133 s.Printf ("=%s", other_reg_info->name);
134 else
135 s.Printf ("=reg(%u)", m_location.reg_num);
136 }
Jason Molendafbcb7f22010-09-10 07:49:16 +0000137 break;
Greg Clayton31f1d2f2011-05-11 18:39:18 +0000138
Jason Molendafbcb7f22010-09-10 07:49:16 +0000139 case atDWARFExpression:
Jason Molendafbcb7f22010-09-10 07:49:16 +0000140 case isDWARFExpression:
Greg Clayton31f1d2f2011-05-11 18:39:18 +0000141 {
142 s.PutChar('=');
143 if (m_type == atDWARFExpression)
144 s.PutCString("[dwarf-expr]");
145 else
146 s.PutCString("dwarf-expr");
147 }
Jason Molendafbcb7f22010-09-10 07:49:16 +0000148 break;
Greg Clayton31f1d2f2011-05-11 18:39:18 +0000149
Jason Molendafbcb7f22010-09-10 07:49:16 +0000150 }
151}
152
153void
154UnwindPlan::Row::Clear ()
155{
Justin Hibbits43bcdbd2014-11-12 15:14:03 +0000156 m_cfa_type = CFAIsRegisterPlusOffset;
Jason Molendafbcb7f22010-09-10 07:49:16 +0000157 m_offset = 0;
Jason Molenda60f0bd42012-10-26 06:08:58 +0000158 m_cfa_reg_num = LLDB_INVALID_REGNUM;
Jason Molendafbcb7f22010-09-10 07:49:16 +0000159 m_cfa_offset = 0;
160 m_register_locations.clear();
161}
162
163void
Greg Clayton31f1d2f2011-05-11 18:39:18 +0000164UnwindPlan::Row::Dump (Stream& s, const UnwindPlan* unwind_plan, Thread* thread, addr_t base_addr) const
Jason Molendafbcb7f22010-09-10 07:49:16 +0000165{
Greg Clayton31f1d2f2011-05-11 18:39:18 +0000166 const RegisterInfo *reg_info = unwind_plan->GetRegisterInfo (thread, GetCFARegister());
Greg Clayton5ccbd292011-01-06 22:15:06 +0000167
Greg Clayton31f1d2f2011-05-11 18:39:18 +0000168 if (base_addr != LLDB_INVALID_ADDRESS)
Daniel Malead01b2952012-11-29 21:49:15 +0000169 s.Printf ("0x%16.16" PRIx64 ": CFA=", base_addr + GetOffset());
Jason Molendafbcb7f22010-09-10 07:49:16 +0000170 else
Jason Molenda34549b82015-01-13 06:04:04 +0000171 s.Printf ("%4" PRId64 ": CFA=", GetOffset());
Greg Clayton31f1d2f2011-05-11 18:39:18 +0000172
173 if (reg_info)
174 s.Printf ("%s", reg_info->name);
175 else
176 s.Printf ("reg(%u)", GetCFARegister());
Jason Molenda42107132012-08-10 20:52:59 +0000177 s.Printf ("%+3d => ", GetCFAOffset ());
Jason Molendafbcb7f22010-09-10 07:49:16 +0000178 for (collection::const_iterator idx = m_register_locations.begin (); idx != m_register_locations.end (); ++idx)
179 {
Greg Clayton31f1d2f2011-05-11 18:39:18 +0000180 reg_info = unwind_plan->GetRegisterInfo (thread, idx->first);
181 if (reg_info)
182 s.Printf ("%s", reg_info->name);
183 else
184 s.Printf ("reg(%u)", idx->first);
185 const bool verbose = false;
186 idx->second.Dump(s, unwind_plan, this, thread, verbose);
187 s.PutChar (' ');
Jason Molendafbcb7f22010-09-10 07:49:16 +0000188 }
Greg Clayton877aaa52011-01-08 21:19:00 +0000189 s.EOL();
Jason Molendafbcb7f22010-09-10 07:49:16 +0000190}
191
192UnwindPlan::Row::Row() :
Justin Hibbits43bcdbd2014-11-12 15:14:03 +0000193 m_offset (0),
194 m_cfa_type (CFAIsRegisterPlusOffset),
195 m_cfa_reg_num (LLDB_INVALID_REGNUM),
196 m_cfa_offset (0),
197 m_register_locations ()
Jason Molendafbcb7f22010-09-10 07:49:16 +0000198{
199}
200
201bool
202UnwindPlan::Row::GetRegisterInfo (uint32_t reg_num, UnwindPlan::Row::RegisterLocation& register_location) const
203{
204 collection::const_iterator pos = m_register_locations.find(reg_num);
205 if (pos != m_register_locations.end())
206 {
207 register_location = pos->second;
208 return true;
209 }
210 return false;
211}
212
213void
Jason Molenda34549b82015-01-13 06:04:04 +0000214UnwindPlan::Row::RemoveRegisterInfo (uint32_t reg_num)
215{
216 collection::const_iterator pos = m_register_locations.find(reg_num);
217 if (pos != m_register_locations.end())
218 {
219 m_register_locations.erase(pos);
220 }
221}
222
223void
Jason Molendafbcb7f22010-09-10 07:49:16 +0000224UnwindPlan::Row::SetRegisterInfo (uint32_t reg_num, const UnwindPlan::Row::RegisterLocation register_location)
225{
226 m_register_locations[reg_num] = register_location;
227}
228
Greg Clayton31f1d2f2011-05-11 18:39:18 +0000229bool
230UnwindPlan::Row::SetRegisterLocationToAtCFAPlusOffset (uint32_t reg_num, int32_t offset, bool can_replace)
231{
232 if (!can_replace && m_register_locations.find(reg_num) != m_register_locations.end())
233 return false;
234 RegisterLocation reg_loc;
235 reg_loc.SetAtCFAPlusOffset(offset);
236 m_register_locations[reg_num] = reg_loc;
237 return true;
238}
239
240bool
241UnwindPlan::Row::SetRegisterLocationToIsCFAPlusOffset (uint32_t reg_num, int32_t offset, bool can_replace)
242{
243 if (!can_replace && m_register_locations.find(reg_num) != m_register_locations.end())
244 return false;
245 RegisterLocation reg_loc;
246 reg_loc.SetIsCFAPlusOffset(offset);
247 m_register_locations[reg_num] = reg_loc;
248 return true;
249}
250
251bool
252UnwindPlan::Row::SetRegisterLocationToUndefined (uint32_t reg_num, bool can_replace, bool can_replace_only_if_unspecified)
253{
254 collection::iterator pos = m_register_locations.find(reg_num);
255 collection::iterator end = m_register_locations.end();
256
257 if (pos != end)
258 {
259 if (!can_replace)
260 return false;
261 if (can_replace_only_if_unspecified && !pos->second.IsUnspecified())
262 return false;
263 }
264 RegisterLocation reg_loc;
265 reg_loc.SetUndefined();
266 m_register_locations[reg_num] = reg_loc;
267 return true;
268}
269
270bool
271UnwindPlan::Row::SetRegisterLocationToUnspecified (uint32_t reg_num, bool can_replace)
272{
273 if (!can_replace && m_register_locations.find(reg_num) != m_register_locations.end())
274 return false;
275 RegisterLocation reg_loc;
276 reg_loc.SetUnspecified();
277 m_register_locations[reg_num] = reg_loc;
278 return true;
279}
280
281bool
282UnwindPlan::Row::SetRegisterLocationToRegister (uint32_t reg_num,
283 uint32_t other_reg_num,
284 bool can_replace)
285{
286 if (!can_replace && m_register_locations.find(reg_num) != m_register_locations.end())
287 return false;
288 RegisterLocation reg_loc;
289 reg_loc.SetInRegister(other_reg_num);
290 m_register_locations[reg_num] = reg_loc;
291 return true;
292}
293
294bool
295UnwindPlan::Row::SetRegisterLocationToSame (uint32_t reg_num, bool must_replace)
296{
297 if (must_replace && m_register_locations.find(reg_num) == m_register_locations.end())
298 return false;
299 RegisterLocation reg_loc;
300 reg_loc.SetSame();
301 m_register_locations[reg_num] = reg_loc;
302 return true;
303}
304
305void
306UnwindPlan::Row::SetCFARegister (uint32_t reg_num)
307{
308 m_cfa_reg_num = reg_num;
309}
Jason Molendafbcb7f22010-09-10 07:49:16 +0000310
Jason Molenda24a83782012-07-17 01:57:24 +0000311bool
312UnwindPlan::Row::operator == (const UnwindPlan::Row& rhs) const
313{
314 if (m_offset != rhs.m_offset || m_cfa_reg_num != rhs.m_cfa_reg_num || m_cfa_offset != rhs.m_cfa_offset)
315 return false;
Justin Hibbits43bcdbd2014-11-12 15:14:03 +0000316
317 if (m_cfa_type != rhs.m_cfa_type)
318 return false;
319
320 if (m_cfa_type == CFAIsRegisterPlusOffset)
321 {
322 if (m_cfa_reg_num != rhs.m_cfa_reg_num)
323 return false;
324 if (m_cfa_offset != rhs.m_cfa_offset)
325 return false;
326 }
327 if (m_cfa_type == CFAIsRegisterDereferenced)
328 {
329 if (m_cfa_reg_num != rhs.m_cfa_reg_num)
330 return false;
331 }
332
Greg Clayton358a7892012-07-18 20:37:53 +0000333 return m_register_locations == rhs.m_register_locations;
Jason Molenda24a83782012-07-17 01:57:24 +0000334}
335
Jason Molendafbcb7f22010-09-10 07:49:16 +0000336void
Greg Clayton358a7892012-07-18 20:37:53 +0000337UnwindPlan::AppendRow (const UnwindPlan::RowSP &row_sp)
Jason Molendafbcb7f22010-09-10 07:49:16 +0000338{
Greg Clayton358a7892012-07-18 20:37:53 +0000339 if (m_row_list.empty() || m_row_list.back()->GetOffset() != row_sp->GetOffset())
340 m_row_list.push_back(row_sp);
Jason Molendafbcb7f22010-09-10 07:49:16 +0000341 else
Greg Clayton358a7892012-07-18 20:37:53 +0000342 m_row_list.back() = row_sp;
Jason Molendafbcb7f22010-09-10 07:49:16 +0000343}
344
Todd Fiala05625242014-08-25 20:29:09 +0000345void
346UnwindPlan::InsertRow (const UnwindPlan::RowSP &row_sp)
347{
348 collection::iterator it = m_row_list.begin();
349 while (it != m_row_list.end()) {
350 RowSP row = *it;
351 if (row->GetOffset() > row_sp->GetOffset())
352 break;
353 it++;
354 }
355 m_row_list.insert(it, row_sp);
356}
357
Jason Molenda1d42c7b2012-07-14 04:52:53 +0000358UnwindPlan::RowSP
Jason Molendafbcb7f22010-09-10 07:49:16 +0000359UnwindPlan::GetRowForFunctionOffset (int offset) const
360{
Jason Molenda1d42c7b2012-07-14 04:52:53 +0000361 RowSP row;
Greg Clayton877aaa52011-01-08 21:19:00 +0000362 if (!m_row_list.empty())
Jason Molendaab4f1922010-10-25 11:12:07 +0000363 {
Greg Clayton877aaa52011-01-08 21:19:00 +0000364 if (offset == -1)
Jason Molenda1d42c7b2012-07-14 04:52:53 +0000365 row = m_row_list.back();
Jason Molendafbcb7f22010-09-10 07:49:16 +0000366 else
367 {
Greg Clayton877aaa52011-01-08 21:19:00 +0000368 collection::const_iterator pos, end = m_row_list.end();
369 for (pos = m_row_list.begin(); pos != end; ++pos)
370 {
Saleem Abdulrasool3985c8c2014-04-02 03:51:35 +0000371 if ((*pos)->GetOffset() <= static_cast<lldb::offset_t>(offset))
Jason Molenda1d42c7b2012-07-14 04:52:53 +0000372 row = *pos;
Greg Clayton877aaa52011-01-08 21:19:00 +0000373 else
374 break;
375 }
Jason Molendafbcb7f22010-09-10 07:49:16 +0000376 }
377 }
Jason Molenda1d42c7b2012-07-14 04:52:53 +0000378 return row;
Jason Molendafbcb7f22010-09-10 07:49:16 +0000379}
380
381bool
382UnwindPlan::IsValidRowIndex (uint32_t idx) const
383{
384 return idx < m_row_list.size();
385}
386
Jason Molenda1d42c7b2012-07-14 04:52:53 +0000387const UnwindPlan::RowSP
Jason Molendafbcb7f22010-09-10 07:49:16 +0000388UnwindPlan::GetRowAtIndex (uint32_t idx) const
389{
390 // You must call IsValidRowIndex(idx) first before calling this!!!
Greg Clayton877aaa52011-01-08 21:19:00 +0000391 assert (idx < m_row_list.size());
Jason Molendafbcb7f22010-09-10 07:49:16 +0000392 return m_row_list[idx];
393}
394
Jason Molenda1d42c7b2012-07-14 04:52:53 +0000395const UnwindPlan::RowSP
Greg Clayton31f1d2f2011-05-11 18:39:18 +0000396UnwindPlan::GetLastRow () const
397{
398 // You must call GetRowCount() first to make sure there is at least one row
399 assert (!m_row_list.empty());
400 return m_row_list.back();
401}
402
Jason Molendafbcb7f22010-09-10 07:49:16 +0000403int
404UnwindPlan::GetRowCount () const
405{
406 return m_row_list.size ();
407}
408
409void
Jason Molendafbcb7f22010-09-10 07:49:16 +0000410UnwindPlan::SetPlanValidAddressRange (const AddressRange& range)
411{
Jason Molendaab4f1922010-10-25 11:12:07 +0000412 if (range.GetBaseAddress().IsValid() && range.GetByteSize() != 0)
Jason Molendaab4f1922010-10-25 11:12:07 +0000413 m_plan_valid_address_range = range;
Jason Molendafbcb7f22010-09-10 07:49:16 +0000414}
415
416bool
417UnwindPlan::PlanValidAtAddress (Address addr)
418{
Jason Molenda61cd0722013-12-03 04:46:27 +0000419 // If this UnwindPlan has no rows, it is an invalid UnwindPlan.
420 if (GetRowCount() == 0)
421 {
422 Log *log(GetLogIfAllCategoriesSet (LIBLLDB_LOG_UNWIND));
423 if (log)
Jason Molenda135e55f2013-12-03 21:59:39 +0000424 {
425 StreamString s;
Ed Masted4612ad2014-04-20 13:17:36 +0000426 if (addr.Dump (&s, nullptr, Address::DumpStyleSectionNameOffset))
Jason Molenda135e55f2013-12-03 21:59:39 +0000427 {
428 log->Printf ("UnwindPlan is invalid -- no unwind rows for UnwindPlan '%s' at address %s",
429 m_source_name.GetCString(), s.GetData());
430 }
431 else
432 {
433 log->Printf ("UnwindPlan is invalid -- no unwind rows for UnwindPlan '%s'",
434 m_source_name.GetCString());
435 }
436 }
Jason Molenda61cd0722013-12-03 04:46:27 +0000437 return false;
438 }
439
440 // If the 0th Row of unwind instructions is missing, or if it doesn't provide
441 // a register to use to find the Canonical Frame Address, this is not a valid UnwindPlan.
Ed Masted4612ad2014-04-20 13:17:36 +0000442 if (GetRowAtIndex(0).get() == nullptr || GetRowAtIndex(0)->GetCFARegister() == LLDB_INVALID_REGNUM)
Jason Molenda61cd0722013-12-03 04:46:27 +0000443 {
444 Log *log(GetLogIfAllCategoriesSet (LIBLLDB_LOG_UNWIND));
445 if (log)
Jason Molenda135e55f2013-12-03 21:59:39 +0000446 {
447 StreamString s;
Ed Masted4612ad2014-04-20 13:17:36 +0000448 if (addr.Dump (&s, nullptr, Address::DumpStyleSectionNameOffset))
Jason Molenda135e55f2013-12-03 21:59:39 +0000449 {
450 log->Printf ("UnwindPlan is invalid -- no CFA register defined in row 0 for UnwindPlan '%s' at address %s",
451 m_source_name.GetCString(), s.GetData());
452 }
453 else
454 {
455 log->Printf ("UnwindPlan is invalid -- no CFA register defined in row 0 for UnwindPlan '%s'",
456 m_source_name.GetCString());
457 }
458 }
Jason Molenda61cd0722013-12-03 04:46:27 +0000459 return false;
460 }
461
Jason Molendaab4f1922010-10-25 11:12:07 +0000462 if (!m_plan_valid_address_range.GetBaseAddress().IsValid() || m_plan_valid_address_range.GetByteSize() == 0)
Jason Molendafbcb7f22010-09-10 07:49:16 +0000463 return true;
464
Jason Molenda59762002010-11-04 00:53:20 +0000465 if (!addr.IsValid())
466 return true;
467
Jason Molendafbcb7f22010-09-10 07:49:16 +0000468 if (m_plan_valid_address_range.ContainsFileAddress (addr))
469 return true;
470
471 return false;
472}
473
474void
Greg Clayton31f1d2f2011-05-11 18:39:18 +0000475UnwindPlan::Dump (Stream& s, Thread *thread, lldb::addr_t base_addr) const
Jason Molendafbcb7f22010-09-10 07:49:16 +0000476{
Jason Molendaab4f1922010-10-25 11:12:07 +0000477 if (!m_source_name.IsEmpty())
478 {
479 s.Printf ("This UnwindPlan originally sourced from %s\n", m_source_name.GetCString());
480 }
Jason Molendae9c7ecf2014-11-18 02:27:42 +0000481 if (m_lsda_address.IsValid() && m_personality_func_addr.IsValid())
482 {
483 TargetSP target_sp(thread->CalculateTarget());
484 addr_t lsda_load_addr = m_lsda_address.GetLoadAddress (target_sp.get());
485 addr_t personality_func_load_addr = m_personality_func_addr.GetLoadAddress (target_sp.get());
486
487 if (lsda_load_addr != LLDB_INVALID_ADDRESS && personality_func_load_addr != LLDB_INVALID_ADDRESS)
488 {
489 s.Printf("LSDA address 0x%" PRIx64 ", personality routine is at address 0x%" PRIx64 "\n",
490 lsda_load_addr, personality_func_load_addr);
491 }
492 }
493 s.Printf ("This UnwindPlan is sourced from the compiler: ");
494 switch (m_plan_is_sourced_from_compiler)
495 {
496 case eLazyBoolYes:
497 s.Printf ("yes.\n");
498 break;
499 case eLazyBoolNo:
500 s.Printf ("no.\n");
501 break;
502 case eLazyBoolCalculate:
503 s.Printf ("not specified.\n");
504 break;
505 }
506 s.Printf ("This UnwindPlan is valid at all instruction locations: ");
507 switch (m_plan_is_valid_at_all_instruction_locations)
508 {
509 case eLazyBoolYes:
510 s.Printf ("yes.\n");
511 break;
512 case eLazyBoolNo:
513 s.Printf ("no.\n");
514 break;
515 case eLazyBoolCalculate:
516 s.Printf ("not specified.\n");
517 break;
518 }
Jason Molendaab4f1922010-10-25 11:12:07 +0000519 if (m_plan_valid_address_range.GetBaseAddress().IsValid() && m_plan_valid_address_range.GetByteSize() > 0)
520 {
Greg Clayton877aaa52011-01-08 21:19:00 +0000521 s.PutCString ("Address range of this UnwindPlan: ");
Greg Clayton1ac04c32012-02-21 00:09:25 +0000522 TargetSP target_sp(thread->CalculateTarget());
523 m_plan_valid_address_range.Dump (&s, target_sp.get(), Address::DumpStyleSectionNameOffset);
Greg Clayton877aaa52011-01-08 21:19:00 +0000524 s.EOL();
Jason Molendaab4f1922010-10-25 11:12:07 +0000525 }
Greg Clayton31f1d2f2011-05-11 18:39:18 +0000526 collection::const_iterator pos, begin = m_row_list.begin(), end = m_row_list.end();
527 for (pos = begin; pos != end; ++pos)
Jason Molendafbcb7f22010-09-10 07:49:16 +0000528 {
Greg Clayton31f1d2f2011-05-11 18:39:18 +0000529 s.Printf ("row[%u]: ", (uint32_t)std::distance (begin, pos));
Jason Molenda1d42c7b2012-07-14 04:52:53 +0000530 (*pos)->Dump(s, this, thread, base_addr);
Jason Molendafbcb7f22010-09-10 07:49:16 +0000531 }
532}
Jason Molendaab4f1922010-10-25 11:12:07 +0000533
534void
535UnwindPlan::SetSourceName (const char *source)
536{
537 m_source_name = ConstString (source);
538}
539
540ConstString
541UnwindPlan::GetSourceName () const
542{
543 return m_source_name;
544}
Greg Clayton31f1d2f2011-05-11 18:39:18 +0000545
546const RegisterInfo *
547UnwindPlan::GetRegisterInfo (Thread* thread, uint32_t unwind_reg) const
548{
549 if (thread)
550 {
551 RegisterContext *reg_ctx = thread->GetRegisterContext().get();
552 if (reg_ctx)
553 {
554 uint32_t reg;
555 if (m_register_kind == eRegisterKindLLDB)
556 reg = unwind_reg;
557 else
558 reg = reg_ctx->ConvertRegisterKindToRegisterNumber (m_register_kind, unwind_reg);
559 if (reg != LLDB_INVALID_REGNUM)
560 return reg_ctx->GetRegisterInfoAtIndex (reg);
561 }
562 }
Ed Masted4612ad2014-04-20 13:17:36 +0000563 return nullptr;
Greg Clayton31f1d2f2011-05-11 18:39:18 +0000564}
565