summaryrefslogtreecommitdiffstats
path: root/llvm/lib/DebugInfo
diff options
context:
space:
mode:
authorGeorge Rimar <grimar@accesssoftek.com>2018-10-25 10:56:44 +0000
committerGeorge Rimar <grimar@accesssoftek.com>2018-10-25 10:56:44 +0000
commit581fc63dc05041e9c17445a1e55b59e6dfb431ee (patch)
tree286be52d342883ecc9fde77611a13b18d8dc85da /llvm/lib/DebugInfo
parent071e82218f505396535b2d4abcf008117feb5685 (diff)
downloadbcm5719-llvm-581fc63dc05041e9c17445a1e55b59e6dfb431ee.tar.gz
bcm5719-llvm-581fc63dc05041e9c17445a1e55b59e6dfb431ee.zip
[llvm-dwarfdump] - Fix incorrect parsing of the DW_LLE_startx_length
As was already mentioned in comments for D53364, DWARF 5 spec says about DW_LLE_startx_length: "This is a form of bounded location description that has two unsigned ULEB operands. The first value is an address index (into the .debug_addr section) that indicates the beginning of the address range over which the location is valid. The second value is the length of the range. ") Currently, the length is always parsed as U32. Patch change the behavior to parse DW_LLE_startx_length as ULEB128 for DWARF 5 and keeps it as U32 for DWARF4+(pre-DWARF5) for compatibility. Differential revision: https://reviews.llvm.org/D53564 llvm-svn: 345254
Diffstat (limited to 'llvm/lib/DebugInfo')
-rw-r--r--llvm/lib/DebugInfo/DWARF/DWARFContext.cpp7
-rw-r--r--llvm/lib/DebugInfo/DWARF/DWARFDebugLoc.cpp14
-rw-r--r--llvm/lib/DebugInfo/DWARF/DWARFDie.cpp12
3 files changed, 25 insertions, 8 deletions
diff --git a/llvm/lib/DebugInfo/DWARF/DWARFContext.cpp b/llvm/lib/DebugInfo/DWARF/DWARFContext.cpp
index 1f3753809a2..a29c9c2f160 100644
--- a/llvm/lib/DebugInfo/DWARF/DWARFContext.cpp
+++ b/llvm/lib/DebugInfo/DWARF/DWARFContext.cpp
@@ -309,7 +309,7 @@ static void dumpLoclistsSection(raw_ostream &OS, DIDumpOptions DumpOpts,
DataExtractor LocData(Data.getData().drop_front(Offset),
Data.isLittleEndian(), Header.getAddrSize());
- Loclists.parse(LocData);
+ Loclists.parse(LocData, Header.getVersion());
Loclists.dump(OS, 0, MRI, DumpOffset);
}
@@ -732,7 +732,10 @@ const DWARFDebugLoclists *DWARFContext::getDebugLocDWO() {
// FIXME: We don't need AddressSize for split DWARF since relocatable
// addresses cannot appear there. At the moment DWARFExpression requires it.
DataExtractor LocData(DObj->getLocDWOSection().Data, isLittleEndian(), 4);
- LocDWO->parse(LocData);
+ // Use version 4. DWO does not support the DWARF v5 .debug_loclists yet and
+ // that means we are parsing the new style .debug_loc (pre-standatized version
+ // of the .debug_loclists).
+ LocDWO->parse(LocData, 4 /* Version */);
return LocDWO.get();
}
diff --git a/llvm/lib/DebugInfo/DWARF/DWARFDebugLoc.cpp b/llvm/lib/DebugInfo/DWARF/DWARFDebugLoc.cpp
index b4bdaaac0c2..044a0243360 100644
--- a/llvm/lib/DebugInfo/DWARF/DWARFDebugLoc.cpp
+++ b/llvm/lib/DebugInfo/DWARF/DWARFDebugLoc.cpp
@@ -145,7 +145,8 @@ void DWARFDebugLoc::parse(const DWARFDataExtractor &data) {
}
Optional<DWARFDebugLoclists::LocationList>
-DWARFDebugLoclists::parseOneLocationList(DataExtractor Data, unsigned *Offset) {
+DWARFDebugLoclists::parseOneLocationList(DataExtractor Data, unsigned *Offset,
+ unsigned Version) {
LocationList LL;
LL.Offset = *Offset;
@@ -158,7 +159,12 @@ DWARFDebugLoclists::parseOneLocationList(DataExtractor Data, unsigned *Offset) {
switch (Kind) {
case dwarf::DW_LLE_startx_length:
E.Value0 = Data.getULEB128(Offset);
- E.Value1 = Data.getU32(Offset);
+ // Pre-DWARF 5 has different interpretation of the length field. We have
+ // to support both pre- and standartized styles for the compatibility.
+ if (Version < 5)
+ E.Value1 = Data.getU32(Offset);
+ else
+ E.Value1 = Data.getULEB128(Offset);
break;
case dwarf::DW_LLE_start_length:
E.Value0 = Data.getAddress(Offset);
@@ -189,13 +195,13 @@ DWARFDebugLoclists::parseOneLocationList(DataExtractor Data, unsigned *Offset) {
return LL;
}
-void DWARFDebugLoclists::parse(DataExtractor data) {
+void DWARFDebugLoclists::parse(DataExtractor data, unsigned Version) {
IsLittleEndian = data.isLittleEndian();
AddressSize = data.getAddressSize();
uint32_t Offset = 0;
while (data.isValidOffset(Offset)) {
- if (auto LL = parseOneLocationList(data, &Offset))
+ if (auto LL = parseOneLocationList(data, &Offset, Version))
Locations.push_back(std::move(*LL));
else
return;
diff --git a/llvm/lib/DebugInfo/DWARF/DWARFDie.cpp b/llvm/lib/DebugInfo/DWARF/DWARFDie.cpp
index 76430b41f18..31c4cd5e472 100644
--- a/llvm/lib/DebugInfo/DWARF/DWARFDie.cpp
+++ b/llvm/lib/DebugInfo/DWARF/DWARFDie.cpp
@@ -118,12 +118,20 @@ static void dumpLocation(raw_ostream &OS, DWARFFormValue &FormValue,
return;
}
+ bool UseLocLists = !U->isDWOUnit();
StringRef LoclistsSectionData =
- U->isDWOUnit() ? U->getLocSectionData() : Obj.getLoclistsSection().Data;
+ UseLocLists ? Obj.getLoclistsSection().Data : U->getLocSectionData();
+
if (!LoclistsSectionData.empty()) {
DataExtractor Data(LoclistsSectionData, Ctx.isLittleEndian(),
Obj.getAddressSize());
- auto LL = DWARFDebugLoclists::parseOneLocationList(Data, &Offset);
+
+ // Old-style location list were used in DWARF v4 (.debug_loc.dwo section).
+ // Modern locations list (.debug_loclists) are used starting from v5.
+ // Ideally we should take the version from the .debug_loclists section
+ // header, but using CU's version for simplicity.
+ auto LL = DWARFDebugLoclists::parseOneLocationList(
+ Data, &Offset, UseLocLists ? U->getVersion() : 4);
uint64_t BaseAddr = 0;
if (Optional<SectionedAddress> BA = U->getBaseAddress())
OpenPOWER on IntegriCloud