summaryrefslogtreecommitdiffstats
path: root/lldb/source/Plugins/SymbolFile
diff options
context:
space:
mode:
Diffstat (limited to 'lldb/source/Plugins/SymbolFile')
-rw-r--r--lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugInfoEntry.cpp9
-rw-r--r--lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugInfoEntry.h6
-rw-r--r--lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugRanges.cpp161
-rw-r--r--lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugRanges.h23
-rw-r--r--lldb/source/Plugins/SymbolFile/DWARF/DWARFUnit.cpp98
-rw-r--r--lldb/source/Plugins/SymbolFile/DWARF/DWARFUnit.h18
-rw-r--r--lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp15
-rw-r--r--lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h3
8 files changed, 103 insertions, 230 deletions
diff --git a/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugInfoEntry.cpp b/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugInfoEntry.cpp
index 8c0fbeb4b71..1bab4e9db63 100644
--- a/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugInfoEntry.cpp
+++ b/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugInfoEntry.cpp
@@ -200,7 +200,7 @@ bool DWARFDebugInfoEntry::Extract(const DWARFDataExtractor &data,
return false;
}
-static DWARFRangeList GetRangesOrReportError(const DWARFUnit &unit,
+static DWARFRangeList GetRangesOrReportError(DWARFUnit &unit,
const DWARFDebugInfoEntry &die,
const DWARFFormValue &value) {
llvm::Expected<DWARFRangeList> expected_ranges =
@@ -223,7 +223,7 @@ static DWARFRangeList GetRangesOrReportError(const DWARFUnit &unit,
// Gets the valid address ranges for a given DIE by looking for a
// DW_AT_low_pc/DW_AT_high_pc pair, DW_AT_entry_pc, or DW_AT_ranges attributes.
bool DWARFDebugInfoEntry::GetDIENamesAndRanges(
- const DWARFUnit *cu, const char *&name, const char *&mangled,
+ DWARFUnit *cu, const char *&name, const char *&mangled,
DWARFRangeList &ranges, int &decl_file, int &decl_line, int &decl_column,
int &call_file, int &call_line, int &call_column,
DWARFExpression *frame_base) const {
@@ -766,7 +766,7 @@ bool DWARFDebugInfoEntry::GetAttributeAddressRange(
}
size_t DWARFDebugInfoEntry::GetAttributeAddressRanges(
- const DWARFUnit *cu, DWARFRangeList &ranges, bool check_hi_lo_pc,
+ DWARFUnit *cu, DWARFRangeList &ranges, bool check_hi_lo_pc,
bool check_specification_or_abstract_origin) const {
ranges.Clear();
@@ -1012,8 +1012,7 @@ DWARFDebugInfoEntry::GetQualifiedName(DWARFUnit *cu,
return storage.c_str();
}
-bool DWARFDebugInfoEntry::LookupAddress(const dw_addr_t address,
- const DWARFUnit *cu,
+bool DWARFDebugInfoEntry::LookupAddress(const dw_addr_t address, DWARFUnit *cu,
DWARFDebugInfoEntry **function_die,
DWARFDebugInfoEntry **block_die) {
bool found_address = false;
diff --git a/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugInfoEntry.h b/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugInfoEntry.h
index f3952ae9598..f35af6e7d49 100644
--- a/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugInfoEntry.h
+++ b/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugInfoEntry.h
@@ -50,7 +50,7 @@ public:
bool Extract(const lldb_private::DWARFDataExtractor &data,
const DWARFUnit *cu, lldb::offset_t *offset_ptr);
- bool LookupAddress(const dw_addr_t address, const DWARFUnit *cu,
+ bool LookupAddress(const dw_addr_t address, DWARFUnit *cu,
DWARFDebugInfoEntry **function_die,
DWARFDebugInfoEntry **block_die);
@@ -91,7 +91,7 @@ public:
bool check_specification_or_abstract_origin = false) const;
size_t GetAttributeAddressRanges(
- const DWARFUnit *cu, DWARFRangeList &ranges, bool check_hi_lo_pc,
+ DWARFUnit *cu, DWARFRangeList &ranges, bool check_hi_lo_pc,
bool check_specification_or_abstract_origin = false) const;
const char *GetName(const DWARFUnit *cu) const;
@@ -116,7 +116,7 @@ public:
dw_attr_t attr, DWARFFormValue &form_value);
bool GetDIENamesAndRanges(
- const DWARFUnit *cu, const char *&name, const char *&mangled,
+ DWARFUnit *cu, const char *&name, const char *&mangled,
DWARFRangeList &rangeList, int &decl_file, int &decl_line,
int &decl_column, int &call_file, int &call_line, int &call_column,
lldb_private::DWARFExpression *frame_base = nullptr) const;
diff --git a/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugRanges.cpp b/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugRanges.cpp
index 0b08fa09f90..3b344f45091 100644
--- a/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugRanges.cpp
+++ b/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugRanges.cpp
@@ -122,164 +122,3 @@ bool DWARFDebugRanges::FindRanges(const DWARFUnit *cu,
}
return false;
}
-
-bool DWARFDebugRngLists::ExtractRangeList(
- const DWARFDataExtractor &data, uint8_t addrSize,
- lldb::offset_t *offset_ptr, std::vector<RngListEntry> &rangeList) {
- rangeList.clear();
-
- bool error = false;
- while (!error) {
- switch (data.GetU8(offset_ptr)) {
- case DW_RLE_end_of_list:
- return true;
-
- case DW_RLE_start_length: {
- dw_addr_t begin = data.GetMaxU64(offset_ptr, addrSize);
- dw_addr_t len = data.GetULEB128(offset_ptr);
- rangeList.push_back({DW_RLE_start_length, begin, len});
- break;
- }
-
- case DW_RLE_start_end: {
- dw_addr_t begin = data.GetMaxU64(offset_ptr, addrSize);
- dw_addr_t end = data.GetMaxU64(offset_ptr, addrSize);
- rangeList.push_back({DW_RLE_start_end, begin, end});
- break;
- }
-
- case DW_RLE_base_address: {
- dw_addr_t base = data.GetMaxU64(offset_ptr, addrSize);
- rangeList.push_back({DW_RLE_base_address, base, 0});
- break;
- }
-
- case DW_RLE_offset_pair: {
- dw_addr_t begin = data.GetULEB128(offset_ptr);
- dw_addr_t end = data.GetULEB128(offset_ptr);
- rangeList.push_back({DW_RLE_offset_pair, begin, end});
- break;
- }
-
- case DW_RLE_base_addressx: {
- dw_addr_t base = data.GetULEB128(offset_ptr);
- rangeList.push_back({DW_RLE_base_addressx, base, 0});
- break;
- }
-
- case DW_RLE_startx_endx: {
- dw_addr_t start = data.GetULEB128(offset_ptr);
- dw_addr_t end = data.GetULEB128(offset_ptr);
- rangeList.push_back({DW_RLE_startx_endx, start, end});
- break;
- }
-
- case DW_RLE_startx_length: {
- dw_addr_t start = data.GetULEB128(offset_ptr);
- dw_addr_t length = data.GetULEB128(offset_ptr);
- rangeList.push_back({DW_RLE_startx_length, start, length});
- break;
- }
-
- default:
- lldbassert(0 && "unknown range list entry encoding");
- error = true;
- }
- }
-
- return false;
-}
-
-static uint64_t ReadAddressFromDebugAddrSection(const DWARFUnit *cu,
- uint32_t index) {
- uint32_t index_size = cu->GetAddressByteSize();
- dw_offset_t addr_base = cu->GetAddrBase();
- lldb::offset_t offset = addr_base + index * index_size;
- return cu->GetSymbolFileDWARF()
- .GetDWARFContext()
- .getOrLoadAddrData()
- .GetMaxU64(&offset, index_size);
-}
-
-bool DWARFDebugRngLists::FindRanges(const DWARFUnit *cu,
- dw_offset_t debug_ranges_offset,
- DWARFRangeList &range_list) const {
- range_list.Clear();
- dw_addr_t debug_ranges_address = cu->GetRangesBase() + debug_ranges_offset;
- auto pos = m_range_map.find(debug_ranges_address);
- if (pos != m_range_map.end()) {
- dw_addr_t BaseAddr = cu->GetBaseAddress();
- for (const RngListEntry &E : pos->second) {
- switch (E.encoding) {
- case DW_RLE_start_length:
- range_list.Append(DWARFRangeList::Entry(E.value0, E.value1));
- break;
- case DW_RLE_base_address:
- BaseAddr = E.value0;
- break;
- case DW_RLE_start_end:
- range_list.Append(DWARFRangeList::Entry(E.value0, E.value1 - E.value0));
- break;
- case DW_RLE_offset_pair:
- range_list.Append(
- DWARFRangeList::Entry(BaseAddr + E.value0, E.value1 - E.value0));
- break;
- case DW_RLE_base_addressx: {
- BaseAddr = ReadAddressFromDebugAddrSection(cu, E.value0);
- break;
- }
- case DW_RLE_startx_endx: {
- dw_addr_t start = ReadAddressFromDebugAddrSection(cu, E.value0);
- dw_addr_t end = ReadAddressFromDebugAddrSection(cu, E.value1);
- range_list.Append(DWARFRangeList::Entry(start, end - start));
- break;
- }
- case DW_RLE_startx_length: {
- dw_addr_t start = ReadAddressFromDebugAddrSection(cu, E.value0);
- range_list.Append(DWARFRangeList::Entry(start, E.value1));
- break;
- }
- default:
- llvm_unreachable("unexpected encoding");
- }
- }
- return true;
- }
- return false;
-}
-
-void DWARFDebugRngLists::Extract(DWARFContext &context) {
- const DWARFDataExtractor &data = context.getOrLoadRngListsData();
- lldb::offset_t offset = 0;
-
- uint64_t length = data.GetU32(&offset);
- // FIXME: Handle DWARF64.
- lldb::offset_t end = offset + length;
-
- // Check version.
- if (data.GetU16(&offset) < 5)
- return;
-
- uint8_t addrSize = data.GetU8(&offset);
-
- // We do not support non-zero segment selector size.
- if (data.GetU8(&offset) != 0) {
- lldbassert(0 && "not implemented");
- return;
- }
-
- uint32_t offsetsAmount = data.GetU32(&offset);
- for (uint32_t i = 0; i < offsetsAmount; ++i)
- Offsets.push_back(data.GetMaxU64(&offset, 4));
-
- lldb::offset_t listOffset = offset;
- std::vector<RngListEntry> rangeList;
- while (offset < end && ExtractRangeList(data, addrSize, &offset, rangeList)) {
- m_range_map[listOffset] = rangeList;
- listOffset = offset;
- }
-}
-
-uint64_t DWARFDebugRngLists::GetOffset(size_t Index) const {
- return Offsets[Index];
-}
diff --git a/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugRanges.h b/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugRanges.h
index c398259056b..99ef04d7ee2 100644
--- a/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugRanges.h
+++ b/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugRanges.h
@@ -48,27 +48,4 @@ protected:
range_map m_range_map;
};
-// DWARF v5 .debug_rnglists section.
-class DWARFDebugRngLists final : public DWARFDebugRangesBase {
- struct RngListEntry {
- uint8_t encoding;
- uint64_t value0;
- uint64_t value1;
- };
-
-public:
- void Extract(lldb_private::DWARFContext &context) override;
- bool FindRanges(const DWARFUnit *cu, dw_offset_t debug_ranges_offset,
- DWARFRangeList &range_list) const override;
- uint64_t GetOffset(size_t Index) const;
-
-protected:
- bool ExtractRangeList(const lldb_private::DWARFDataExtractor &data,
- uint8_t addrSize, lldb::offset_t *offset_ptr,
- std::vector<RngListEntry> &list);
-
- std::vector<uint64_t> Offsets;
- std::map<dw_offset_t, std::vector<RngListEntry>> m_range_map;
-};
-
#endif // SymbolFileDWARF_DWARFDebugRanges_h_
diff --git a/lldb/source/Plugins/SymbolFile/DWARF/DWARFUnit.cpp b/lldb/source/Plugins/SymbolFile/DWARF/DWARFUnit.cpp
index 9964cf4b893..71375da844d 100644
--- a/lldb/source/Plugins/SymbolFile/DWARF/DWARFUnit.cpp
+++ b/lldb/source/Plugins/SymbolFile/DWARF/DWARFUnit.cpp
@@ -417,8 +417,44 @@ dw_offset_t DWARFUnit::GetLineTableOffset() {
void DWARFUnit::SetAddrBase(dw_addr_t addr_base) { m_addr_base = addr_base; }
+// Parse the rangelist table header, including the optional array of offsets
+// following it (DWARF v5 and later).
+template <typename ListTableType>
+static llvm::Expected<ListTableType>
+ParseListTableHeader(const llvm::DWARFDataExtractor &data, uint64_t offset,
+ DwarfFormat format) {
+ // We are expected to be called with Offset 0 or pointing just past the table
+ // header. Correct Offset in the latter case so that it points to the start
+ // of the header.
+ if (offset > 0) {
+ uint64_t HeaderSize = llvm::DWARFListTableHeader::getHeaderSize(format);
+ if (offset < HeaderSize)
+ return llvm::createStringError(errc::invalid_argument,
+ "did not detect a valid"
+ " list table with base = 0x%" PRIx64 "\n",
+ offset);
+ offset -= HeaderSize;
+ }
+ ListTableType Table;
+ if (llvm::Error E = Table.extractHeaderAndOffsets(data, &offset))
+ return std::move(E);
+ return Table;
+}
+
void DWARFUnit::SetRangesBase(dw_addr_t ranges_base) {
m_ranges_base = ranges_base;
+
+ if (GetVersion() < 5)
+ return;
+
+ if (auto table_or_error = ParseListTableHeader<llvm::DWARFDebugRnglistTable>(
+ m_dwarf.GetDWARFContext().getOrLoadRngListsData().GetAsLLVM(),
+ ranges_base, DWARF32))
+ m_rnglist_table = std::move(table_or_error.get());
+ else
+ GetSymbolFileDWARF().GetObjectFile()->GetModule()->ReportError(
+ "Failed to extract range list table at offset 0x%" PRIx64 ": %s",
+ ranges_base, toString(table_or_error.takeError()).c_str());
}
void DWARFUnit::SetStrOffsetsBase(dw_offset_t str_offsets_base) {
@@ -845,30 +881,56 @@ uint32_t DWARFUnit::GetHeaderByteSize() const {
}
llvm::Expected<DWARFRangeList>
-DWARFUnit::FindRnglistFromOffset(dw_offset_t offset) const {
- const DWARFDebugRangesBase *debug_ranges;
- llvm::StringRef section;
+DWARFUnit::FindRnglistFromOffset(dw_offset_t offset) {
if (GetVersion() <= 4) {
- debug_ranges = m_dwarf.GetDebugRanges();
- section = "debug_ranges";
- } else {
- debug_ranges = m_dwarf.GetDebugRngLists();
- section = "debug_rnglists";
+ const DWARFDebugRangesBase *debug_ranges = m_dwarf.GetDebugRanges();
+ if (!debug_ranges)
+ return llvm::make_error<llvm::object::GenericBinaryError>(
+ "No debug_ranges section");
+ DWARFRangeList ranges;
+ debug_ranges->FindRanges(this, offset, ranges);
+ return ranges;
}
- if (!debug_ranges)
- return llvm::make_error<llvm::object::GenericBinaryError>("No " + section +
- " section");
+
+ if (!m_rnglist_table)
+ return llvm::createStringError(errc::invalid_argument,
+ "missing or invalid range list table");
+
+ auto range_list_or_error = m_rnglist_table->findList(
+ m_dwarf.GetDWARFContext().getOrLoadRngListsData().GetAsLLVM(), offset);
+ if (!range_list_or_error)
+ return range_list_or_error.takeError();
+
+ llvm::Expected<llvm::DWARFAddressRangesVector> llvm_ranges =
+ range_list_or_error->getAbsoluteRanges(
+ llvm::object::SectionedAddress{GetBaseAddress()},
+ [&](uint32_t index) {
+ uint32_t index_size = GetAddressByteSize();
+ dw_offset_t addr_base = GetAddrBase();
+ lldb::offset_t offset = addr_base + index * index_size;
+ return llvm::object::SectionedAddress{
+ m_dwarf.GetDWARFContext().getOrLoadAddrData().GetMaxU64(
+ &offset, index_size)};
+ });
+ if (!llvm_ranges)
+ return llvm_ranges.takeError();
DWARFRangeList ranges;
- debug_ranges->FindRanges(this, offset, ranges);
+ for (const llvm::DWARFAddressRange &llvm_range : *llvm_ranges) {
+ ranges.Append(DWARFRangeList::Entry(llvm_range.LowPC,
+ llvm_range.HighPC - llvm_range.LowPC));
+ }
return ranges;
}
llvm::Expected<DWARFRangeList>
-DWARFUnit::FindRnglistFromIndex(uint32_t index) const {
- const DWARFDebugRngLists *debug_rnglists = m_dwarf.GetDebugRngLists();
- if (!debug_rnglists)
- return llvm::make_error<llvm::object::GenericBinaryError>(
- "No debug_rnglists section");
- return FindRnglistFromOffset(debug_rnglists->GetOffset(index));
+DWARFUnit::FindRnglistFromIndex(uint32_t index) {
+ if (llvm::Optional<uint64_t> offset = GetRnglistOffset(index))
+ return FindRnglistFromOffset(*offset);
+ if (m_rnglist_table)
+ return llvm::createStringError(errc::invalid_argument,
+ "invalid range list table index %d", index);
+
+ return llvm::createStringError(errc::invalid_argument,
+ "missing or invalid range list table");
}
diff --git a/lldb/source/Plugins/SymbolFile/DWARF/DWARFUnit.h b/lldb/source/Plugins/SymbolFile/DWARF/DWARFUnit.h
index 87e0de283de..fe64222f8f5 100644
--- a/lldb/source/Plugins/SymbolFile/DWARF/DWARFUnit.h
+++ b/lldb/source/Plugins/SymbolFile/DWARF/DWARFUnit.h
@@ -216,12 +216,23 @@ public:
/// Return a list of address ranges resulting from a (possibly encoded)
/// range list starting at a given offset in the appropriate ranges section.
- llvm::Expected<DWARFRangeList> FindRnglistFromOffset(dw_offset_t offset) const;
+ llvm::Expected<DWARFRangeList> FindRnglistFromOffset(dw_offset_t offset);
/// Return a list of address ranges retrieved from an encoded range
/// list whose offset is found via a table lookup given an index (DWARF v5
/// and later).
- llvm::Expected<DWARFRangeList> FindRnglistFromIndex(uint32_t index) const;
+ llvm::Expected<DWARFRangeList> FindRnglistFromIndex(uint32_t index);
+
+ /// Return a rangelist's offset based on an index. The index designates
+ /// an entry in the rangelist table's offset array and is supplied by
+ /// DW_FORM_rnglistx.
+ llvm::Optional<uint64_t> GetRnglistOffset(uint32_t Index) const {
+ if (!m_rnglist_table)
+ return llvm::None;
+ if (llvm::Optional<uint64_t> off = m_rnglist_table->getOffsetEntry(Index))
+ return *off + m_ranges_base;
+ return llvm::None;
+ }
protected:
DWARFUnit(SymbolFileDWARF &dwarf, lldb::user_id_t uid,
@@ -288,6 +299,9 @@ protected:
dw_offset_t m_line_table_offset = DW_INVALID_OFFSET;
dw_offset_t m_str_offsets_base = 0; // Value of DW_AT_str_offsets_base.
+
+ llvm::Optional<llvm::DWARFDebugRnglistTable> m_rnglist_table;
+
const DIERef::Section m_section;
private:
diff --git a/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp b/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp
index fc8fe30101c..9b9077a450b 100644
--- a/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp
+++ b/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp
@@ -684,21 +684,6 @@ DWARFDebugRanges *SymbolFileDWARF::GetDebugRanges() {
return m_ranges.get();
}
-DWARFDebugRngLists *SymbolFileDWARF::GetDebugRngLists() {
- if (!m_rnglists) {
- static Timer::Category func_cat(LLVM_PRETTY_FUNCTION);
- Timer scoped_timer(func_cat, "%s this = %p", LLVM_PRETTY_FUNCTION,
- static_cast<void *>(this));
-
- if (m_context.getOrLoadRngListsData().GetByteSize() > 0)
- m_rnglists.reset(new DWARFDebugRngLists());
-
- if (m_rnglists)
- m_rnglists->Extract(m_context);
- }
- return m_rnglists.get();
-}
-
lldb::CompUnitSP SymbolFileDWARF::ParseCompileUnit(DWARFCompileUnit &dwarf_cu) {
CompUnitSP cu_sp;
CompileUnit *comp_unit = (CompileUnit *)dwarf_cu.GetUserData();
diff --git a/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h b/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h
index 9e4e4279eec..35b18f4b02b 100644
--- a/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h
+++ b/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h
@@ -47,7 +47,6 @@ class DWARFDebugInfo;
class DWARFDebugInfoEntry;
class DWARFDebugLine;
class DWARFDebugRanges;
-class DWARFDebugRngLists;
class DWARFDeclContext;
class DWARFFormValue;
class DWARFTypeUnit;
@@ -236,7 +235,6 @@ public:
const DWARFDebugInfo *DebugInfo() const;
DWARFDebugRanges *GetDebugRanges();
- DWARFDebugRngLists *GetDebugRngLists();
const lldb_private::DWARFDataExtractor &DebugLocData();
@@ -499,7 +497,6 @@ protected:
typedef llvm::StringMap<DIERefSet> NameToOffsetMap;
NameToOffsetMap m_function_scope_qualified_name_map;
std::unique_ptr<DWARFDebugRanges> m_ranges;
- std::unique_ptr<DWARFDebugRngLists> m_rnglists;
UniqueDWARFASTTypeMap m_unique_ast_type_map;
DIEToTypePtr m_die_to_type;
DIEToVariableSP m_die_to_variable_sp;
OpenPOWER on IntegriCloud