summaryrefslogtreecommitdiffstats
path: root/llvm/lib
diff options
context:
space:
mode:
authorGeorge Rimar <grimar@accesssoftek.com>2017-09-04 10:30:39 +0000
committerGeorge Rimar <grimar@accesssoftek.com>2017-09-04 10:30:39 +0000
commit2f95c8bccb73cb4d292a2c4e3704887da3414394 (patch)
tree8a825101811f635e11bca7d99282a48a8da26c34 /llvm/lib
parent8703e3838068156b2e0ff80b218bf854a7eba84e (diff)
downloadbcm5719-llvm-2f95c8bccb73cb4d292a2c4e3704887da3414394.tar.gz
bcm5719-llvm-2f95c8bccb73cb4d292a2c4e3704887da3414394.zip
[DebugInfo] - Fix for lld DWARF parsing of base address selection entries in range lists.
It solves issue of wrong section index evaluating for ranges when base address is used. Based on David Blaikie's patch D36097. Differential revision: https://reviews.llvm.org/D37214 llvm-svn: 312477
Diffstat (limited to 'llvm/lib')
-rw-r--r--llvm/lib/DebugInfo/DWARF/DWARFDataExtractor.cpp2
-rw-r--r--llvm/lib/DebugInfo/DWARF/DWARFDebugRangeList.cpp25
-rw-r--r--llvm/lib/DebugInfo/DWARF/DWARFUnit.cpp9
3 files changed, 26 insertions, 10 deletions
diff --git a/llvm/lib/DebugInfo/DWARF/DWARFDataExtractor.cpp b/llvm/lib/DebugInfo/DWARF/DWARFDataExtractor.cpp
index a40635568cd..861dd313fb0 100644
--- a/llvm/lib/DebugInfo/DWARF/DWARFDataExtractor.cpp
+++ b/llvm/lib/DebugInfo/DWARF/DWARFDataExtractor.cpp
@@ -14,6 +14,8 @@ using namespace llvm;
uint64_t DWARFDataExtractor::getRelocatedValue(uint32_t Size, uint32_t *Off,
uint64_t *SecNdx) const {
+ if (SecNdx)
+ *SecNdx = -1ULL;
if (!Section)
return getUnsigned(Off, Size);
Optional<RelocAddrEntry> Rel = Obj->find(*Section, *Off);
diff --git a/llvm/lib/DebugInfo/DWARF/DWARFDebugRangeList.cpp b/llvm/lib/DebugInfo/DWARF/DWARFDebugRangeList.cpp
index aa1f17934b5..62bd5af4e64 100644
--- a/llvm/lib/DebugInfo/DWARF/DWARFDebugRangeList.cpp
+++ b/llvm/lib/DebugInfo/DWARF/DWARFDebugRangeList.cpp
@@ -63,16 +63,29 @@ void DWARFDebugRangeList::dump(raw_ostream &OS) const {
OS << format("%08x <End of list>\n", Offset);
}
-DWARFAddressRangesVector
-DWARFDebugRangeList::getAbsoluteRanges(uint64_t BaseAddress) const {
+DWARFAddressRangesVector DWARFDebugRangeList::getAbsoluteRanges(
+ llvm::Optional<BaseAddress> BaseAddr) const {
DWARFAddressRangesVector Res;
for (const RangeListEntry &RLE : Entries) {
if (RLE.isBaseAddressSelectionEntry(AddressSize)) {
- BaseAddress = RLE.EndAddress;
- } else {
- Res.push_back({BaseAddress + RLE.StartAddress,
- BaseAddress + RLE.EndAddress, RLE.SectionIndex});
+ BaseAddr = {RLE.EndAddress, RLE.SectionIndex};
+ continue;
}
+
+ DWARFAddressRange E;
+ E.LowPC = RLE.StartAddress;
+ E.HighPC = RLE.EndAddress;
+ E.SectionIndex = RLE.SectionIndex;
+ // Base address of a range list entry is determined by the closest preceding
+ // base address selection entry in the same range list. It defaults to the
+ // base address of the compilation unit if there is no such entry.
+ if (BaseAddr) {
+ E.LowPC += BaseAddr->Address;
+ E.HighPC += BaseAddr->Address;
+ if (E.SectionIndex == -1ULL)
+ E.SectionIndex = BaseAddr->SectionIndex;
+ }
+ Res.push_back(E);
}
return Res;
}
diff --git a/llvm/lib/DebugInfo/DWARF/DWARFUnit.cpp b/llvm/lib/DebugInfo/DWARF/DWARFUnit.cpp
index 5b0b3f65f6c..813960ca95d 100644
--- a/llvm/lib/DebugInfo/DWARF/DWARFUnit.cpp
+++ b/llvm/lib/DebugInfo/DWARF/DWARFUnit.cpp
@@ -160,7 +160,7 @@ void DWARFUnit::clear() {
Length = 0;
Abbrevs = nullptr;
FormParams = DWARFFormParams({0, 0, DWARF32});
- BaseAddr = 0;
+ BaseAddr.reset();
RangeSectionBase = 0;
AddrOffsetSectionBase = 0;
clearDIEs(false);
@@ -242,9 +242,10 @@ size_t DWARFUnit::extractDIEsIfNeeded(bool CUDieOnly) {
// If CU DIE was just parsed, copy several attribute values from it.
if (!HasCUDie) {
DWARFDie UnitDie = getUnitDIE();
- auto BaseAddr = toAddress(UnitDie.find({DW_AT_low_pc, DW_AT_entry_pc}));
- if (BaseAddr)
- setBaseAddress(*BaseAddr);
+ Optional<DWARFFormValue> PC = UnitDie.find({DW_AT_low_pc, DW_AT_entry_pc});
+ if (Optional<uint64_t> Addr = toAddress(PC))
+ setBaseAddress({*Addr, PC->getSectionIndex()});
+
if (!isDWO) {
assert(AddrOffsetSectionBase == 0);
assert(RangeSectionBase == 0);
OpenPOWER on IntegriCloud