LLDB  mainline
UnwindPlan.cpp
Go to the documentation of this file.
1 //===-- UnwindPlan.cpp ----------------------------------------------------===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 
10 
11 #include "lldb/Target/Process.h"
13 #include "lldb/Target/Target.h"
14 #include "lldb/Target/Thread.h"
16 #include "lldb/Utility/LLDBLog.h"
17 #include "lldb/Utility/Log.h"
18 #include "llvm/DebugInfo/DIContext.h"
19 #include "llvm/DebugInfo/DWARF/DWARFExpression.h"
20 
21 using namespace lldb;
22 using namespace lldb_private;
23 
26  if (m_type == rhs.m_type) {
27  switch (m_type) {
28  case unspecified:
29  case undefined:
30  case same:
31  return true;
32 
33  case atCFAPlusOffset:
34  case isCFAPlusOffset:
35  case atAFAPlusOffset:
36  case isAFAPlusOffset:
37  return m_location.offset == rhs.m_location.offset;
38 
39  case inOtherRegister:
40  return m_location.reg_num == rhs.m_location.reg_num;
41 
42  case atDWARFExpression:
43  case isDWARFExpression:
44  if (m_location.expr.length == rhs.m_location.expr.length)
45  return !memcmp(m_location.expr.opcodes, rhs.m_location.expr.opcodes,
46  m_location.expr.length);
47  break;
48  }
49  }
50  return false;
51 }
52 
53 // This function doesn't copy the dwarf expression bytes; they must remain in
54 // allocated memory for the lifespan of this UnwindPlan object.
55 void UnwindPlan::Row::RegisterLocation::SetAtDWARFExpression(
56  const uint8_t *opcodes, uint32_t len) {
57  m_type = atDWARFExpression;
58  m_location.expr.opcodes = opcodes;
59  m_location.expr.length = len;
60 }
61 
62 // This function doesn't copy the dwarf expression bytes; they must remain in
63 // allocated memory for the lifespan of this UnwindPlan object.
64 void UnwindPlan::Row::RegisterLocation::SetIsDWARFExpression(
65  const uint8_t *opcodes, uint32_t len) {
66  m_type = isDWARFExpression;
67  m_location.expr.opcodes = opcodes;
68  m_location.expr.length = len;
69 }
70 
71 static llvm::Optional<std::pair<lldb::ByteOrder, uint32_t>>
73  if (!thread)
74  return llvm::None;
75  ProcessSP process_sp = thread->GetProcess();
76  if (!process_sp)
77  return llvm::None;
78  ArchSpec arch = process_sp->GetTarget().GetArchitecture();
79  return std::make_pair(arch.GetByteOrder(), arch.GetAddressByteSize());
80 }
81 
82 static void DumpDWARFExpr(Stream &s, llvm::ArrayRef<uint8_t> expr, Thread *thread) {
83  if (auto order_and_width = GetByteOrderAndAddrSize(thread)) {
84  llvm::DataExtractor data(expr, order_and_width->first == eByteOrderLittle,
85  order_and_width->second);
86  llvm::DWARFExpression(data, order_and_width->second, llvm::dwarf::DWARF32)
87  .print(s.AsRawOstream(), llvm::DIDumpOptions(), nullptr, nullptr);
88  } else
89  s.PutCString("dwarf-expr");
90 }
91 
92 void UnwindPlan::Row::RegisterLocation::Dump(Stream &s,
93  const UnwindPlan *unwind_plan,
94  const UnwindPlan::Row *row,
95  Thread *thread,
96  bool verbose) const {
97  switch (m_type) {
98  case unspecified:
99  if (verbose)
100  s.PutCString("=<unspec>");
101  else
102  s.PutCString("=!");
103  break;
104  case undefined:
105  if (verbose)
106  s.PutCString("=<undef>");
107  else
108  s.PutCString("=?");
109  break;
110  case same:
111  s.PutCString("= <same>");
112  break;
113 
114  case atCFAPlusOffset:
115  case isCFAPlusOffset: {
116  s.PutChar('=');
117  if (m_type == atCFAPlusOffset)
118  s.PutChar('[');
119  s.Printf("CFA%+d", m_location.offset);
120  if (m_type == atCFAPlusOffset)
121  s.PutChar(']');
122  } break;
123 
124  case atAFAPlusOffset:
125  case isAFAPlusOffset: {
126  s.PutChar('=');
127  if (m_type == atAFAPlusOffset)
128  s.PutChar('[');
129  s.Printf("AFA%+d", m_location.offset);
130  if (m_type == atAFAPlusOffset)
131  s.PutChar(']');
132  } break;
133 
134  case inOtherRegister: {
135  const RegisterInfo *other_reg_info = nullptr;
136  if (unwind_plan)
137  other_reg_info = unwind_plan->GetRegisterInfo(thread, m_location.reg_num);
138  if (other_reg_info)
139  s.Printf("=%s", other_reg_info->name);
140  else
141  s.Printf("=reg(%u)", m_location.reg_num);
142  } break;
143 
144  case atDWARFExpression:
145  case isDWARFExpression: {
146  s.PutChar('=');
147  if (m_type == atDWARFExpression)
148  s.PutChar('[');
150  s, llvm::makeArrayRef(m_location.expr.opcodes, m_location.expr.length),
151  thread);
152  if (m_type == atDWARFExpression)
153  s.PutChar(']');
154  } break;
155  }
156 }
157 
158 static void DumpRegisterName(Stream &s, const UnwindPlan *unwind_plan,
159  Thread *thread, uint32_t reg_num) {
160  const RegisterInfo *reg_info = unwind_plan->GetRegisterInfo(thread, reg_num);
161  if (reg_info)
162  s.PutCString(reg_info->name);
163  else
164  s.Printf("reg(%u)", reg_num);
165 }
166 
169  if (m_type == rhs.m_type) {
170  switch (m_type) {
171  case unspecified:
172  case isRaSearch:
173  return m_value.ra_search_offset == rhs.m_value.ra_search_offset;
174 
175  case isRegisterPlusOffset:
176  return m_value.reg.offset == rhs.m_value.reg.offset;
177 
178  case isRegisterDereferenced:
179  return m_value.reg.reg_num == rhs.m_value.reg.reg_num;
180 
181  case isDWARFExpression:
182  if (m_value.expr.length == rhs.m_value.expr.length)
183  return !memcmp(m_value.expr.opcodes, rhs.m_value.expr.opcodes,
184  m_value.expr.length);
185  break;
186  }
187  }
188  return false;
189 }
190 
191 void UnwindPlan::Row::FAValue::Dump(Stream &s, const UnwindPlan *unwind_plan,
192  Thread *thread) const {
193  switch (m_type) {
194  case isRegisterPlusOffset:
195  DumpRegisterName(s, unwind_plan, thread, m_value.reg.reg_num);
196  s.Printf("%+3d", m_value.reg.offset);
197  break;
198  case isRegisterDereferenced:
199  s.PutChar('[');
200  DumpRegisterName(s, unwind_plan, thread, m_value.reg.reg_num);
201  s.PutChar(']');
202  break;
203  case isDWARFExpression:
204  DumpDWARFExpr(s,
205  llvm::makeArrayRef(m_value.expr.opcodes, m_value.expr.length),
206  thread);
207  break;
208  case unspecified:
209  s.PutCString("unspecified");
210  break;
211  case isRaSearch:
212  s.Printf("RaSearch@SP%+d", m_value.ra_search_offset);
213  break;
214  }
215 }
216 
217 void UnwindPlan::Row::Clear() {
218  m_cfa_value.SetUnspecified();
219  m_afa_value.SetUnspecified();
220  m_offset = 0;
221  m_unspecified_registers_are_undefined = false;
222  m_register_locations.clear();
223 }
224 
225 void UnwindPlan::Row::Dump(Stream &s, const UnwindPlan *unwind_plan,
226  Thread *thread, addr_t base_addr) const {
227  if (base_addr != LLDB_INVALID_ADDRESS)
228  s.Printf("0x%16.16" PRIx64 ": CFA=", base_addr + GetOffset());
229  else
230  s.Printf("%4" PRId64 ": CFA=", GetOffset());
231 
232  m_cfa_value.Dump(s, unwind_plan, thread);
233 
234  if (!m_afa_value.IsUnspecified()) {
235  s.Printf(" AFA=");
236  m_afa_value.Dump(s, unwind_plan, thread);
237  }
238 
239  s.Printf(" => ");
240  for (collection::const_iterator idx = m_register_locations.begin();
241  idx != m_register_locations.end(); ++idx) {
242  DumpRegisterName(s, unwind_plan, thread, idx->first);
243  const bool verbose = false;
244  idx->second.Dump(s, unwind_plan, this, thread, verbose);
245  s.PutChar(' ');
246  }
247 }
248 
249 UnwindPlan::Row::Row() : m_cfa_value(), m_afa_value(), m_register_locations() {}
250 
252  uint32_t reg_num,
253  UnwindPlan::Row::RegisterLocation &register_location) const {
254  collection::const_iterator pos = m_register_locations.find(reg_num);
255  if (pos != m_register_locations.end()) {
256  register_location = pos->second;
257  return true;
258  }
259  if (m_unspecified_registers_are_undefined) {
260  register_location.SetUndefined();
261  return true;
262  }
263  return false;
264 }
265 
267  collection::const_iterator pos = m_register_locations.find(reg_num);
268  if (pos != m_register_locations.end()) {
269  m_register_locations.erase(pos);
270  }
271 }
272 
274  uint32_t reg_num,
275  const UnwindPlan::Row::RegisterLocation register_location) {
276  m_register_locations[reg_num] = register_location;
277 }
278 
280  int32_t offset,
281  bool can_replace) {
282  if (!can_replace &&
283  m_register_locations.find(reg_num) != m_register_locations.end())
284  return false;
285  RegisterLocation reg_loc;
286  reg_loc.SetAtCFAPlusOffset(offset);
287  m_register_locations[reg_num] = reg_loc;
288  return true;
289 }
290 
292  int32_t offset,
293  bool can_replace) {
294  if (!can_replace &&
295  m_register_locations.find(reg_num) != m_register_locations.end())
296  return false;
297  RegisterLocation reg_loc;
298  reg_loc.SetIsCFAPlusOffset(offset);
299  m_register_locations[reg_num] = reg_loc;
300  return true;
301 }
302 
304  uint32_t reg_num, bool can_replace, bool can_replace_only_if_unspecified) {
305  collection::iterator pos = m_register_locations.find(reg_num);
306  collection::iterator end = m_register_locations.end();
307 
308  if (pos != end) {
309  if (!can_replace)
310  return false;
311  if (can_replace_only_if_unspecified && !pos->second.IsUnspecified())
312  return false;
313  }
314  RegisterLocation reg_loc;
315  reg_loc.SetUndefined();
316  m_register_locations[reg_num] = reg_loc;
317  return true;
318 }
319 
321  bool can_replace) {
322  if (!can_replace &&
323  m_register_locations.find(reg_num) != m_register_locations.end())
324  return false;
325  RegisterLocation reg_loc;
326  reg_loc.SetUnspecified();
327  m_register_locations[reg_num] = reg_loc;
328  return true;
329 }
330 
332  uint32_t other_reg_num,
333  bool can_replace) {
334  if (!can_replace &&
335  m_register_locations.find(reg_num) != m_register_locations.end())
336  return false;
337  RegisterLocation reg_loc;
338  reg_loc.SetInRegister(other_reg_num);
339  m_register_locations[reg_num] = reg_loc;
340  return true;
341 }
342 
344  bool must_replace) {
345  if (must_replace &&
346  m_register_locations.find(reg_num) == m_register_locations.end())
347  return false;
348  RegisterLocation reg_loc;
349  reg_loc.SetSame();
350  m_register_locations[reg_num] = reg_loc;
351  return true;
352 }
353 
355  return m_offset == rhs.m_offset && m_cfa_value == rhs.m_cfa_value &&
356  m_afa_value == rhs.m_afa_value &&
357  m_unspecified_registers_are_undefined ==
359  m_register_locations == rhs.m_register_locations;
360 }
361 
363  if (m_row_list.empty() ||
364  m_row_list.back()->GetOffset() != row_sp->GetOffset())
365  m_row_list.push_back(row_sp);
366  else
367  m_row_list.back() = row_sp;
368 }
369 
371  bool replace_existing) {
372  collection::iterator it = m_row_list.begin();
373  while (it != m_row_list.end()) {
374  RowSP row = *it;
375  if (row->GetOffset() >= row_sp->GetOffset())
376  break;
377  it++;
378  }
379  if (it == m_row_list.end() || (*it)->GetOffset() != row_sp->GetOffset())
380  m_row_list.insert(it, row_sp);
381  else if (replace_existing)
382  *it = row_sp;
383 }
384 
386  RowSP row;
387  if (!m_row_list.empty()) {
388  if (offset == -1)
389  row = m_row_list.back();
390  else {
391  collection::const_iterator pos, end = m_row_list.end();
392  for (pos = m_row_list.begin(); pos != end; ++pos) {
393  if ((*pos)->GetOffset() <= static_cast<lldb::offset_t>(offset))
394  row = *pos;
395  else
396  break;
397  }
398  }
399  }
400  return row;
401 }
402 
404  return idx < m_row_list.size();
405 }
406 
408  if (idx < m_row_list.size())
409  return m_row_list[idx];
410  else {
411  Log *log = GetLog(LLDBLog::Unwind);
412  LLDB_LOGF(log,
413  "error: UnwindPlan::GetRowAtIndex(idx = %u) invalid index "
414  "(number rows is %u)",
415  idx, (uint32_t)m_row_list.size());
416  return UnwindPlan::RowSP();
417  }
418 }
419 
421  if (m_row_list.empty()) {
422  Log *log = GetLog(LLDBLog::Unwind);
423  LLDB_LOGF(log, "UnwindPlan::GetLastRow() when rows are empty");
424  return UnwindPlan::RowSP();
425  }
426  return m_row_list.back();
427 }
428 
429 int UnwindPlan::GetRowCount() const { return m_row_list.size(); }
430 
432  if (range.GetBaseAddress().IsValid() && range.GetByteSize() != 0)
434 }
435 
437  // If this UnwindPlan has no rows, it is an invalid UnwindPlan.
438  if (GetRowCount() == 0) {
439  Log *log = GetLog(LLDBLog::Unwind);
440  if (log) {
441  StreamString s;
442  if (addr.Dump(&s, nullptr, Address::DumpStyleSectionNameOffset)) {
443  LLDB_LOGF(log,
444  "UnwindPlan is invalid -- no unwind rows for UnwindPlan "
445  "'%s' at address %s",
447  } else {
448  LLDB_LOGF(log,
449  "UnwindPlan is invalid -- no unwind rows for UnwindPlan '%s'",
451  }
452  }
453  return false;
454  }
455 
456  // If the 0th Row of unwind instructions is missing, or if it doesn't provide
457  // a register to use to find the Canonical Frame Address, this is not a valid
458  // UnwindPlan.
459  if (GetRowAtIndex(0).get() == nullptr ||
460  GetRowAtIndex(0)->GetCFAValue().GetValueType() ==
462  Log *log = GetLog(LLDBLog::Unwind);
463  if (log) {
464  StreamString s;
465  if (addr.Dump(&s, nullptr, Address::DumpStyleSectionNameOffset)) {
466  LLDB_LOGF(log,
467  "UnwindPlan is invalid -- no CFA register defined in row 0 "
468  "for UnwindPlan '%s' at address %s",
470  } else {
471  LLDB_LOGF(log,
472  "UnwindPlan is invalid -- no CFA register defined in row 0 "
473  "for UnwindPlan '%s'",
475  }
476  }
477  return false;
478  }
479 
482  return true;
483 
484  if (!addr.IsValid())
485  return true;
486 
488  return true;
489 
490  return false;
491 }
492 
493 void UnwindPlan::Dump(Stream &s, Thread *thread, lldb::addr_t base_addr) const {
494  if (!m_source_name.IsEmpty()) {
495  s.Printf("This UnwindPlan originally sourced from %s\n",
497  }
499  TargetSP target_sp(thread->CalculateTarget());
500  addr_t lsda_load_addr = m_lsda_address.GetLoadAddress(target_sp.get());
501  addr_t personality_func_load_addr =
502  m_personality_func_addr.GetLoadAddress(target_sp.get());
503 
504  if (lsda_load_addr != LLDB_INVALID_ADDRESS &&
505  personality_func_load_addr != LLDB_INVALID_ADDRESS) {
506  s.Printf("LSDA address 0x%" PRIx64
507  ", personality routine is at address 0x%" PRIx64 "\n",
508  lsda_load_addr, personality_func_load_addr);
509  }
510  }
511  s.Printf("This UnwindPlan is sourced from the compiler: ");
513  case eLazyBoolYes:
514  s.Printf("yes.\n");
515  break;
516  case eLazyBoolNo:
517  s.Printf("no.\n");
518  break;
519  case eLazyBoolCalculate:
520  s.Printf("not specified.\n");
521  break;
522  }
523  s.Printf("This UnwindPlan is valid at all instruction locations: ");
525  case eLazyBoolYes:
526  s.Printf("yes.\n");
527  break;
528  case eLazyBoolNo:
529  s.Printf("no.\n");
530  break;
531  case eLazyBoolCalculate:
532  s.Printf("not specified.\n");
533  break;
534  }
535  s.Printf("This UnwindPlan is for a trap handler function: ");
536  switch (m_plan_is_for_signal_trap) {
537  case eLazyBoolYes:
538  s.Printf("yes.\n");
539  break;
540  case eLazyBoolNo:
541  s.Printf("no.\n");
542  break;
543  case eLazyBoolCalculate:
544  s.Printf("not specified.\n");
545  break;
546  }
549  s.PutCString("Address range of this UnwindPlan: ");
550  TargetSP target_sp(thread->CalculateTarget());
551  m_plan_valid_address_range.Dump(&s, target_sp.get(),
553  s.EOL();
554  }
555  collection::const_iterator pos, begin = m_row_list.begin(),
556  end = m_row_list.end();
557  for (pos = begin; pos != end; ++pos) {
558  s.Printf("row[%u]: ", (uint32_t)std::distance(begin, pos));
559  (*pos)->Dump(s, this, thread, base_addr);
560  s.Printf("\n");
561  }
562 }
563 
564 void UnwindPlan::SetSourceName(const char *source) {
565  m_source_name = ConstString(source);
566 }
567 
569 
570 const RegisterInfo *UnwindPlan::GetRegisterInfo(Thread *thread,
571  uint32_t unwind_reg) const {
572  if (thread) {
573  RegisterContext *reg_ctx = thread->GetRegisterContext().get();
574  if (reg_ctx) {
575  uint32_t reg;
577  reg = unwind_reg;
578  else
580  unwind_reg);
581  if (reg != LLDB_INVALID_REGNUM)
582  return reg_ctx->GetRegisterInfoAtIndex(reg);
583  }
584  }
585  return nullptr;
586 }
lldb_private::UnwindPlan::Row::RegisterLocation::reg_num
uint32_t reg_num
Definition: UnwindPlan.h:189
lldb_private::AddressRange::GetBaseAddress
Address & GetBaseAddress()
Get accessor for the base address of the range.
Definition: AddressRange.h:209
lldb_private::UnwindPlan::Row::m_cfa_value
FAValue m_cfa_value
Definition: UnwindPlan.h:389
lldb_private::UnwindPlan::Row::SetRegisterLocationToIsCFAPlusOffset
bool SetRegisterLocationToIsCFAPlusOffset(uint32_t reg_num, int32_t offset, bool can_replace)
Definition: UnwindPlan.cpp:291
lldb_private::Address::DumpStyleSectionNameOffset
@ DumpStyleSectionNameOffset
Display as the section name + offset.
Definition: Address.h:71
lldb_private::UnwindPlan::InsertRow
void InsertRow(const RowSP &row_sp, bool replace_existing=false)
Definition: UnwindPlan.cpp:370
lldb_private::ArchSpec::GetByteOrder
lldb::ByteOrder GetByteOrder() const
Returns the byte order for the architecture specification.
Definition: ArchSpec.cpp:731
lldb_private::UnwindPlan::AppendRow
void AppendRow(const RowSP &row_sp)
Definition: UnwindPlan.cpp:362
lldb_private::UnwindPlan::m_source_name
lldb_private::ConstString m_source_name
Definition: UnwindPlan.h:543
lldb_private::ArchSpec
Definition: ArchSpec.h:33
LLDB_INVALID_REGNUM
#define LLDB_INVALID_REGNUM
Definition: lldb-defines.h:79
lldb_private::Address::IsValid
bool IsValid() const
Check if the object state is valid.
Definition: Address.h:345
lldb_private::UnwindPlan::Row::SetRegisterLocationToRegister
bool SetRegisterLocationToRegister(uint32_t reg_num, uint32_t other_reg_num, bool can_replace)
Definition: UnwindPlan.cpp:331
lldb_private::UnwindPlan::Row::operator==
bool operator==(const Row &rhs) const
Definition: UnwindPlan.cpp:354
lldb_private::UnwindPlan::Row::SetRegisterInfo
void SetRegisterInfo(uint32_t reg_num, const RegisterLocation register_location)
Definition: UnwindPlan.cpp:273
lldb_private::UnwindPlan::Row::FAValue::ra_search_offset
int32_t ra_search_offset
Definition: UnwindPlan.h:319
lldb_private::UnwindPlan::Row::SetRegisterLocationToSame
bool SetRegisterLocationToSame(uint32_t reg_num, bool must_replace)
Definition: UnwindPlan.cpp:343
lldb_private::UnwindPlan::Row::FAValue::expr
struct lldb_private::UnwindPlan::Row::FAValue::@29::@31 expr
lldb_private::UnwindPlan::Row::RegisterLocation::SetSame
void SetSame()
Definition: UnwindPlan.h:86
lldb_private::eLazyBoolYes
@ eLazyBoolYes
Definition: lldb-private-enumerations.h:115
LLDB_LOGF
#define LLDB_LOGF(log,...)
Definition: Log.h:270
GetByteOrderAndAddrSize
static llvm::Optional< std::pair< lldb::ByteOrder, uint32_t > > GetByteOrderAndAddrSize(Thread *thread)
Definition: UnwindPlan.cpp:72
lldb_private::Thread::CalculateTarget
lldb::TargetSP CalculateTarget() override
Definition: Thread.cpp:1383
lldb_private::AddressRange::GetByteSize
lldb::addr_t GetByteSize() const
Get accessor for the byte size of this range.
Definition: AddressRange.h:221
lldb_private::RegisterContext::ConvertRegisterKindToRegisterNumber
virtual uint32_t ConvertRegisterKindToRegisterNumber(lldb::RegisterKind kind, uint32_t num)
Convert from a given register numbering scheme to the lldb register numbering scheme.
Definition: RegisterContext.cpp:268
lldb_private::UnwindPlan::GetRowForFunctionOffset
UnwindPlan::RowSP GetRowForFunctionOffset(int offset) const
Definition: UnwindPlan.cpp:385
lldb_private::UnwindPlan::Row::RegisterLocation::SetUndefined
void SetUndefined()
Definition: UnwindPlan.h:84
lldb::offset_t
uint64_t offset_t
Definition: lldb-types.h:87
lldb_private::UnwindPlan::Row::RegisterLocation::m_type
RestoreType m_type
Definition: UnwindPlan.h:184
lldb_private::UnwindPlan::Row::m_register_locations
collection m_register_locations
Definition: UnwindPlan.h:391
lldb_private::UnwindPlan::Row::SetRegisterLocationToUndefined
bool SetRegisterLocationToUndefined(uint32_t reg_num, bool can_replace, bool can_replace_only_if_unspecified)
Definition: UnwindPlan.cpp:303
lldb_private::Stream
Definition: Stream.h:28
lldb::addr_t
uint64_t addr_t
Definition: lldb-types.h:83
lldb_private::UnwindPlan::Row::RegisterLocation::expr
struct lldb_private::UnwindPlan::Row::RegisterLocation::@27::@28 expr
lldb_private::RegisterContext::GetRegisterInfoAtIndex
virtual const RegisterInfo * GetRegisterInfoAtIndex(size_t reg)=0
lldb_private::UnwindPlan::SetSourceName
void SetSourceName(const char *)
Definition: UnwindPlan.cpp:564
lldb_private::UnwindPlan::Row::SetRegisterLocationToAtCFAPlusOffset
bool SetRegisterLocationToAtCFAPlusOffset(uint32_t reg_num, int32_t offset, bool can_replace)
Definition: UnwindPlan.cpp:279
Process.h
lldb_private::UnwindPlan::Row::m_afa_value
FAValue m_afa_value
Definition: UnwindPlan.h:390
lldb_private::UnwindPlan::Row::SetRegisterLocationToUnspecified
bool SetRegisterLocationToUnspecified(uint32_t reg_num, bool can_replace)
Definition: UnwindPlan.cpp:320
Target.h
lldb_private::Thread::GetProcess
lldb::ProcessSP GetProcess() const
Definition: Thread.h:153
lldb_private::UnwindPlan::Row::RegisterLocation::SetUnspecified
void SetUnspecified()
Definition: UnwindPlan.h:82
lldb_private::UnwindPlan::SetPlanValidAddressRange
void SetPlanValidAddressRange(const AddressRange &range)
Definition: UnwindPlan.cpp:431
lldb_private::LLDBLog::Unwind
@ Unwind
lldb_private::UnwindPlan::PlanValidAtAddress
bool PlanValidAtAddress(Address addr)
Definition: UnwindPlan.cpp:436
lldb::eRegisterKindLLDB
@ eRegisterKindLLDB
lldb's internal register numbers
Definition: lldb-enumerations.h:234
Log.h
DumpDWARFExpr
static void DumpDWARFExpr(Stream &s, llvm::ArrayRef< uint8_t > expr, Thread *thread)
Definition: UnwindPlan.cpp:82
lldb_private::ConstString::IsEmpty
bool IsEmpty() const
Test for empty string.
Definition: ConstString.h:304
lldb_private::UnwindPlan::m_personality_func_addr
Address m_personality_func_addr
Definition: UnwindPlan.h:551
lldb_private::UnwindPlan::Row::RemoveRegisterInfo
void RemoveRegisterInfo(uint32_t reg_num)
Definition: UnwindPlan.cpp:266
lldb_private::Thread
Definition: Thread.h:61
lldb_private::StreamString::GetData
const char * GetData() const
Definition: StreamString.h:43
lldb_private::UnwindPlan::Dump
void Dump(Stream &s, Thread *thread, lldb::addr_t base_addr) const
Definition: UnwindPlan.cpp:493
lldb_private::UnwindPlan::Row::m_unspecified_registers_are_undefined
bool m_unspecified_registers_are_undefined
Definition: UnwindPlan.h:392
lldb_private::UnwindPlan::Row::FAValue
Definition: UnwindPlan.h:198
lldb_private::ConstString
Definition: ConstString.h:40
lldb_private::UnwindPlan::Row::GetRegisterInfo
bool GetRegisterInfo(uint32_t reg_num, RegisterLocation &register_location) const
Definition: UnwindPlan.cpp:251
lldb_private::StreamString
Definition: StreamString.h:23
lldb_private::AddressRange
Definition: AddressRange.h:25
lldb::operator==
bool LLDB_API operator==(const SBAddress &lhs, const SBAddress &rhs)
Definition: SBAddress.cpp:60
lldb_private::UnwindPlan::m_row_list
collection m_row_list
Definition: UnwindPlan.h:534
lldb_private::UnwindPlan::GetLastRow
const UnwindPlan::RowSP GetLastRow() const
Definition: UnwindPlan.cpp:420
lldb_private::UnwindPlan::Row::RegisterLocation::SetInRegister
void SetInRegister(uint32_t reg_num)
Definition: UnwindPlan.h:128
DumpRegisterName
static void DumpRegisterName(Stream &s, const UnwindPlan *unwind_plan, Thread *thread, uint32_t reg_num)
Definition: UnwindPlan.cpp:158
Thread.h
lldb_private::Stream::PutChar
size_t PutChar(char ch)
Definition: Stream.cpp:104
UnwindPlan.h
lldb_private::RegisterContext
Definition: RegisterContext.h:17
lldb_private::ArchSpec::GetAddressByteSize
uint32_t GetAddressByteSize() const
Returns the size in bytes of an address of the current architecture.
Definition: ArchSpec.cpp:684
lldb_private::AddressRange::ContainsFileAddress
bool ContainsFileAddress(const Address &so_addr) const
Check if a section offset address is contained in this range.
Definition: AddressRange.cpp:62
lldb_private::UnwindPlan::Row::RegisterLocation
Definition: UnwindPlan.h:57
lldb_private::UnwindPlan::RowSP
std::shared_ptr< Row > RowSP
Definition: UnwindPlan.h:395
lldb_private::UnwindPlan::m_plan_is_sourced_from_compiler
lldb_private::LazyBool m_plan_is_sourced_from_compiler
Definition: UnwindPlan.h:544
lldb_private::UnwindPlan::GetRowCount
int GetRowCount() const
Definition: UnwindPlan.cpp:429
lldb_private::Address::Dump
bool Dump(Stream *s, ExecutionContextScope *exe_scope, DumpStyle style, DumpStyle fallback_style=DumpStyleInvalid, uint32_t addr_byte_size=UINT32_MAX, bool all_ranges=false) const
Dump a description of this object to a Stream.
Definition: Address.cpp:406
lldb_private::UnwindPlan::GetRowAtIndex
const UnwindPlan::RowSP GetRowAtIndex(uint32_t idx) const
Definition: UnwindPlan.cpp:407
lldb_private::UnwindPlan::Row
Definition: UnwindPlan.h:55
uint32_t
lldb_private::eLazyBoolNo
@ eLazyBoolNo
Definition: lldb-private-enumerations.h:115
lldb_private::UnwindPlan::IsValidRowIndex
bool IsValidRowIndex(uint32_t idx) const
Definition: UnwindPlan.cpp:403
lldb_private::AddressRange::Dump
bool Dump(Stream *s, Target *target, Address::DumpStyle style, Address::DumpStyle fallback_style=Address::DumpStyleInvalid) const
Dump a description of this object to a Stream.
Definition: AddressRange.cpp:148
lldb_private::UnwindPlan::Row::FAValue::reg
struct lldb_private::UnwindPlan::Row::FAValue::@29::@30 reg
lldb_private::Address
Definition: Address.h:59
lldb_private::Stream::EOL
size_t EOL()
Output and End of Line character to the stream.
Definition: Stream.cpp:128
lldb_private::UnwindPlan::GetSourceName
lldb_private::ConstString GetSourceName() const
Definition: UnwindPlan.cpp:568
lldb_private::UnwindPlan::m_plan_is_valid_at_all_instruction_locations
lldb_private::LazyBool m_plan_is_valid_at_all_instruction_locations
Definition: UnwindPlan.h:545
lldb_private::Address::GetLoadAddress
lldb::addr_t GetLoadAddress(Target *target) const
Get the load address.
Definition: Address.cpp:311
lldb_private::Stream::AsRawOstream
llvm::raw_ostream & AsRawOstream()
Returns a raw_ostream that forwards the data to this Stream object.
Definition: Stream.h:357
lldb_private::UnwindPlan::Row::RegisterLocation::SetAtCFAPlusOffset
void SetAtCFAPlusOffset(int32_t offset)
Definition: UnwindPlan.h:108
lldb_private::UnwindPlan::m_plan_valid_address_range
AddressRange m_plan_valid_address_range
Definition: UnwindPlan.h:535
LLDB_INVALID_ADDRESS
#define LLDB_INVALID_ADDRESS
Definition: lldb-defines.h:74
lldb_private::ConstString::GetCString
const char * GetCString() const
Get the string value as a C string.
Definition: ConstString.h:216
lldb_private::UnwindPlan::m_plan_is_for_signal_trap
lldb_private::LazyBool m_plan_is_for_signal_trap
Definition: UnwindPlan.h:546
lldb_private::Stream::Printf
size_t Printf(const char *format,...) __attribute__((format(printf
Output printf formatted output to the stream.
Definition: Stream.cpp:107
lldb_private
A class that represents a running process on the host machine.
Definition: SBCommandInterpreterRunOptions.h:16
lldb_private::eLazyBoolCalculate
@ eLazyBoolCalculate
Definition: lldb-private-enumerations.h:115
lldb_private::UnwindPlan::Row::RegisterLocation::offset
int32_t offset
Definition: UnwindPlan.h:187
lldb_private::UnwindPlan::Row::FAValue::unspecified
@ unspecified
Definition: UnwindPlan.h:201
ConstString.h
lldb_private::UnwindPlan::Row::FAValue::m_type
ValueType m_type
Definition: UnwindPlan.h:304
lldb_private::UnwindPlan::Row::RegisterLocation::SetIsCFAPlusOffset
void SetIsCFAPlusOffset(int32_t offset)
Definition: UnwindPlan.h:113
lldb_private::Log
Definition: Log.h:48
lldb_private::Stream::PutCString
size_t PutCString(llvm::StringRef cstr)
Output a C string to the stream.
Definition: Stream.cpp:63
lldb_private::UnwindPlan::m_lsda_address
Address m_lsda_address
Definition: UnwindPlan.h:548
lldb_private::Thread::GetRegisterContext
virtual lldb::RegisterContextSP GetRegisterContext()=0
lldb_private::UnwindPlan::GetRegisterInfo
const RegisterInfo * GetRegisterInfo(Thread *thread, uint32_t reg_num) const
Definition: UnwindPlan.cpp:570
lldb_private::GetLog
Log * GetLog(Cat mask)
Retrieve the Log object for the channel associated with the given log enum.
Definition: Log.h:235
lldb::eByteOrderLittle
@ eByteOrderLittle
Definition: lldb-enumerations.h:142
lldb_private::UnwindPlan::m_register_kind
lldb::RegisterKind m_register_kind
Definition: UnwindPlan.h:536
lldb_private::UnwindPlan
Definition: UnwindPlan.h:53
lldb
Definition: SBAddress.h:15
lldb_private::UnwindPlan::Row::FAValue::m_value
union lldb_private::UnwindPlan::Row::FAValue::@29 m_value
RegisterContext.h
LLDBLog.h
lldb_private::UnwindPlan::Row::RegisterLocation::m_location
union lldb_private::UnwindPlan::Row::RegisterLocation::@27 m_location
lldb_private::UnwindPlan::Row::m_offset
lldb::addr_t m_offset
Definition: UnwindPlan.h:387