blob: d4b06d5c925174c4b64f23f58685e9c852e327a5 [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('[');
Pavel Labathab970f52015-02-23 10:19:16 +000097 s.Printf ("CFA%+d", m_location.offset);
Greg Clayton31f1d2f2011-05-11 18:39:18 +000098 if (m_type == atCFAPlusOffset)
99 s.PutChar(']');
100 }
Jason Molendafbcb7f22010-09-10 07:49:16 +0000101 break;
Greg Clayton31f1d2f2011-05-11 18:39:18 +0000102
Jason Molendafbcb7f22010-09-10 07:49:16 +0000103 case inOtherRegister:
Greg Clayton31f1d2f2011-05-11 18:39:18 +0000104 {
Ed Masted4612ad2014-04-20 13:17:36 +0000105 const RegisterInfo *other_reg_info = nullptr;
Greg Clayton31f1d2f2011-05-11 18:39:18 +0000106 if (unwind_plan)
107 other_reg_info = unwind_plan->GetRegisterInfo (thread, m_location.reg_num);
108 if (other_reg_info)
109 s.Printf ("=%s", other_reg_info->name);
110 else
111 s.Printf ("=reg(%u)", m_location.reg_num);
112 }
Jason Molendafbcb7f22010-09-10 07:49:16 +0000113 break;
Greg Clayton31f1d2f2011-05-11 18:39:18 +0000114
Jason Molendafbcb7f22010-09-10 07:49:16 +0000115 case atDWARFExpression:
Jason Molendafbcb7f22010-09-10 07:49:16 +0000116 case isDWARFExpression:
Greg Clayton31f1d2f2011-05-11 18:39:18 +0000117 {
118 s.PutChar('=');
119 if (m_type == atDWARFExpression)
120 s.PutCString("[dwarf-expr]");
121 else
122 s.PutCString("dwarf-expr");
123 }
Jason Molendafbcb7f22010-09-10 07:49:16 +0000124 break;
Greg Clayton31f1d2f2011-05-11 18:39:18 +0000125
Jason Molendafbcb7f22010-09-10 07:49:16 +0000126 }
127}
128
Pavel Labathab970f52015-02-23 10:19:16 +0000129static void
130DumpRegisterName (Stream &s, const UnwindPlan* unwind_plan, Thread *thread, uint32_t reg_num) {
131 const RegisterInfo *reg_info = unwind_plan->GetRegisterInfo (thread, reg_num);
132 if (reg_info)
133 s.PutCString (reg_info->name);
134 else
135 s.Printf ("reg(%u)", reg_num);
136}
137
138bool
139UnwindPlan::Row::CFAValue::operator == (const UnwindPlan::Row::CFAValue& rhs) const
140{
141 if (m_type == rhs.m_type)
142 {
143 switch (m_type)
144 {
145 case unspecified:
146 return true;
147
148 case isRegisterPlusOffset:
149 return m_value.reg.offset == rhs.m_value.reg.offset;
150
151 case isRegisterDereferenced:
152 return m_value.reg.reg_num == rhs.m_value.reg.reg_num;
153
154 case isDWARFExpression:
155 if (m_value.expr.length == rhs.m_value.expr.length)
156 return !memcmp (m_value.expr.opcodes, rhs.m_value.expr.opcodes, m_value.expr.length);
157 break;
158 }
159 }
160 return false;
161}
162
163void
164UnwindPlan::Row::CFAValue::Dump(Stream &s, const UnwindPlan* unwind_plan, Thread* thread) const
165{
166 switch(m_type) {
167 case isRegisterPlusOffset:
168 DumpRegisterName(s, unwind_plan, thread, m_value.reg.reg_num);
169 s.Printf ("%+3d", m_value.reg.offset);
170 break;
171 case isRegisterDereferenced:
172 s.PutChar ('[');
173 DumpRegisterName(s, unwind_plan, thread, m_value.reg.reg_num);
174 s.PutChar (']');
175 break;
176 case isDWARFExpression:
177 s.PutCString ("dwarf-expr");
178 break;
179 default:
180 s.PutCString ("unspecified");
181 break;
182 }
183}
184
Jason Molendafbcb7f22010-09-10 07:49:16 +0000185void
186UnwindPlan::Row::Clear ()
187{
Pavel Labathab970f52015-02-23 10:19:16 +0000188 m_cfa_value.SetUnspecified();
Jason Molendafbcb7f22010-09-10 07:49:16 +0000189 m_offset = 0;
Jason Molendafbcb7f22010-09-10 07:49:16 +0000190 m_register_locations.clear();
191}
192
193void
Greg Clayton31f1d2f2011-05-11 18:39:18 +0000194UnwindPlan::Row::Dump (Stream& s, const UnwindPlan* unwind_plan, Thread* thread, addr_t base_addr) const
Jason Molendafbcb7f22010-09-10 07:49:16 +0000195{
Greg Clayton31f1d2f2011-05-11 18:39:18 +0000196 if (base_addr != LLDB_INVALID_ADDRESS)
Daniel Malead01b2952012-11-29 21:49:15 +0000197 s.Printf ("0x%16.16" PRIx64 ": CFA=", base_addr + GetOffset());
Jason Molendafbcb7f22010-09-10 07:49:16 +0000198 else
Jason Molenda34549b82015-01-13 06:04:04 +0000199 s.Printf ("%4" PRId64 ": CFA=", GetOffset());
Greg Clayton31f1d2f2011-05-11 18:39:18 +0000200
Pavel Labathab970f52015-02-23 10:19:16 +0000201 m_cfa_value.Dump(s, unwind_plan, thread);
202 s.Printf(" => ");
Jason Molendafbcb7f22010-09-10 07:49:16 +0000203 for (collection::const_iterator idx = m_register_locations.begin (); idx != m_register_locations.end (); ++idx)
204 {
Pavel Labathab970f52015-02-23 10:19:16 +0000205 DumpRegisterName(s, unwind_plan, thread, idx->first);
Greg Clayton31f1d2f2011-05-11 18:39:18 +0000206 const bool verbose = false;
207 idx->second.Dump(s, unwind_plan, this, thread, verbose);
208 s.PutChar (' ');
Jason Molendafbcb7f22010-09-10 07:49:16 +0000209 }
Greg Clayton877aaa52011-01-08 21:19:00 +0000210 s.EOL();
Jason Molendafbcb7f22010-09-10 07:49:16 +0000211}
212
213UnwindPlan::Row::Row() :
Justin Hibbits43bcdbd2014-11-12 15:14:03 +0000214 m_offset (0),
Pavel Labathab970f52015-02-23 10:19:16 +0000215 m_cfa_value (),
Justin Hibbits43bcdbd2014-11-12 15:14:03 +0000216 m_register_locations ()
Jason Molendafbcb7f22010-09-10 07:49:16 +0000217{
218}
219
220bool
221UnwindPlan::Row::GetRegisterInfo (uint32_t reg_num, UnwindPlan::Row::RegisterLocation& register_location) const
222{
223 collection::const_iterator pos = m_register_locations.find(reg_num);
224 if (pos != m_register_locations.end())
225 {
226 register_location = pos->second;
227 return true;
228 }
229 return false;
230}
231
232void
Jason Molenda34549b82015-01-13 06:04:04 +0000233UnwindPlan::Row::RemoveRegisterInfo (uint32_t reg_num)
234{
235 collection::const_iterator pos = m_register_locations.find(reg_num);
236 if (pos != m_register_locations.end())
237 {
238 m_register_locations.erase(pos);
239 }
240}
241
242void
Jason Molendafbcb7f22010-09-10 07:49:16 +0000243UnwindPlan::Row::SetRegisterInfo (uint32_t reg_num, const UnwindPlan::Row::RegisterLocation register_location)
244{
245 m_register_locations[reg_num] = register_location;
246}
247
Greg Clayton31f1d2f2011-05-11 18:39:18 +0000248bool
249UnwindPlan::Row::SetRegisterLocationToAtCFAPlusOffset (uint32_t reg_num, int32_t offset, bool can_replace)
250{
251 if (!can_replace && m_register_locations.find(reg_num) != m_register_locations.end())
252 return false;
253 RegisterLocation reg_loc;
254 reg_loc.SetAtCFAPlusOffset(offset);
255 m_register_locations[reg_num] = reg_loc;
256 return true;
257}
258
259bool
260UnwindPlan::Row::SetRegisterLocationToIsCFAPlusOffset (uint32_t reg_num, int32_t offset, bool can_replace)
261{
262 if (!can_replace && m_register_locations.find(reg_num) != m_register_locations.end())
263 return false;
264 RegisterLocation reg_loc;
265 reg_loc.SetIsCFAPlusOffset(offset);
266 m_register_locations[reg_num] = reg_loc;
267 return true;
268}
269
270bool
271UnwindPlan::Row::SetRegisterLocationToUndefined (uint32_t reg_num, bool can_replace, bool can_replace_only_if_unspecified)
272{
273 collection::iterator pos = m_register_locations.find(reg_num);
274 collection::iterator end = m_register_locations.end();
275
276 if (pos != end)
277 {
278 if (!can_replace)
279 return false;
280 if (can_replace_only_if_unspecified && !pos->second.IsUnspecified())
281 return false;
282 }
283 RegisterLocation reg_loc;
284 reg_loc.SetUndefined();
285 m_register_locations[reg_num] = reg_loc;
286 return true;
287}
288
289bool
290UnwindPlan::Row::SetRegisterLocationToUnspecified (uint32_t reg_num, bool can_replace)
291{
292 if (!can_replace && m_register_locations.find(reg_num) != m_register_locations.end())
293 return false;
294 RegisterLocation reg_loc;
295 reg_loc.SetUnspecified();
296 m_register_locations[reg_num] = reg_loc;
297 return true;
298}
299
300bool
301UnwindPlan::Row::SetRegisterLocationToRegister (uint32_t reg_num,
302 uint32_t other_reg_num,
303 bool can_replace)
304{
305 if (!can_replace && m_register_locations.find(reg_num) != m_register_locations.end())
306 return false;
307 RegisterLocation reg_loc;
308 reg_loc.SetInRegister(other_reg_num);
309 m_register_locations[reg_num] = reg_loc;
310 return true;
311}
312
313bool
314UnwindPlan::Row::SetRegisterLocationToSame (uint32_t reg_num, bool must_replace)
315{
316 if (must_replace && m_register_locations.find(reg_num) == m_register_locations.end())
317 return false;
318 RegisterLocation reg_loc;
319 reg_loc.SetSame();
320 m_register_locations[reg_num] = reg_loc;
321 return true;
322}
323
Jason Molenda24a83782012-07-17 01:57:24 +0000324bool
325UnwindPlan::Row::operator == (const UnwindPlan::Row& rhs) const
326{
Pavel Labathab970f52015-02-23 10:19:16 +0000327 return m_offset == rhs.m_offset && m_cfa_value == rhs.m_cfa_value &&
328 m_register_locations == rhs.m_register_locations;
Jason Molenda24a83782012-07-17 01:57:24 +0000329}
330
Jason Molendafbcb7f22010-09-10 07:49:16 +0000331void
Greg Clayton358a7892012-07-18 20:37:53 +0000332UnwindPlan::AppendRow (const UnwindPlan::RowSP &row_sp)
Jason Molendafbcb7f22010-09-10 07:49:16 +0000333{
Greg Clayton358a7892012-07-18 20:37:53 +0000334 if (m_row_list.empty() || m_row_list.back()->GetOffset() != row_sp->GetOffset())
335 m_row_list.push_back(row_sp);
Jason Molendafbcb7f22010-09-10 07:49:16 +0000336 else
Greg Clayton358a7892012-07-18 20:37:53 +0000337 m_row_list.back() = row_sp;
Jason Molendafbcb7f22010-09-10 07:49:16 +0000338}
339
Todd Fiala05625242014-08-25 20:29:09 +0000340void
341UnwindPlan::InsertRow (const UnwindPlan::RowSP &row_sp)
342{
343 collection::iterator it = m_row_list.begin();
344 while (it != m_row_list.end()) {
345 RowSP row = *it;
346 if (row->GetOffset() > row_sp->GetOffset())
347 break;
348 it++;
349 }
350 m_row_list.insert(it, row_sp);
351}
352
Jason Molenda1d42c7b2012-07-14 04:52:53 +0000353UnwindPlan::RowSP
Jason Molendafbcb7f22010-09-10 07:49:16 +0000354UnwindPlan::GetRowForFunctionOffset (int offset) const
355{
Jason Molenda1d42c7b2012-07-14 04:52:53 +0000356 RowSP row;
Greg Clayton877aaa52011-01-08 21:19:00 +0000357 if (!m_row_list.empty())
Jason Molendaab4f1922010-10-25 11:12:07 +0000358 {
Greg Clayton877aaa52011-01-08 21:19:00 +0000359 if (offset == -1)
Jason Molenda1d42c7b2012-07-14 04:52:53 +0000360 row = m_row_list.back();
Jason Molendafbcb7f22010-09-10 07:49:16 +0000361 else
362 {
Greg Clayton877aaa52011-01-08 21:19:00 +0000363 collection::const_iterator pos, end = m_row_list.end();
364 for (pos = m_row_list.begin(); pos != end; ++pos)
365 {
Saleem Abdulrasool3985c8c2014-04-02 03:51:35 +0000366 if ((*pos)->GetOffset() <= static_cast<lldb::offset_t>(offset))
Jason Molenda1d42c7b2012-07-14 04:52:53 +0000367 row = *pos;
Greg Clayton877aaa52011-01-08 21:19:00 +0000368 else
369 break;
370 }
Jason Molendafbcb7f22010-09-10 07:49:16 +0000371 }
372 }
Jason Molenda1d42c7b2012-07-14 04:52:53 +0000373 return row;
Jason Molendafbcb7f22010-09-10 07:49:16 +0000374}
375
376bool
377UnwindPlan::IsValidRowIndex (uint32_t idx) const
378{
379 return idx < m_row_list.size();
380}
381
Jason Molenda1d42c7b2012-07-14 04:52:53 +0000382const UnwindPlan::RowSP
Jason Molendafbcb7f22010-09-10 07:49:16 +0000383UnwindPlan::GetRowAtIndex (uint32_t idx) const
384{
385 // You must call IsValidRowIndex(idx) first before calling this!!!
Greg Clayton877aaa52011-01-08 21:19:00 +0000386 assert (idx < m_row_list.size());
Jason Molendafbcb7f22010-09-10 07:49:16 +0000387 return m_row_list[idx];
388}
389
Jason Molenda1d42c7b2012-07-14 04:52:53 +0000390const UnwindPlan::RowSP
Greg Clayton31f1d2f2011-05-11 18:39:18 +0000391UnwindPlan::GetLastRow () const
392{
393 // You must call GetRowCount() first to make sure there is at least one row
394 assert (!m_row_list.empty());
395 return m_row_list.back();
396}
397
Jason Molendafbcb7f22010-09-10 07:49:16 +0000398int
399UnwindPlan::GetRowCount () const
400{
401 return m_row_list.size ();
402}
403
404void
Jason Molendafbcb7f22010-09-10 07:49:16 +0000405UnwindPlan::SetPlanValidAddressRange (const AddressRange& range)
406{
Jason Molendaab4f1922010-10-25 11:12:07 +0000407 if (range.GetBaseAddress().IsValid() && range.GetByteSize() != 0)
Jason Molendaab4f1922010-10-25 11:12:07 +0000408 m_plan_valid_address_range = range;
Jason Molendafbcb7f22010-09-10 07:49:16 +0000409}
410
411bool
412UnwindPlan::PlanValidAtAddress (Address addr)
413{
Jason Molenda61cd0722013-12-03 04:46:27 +0000414 // If this UnwindPlan has no rows, it is an invalid UnwindPlan.
415 if (GetRowCount() == 0)
416 {
417 Log *log(GetLogIfAllCategoriesSet (LIBLLDB_LOG_UNWIND));
418 if (log)
Jason Molenda135e55f2013-12-03 21:59:39 +0000419 {
420 StreamString s;
Ed Masted4612ad2014-04-20 13:17:36 +0000421 if (addr.Dump (&s, nullptr, Address::DumpStyleSectionNameOffset))
Jason Molenda135e55f2013-12-03 21:59:39 +0000422 {
423 log->Printf ("UnwindPlan is invalid -- no unwind rows for UnwindPlan '%s' at address %s",
424 m_source_name.GetCString(), s.GetData());
425 }
426 else
427 {
428 log->Printf ("UnwindPlan is invalid -- no unwind rows for UnwindPlan '%s'",
429 m_source_name.GetCString());
430 }
431 }
Jason Molenda61cd0722013-12-03 04:46:27 +0000432 return false;
433 }
434
435 // If the 0th Row of unwind instructions is missing, or if it doesn't provide
436 // a register to use to find the Canonical Frame Address, this is not a valid UnwindPlan.
Pavel Labathab970f52015-02-23 10:19:16 +0000437 // CFA set by a DWARF expression is not currently supported, so ignore that as well.
438 if (GetRowAtIndex(0).get() == nullptr ||
439 GetRowAtIndex(0)->GetCFAValue().GetValueType() == Row::CFAValue::unspecified ||
440 GetRowAtIndex(0)->GetCFAValue().GetValueType() == Row::CFAValue::isDWARFExpression)
Jason Molenda61cd0722013-12-03 04:46:27 +0000441 {
442 Log *log(GetLogIfAllCategoriesSet (LIBLLDB_LOG_UNWIND));
443 if (log)
Jason Molenda135e55f2013-12-03 21:59:39 +0000444 {
445 StreamString s;
Ed Masted4612ad2014-04-20 13:17:36 +0000446 if (addr.Dump (&s, nullptr, Address::DumpStyleSectionNameOffset))
Jason Molenda135e55f2013-12-03 21:59:39 +0000447 {
448 log->Printf ("UnwindPlan is invalid -- no CFA register defined in row 0 for UnwindPlan '%s' at address %s",
449 m_source_name.GetCString(), s.GetData());
450 }
451 else
452 {
453 log->Printf ("UnwindPlan is invalid -- no CFA register defined in row 0 for UnwindPlan '%s'",
454 m_source_name.GetCString());
455 }
456 }
Jason Molenda61cd0722013-12-03 04:46:27 +0000457 return false;
458 }
459
Jason Molendaab4f1922010-10-25 11:12:07 +0000460 if (!m_plan_valid_address_range.GetBaseAddress().IsValid() || m_plan_valid_address_range.GetByteSize() == 0)
Jason Molendafbcb7f22010-09-10 07:49:16 +0000461 return true;
462
Jason Molenda59762002010-11-04 00:53:20 +0000463 if (!addr.IsValid())
464 return true;
465
Jason Molendafbcb7f22010-09-10 07:49:16 +0000466 if (m_plan_valid_address_range.ContainsFileAddress (addr))
467 return true;
468
469 return false;
470}
471
472void
Greg Clayton31f1d2f2011-05-11 18:39:18 +0000473UnwindPlan::Dump (Stream& s, Thread *thread, lldb::addr_t base_addr) const
Jason Molendafbcb7f22010-09-10 07:49:16 +0000474{
Jason Molendaab4f1922010-10-25 11:12:07 +0000475 if (!m_source_name.IsEmpty())
476 {
477 s.Printf ("This UnwindPlan originally sourced from %s\n", m_source_name.GetCString());
478 }
Jason Molendae9c7ecf2014-11-18 02:27:42 +0000479 if (m_lsda_address.IsValid() && m_personality_func_addr.IsValid())
480 {
481 TargetSP target_sp(thread->CalculateTarget());
482 addr_t lsda_load_addr = m_lsda_address.GetLoadAddress (target_sp.get());
483 addr_t personality_func_load_addr = m_personality_func_addr.GetLoadAddress (target_sp.get());
484
485 if (lsda_load_addr != LLDB_INVALID_ADDRESS && personality_func_load_addr != LLDB_INVALID_ADDRESS)
486 {
487 s.Printf("LSDA address 0x%" PRIx64 ", personality routine is at address 0x%" PRIx64 "\n",
488 lsda_load_addr, personality_func_load_addr);
489 }
490 }
491 s.Printf ("This UnwindPlan is sourced from the compiler: ");
492 switch (m_plan_is_sourced_from_compiler)
493 {
494 case eLazyBoolYes:
495 s.Printf ("yes.\n");
496 break;
497 case eLazyBoolNo:
498 s.Printf ("no.\n");
499 break;
500 case eLazyBoolCalculate:
501 s.Printf ("not specified.\n");
502 break;
503 }
504 s.Printf ("This UnwindPlan is valid at all instruction locations: ");
505 switch (m_plan_is_valid_at_all_instruction_locations)
506 {
507 case eLazyBoolYes:
508 s.Printf ("yes.\n");
509 break;
510 case eLazyBoolNo:
511 s.Printf ("no.\n");
512 break;
513 case eLazyBoolCalculate:
514 s.Printf ("not specified.\n");
515 break;
516 }
Jason Molendaab4f1922010-10-25 11:12:07 +0000517 if (m_plan_valid_address_range.GetBaseAddress().IsValid() && m_plan_valid_address_range.GetByteSize() > 0)
518 {
Greg Clayton877aaa52011-01-08 21:19:00 +0000519 s.PutCString ("Address range of this UnwindPlan: ");
Greg Clayton1ac04c32012-02-21 00:09:25 +0000520 TargetSP target_sp(thread->CalculateTarget());
521 m_plan_valid_address_range.Dump (&s, target_sp.get(), Address::DumpStyleSectionNameOffset);
Greg Clayton877aaa52011-01-08 21:19:00 +0000522 s.EOL();
Jason Molendaab4f1922010-10-25 11:12:07 +0000523 }
Greg Clayton31f1d2f2011-05-11 18:39:18 +0000524 collection::const_iterator pos, begin = m_row_list.begin(), end = m_row_list.end();
525 for (pos = begin; pos != end; ++pos)
Jason Molendafbcb7f22010-09-10 07:49:16 +0000526 {
Greg Clayton31f1d2f2011-05-11 18:39:18 +0000527 s.Printf ("row[%u]: ", (uint32_t)std::distance (begin, pos));
Jason Molenda1d42c7b2012-07-14 04:52:53 +0000528 (*pos)->Dump(s, this, thread, base_addr);
Jason Molendafbcb7f22010-09-10 07:49:16 +0000529 }
530}
Jason Molendaab4f1922010-10-25 11:12:07 +0000531
532void
533UnwindPlan::SetSourceName (const char *source)
534{
535 m_source_name = ConstString (source);
536}
537
538ConstString
539UnwindPlan::GetSourceName () const
540{
541 return m_source_name;
542}
Greg Clayton31f1d2f2011-05-11 18:39:18 +0000543
544const RegisterInfo *
545UnwindPlan::GetRegisterInfo (Thread* thread, uint32_t unwind_reg) const
546{
547 if (thread)
548 {
549 RegisterContext *reg_ctx = thread->GetRegisterContext().get();
550 if (reg_ctx)
551 {
552 uint32_t reg;
553 if (m_register_kind == eRegisterKindLLDB)
554 reg = unwind_reg;
555 else
556 reg = reg_ctx->ConvertRegisterKindToRegisterNumber (m_register_kind, unwind_reg);
557 if (reg != LLDB_INVALID_REGNUM)
558 return reg_ctx->GetRegisterInfoAtIndex (reg);
559 }
560 }
Ed Masted4612ad2014-04-20 13:17:36 +0000561 return nullptr;
Greg Clayton31f1d2f2011-05-11 18:39:18 +0000562}
563