libDebugInfo/DWARF: Apply relocations for debug_addr addresses in object files

llvm-symbolizer would fail to symbolize addresses in unlinked object
files when handling .dwo file data because the addresses would not be
relocated in the same way as the ranges in the skeleton CU in the object
file.

Fix that so object files can be symbolized the same as executables.

llvm-svn: 303532
This commit is contained in:
David Blaikie 2017-05-22 07:02:47 +00:00
parent 036dda25a5
commit d2f3a941e0
9 changed files with 45 additions and 36 deletions

View File

@ -19,8 +19,9 @@ class DWARFCompileUnit : public DWARFUnit {
public:
DWARFCompileUnit(DWARFContext &Context, const DWARFSection &Section,
const DWARFDebugAbbrev *DA, const DWARFSection *RS,
StringRef SS, StringRef SOS, StringRef AOS, StringRef LS,
bool LE, bool IsDWO, const DWARFUnitSectionBase &UnitSection,
StringRef SS, StringRef SOS, const DWARFSection *AOS,
StringRef LS, bool LE, bool IsDWO,
const DWARFUnitSectionBase &UnitSection,
const DWARFUnitIndex::Entry *Entry)
: DWARFUnit(Context, Section, DA, RS, SS, SOS, AOS, LS, LE, IsDWO,
UnitSection, Entry) {}

View File

@ -235,7 +235,7 @@ public:
virtual StringRef getStringDWOSection() = 0;
virtual StringRef getStringOffsetDWOSection() = 0;
virtual const DWARFSection &getRangeDWOSection() = 0;
virtual StringRef getAddrSection() = 0;
virtual const DWARFSection &getAddrSection() = 0;
virtual const DWARFSection& getAppleNamesSection() = 0;
virtual const DWARFSection& getAppleTypesSection() = 0;
virtual const DWARFSection& getAppleNamespacesSection() = 0;
@ -290,7 +290,7 @@ class DWARFContextInMemory : public DWARFContext {
StringRef StringDWOSection;
StringRef StringOffsetDWOSection;
DWARFSection RangeDWOSection;
StringRef AddrSection;
DWARFSection AddrSection;
DWARFSection AppleNamesSection;
DWARFSection AppleTypesSection;
DWARFSection AppleNamespacesSection;
@ -356,9 +356,7 @@ public:
const DWARFSection &getRangeDWOSection() override { return RangeDWOSection; }
StringRef getAddrSection() override {
return AddrSection;
}
const DWARFSection &getAddrSection() override { return AddrSection; }
StringRef getCUIndexSection() override { return CUIndexSection; }
StringRef getGdbIndexSection() override { return GdbIndexSection; }

View File

@ -31,8 +31,9 @@ private:
public:
DWARFTypeUnit(DWARFContext &Context, const DWARFSection &Section,
const DWARFDebugAbbrev *DA, const DWARFSection *RS,
StringRef SS, StringRef SOS, StringRef AOS, StringRef LS,
bool LE, bool IsDWO, const DWARFUnitSectionBase &UnitSection,
StringRef SS, StringRef SOS, const DWARFSection *AOS,
StringRef LS, bool LE, bool IsDWO,
const DWARFUnitSectionBase &UnitSection,
const DWARFUnitIndex::Entry *Entry)
: DWARFUnit(Context, Section, DA, RS, SS, SOS, AOS, LS, LE, IsDWO,
UnitSection, Entry) {}

View File

@ -57,7 +57,7 @@ protected:
virtual void parseImpl(DWARFContext &Context, const DWARFSection &Section,
const DWARFDebugAbbrev *DA, const DWARFSection *RS,
StringRef SS, StringRef SOS, StringRef AOS,
StringRef SS, StringRef SOS, const DWARFSection *AOS,
StringRef LS, bool isLittleEndian, bool isDWO) = 0;
};
@ -89,8 +89,8 @@ public:
private:
void parseImpl(DWARFContext &Context, const DWARFSection &Section,
const DWARFDebugAbbrev *DA, const DWARFSection *RS,
StringRef SS, StringRef SOS, StringRef AOS, StringRef LS,
bool LE, bool IsDWO) override {
StringRef SS, StringRef SOS, const DWARFSection *AOS,
StringRef LS, bool LE, bool IsDWO) override {
if (Parsed)
return;
const auto &Index = getDWARFUnitIndex(Context, UnitType::Section);
@ -120,7 +120,7 @@ class DWARFUnit {
StringRef LineSection;
StringRef StringSection;
StringRef StringOffsetSection;
StringRef AddrOffsetSection;
const DWARFSection *AddrOffsetSection;
uint32_t AddrOffsetSectionBase;
bool isLittleEndian;
bool isDWO;
@ -172,8 +172,8 @@ protected:
public:
DWARFUnit(DWARFContext &Context, const DWARFSection &Section,
const DWARFDebugAbbrev *DA, const DWARFSection *RS, StringRef SS,
StringRef SOS, StringRef AOS, StringRef LS, bool LE, bool IsDWO,
const DWARFUnitSectionBase &UnitSection,
StringRef SOS, const DWARFSection *AOS, StringRef LS, bool LE,
bool IsDWO, const DWARFUnitSectionBase &UnitSection,
const DWARFUnitIndex::Entry *IndexEntry = nullptr);
virtual ~DWARFUnit();
@ -184,7 +184,7 @@ public:
StringRef getStringSection() const { return StringSection; }
StringRef getStringOffsetSection() const { return StringOffsetSection; }
void setAddrOffsetSection(StringRef AOS, uint32_t Base) {
void setAddrOffsetSection(const DWARFSection *AOS, uint32_t Base) {
AddrOffsetSection = AOS;
AddrOffsetSectionBase = Base;
}

View File

@ -1063,18 +1063,20 @@ DWARFContextInMemory::DWARFContextInMemory(const object::ObjectFile &Obj,
// TODO: Add support for relocations in other sections as needed.
// Record relocations for the debug_info and debug_line sections.
RelocAddrMap *Map = StringSwitch<RelocAddrMap*>(RelSecName)
.Case("debug_info", &InfoSection.Relocs)
.Case("debug_loc", &LocSection.Relocs)
.Case("debug_info.dwo", &InfoDWOSection.Relocs)
.Case("debug_line", &LineSection.Relocs)
.Case("debug_ranges", &RangeSection.Relocs)
.Case("apple_names", &AppleNamesSection.Relocs)
.Case("apple_types", &AppleTypesSection.Relocs)
.Case("apple_namespaces", &AppleNamespacesSection.Relocs)
.Case("apple_namespac", &AppleNamespacesSection.Relocs)
.Case("apple_objc", &AppleObjCSection.Relocs)
.Default(nullptr);
RelocAddrMap *Map =
StringSwitch<RelocAddrMap *>(RelSecName)
.Case("debug_info", &InfoSection.Relocs)
.Case("debug_loc", &LocSection.Relocs)
.Case("debug_info.dwo", &InfoDWOSection.Relocs)
.Case("debug_line", &LineSection.Relocs)
.Case("debug_ranges", &RangeSection.Relocs)
.Case("debug_addr", &AddrSection.Relocs)
.Case("apple_names", &AppleNamesSection.Relocs)
.Case("apple_types", &AppleTypesSection.Relocs)
.Case("apple_namespaces", &AppleNamespacesSection.Relocs)
.Case("apple_namespac", &AppleNamespacesSection.Relocs)
.Case("apple_objc", &AppleObjCSection.Relocs)
.Default(nullptr);
if (!Map) {
// Find debug_types relocs by section rather than name as there are
// multiple, comdat grouped, debug_types sections.
@ -1148,7 +1150,7 @@ StringRef *DWARFContextInMemory::MapSectionToMember(StringRef Name) {
.Case("debug_line.dwo", &LineDWOSection.Data)
.Case("debug_str.dwo", &StringDWOSection)
.Case("debug_str_offsets.dwo", &StringOffsetDWOSection)
.Case("debug_addr", &AddrSection)
.Case("debug_addr", &AddrSection.Data)
.Case("apple_names", &AppleNamesSection.Data)
.Case("apple_types", &AppleTypesSection.Data)
.Case("apple_namespaces", &AppleNamespacesSection.Data)

View File

@ -33,7 +33,7 @@ using namespace dwarf;
void DWARFUnitSectionBase::parse(DWARFContext &C, const DWARFSection &Section) {
parseImpl(C, Section, C.getDebugAbbrev(), &C.getRangeSection(),
C.getStringSection(), StringRef(), C.getAddrSection(),
C.getStringSection(), StringRef(), &C.getAddrSection(),
C.getLineSection().Data, C.isLittleEndian(), false);
}
@ -42,14 +42,14 @@ void DWARFUnitSectionBase::parseDWO(DWARFContext &C,
DWARFUnitIndex *Index) {
parseImpl(C, DWOSection, C.getDebugAbbrevDWO(), &C.getRangeDWOSection(),
C.getStringDWOSection(), C.getStringOffsetDWOSection(),
C.getAddrSection(), C.getLineDWOSection().Data, C.isLittleEndian(),
&C.getAddrSection(), C.getLineDWOSection().Data, C.isLittleEndian(),
true);
}
DWARFUnit::DWARFUnit(DWARFContext &DC, const DWARFSection &Section,
const DWARFDebugAbbrev *DA, const DWARFSection *RS,
StringRef SS, StringRef SOS, StringRef AOS, StringRef LS,
bool LE, bool IsDWO,
StringRef SS, StringRef SOS, const DWARFSection *AOS,
StringRef LS, bool LE, bool IsDWO,
const DWARFUnitSectionBase &UnitSection,
const DWARFUnitIndex::Entry *IndexEntry)
: Context(DC), InfoSection(Section), Abbrev(DA), RangeSection(RS),
@ -69,10 +69,10 @@ DWARFUnit::~DWARFUnit() = default;
bool DWARFUnit::getAddrOffsetSectionItem(uint32_t Index,
uint64_t &Result) const {
uint32_t Offset = AddrOffsetSectionBase + Index * AddrSize;
if (AddrOffsetSection.size() < Offset + AddrSize)
if (AddrOffsetSection->Data.size() < Offset + AddrSize)
return false;
DataExtractor DA(AddrOffsetSection, isLittleEndian, AddrSize);
Result = DA.getAddress(&Offset);
DataExtractor DA(AddrOffsetSection->Data, isLittleEndian, AddrSize);
Result = getRelocatedValue(DA, AddrSize, &Offset, &AddrOffsetSection->Relocs);
return true;
}

View File

@ -25,6 +25,8 @@ RUN: echo "%p/Inputs/split-dwarf-test 0x4005c4" >> %t.input
RUN: echo "%p/Inputs/cross-cu-inlining.x86_64-macho.o 0x17" >> %t.input
RUN: cp %p/Inputs/split-dwarf-multiple-cu.dwo %T
RUN: echo "%p/Inputs/split-dwarf-multiple-cu.o 0x4" >> %t.input
RUN: cp %p/Inputs/split-dwarf-addr-object-relocation.dwo %T
RUN: echo "%p/Inputs/split-dwarf-addr-object-relocation.o 0x14" >> %t.input
RUN: llvm-symbolizer --functions=linkage --inlining --demangle=false \
RUN: --default-arch=i386 < %t.input | FileCheck --check-prefix=CHECK --check-prefix=SPLIT --check-prefix=DWO %s
@ -140,6 +142,11 @@ CHECK-NEXT: b.cpp:3:3
CHECK-NEXT: f3
CHECK-NEXT: b.cpp:6:0
CHECK: f2
CHECK-NEXT: split-dwarf-addr-object-relocation.cpp:3:3
CHECK-NEXT: f3
CHECK-NEXT: split-dwarf-addr-object-relocation.cpp:6:0
RUN: echo "unexisting-file 0x1234" > %t.input2
RUN: llvm-symbolizer < %t.input2 2>&1 | FileCheck %s --check-prefix=MISSING-FILE