diff options
author | Kate Stone <katherine.stone@apple.com> | 2016-09-06 20:57:50 +0000 |
---|---|---|
committer | Kate Stone <katherine.stone@apple.com> | 2016-09-06 20:57:50 +0000 |
commit | b9c1b51e45b845debb76d8658edabca70ca56079 (patch) | |
tree | dfcb5a13ef2b014202340f47036da383eaee74aa /lldb/source/Symbol/UnwindPlan.cpp | |
parent | d5aa73376966339caad04013510626ec2e42c760 (diff) | |
download | llvm-b9c1b51e45b845debb76d8658edabca70ca56079.zip llvm-b9c1b51e45b845debb76d8658edabca70ca56079.tar.gz llvm-b9c1b51e45b845debb76d8658edabca70ca56079.tar.bz2 |
*** This commit represents a complete reformatting of the LLDB source code
*** to conform to clang-format’s LLVM style. This kind of mass change has
*** two obvious implications:
Firstly, merging this particular commit into a downstream fork may be a huge
effort. Alternatively, it may be worth merging all changes up to this commit,
performing the same reformatting operation locally, and then discarding the
merge for this particular commit. The commands used to accomplish this
reformatting were as follows (with current working directory as the root of
the repository):
find . \( -iname "*.c" -or -iname "*.cpp" -or -iname "*.h" -or -iname "*.mm" \) -exec clang-format -i {} +
find . -iname "*.py" -exec autopep8 --in-place --aggressive --aggressive {} + ;
The version of clang-format used was 3.9.0, and autopep8 was 1.2.4.
Secondly, “blame” style tools will generally point to this commit instead of
a meaningful prior commit. There are alternatives available that will attempt
to look through this change and find the appropriate prior commit. YMMV.
llvm-svn: 280751
Diffstat (limited to 'lldb/source/Symbol/UnwindPlan.cpp')
-rw-r--r-- | lldb/source/Symbol/UnwindPlan.cpp | 967 |
1 files changed, 453 insertions, 514 deletions
diff --git a/lldb/source/Symbol/UnwindPlan.cpp b/lldb/source/Symbol/UnwindPlan.cpp index 18f0cb7..8a20ef8 100644 --- a/lldb/source/Symbol/UnwindPlan.cpp +++ b/lldb/source/Symbol/UnwindPlan.cpp @@ -18,558 +18,497 @@ using namespace lldb; using namespace lldb_private; -bool -UnwindPlan::Row::RegisterLocation::operator == (const UnwindPlan::Row::RegisterLocation& rhs) const -{ - if (m_type == rhs.m_type) - { - switch (m_type) - { - case unspecified: - case undefined: - case same: - return true; - - case atCFAPlusOffset: - case isCFAPlusOffset: - return m_location.offset == rhs.m_location.offset; - - case inOtherRegister: - return m_location.reg_num == rhs.m_location.reg_num; - - case atDWARFExpression: - case isDWARFExpression: - if (m_location.expr.length == rhs.m_location.expr.length) - return !memcmp (m_location.expr.opcodes, rhs.m_location.expr.opcodes, m_location.expr.length); - break; - } +bool UnwindPlan::Row::RegisterLocation:: +operator==(const UnwindPlan::Row::RegisterLocation &rhs) const { + if (m_type == rhs.m_type) { + switch (m_type) { + case unspecified: + case undefined: + case same: + return true; + + case atCFAPlusOffset: + case isCFAPlusOffset: + return m_location.offset == rhs.m_location.offset; + + case inOtherRegister: + return m_location.reg_num == rhs.m_location.reg_num; + + case atDWARFExpression: + case isDWARFExpression: + if (m_location.expr.length == rhs.m_location.expr.length) + return !memcmp(m_location.expr.opcodes, rhs.m_location.expr.opcodes, + m_location.expr.length); + break; } - return false; + } + return false; } -// This function doesn't copy the dwarf expression bytes; they must remain in allocated +// This function doesn't copy the dwarf expression bytes; they must remain in +// allocated // memory for the lifespan of this UnwindPlan object. -void -UnwindPlan::Row::RegisterLocation::SetAtDWARFExpression (const uint8_t *opcodes, uint32_t len) -{ - m_type = atDWARFExpression; - m_location.expr.opcodes = opcodes; - m_location.expr.length = len; +void UnwindPlan::Row::RegisterLocation::SetAtDWARFExpression( + const uint8_t *opcodes, uint32_t len) { + m_type = atDWARFExpression; + m_location.expr.opcodes = opcodes; + m_location.expr.length = len; } -// This function doesn't copy the dwarf expression bytes; they must remain in allocated +// This function doesn't copy the dwarf expression bytes; they must remain in +// allocated // memory for the lifespan of this UnwindPlan object. -void -UnwindPlan::Row::RegisterLocation::SetIsDWARFExpression (const uint8_t *opcodes, uint32_t len) -{ - m_type = isDWARFExpression; - m_location.expr.opcodes = opcodes; - m_location.expr.length = len; -} - -void -UnwindPlan::Row::RegisterLocation::Dump (Stream &s, const UnwindPlan* unwind_plan, const UnwindPlan::Row* row, Thread* thread, bool verbose) const -{ - switch (m_type) - { - case unspecified: - if (verbose) - s.PutCString ("=<unspec>"); - else - s.PutCString ("=!"); - break; - case undefined: - if (verbose) - s.PutCString ("=<undef>"); - else - s.PutCString ("=?"); - break; - case same: - s.PutCString ("= <same>"); - break; - - case atCFAPlusOffset: - case isCFAPlusOffset: - { - s.PutChar('='); - if (m_type == atCFAPlusOffset) - s.PutChar('['); - s.Printf ("CFA%+d", m_location.offset); - if (m_type == atCFAPlusOffset) - s.PutChar(']'); - } - break; - - case inOtherRegister: - { - const RegisterInfo *other_reg_info = nullptr; - if (unwind_plan) - other_reg_info = unwind_plan->GetRegisterInfo (thread, m_location.reg_num); - if (other_reg_info) - s.Printf ("=%s", other_reg_info->name); - else - s.Printf ("=reg(%u)", m_location.reg_num); - } - break; - - case atDWARFExpression: - case isDWARFExpression: - { - s.PutChar('='); - if (m_type == atDWARFExpression) - s.PutCString("[dwarf-expr]"); - else - s.PutCString("dwarf-expr"); - } - break; - - } -} - -static void -DumpRegisterName (Stream &s, const UnwindPlan* unwind_plan, Thread *thread, uint32_t reg_num) { - const RegisterInfo *reg_info = unwind_plan->GetRegisterInfo (thread, reg_num); - if (reg_info) - s.PutCString (reg_info->name); +void UnwindPlan::Row::RegisterLocation::SetIsDWARFExpression( + const uint8_t *opcodes, uint32_t len) { + m_type = isDWARFExpression; + m_location.expr.opcodes = opcodes; + m_location.expr.length = len; +} + +void UnwindPlan::Row::RegisterLocation::Dump(Stream &s, + const UnwindPlan *unwind_plan, + const UnwindPlan::Row *row, + Thread *thread, + bool verbose) const { + switch (m_type) { + case unspecified: + if (verbose) + s.PutCString("=<unspec>"); else - s.Printf ("reg(%u)", reg_num); -} - -bool -UnwindPlan::Row::CFAValue::operator == (const UnwindPlan::Row::CFAValue& rhs) const -{ - if (m_type == rhs.m_type) - { - switch (m_type) - { - case unspecified: - return true; - - case isRegisterPlusOffset: - return m_value.reg.offset == rhs.m_value.reg.offset; - - case isRegisterDereferenced: - return m_value.reg.reg_num == rhs.m_value.reg.reg_num; - - case isDWARFExpression: - if (m_value.expr.length == rhs.m_value.expr.length) - return !memcmp (m_value.expr.opcodes, rhs.m_value.expr.opcodes, m_value.expr.length); - break; - } - } - return false; -} - -void -UnwindPlan::Row::CFAValue::Dump(Stream &s, const UnwindPlan* unwind_plan, Thread* thread) const -{ - switch(m_type) { - case isRegisterPlusOffset: - DumpRegisterName(s, unwind_plan, thread, m_value.reg.reg_num); - s.Printf ("%+3d", m_value.reg.offset); - break; - case isRegisterDereferenced: - s.PutChar ('['); - DumpRegisterName(s, unwind_plan, thread, m_value.reg.reg_num); - s.PutChar (']'); - break; - case isDWARFExpression: - s.PutCString ("dwarf-expr"); - break; - default: - s.PutCString ("unspecified"); - break; - } -} - -void -UnwindPlan::Row::Clear () -{ - m_cfa_value.SetUnspecified(); - m_offset = 0; - m_register_locations.clear(); -} - -void -UnwindPlan::Row::Dump (Stream& s, const UnwindPlan* unwind_plan, Thread* thread, addr_t base_addr) const -{ - if (base_addr != LLDB_INVALID_ADDRESS) - s.Printf ("0x%16.16" PRIx64 ": CFA=", base_addr + GetOffset()); + s.PutCString("=!"); + break; + case undefined: + if (verbose) + s.PutCString("=<undef>"); else - s.Printf ("%4" PRId64 ": CFA=", GetOffset()); - - m_cfa_value.Dump(s, unwind_plan, thread); - s.Printf(" => "); - for (collection::const_iterator idx = m_register_locations.begin (); idx != m_register_locations.end (); ++idx) - { - DumpRegisterName(s, unwind_plan, thread, idx->first); - const bool verbose = false; - idx->second.Dump(s, unwind_plan, this, thread, verbose); - s.PutChar (' '); - } - s.EOL(); -} - -UnwindPlan::Row::Row() : - m_offset (0), - m_cfa_value (), - m_register_locations () -{ -} - -bool -UnwindPlan::Row::GetRegisterInfo (uint32_t reg_num, UnwindPlan::Row::RegisterLocation& register_location) const -{ - collection::const_iterator pos = m_register_locations.find(reg_num); - if (pos != m_register_locations.end()) - { - register_location = pos->second; - return true; - } - return false; + s.PutCString("=?"); + break; + case same: + s.PutCString("= <same>"); + break; + + case atCFAPlusOffset: + case isCFAPlusOffset: { + s.PutChar('='); + if (m_type == atCFAPlusOffset) + s.PutChar('['); + s.Printf("CFA%+d", m_location.offset); + if (m_type == atCFAPlusOffset) + s.PutChar(']'); + } break; + + case inOtherRegister: { + const RegisterInfo *other_reg_info = nullptr; + if (unwind_plan) + other_reg_info = unwind_plan->GetRegisterInfo(thread, m_location.reg_num); + if (other_reg_info) + s.Printf("=%s", other_reg_info->name); + else + s.Printf("=reg(%u)", m_location.reg_num); + } break; + + case atDWARFExpression: + case isDWARFExpression: { + s.PutChar('='); + if (m_type == atDWARFExpression) + s.PutCString("[dwarf-expr]"); + else + s.PutCString("dwarf-expr"); + } break; + } } -void -UnwindPlan::Row::RemoveRegisterInfo (uint32_t reg_num) -{ - collection::const_iterator pos = m_register_locations.find(reg_num); - if (pos != m_register_locations.end()) - { - m_register_locations.erase(pos); - } +static void DumpRegisterName(Stream &s, const UnwindPlan *unwind_plan, + Thread *thread, uint32_t reg_num) { + const RegisterInfo *reg_info = unwind_plan->GetRegisterInfo(thread, reg_num); + if (reg_info) + s.PutCString(reg_info->name); + else + s.Printf("reg(%u)", reg_num); } -void -UnwindPlan::Row::SetRegisterInfo (uint32_t reg_num, const UnwindPlan::Row::RegisterLocation register_location) -{ - m_register_locations[reg_num] = register_location; -} +bool UnwindPlan::Row::CFAValue:: +operator==(const UnwindPlan::Row::CFAValue &rhs) const { + if (m_type == rhs.m_type) { + switch (m_type) { + case unspecified: + return true; -bool -UnwindPlan::Row::SetRegisterLocationToAtCFAPlusOffset (uint32_t reg_num, int32_t offset, bool can_replace) -{ - if (!can_replace && m_register_locations.find(reg_num) != m_register_locations.end()) - return false; - RegisterLocation reg_loc; - reg_loc.SetAtCFAPlusOffset(offset); - m_register_locations[reg_num] = reg_loc; - return true; -} + case isRegisterPlusOffset: + return m_value.reg.offset == rhs.m_value.reg.offset; -bool -UnwindPlan::Row::SetRegisterLocationToIsCFAPlusOffset (uint32_t reg_num, int32_t offset, bool can_replace) -{ - if (!can_replace && m_register_locations.find(reg_num) != m_register_locations.end()) - return false; - RegisterLocation reg_loc; - reg_loc.SetIsCFAPlusOffset(offset); - m_register_locations[reg_num] = reg_loc; - return true; -} + case isRegisterDereferenced: + return m_value.reg.reg_num == rhs.m_value.reg.reg_num; -bool -UnwindPlan::Row::SetRegisterLocationToUndefined (uint32_t reg_num, bool can_replace, bool can_replace_only_if_unspecified) -{ - collection::iterator pos = m_register_locations.find(reg_num); - collection::iterator end = m_register_locations.end(); - - if (pos != end) - { - if (!can_replace) - return false; - if (can_replace_only_if_unspecified && !pos->second.IsUnspecified()) - return false; + case isDWARFExpression: + if (m_value.expr.length == rhs.m_value.expr.length) + return !memcmp(m_value.expr.opcodes, rhs.m_value.expr.opcodes, + m_value.expr.length); + break; } - RegisterLocation reg_loc; - reg_loc.SetUndefined(); - m_register_locations[reg_num] = reg_loc; + } + return false; +} + +void UnwindPlan::Row::CFAValue::Dump(Stream &s, const UnwindPlan *unwind_plan, + Thread *thread) const { + switch (m_type) { + case isRegisterPlusOffset: + DumpRegisterName(s, unwind_plan, thread, m_value.reg.reg_num); + s.Printf("%+3d", m_value.reg.offset); + break; + case isRegisterDereferenced: + s.PutChar('['); + DumpRegisterName(s, unwind_plan, thread, m_value.reg.reg_num); + s.PutChar(']'); + break; + case isDWARFExpression: + s.PutCString("dwarf-expr"); + break; + default: + s.PutCString("unspecified"); + break; + } +} + +void UnwindPlan::Row::Clear() { + m_cfa_value.SetUnspecified(); + m_offset = 0; + m_register_locations.clear(); +} + +void UnwindPlan::Row::Dump(Stream &s, const UnwindPlan *unwind_plan, + Thread *thread, addr_t base_addr) const { + if (base_addr != LLDB_INVALID_ADDRESS) + s.Printf("0x%16.16" PRIx64 ": CFA=", base_addr + GetOffset()); + else + s.Printf("%4" PRId64 ": CFA=", GetOffset()); + + m_cfa_value.Dump(s, unwind_plan, thread); + s.Printf(" => "); + for (collection::const_iterator idx = m_register_locations.begin(); + idx != m_register_locations.end(); ++idx) { + DumpRegisterName(s, unwind_plan, thread, idx->first); + const bool verbose = false; + idx->second.Dump(s, unwind_plan, this, thread, verbose); + s.PutChar(' '); + } + s.EOL(); +} + +UnwindPlan::Row::Row() : m_offset(0), m_cfa_value(), m_register_locations() {} + +bool UnwindPlan::Row::GetRegisterInfo( + uint32_t reg_num, + UnwindPlan::Row::RegisterLocation ®ister_location) const { + collection::const_iterator pos = m_register_locations.find(reg_num); + if (pos != m_register_locations.end()) { + register_location = pos->second; return true; + } + return false; } -bool -UnwindPlan::Row::SetRegisterLocationToUnspecified (uint32_t reg_num, bool can_replace) -{ - if (!can_replace && m_register_locations.find(reg_num) != m_register_locations.end()) - return false; - RegisterLocation reg_loc; - reg_loc.SetUnspecified(); - m_register_locations[reg_num] = reg_loc; - return true; -} - -bool -UnwindPlan::Row::SetRegisterLocationToRegister (uint32_t reg_num, - uint32_t other_reg_num, - bool can_replace) -{ - if (!can_replace && m_register_locations.find(reg_num) != m_register_locations.end()) - return false; - RegisterLocation reg_loc; - reg_loc.SetInRegister(other_reg_num); - m_register_locations[reg_num] = reg_loc; - return true; +void UnwindPlan::Row::RemoveRegisterInfo(uint32_t reg_num) { + collection::const_iterator pos = m_register_locations.find(reg_num); + if (pos != m_register_locations.end()) { + m_register_locations.erase(pos); + } } -bool -UnwindPlan::Row::SetRegisterLocationToSame (uint32_t reg_num, bool must_replace) -{ - if (must_replace && m_register_locations.find(reg_num) == m_register_locations.end()) - return false; - RegisterLocation reg_loc; - reg_loc.SetSame(); - m_register_locations[reg_num] = reg_loc; - return true; +void UnwindPlan::Row::SetRegisterInfo( + uint32_t reg_num, + const UnwindPlan::Row::RegisterLocation register_location) { + m_register_locations[reg_num] = register_location; } -bool -UnwindPlan::Row::operator == (const UnwindPlan::Row& rhs) const -{ - return m_offset == rhs.m_offset && m_cfa_value == rhs.m_cfa_value && - m_register_locations == rhs.m_register_locations; +bool UnwindPlan::Row::SetRegisterLocationToAtCFAPlusOffset(uint32_t reg_num, + int32_t offset, + bool can_replace) { + if (!can_replace && + m_register_locations.find(reg_num) != m_register_locations.end()) + return false; + RegisterLocation reg_loc; + reg_loc.SetAtCFAPlusOffset(offset); + m_register_locations[reg_num] = reg_loc; + return true; } -void -UnwindPlan::AppendRow (const UnwindPlan::RowSP &row_sp) -{ - if (m_row_list.empty() || m_row_list.back()->GetOffset() != row_sp->GetOffset()) - m_row_list.push_back(row_sp); - else - m_row_list.back() = row_sp; +bool UnwindPlan::Row::SetRegisterLocationToIsCFAPlusOffset(uint32_t reg_num, + int32_t offset, + bool can_replace) { + if (!can_replace && + m_register_locations.find(reg_num) != m_register_locations.end()) + return false; + RegisterLocation reg_loc; + reg_loc.SetIsCFAPlusOffset(offset); + m_register_locations[reg_num] = reg_loc; + return true; +} + +bool UnwindPlan::Row::SetRegisterLocationToUndefined( + uint32_t reg_num, bool can_replace, bool can_replace_only_if_unspecified) { + collection::iterator pos = m_register_locations.find(reg_num); + collection::iterator end = m_register_locations.end(); + + if (pos != end) { + if (!can_replace) + return false; + if (can_replace_only_if_unspecified && !pos->second.IsUnspecified()) + return false; + } + RegisterLocation reg_loc; + reg_loc.SetUndefined(); + m_register_locations[reg_num] = reg_loc; + return true; +} + +bool UnwindPlan::Row::SetRegisterLocationToUnspecified(uint32_t reg_num, + bool can_replace) { + if (!can_replace && + m_register_locations.find(reg_num) != m_register_locations.end()) + return false; + RegisterLocation reg_loc; + reg_loc.SetUnspecified(); + m_register_locations[reg_num] = reg_loc; + return true; } -void -UnwindPlan::InsertRow (const UnwindPlan::RowSP &row_sp, bool replace_existing) -{ - collection::iterator it = m_row_list.begin(); - while (it != m_row_list.end()) { - RowSP row = *it; - if (row->GetOffset() >= row_sp->GetOffset()) - break; - it++; - } - if (it == m_row_list.end() || (*it)->GetOffset() != row_sp->GetOffset()) - m_row_list.insert(it, row_sp); - else if (replace_existing) - *it = row_sp; +bool UnwindPlan::Row::SetRegisterLocationToRegister(uint32_t reg_num, + uint32_t other_reg_num, + bool can_replace) { + if (!can_replace && + m_register_locations.find(reg_num) != m_register_locations.end()) + return false; + RegisterLocation reg_loc; + reg_loc.SetInRegister(other_reg_num); + m_register_locations[reg_num] = reg_loc; + return true; } -UnwindPlan::RowSP -UnwindPlan::GetRowForFunctionOffset (int offset) const -{ - RowSP row; - if (!m_row_list.empty()) - { - if (offset == -1) - row = m_row_list.back(); +bool UnwindPlan::Row::SetRegisterLocationToSame(uint32_t reg_num, + bool must_replace) { + if (must_replace && + m_register_locations.find(reg_num) == m_register_locations.end()) + return false; + RegisterLocation reg_loc; + reg_loc.SetSame(); + m_register_locations[reg_num] = reg_loc; + return true; +} + +bool UnwindPlan::Row::operator==(const UnwindPlan::Row &rhs) const { + return m_offset == rhs.m_offset && m_cfa_value == rhs.m_cfa_value && + m_register_locations == rhs.m_register_locations; +} + +void UnwindPlan::AppendRow(const UnwindPlan::RowSP &row_sp) { + if (m_row_list.empty() || + m_row_list.back()->GetOffset() != row_sp->GetOffset()) + m_row_list.push_back(row_sp); + else + m_row_list.back() = row_sp; +} + +void UnwindPlan::InsertRow(const UnwindPlan::RowSP &row_sp, + bool replace_existing) { + collection::iterator it = m_row_list.begin(); + while (it != m_row_list.end()) { + RowSP row = *it; + if (row->GetOffset() >= row_sp->GetOffset()) + break; + it++; + } + if (it == m_row_list.end() || (*it)->GetOffset() != row_sp->GetOffset()) + m_row_list.insert(it, row_sp); + else if (replace_existing) + *it = row_sp; +} + +UnwindPlan::RowSP UnwindPlan::GetRowForFunctionOffset(int offset) const { + RowSP row; + if (!m_row_list.empty()) { + if (offset == -1) + row = m_row_list.back(); + else { + collection::const_iterator pos, end = m_row_list.end(); + for (pos = m_row_list.begin(); pos != end; ++pos) { + if ((*pos)->GetOffset() <= static_cast<lldb::offset_t>(offset)) + row = *pos; else - { - collection::const_iterator pos, end = m_row_list.end(); - for (pos = m_row_list.begin(); pos != end; ++pos) - { - if ((*pos)->GetOffset() <= static_cast<lldb::offset_t>(offset)) - row = *pos; - else - break; - } - } - } - return row; -} - -bool -UnwindPlan::IsValidRowIndex (uint32_t idx) const -{ - return idx < m_row_list.size(); -} - -const UnwindPlan::RowSP -UnwindPlan::GetRowAtIndex (uint32_t idx) const -{ - if (idx < m_row_list.size()) - return m_row_list[idx]; - else - { - Log *log(GetLogIfAllCategoriesSet (LIBLLDB_LOG_UNWIND)); - if (log) - log->Printf ("error: UnwindPlan::GetRowAtIndex(idx = %u) invalid index (number rows is %u)", idx, (uint32_t)m_row_list.size()); - return UnwindPlan::RowSP(); - } -} - -const UnwindPlan::RowSP -UnwindPlan::GetLastRow () const -{ - if (m_row_list.empty()) - { - Log *log(GetLogIfAllCategoriesSet (LIBLLDB_LOG_UNWIND)); - if (log) - log->Printf ("UnwindPlan::GetLastRow() when rows are empty"); - return UnwindPlan::RowSP(); + break; + } } - return m_row_list.back(); -} - -int -UnwindPlan::GetRowCount () const -{ - return m_row_list.size (); -} - -void -UnwindPlan::SetPlanValidAddressRange (const AddressRange& range) -{ - if (range.GetBaseAddress().IsValid() && range.GetByteSize() != 0) - m_plan_valid_address_range = range; -} - -bool -UnwindPlan::PlanValidAtAddress (Address addr) -{ - // If this UnwindPlan has no rows, it is an invalid UnwindPlan. - if (GetRowCount() == 0) - { - Log *log(GetLogIfAllCategoriesSet (LIBLLDB_LOG_UNWIND)); - if (log) - { - StreamString s; - if (addr.Dump (&s, nullptr, Address::DumpStyleSectionNameOffset)) - { - log->Printf ("UnwindPlan is invalid -- no unwind rows for UnwindPlan '%s' at address %s", - m_source_name.GetCString(), s.GetData()); - } - else - { - log->Printf ("UnwindPlan is invalid -- no unwind rows for UnwindPlan '%s'", - m_source_name.GetCString()); - } - } - return false; + } + return row; +} + +bool UnwindPlan::IsValidRowIndex(uint32_t idx) const { + return idx < m_row_list.size(); +} + +const UnwindPlan::RowSP UnwindPlan::GetRowAtIndex(uint32_t idx) const { + if (idx < m_row_list.size()) + return m_row_list[idx]; + else { + Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_UNWIND)); + if (log) + log->Printf("error: UnwindPlan::GetRowAtIndex(idx = %u) invalid index " + "(number rows is %u)", + idx, (uint32_t)m_row_list.size()); + return UnwindPlan::RowSP(); + } +} + +const UnwindPlan::RowSP UnwindPlan::GetLastRow() const { + if (m_row_list.empty()) { + Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_UNWIND)); + if (log) + log->Printf("UnwindPlan::GetLastRow() when rows are empty"); + return UnwindPlan::RowSP(); + } + return m_row_list.back(); +} + +int UnwindPlan::GetRowCount() const { return m_row_list.size(); } + +void UnwindPlan::SetPlanValidAddressRange(const AddressRange &range) { + if (range.GetBaseAddress().IsValid() && range.GetByteSize() != 0) + m_plan_valid_address_range = range; +} + +bool UnwindPlan::PlanValidAtAddress(Address addr) { + // If this UnwindPlan has no rows, it is an invalid UnwindPlan. + if (GetRowCount() == 0) { + Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_UNWIND)); + if (log) { + StreamString s; + if (addr.Dump(&s, nullptr, Address::DumpStyleSectionNameOffset)) { + log->Printf("UnwindPlan is invalid -- no unwind rows for UnwindPlan " + "'%s' at address %s", + m_source_name.GetCString(), s.GetData()); + } else { + log->Printf( + "UnwindPlan is invalid -- no unwind rows for UnwindPlan '%s'", + m_source_name.GetCString()); + } } - - // If the 0th Row of unwind instructions is missing, or if it doesn't provide - // a register to use to find the Canonical Frame Address, this is not a valid UnwindPlan. - if (GetRowAtIndex(0).get() == nullptr || - GetRowAtIndex(0)->GetCFAValue().GetValueType() == Row::CFAValue::unspecified) - { - Log *log(GetLogIfAllCategoriesSet (LIBLLDB_LOG_UNWIND)); - if (log) - { - StreamString s; - if (addr.Dump (&s, nullptr, Address::DumpStyleSectionNameOffset)) - { - log->Printf ("UnwindPlan is invalid -- no CFA register defined in row 0 for UnwindPlan '%s' at address %s", - m_source_name.GetCString(), s.GetData()); - } - else - { - log->Printf ("UnwindPlan is invalid -- no CFA register defined in row 0 for UnwindPlan '%s'", - m_source_name.GetCString()); - } - } - return false; + return false; + } + + // If the 0th Row of unwind instructions is missing, or if it doesn't provide + // a register to use to find the Canonical Frame Address, this is not a valid + // UnwindPlan. + if (GetRowAtIndex(0).get() == nullptr || + GetRowAtIndex(0)->GetCFAValue().GetValueType() == + Row::CFAValue::unspecified) { + Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_UNWIND)); + if (log) { + StreamString s; + if (addr.Dump(&s, nullptr, Address::DumpStyleSectionNameOffset)) { + log->Printf("UnwindPlan is invalid -- no CFA register defined in row 0 " + "for UnwindPlan '%s' at address %s", + m_source_name.GetCString(), s.GetData()); + } else { + log->Printf("UnwindPlan is invalid -- no CFA register defined in row 0 " + "for UnwindPlan '%s'", + m_source_name.GetCString()); + } } - - if (!m_plan_valid_address_range.GetBaseAddress().IsValid() || m_plan_valid_address_range.GetByteSize() == 0) - return true; - - if (!addr.IsValid()) - return true; - - if (m_plan_valid_address_range.ContainsFileAddress (addr)) - return true; - return false; -} + } -void -UnwindPlan::Dump (Stream& s, Thread *thread, lldb::addr_t base_addr) const -{ - if (!m_source_name.IsEmpty()) - { - s.Printf ("This UnwindPlan originally sourced from %s\n", m_source_name.GetCString()); - } - if (m_lsda_address.IsValid() && m_personality_func_addr.IsValid()) - { - TargetSP target_sp(thread->CalculateTarget()); - addr_t lsda_load_addr = m_lsda_address.GetLoadAddress (target_sp.get()); - addr_t personality_func_load_addr = m_personality_func_addr.GetLoadAddress (target_sp.get()); - - if (lsda_load_addr != LLDB_INVALID_ADDRESS && personality_func_load_addr != LLDB_INVALID_ADDRESS) - { - s.Printf("LSDA address 0x%" PRIx64 ", personality routine is at address 0x%" PRIx64 "\n", - lsda_load_addr, personality_func_load_addr); - } - } - s.Printf ("This UnwindPlan is sourced from the compiler: "); - switch (m_plan_is_sourced_from_compiler) - { - case eLazyBoolYes: - s.Printf ("yes.\n"); - break; - case eLazyBoolNo: - s.Printf ("no.\n"); - break; - case eLazyBoolCalculate: - s.Printf ("not specified.\n"); - break; - } - s.Printf ("This UnwindPlan is valid at all instruction locations: "); - switch (m_plan_is_valid_at_all_instruction_locations) - { - case eLazyBoolYes: - s.Printf ("yes.\n"); - break; - case eLazyBoolNo: - s.Printf ("no.\n"); - break; - case eLazyBoolCalculate: - s.Printf ("not specified.\n"); - break; - } - if (m_plan_valid_address_range.GetBaseAddress().IsValid() && m_plan_valid_address_range.GetByteSize() > 0) - { - s.PutCString ("Address range of this UnwindPlan: "); - TargetSP target_sp(thread->CalculateTarget()); - m_plan_valid_address_range.Dump (&s, target_sp.get(), Address::DumpStyleSectionNameOffset); - s.EOL(); - } - collection::const_iterator pos, begin = m_row_list.begin(), end = m_row_list.end(); - for (pos = begin; pos != end; ++pos) - { - s.Printf ("row[%u]: ", (uint32_t)std::distance (begin, pos)); - (*pos)->Dump(s, this, thread, base_addr); - } -} + if (!m_plan_valid_address_range.GetBaseAddress().IsValid() || + m_plan_valid_address_range.GetByteSize() == 0) + return true; -void -UnwindPlan::SetSourceName (const char *source) -{ - m_source_name = ConstString (source); -} + if (!addr.IsValid()) + return true; -ConstString -UnwindPlan::GetSourceName () const -{ - return m_source_name; -} + if (m_plan_valid_address_range.ContainsFileAddress(addr)) + return true; -const RegisterInfo * -UnwindPlan::GetRegisterInfo (Thread* thread, uint32_t unwind_reg) const -{ - if (thread) - { - RegisterContext *reg_ctx = thread->GetRegisterContext().get(); - if (reg_ctx) - { - uint32_t reg; - if (m_register_kind == eRegisterKindLLDB) - reg = unwind_reg; - else - reg = reg_ctx->ConvertRegisterKindToRegisterNumber (m_register_kind, unwind_reg); - if (reg != LLDB_INVALID_REGNUM) - return reg_ctx->GetRegisterInfoAtIndex (reg); - } + return false; +} + +void UnwindPlan::Dump(Stream &s, Thread *thread, lldb::addr_t base_addr) const { + if (!m_source_name.IsEmpty()) { + s.Printf("This UnwindPlan originally sourced from %s\n", + m_source_name.GetCString()); + } + if (m_lsda_address.IsValid() && m_personality_func_addr.IsValid()) { + TargetSP target_sp(thread->CalculateTarget()); + addr_t lsda_load_addr = m_lsda_address.GetLoadAddress(target_sp.get()); + addr_t personality_func_load_addr = + m_personality_func_addr.GetLoadAddress(target_sp.get()); + + if (lsda_load_addr != LLDB_INVALID_ADDRESS && + personality_func_load_addr != LLDB_INVALID_ADDRESS) { + s.Printf("LSDA address 0x%" PRIx64 + ", personality routine is at address 0x%" PRIx64 "\n", + lsda_load_addr, personality_func_load_addr); + } + } + s.Printf("This UnwindPlan is sourced from the compiler: "); + switch (m_plan_is_sourced_from_compiler) { + case eLazyBoolYes: + s.Printf("yes.\n"); + break; + case eLazyBoolNo: + s.Printf("no.\n"); + break; + case eLazyBoolCalculate: + s.Printf("not specified.\n"); + break; + } + s.Printf("This UnwindPlan is valid at all instruction locations: "); + switch (m_plan_is_valid_at_all_instruction_locations) { + case eLazyBoolYes: + s.Printf("yes.\n"); + break; + case eLazyBoolNo: + s.Printf("no.\n"); + break; + case eLazyBoolCalculate: + s.Printf("not specified.\n"); + break; + } + if (m_plan_valid_address_range.GetBaseAddress().IsValid() && + m_plan_valid_address_range.GetByteSize() > 0) { + s.PutCString("Address range of this UnwindPlan: "); + TargetSP target_sp(thread->CalculateTarget()); + m_plan_valid_address_range.Dump(&s, target_sp.get(), + Address::DumpStyleSectionNameOffset); + s.EOL(); + } + collection::const_iterator pos, begin = m_row_list.begin(), + end = m_row_list.end(); + for (pos = begin; pos != end; ++pos) { + s.Printf("row[%u]: ", (uint32_t)std::distance(begin, pos)); + (*pos)->Dump(s, this, thread, base_addr); + } +} + +void UnwindPlan::SetSourceName(const char *source) { + m_source_name = ConstString(source); +} + +ConstString UnwindPlan::GetSourceName() const { return m_source_name; } + +const RegisterInfo *UnwindPlan::GetRegisterInfo(Thread *thread, + uint32_t unwind_reg) const { + if (thread) { + RegisterContext *reg_ctx = thread->GetRegisterContext().get(); + if (reg_ctx) { + uint32_t reg; + if (m_register_kind == eRegisterKindLLDB) + reg = unwind_reg; + else + reg = reg_ctx->ConvertRegisterKindToRegisterNumber(m_register_kind, + unwind_reg); + if (reg != LLDB_INVALID_REGNUM) + return reg_ctx->GetRegisterInfoAtIndex(reg); } - return nullptr; + } + return nullptr; } - |