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