18#include "llvm/DebugInfo/DIContext.h"
19#include "llvm/DebugInfo/DWARF/DWARFExpression.h"
59 const uint8_t *opcodes, uint32_t len) {
60 m_type = atDWARFExpression;
61 m_location.expr.opcodes = opcodes;
62 m_location.expr.length = len;
68 const uint8_t *opcodes, uint32_t len) {
69 m_type = isDWARFExpression;
70 m_location.expr.opcodes = opcodes;
71 m_location.expr.length = len;
74static std::optional<std::pair<lldb::ByteOrder, uint32_t>>
81 ArchSpec arch = process_sp->GetTarget().GetArchitecture();
88 order_and_width->second);
89 llvm::DWARFExpression(data, order_and_width->second, llvm::dwarf::DWARF32)
90 .print(s.
AsRawOstream(), llvm::DIDumpOptions(),
nullptr);
117 case atCFAPlusOffset:
118 case isCFAPlusOffset: {
120 if (m_type == atCFAPlusOffset)
122 s.
Printf(
"CFA%+d", m_location.offset);
123 if (m_type == atCFAPlusOffset)
127 case atAFAPlusOffset:
128 case isAFAPlusOffset: {
130 if (m_type == atAFAPlusOffset)
132 s.
Printf(
"AFA%+d", m_location.offset);
133 if (m_type == atAFAPlusOffset)
137 case inOtherRegister: {
140 other_reg_info = unwind_plan->
GetRegisterInfo(thread, m_location.reg_num);
144 s.
Printf(
"=reg(%u)", m_location.reg_num);
147 case atDWARFExpression:
148 case isDWARFExpression: {
150 if (m_type == atDWARFExpression)
153 s, llvm::ArrayRef(m_location.expr.opcodes, m_location.expr.length),
155 if (m_type == atDWARFExpression)
159 s.
Printf(
"=0x%" PRIx64, m_location.constant_value);
165 Thread *thread, uint32_t reg_num) {
170 s.
Printf(
"reg(%u)", reg_num);
175 if (m_type == rhs.
m_type) {
181 case isRegisterPlusOffset:
184 case isRegisterDereferenced:
187 case isDWARFExpression:
190 m_value.expr.length);
200 case isRegisterPlusOffset:
202 s.
Printf(
"%+3d", m_value.reg.offset);
204 case isRegisterDereferenced:
209 case isDWARFExpression:
210 DumpDWARFExpr(s, llvm::ArrayRef(m_value.expr.opcodes, m_value.expr.length),
217 s.
Printf(
"RaSearch@SP%+d", m_value.ra_search_offset);
248 const bool verbose =
false;
249 idx->second.Dump(s, unwind_plan,
this, thread, verbose);
259 collection::const_iterator pos = m_register_locations.find(reg_num);
260 if (pos != m_register_locations.end()) {
261 register_location = pos->second;
264 if (m_unspecified_registers_are_undefined) {
272 collection::const_iterator pos = m_register_locations.find(reg_num);
273 if (pos != m_register_locations.end()) {
274 m_register_locations.erase(pos);
281 m_register_locations[reg_num] = register_location;
288 m_register_locations.find(reg_num) != m_register_locations.end())
292 m_register_locations[reg_num] = reg_loc;
300 m_register_locations.find(reg_num) != m_register_locations.end())
304 m_register_locations[reg_num] = reg_loc;
309 uint32_t reg_num,
bool can_replace,
bool can_replace_only_if_unspecified) {
310 collection::iterator pos = m_register_locations.find(reg_num);
311 collection::iterator end = m_register_locations.end();
316 if (can_replace_only_if_unspecified && !pos->second.IsUnspecified())
321 m_register_locations[reg_num] = reg_loc;
328 m_register_locations.find(reg_num) != m_register_locations.end())
332 m_register_locations[reg_num] = reg_loc;
337 uint32_t other_reg_num,
340 m_register_locations.find(reg_num) != m_register_locations.end())
344 m_register_locations[reg_num] = reg_loc;
351 m_register_locations.find(reg_num) == m_register_locations.end())
355 m_register_locations[reg_num] = reg_loc;
363 m_register_locations.find(reg_num) != m_register_locations.end())
367 m_register_locations[reg_num] = reg_loc;
374 m_unspecified_registers_are_undefined ==
381 m_row_list.back()->GetOffset() != row_sp->GetOffset())
388 bool replace_existing) {
392 if (row->GetOffset() >= row_sp->GetOffset())
396 if (it ==
m_row_list.end() || (*it)->GetOffset() != row_sp->GetOffset())
398 else if (replace_existing)
408 collection::const_iterator pos, end =
m_row_list.end();
409 for (pos =
m_row_list.begin(); pos != end; ++pos) {
430 "error: UnwindPlan::GetRowAtIndex(idx = %u) invalid index "
431 "(number rows is %u)",
440 LLDB_LOGF(log,
"UnwindPlan::GetLastRow() when rows are empty");
461 "UnwindPlan is invalid -- no unwind rows for UnwindPlan "
462 "'%s' at address %s",
466 "UnwindPlan is invalid -- no unwind rows for UnwindPlan '%s'",
484 "UnwindPlan is invalid -- no CFA register defined in row 0 "
485 "for UnwindPlan '%s' at address %s",
489 "UnwindPlan is invalid -- no CFA register defined in row 0 "
490 "for UnwindPlan '%s'",
512 s.
Printf(
"This UnwindPlan originally sourced from %s\n",
518 addr_t personality_func_load_addr =
523 s.
Printf(
"LSDA address 0x%" PRIx64
524 ", personality routine is at address 0x%" PRIx64
"\n",
525 lsda_load_addr, personality_func_load_addr);
528 s.
Printf(
"This UnwindPlan is sourced from the compiler: ");
537 s.
Printf(
"not specified.\n");
540 s.
Printf(
"This UnwindPlan is valid at all instruction locations: ");
549 s.
Printf(
"not specified.\n");
552 s.
Printf(
"This UnwindPlan is for a trap handler function: ");
561 s.
Printf(
"not specified.\n");
566 s.
PutCString(
"Address range of this UnwindPlan: ");
572 collection::const_iterator pos, begin =
m_row_list.begin(),
574 for (pos = begin; pos != end; ++pos) {
575 s.
Printf(
"row[%u]: ", (uint32_t)std::distance(begin, pos));
576 (*pos)->Dump(s,
this, thread, base_addr);
588 uint32_t unwind_reg)
const {
#define LLDB_LOGF(log,...)
static std::optional< std::pair< lldb::ByteOrder, uint32_t > > GetByteOrderAndAddrSize(Thread *thread)
static void DumpRegisterName(Stream &s, const UnwindPlan *unwind_plan, Thread *thread, uint32_t reg_num)
static void DumpDWARFExpr(Stream &s, llvm::ArrayRef< uint8_t > expr, Thread *thread)
A section + offset based address range class.
Address & GetBaseAddress()
Get accessor for the base address of the range.
bool ContainsFileAddress(const Address &so_addr) const
Check if a section offset address is contained in this range.
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.
lldb::addr_t GetByteSize() const
Get accessor for the byte size of this range.
A section + offset based address class.
lldb::addr_t GetLoadAddress(Target *target) const
Get the load address.
@ DumpStyleSectionNameOffset
Display as the section name + offset.
bool Dump(Stream *s, ExecutionContextScope *exe_scope, DumpStyle style, DumpStyle fallback_style=DumpStyleInvalid, uint32_t addr_byte_size=UINT32_MAX, bool all_ranges=false, std::optional< Stream::HighlightSettings > settings=std::nullopt) const
Dump a description of this object to a Stream.
bool IsValid() const
Check if the object state is valid.
An architecture specification class.
uint32_t GetAddressByteSize() const
Returns the size in bytes of an address of the current architecture.
lldb::ByteOrder GetByteOrder() const
Returns the byte order for the architecture specification.
A uniqued constant string class.
bool IsEmpty() const
Test for empty string.
const char * GetCString() const
Get the string value as a C string.
virtual uint32_t ConvertRegisterKindToRegisterNumber(lldb::RegisterKind kind, uint32_t num)
Convert from a given register numbering scheme to the lldb register numbering scheme.
virtual const RegisterInfo * GetRegisterInfoAtIndex(size_t reg)=0
const char * GetData() const
A stream class that can stream formatted output to a file.
llvm::raw_ostream & AsRawOstream()
Returns a raw_ostream that forwards the data to this Stream object.
size_t Printf(const char *format,...) __attribute__((format(printf
Output printf formatted output to the stream.
size_t PutCString(llvm::StringRef cstr)
Output a C string to the stream.
size_t EOL()
Output and End of Line character to the stream.
virtual lldb::RegisterContextSP GetRegisterContext()=0
lldb::TargetSP CalculateTarget() override
lldb::ProcessSP GetProcess() const
void Dump(Stream &s, const UnwindPlan *unwind_plan, Thread *thread) const
union lldb_private::UnwindPlan::Row::FAValue::@26 m_value
bool IsUnspecified() const
bool operator==(const FAValue &rhs) const
struct lldb_private::UnwindPlan::Row::FAValue::@26::@27 reg
struct lldb_private::UnwindPlan::Row::FAValue::@26::@28 expr
bool operator==(const RegisterLocation &rhs) const
union lldb_private::UnwindPlan::Row::RegisterLocation::@24 m_location
void SetIsConstant(uint64_t value)
struct lldb_private::UnwindPlan::Row::RegisterLocation::@24::@25 expr
void SetAtDWARFExpression(const uint8_t *opcodes, uint32_t len)
void SetInRegister(uint32_t reg_num)
void Dump(Stream &s, const UnwindPlan *unwind_plan, const UnwindPlan::Row *row, Thread *thread, bool verbose) const
void SetIsDWARFExpression(const uint8_t *opcodes, uint32_t len)
void SetIsCFAPlusOffset(int32_t offset)
void SetAtCFAPlusOffset(int32_t offset)
bool SetRegisterLocationToIsConstant(uint32_t reg_num, uint64_t constant, bool can_replace)
bool SetRegisterLocationToIsCFAPlusOffset(uint32_t reg_num, int32_t offset, bool can_replace)
bool SetRegisterLocationToSame(uint32_t reg_num, bool must_replace)
bool SetRegisterLocationToAtCFAPlusOffset(uint32_t reg_num, int32_t offset, bool can_replace)
collection m_register_locations
bool m_unspecified_registers_are_undefined
bool SetRegisterLocationToRegister(uint32_t reg_num, uint32_t other_reg_num, bool can_replace)
void Dump(Stream &s, const UnwindPlan *unwind_plan, Thread *thread, lldb::addr_t base_addr) const
bool SetRegisterLocationToUnspecified(uint32_t reg_num, bool can_replace)
void RemoveRegisterInfo(uint32_t reg_num)
lldb::addr_t GetOffset() const
bool operator==(const Row &rhs) const
bool SetRegisterLocationToUndefined(uint32_t reg_num, bool can_replace, bool can_replace_only_if_unspecified)
bool GetRegisterInfo(uint32_t reg_num, RegisterLocation ®ister_location) const
void SetRegisterInfo(uint32_t reg_num, const RegisterLocation register_location)
void InsertRow(const RowSP &row_sp, bool replace_existing=false)
const UnwindPlan::RowSP GetRowAtIndex(uint32_t idx) const
Address m_personality_func_addr
lldb::RegisterKind m_register_kind
const RegisterInfo * GetRegisterInfo(Thread *thread, uint32_t reg_num) const
lldb_private::LazyBool m_plan_is_for_signal_trap
const UnwindPlan::RowSP GetLastRow() const
void SetPlanValidAddressRange(const AddressRange &range)
AddressRange m_plan_valid_address_range
bool IsValidRowIndex(uint32_t idx) const
void AppendRow(const RowSP &row_sp)
lldb_private::LazyBool m_plan_is_valid_at_all_instruction_locations
UnwindPlan::RowSP GetRowForFunctionOffset(int offset) const
std::shared_ptr< Row > RowSP
lldb_private::ConstString m_source_name
bool PlanValidAtAddress(Address addr)
void SetSourceName(const char *)
void Dump(Stream &s, Thread *thread, lldb::addr_t base_addr) const
lldb_private::ConstString GetSourceName() const
lldb_private::LazyBool m_plan_is_sourced_from_compiler
#define LLDB_INVALID_ADDRESS
#define LLDB_INVALID_REGNUM
A class that represents a running process on the host machine.
Log * GetLog(Cat mask)
Retrieve the Log object for the channel associated with the given log enum.
std::shared_ptr< lldb_private::Process > ProcessSP
std::shared_ptr< lldb_private::Target > TargetSP
@ eRegisterKindLLDB
lldb's internal register numbers
Every register is described in detail including its name, alternate name (optional),...
const char * name
Name of this register, can't be NULL.