blob: d32955e73b8ea0839131de600f60bc1ea7a9a8a6 [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
Daniel Malead01b2952012-11-29 21:49:15 +0000171 s.Printf ("0x%8.8" PRIx64 ": 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
214UnwindPlan::Row::SetRegisterInfo (uint32_t reg_num, const UnwindPlan::Row::RegisterLocation register_location)
215{
216 m_register_locations[reg_num] = register_location;
217}
218
Greg Clayton31f1d2f2011-05-11 18:39:18 +0000219bool
220UnwindPlan::Row::SetRegisterLocationToAtCFAPlusOffset (uint32_t reg_num, int32_t offset, bool can_replace)
221{
222 if (!can_replace && m_register_locations.find(reg_num) != m_register_locations.end())
223 return false;
224 RegisterLocation reg_loc;
225 reg_loc.SetAtCFAPlusOffset(offset);
226 m_register_locations[reg_num] = reg_loc;
227 return true;
228}
229
230bool
231UnwindPlan::Row::SetRegisterLocationToIsCFAPlusOffset (uint32_t reg_num, int32_t offset, bool can_replace)
232{
233 if (!can_replace && m_register_locations.find(reg_num) != m_register_locations.end())
234 return false;
235 RegisterLocation reg_loc;
236 reg_loc.SetIsCFAPlusOffset(offset);
237 m_register_locations[reg_num] = reg_loc;
238 return true;
239}
240
241bool
242UnwindPlan::Row::SetRegisterLocationToUndefined (uint32_t reg_num, bool can_replace, bool can_replace_only_if_unspecified)
243{
244 collection::iterator pos = m_register_locations.find(reg_num);
245 collection::iterator end = m_register_locations.end();
246
247 if (pos != end)
248 {
249 if (!can_replace)
250 return false;
251 if (can_replace_only_if_unspecified && !pos->second.IsUnspecified())
252 return false;
253 }
254 RegisterLocation reg_loc;
255 reg_loc.SetUndefined();
256 m_register_locations[reg_num] = reg_loc;
257 return true;
258}
259
260bool
261UnwindPlan::Row::SetRegisterLocationToUnspecified (uint32_t reg_num, bool can_replace)
262{
263 if (!can_replace && m_register_locations.find(reg_num) != m_register_locations.end())
264 return false;
265 RegisterLocation reg_loc;
266 reg_loc.SetUnspecified();
267 m_register_locations[reg_num] = reg_loc;
268 return true;
269}
270
271bool
272UnwindPlan::Row::SetRegisterLocationToRegister (uint32_t reg_num,
273 uint32_t other_reg_num,
274 bool can_replace)
275{
276 if (!can_replace && m_register_locations.find(reg_num) != m_register_locations.end())
277 return false;
278 RegisterLocation reg_loc;
279 reg_loc.SetInRegister(other_reg_num);
280 m_register_locations[reg_num] = reg_loc;
281 return true;
282}
283
284bool
285UnwindPlan::Row::SetRegisterLocationToSame (uint32_t reg_num, bool must_replace)
286{
287 if (must_replace && m_register_locations.find(reg_num) == m_register_locations.end())
288 return false;
289 RegisterLocation reg_loc;
290 reg_loc.SetSame();
291 m_register_locations[reg_num] = reg_loc;
292 return true;
293}
294
295void
296UnwindPlan::Row::SetCFARegister (uint32_t reg_num)
297{
298 m_cfa_reg_num = reg_num;
299}
Jason Molendafbcb7f22010-09-10 07:49:16 +0000300
Jason Molenda24a83782012-07-17 01:57:24 +0000301bool
302UnwindPlan::Row::operator == (const UnwindPlan::Row& rhs) const
303{
304 if (m_offset != rhs.m_offset || m_cfa_reg_num != rhs.m_cfa_reg_num || m_cfa_offset != rhs.m_cfa_offset)
305 return false;
Justin Hibbits43bcdbd2014-11-12 15:14:03 +0000306
307 if (m_cfa_type != rhs.m_cfa_type)
308 return false;
309
310 if (m_cfa_type == CFAIsRegisterPlusOffset)
311 {
312 if (m_cfa_reg_num != rhs.m_cfa_reg_num)
313 return false;
314 if (m_cfa_offset != rhs.m_cfa_offset)
315 return false;
316 }
317 if (m_cfa_type == CFAIsRegisterDereferenced)
318 {
319 if (m_cfa_reg_num != rhs.m_cfa_reg_num)
320 return false;
321 }
322
Greg Clayton358a7892012-07-18 20:37:53 +0000323 return m_register_locations == rhs.m_register_locations;
Jason Molenda24a83782012-07-17 01:57:24 +0000324}
325
Jason Molendafbcb7f22010-09-10 07:49:16 +0000326void
Greg Clayton358a7892012-07-18 20:37:53 +0000327UnwindPlan::AppendRow (const UnwindPlan::RowSP &row_sp)
Jason Molendafbcb7f22010-09-10 07:49:16 +0000328{
Greg Clayton358a7892012-07-18 20:37:53 +0000329 if (m_row_list.empty() || m_row_list.back()->GetOffset() != row_sp->GetOffset())
330 m_row_list.push_back(row_sp);
Jason Molendafbcb7f22010-09-10 07:49:16 +0000331 else
Greg Clayton358a7892012-07-18 20:37:53 +0000332 m_row_list.back() = row_sp;
Jason Molendafbcb7f22010-09-10 07:49:16 +0000333}
334
Todd Fiala05625242014-08-25 20:29:09 +0000335void
336UnwindPlan::InsertRow (const UnwindPlan::RowSP &row_sp)
337{
338 collection::iterator it = m_row_list.begin();
339 while (it != m_row_list.end()) {
340 RowSP row = *it;
341 if (row->GetOffset() > row_sp->GetOffset())
342 break;
343 it++;
344 }
345 m_row_list.insert(it, row_sp);
346}
347
Jason Molenda1d42c7b2012-07-14 04:52:53 +0000348UnwindPlan::RowSP
Jason Molendafbcb7f22010-09-10 07:49:16 +0000349UnwindPlan::GetRowForFunctionOffset (int offset) const
350{
Jason Molenda1d42c7b2012-07-14 04:52:53 +0000351 RowSP row;
Greg Clayton877aaa52011-01-08 21:19:00 +0000352 if (!m_row_list.empty())
Jason Molendaab4f1922010-10-25 11:12:07 +0000353 {
Greg Clayton877aaa52011-01-08 21:19:00 +0000354 if (offset == -1)
Jason Molenda1d42c7b2012-07-14 04:52:53 +0000355 row = m_row_list.back();
Jason Molendafbcb7f22010-09-10 07:49:16 +0000356 else
357 {
Greg Clayton877aaa52011-01-08 21:19:00 +0000358 collection::const_iterator pos, end = m_row_list.end();
359 for (pos = m_row_list.begin(); pos != end; ++pos)
360 {
Saleem Abdulrasool3985c8c2014-04-02 03:51:35 +0000361 if ((*pos)->GetOffset() <= static_cast<lldb::offset_t>(offset))
Jason Molenda1d42c7b2012-07-14 04:52:53 +0000362 row = *pos;
Greg Clayton877aaa52011-01-08 21:19:00 +0000363 else
364 break;
365 }
Jason Molendafbcb7f22010-09-10 07:49:16 +0000366 }
367 }
Jason Molenda1d42c7b2012-07-14 04:52:53 +0000368 return row;
Jason Molendafbcb7f22010-09-10 07:49:16 +0000369}
370
371bool
372UnwindPlan::IsValidRowIndex (uint32_t idx) const
373{
374 return idx < m_row_list.size();
375}
376
Jason Molenda1d42c7b2012-07-14 04:52:53 +0000377const UnwindPlan::RowSP
Jason Molendafbcb7f22010-09-10 07:49:16 +0000378UnwindPlan::GetRowAtIndex (uint32_t idx) const
379{
380 // You must call IsValidRowIndex(idx) first before calling this!!!
Greg Clayton877aaa52011-01-08 21:19:00 +0000381 assert (idx < m_row_list.size());
Jason Molendafbcb7f22010-09-10 07:49:16 +0000382 return m_row_list[idx];
383}
384
Jason Molenda1d42c7b2012-07-14 04:52:53 +0000385const UnwindPlan::RowSP
Greg Clayton31f1d2f2011-05-11 18:39:18 +0000386UnwindPlan::GetLastRow () const
387{
388 // You must call GetRowCount() first to make sure there is at least one row
389 assert (!m_row_list.empty());
390 return m_row_list.back();
391}
392
Jason Molendafbcb7f22010-09-10 07:49:16 +0000393int
394UnwindPlan::GetRowCount () const
395{
396 return m_row_list.size ();
397}
398
399void
Jason Molendafbcb7f22010-09-10 07:49:16 +0000400UnwindPlan::SetPlanValidAddressRange (const AddressRange& range)
401{
Jason Molendaab4f1922010-10-25 11:12:07 +0000402 if (range.GetBaseAddress().IsValid() && range.GetByteSize() != 0)
Jason Molendaab4f1922010-10-25 11:12:07 +0000403 m_plan_valid_address_range = range;
Jason Molendafbcb7f22010-09-10 07:49:16 +0000404}
405
406bool
407UnwindPlan::PlanValidAtAddress (Address addr)
408{
Jason Molenda61cd0722013-12-03 04:46:27 +0000409 // If this UnwindPlan has no rows, it is an invalid UnwindPlan.
410 if (GetRowCount() == 0)
411 {
412 Log *log(GetLogIfAllCategoriesSet (LIBLLDB_LOG_UNWIND));
413 if (log)
Jason Molenda135e55f2013-12-03 21:59:39 +0000414 {
415 StreamString s;
Ed Masted4612ad2014-04-20 13:17:36 +0000416 if (addr.Dump (&s, nullptr, Address::DumpStyleSectionNameOffset))
Jason Molenda135e55f2013-12-03 21:59:39 +0000417 {
418 log->Printf ("UnwindPlan is invalid -- no unwind rows for UnwindPlan '%s' at address %s",
419 m_source_name.GetCString(), s.GetData());
420 }
421 else
422 {
423 log->Printf ("UnwindPlan is invalid -- no unwind rows for UnwindPlan '%s'",
424 m_source_name.GetCString());
425 }
426 }
Jason Molenda61cd0722013-12-03 04:46:27 +0000427 return false;
428 }
429
430 // If the 0th Row of unwind instructions is missing, or if it doesn't provide
431 // a register to use to find the Canonical Frame Address, this is not a valid UnwindPlan.
Ed Masted4612ad2014-04-20 13:17:36 +0000432 if (GetRowAtIndex(0).get() == nullptr || GetRowAtIndex(0)->GetCFARegister() == LLDB_INVALID_REGNUM)
Jason Molenda61cd0722013-12-03 04:46:27 +0000433 {
434 Log *log(GetLogIfAllCategoriesSet (LIBLLDB_LOG_UNWIND));
435 if (log)
Jason Molenda135e55f2013-12-03 21:59:39 +0000436 {
437 StreamString s;
Ed Masted4612ad2014-04-20 13:17:36 +0000438 if (addr.Dump (&s, nullptr, Address::DumpStyleSectionNameOffset))
Jason Molenda135e55f2013-12-03 21:59:39 +0000439 {
440 log->Printf ("UnwindPlan is invalid -- no CFA register defined in row 0 for UnwindPlan '%s' at address %s",
441 m_source_name.GetCString(), s.GetData());
442 }
443 else
444 {
445 log->Printf ("UnwindPlan is invalid -- no CFA register defined in row 0 for UnwindPlan '%s'",
446 m_source_name.GetCString());
447 }
448 }
Jason Molenda61cd0722013-12-03 04:46:27 +0000449 return false;
450 }
451
Jason Molendaab4f1922010-10-25 11:12:07 +0000452 if (!m_plan_valid_address_range.GetBaseAddress().IsValid() || m_plan_valid_address_range.GetByteSize() == 0)
Jason Molendafbcb7f22010-09-10 07:49:16 +0000453 return true;
454
Jason Molenda59762002010-11-04 00:53:20 +0000455 if (!addr.IsValid())
456 return true;
457
Jason Molendafbcb7f22010-09-10 07:49:16 +0000458 if (m_plan_valid_address_range.ContainsFileAddress (addr))
459 return true;
460
461 return false;
462}
463
464void
Greg Clayton31f1d2f2011-05-11 18:39:18 +0000465UnwindPlan::Dump (Stream& s, Thread *thread, lldb::addr_t base_addr) const
Jason Molendafbcb7f22010-09-10 07:49:16 +0000466{
Jason Molendaab4f1922010-10-25 11:12:07 +0000467 if (!m_source_name.IsEmpty())
468 {
469 s.Printf ("This UnwindPlan originally sourced from %s\n", m_source_name.GetCString());
470 }
Jason Molendae9c7ecf2014-11-18 02:27:42 +0000471 if (m_lsda_address.IsValid() && m_personality_func_addr.IsValid())
472 {
473 TargetSP target_sp(thread->CalculateTarget());
474 addr_t lsda_load_addr = m_lsda_address.GetLoadAddress (target_sp.get());
475 addr_t personality_func_load_addr = m_personality_func_addr.GetLoadAddress (target_sp.get());
476
477 if (lsda_load_addr != LLDB_INVALID_ADDRESS && personality_func_load_addr != LLDB_INVALID_ADDRESS)
478 {
479 s.Printf("LSDA address 0x%" PRIx64 ", personality routine is at address 0x%" PRIx64 "\n",
480 lsda_load_addr, personality_func_load_addr);
481 }
482 }
483 s.Printf ("This UnwindPlan is sourced from the compiler: ");
484 switch (m_plan_is_sourced_from_compiler)
485 {
486 case eLazyBoolYes:
487 s.Printf ("yes.\n");
488 break;
489 case eLazyBoolNo:
490 s.Printf ("no.\n");
491 break;
492 case eLazyBoolCalculate:
493 s.Printf ("not specified.\n");
494 break;
495 }
496 s.Printf ("This UnwindPlan is valid at all instruction locations: ");
497 switch (m_plan_is_valid_at_all_instruction_locations)
498 {
499 case eLazyBoolYes:
500 s.Printf ("yes.\n");
501 break;
502 case eLazyBoolNo:
503 s.Printf ("no.\n");
504 break;
505 case eLazyBoolCalculate:
506 s.Printf ("not specified.\n");
507 break;
508 }
Jason Molendaab4f1922010-10-25 11:12:07 +0000509 if (m_plan_valid_address_range.GetBaseAddress().IsValid() && m_plan_valid_address_range.GetByteSize() > 0)
510 {
Greg Clayton877aaa52011-01-08 21:19:00 +0000511 s.PutCString ("Address range of this UnwindPlan: ");
Greg Clayton1ac04c32012-02-21 00:09:25 +0000512 TargetSP target_sp(thread->CalculateTarget());
513 m_plan_valid_address_range.Dump (&s, target_sp.get(), Address::DumpStyleSectionNameOffset);
Greg Clayton877aaa52011-01-08 21:19:00 +0000514 s.EOL();
Jason Molendaab4f1922010-10-25 11:12:07 +0000515 }
Greg Clayton31f1d2f2011-05-11 18:39:18 +0000516 collection::const_iterator pos, begin = m_row_list.begin(), end = m_row_list.end();
517 for (pos = begin; pos != end; ++pos)
Jason Molendafbcb7f22010-09-10 07:49:16 +0000518 {
Greg Clayton31f1d2f2011-05-11 18:39:18 +0000519 s.Printf ("row[%u]: ", (uint32_t)std::distance (begin, pos));
Jason Molenda1d42c7b2012-07-14 04:52:53 +0000520 (*pos)->Dump(s, this, thread, base_addr);
Jason Molendafbcb7f22010-09-10 07:49:16 +0000521 }
522}
Jason Molendaab4f1922010-10-25 11:12:07 +0000523
524void
525UnwindPlan::SetSourceName (const char *source)
526{
527 m_source_name = ConstString (source);
528}
529
530ConstString
531UnwindPlan::GetSourceName () const
532{
533 return m_source_name;
534}
Greg Clayton31f1d2f2011-05-11 18:39:18 +0000535
536const RegisterInfo *
537UnwindPlan::GetRegisterInfo (Thread* thread, uint32_t unwind_reg) const
538{
539 if (thread)
540 {
541 RegisterContext *reg_ctx = thread->GetRegisterContext().get();
542 if (reg_ctx)
543 {
544 uint32_t reg;
545 if (m_register_kind == eRegisterKindLLDB)
546 reg = unwind_reg;
547 else
548 reg = reg_ctx->ConvertRegisterKindToRegisterNumber (m_register_kind, unwind_reg);
549 if (reg != LLDB_INVALID_REGNUM)
550 return reg_ctx->GetRegisterInfoAtIndex (reg);
551 }
552 }
Ed Masted4612ad2014-04-20 13:17:36 +0000553 return nullptr;
Greg Clayton31f1d2f2011-05-11 18:39:18 +0000554}
555