[DWARF] Make llvm-dwarfdump display location lists in a .dwp file correctly. Fixes PR38990.

Considers the index when extracting location lists from a .dwp file.
Majority of the patch by David Blaikie.

Reviewers: dblaikie

Differential revision: https://reviews.llvm.org/D53155

llvm-svn: 344807
This commit is contained in:
Wolfgang Pieb 2018-10-19 19:23:16 +00:00
parent 8365cc3a1f
commit 6214c11cb7
8 changed files with 160 additions and 45 deletions

View File

@ -18,13 +18,13 @@ namespace llvm {
class DWARFCompileUnit : public DWARFUnit {
public:
DWARFCompileUnit(DWARFContext &Context, const DWARFSection &Section,
const DWARFUnitHeader &Header,
const DWARFDebugAbbrev *DA, const DWARFSection *RS,
const DWARFUnitHeader &Header, const DWARFDebugAbbrev *DA,
const DWARFSection *RS, const DWARFSection *LocSection,
StringRef SS, const DWARFSection &SOS,
const DWARFSection *AOS, const DWARFSection &LS, bool LE,
bool IsDWO, const DWARFUnitVector &UnitVector)
: DWARFUnit(Context, Section, Header, DA, RS, SS, SOS, AOS, LS, LE, IsDWO,
UnitVector) {}
: DWARFUnit(Context, Section, Header, DA, RS, LocSection, SS, SOS, AOS,
LS, LE, IsDWO, UnitVector) {}
/// VTable anchor.
~DWARFCompileUnit() override;

View File

@ -26,13 +26,13 @@ class raw_ostream;
class DWARFTypeUnit : public DWARFUnit {
public:
DWARFTypeUnit(DWARFContext &Context, const DWARFSection &Section,
const DWARFUnitHeader &Header,
const DWARFDebugAbbrev *DA, const DWARFSection *RS,
const DWARFUnitHeader &Header, const DWARFDebugAbbrev *DA,
const DWARFSection *RS, const DWARFSection *LocSection,
StringRef SS, const DWARFSection &SOS, const DWARFSection *AOS,
const DWARFSection &LS, bool LE, bool IsDWO,
const DWARFUnitVector &UnitVector)
: DWARFUnit(Context, Section, Header, DA, RS, SS, SOS, AOS, LS, LE, IsDWO,
UnitVector) {}
: DWARFUnit(Context, Section, Header, DA, RS, LocSection, SS, SOS, AOS,
LS, LE, IsDWO, UnitVector) {}
uint64_t getTypeHash() const { return getHeader().getTypeHash(); }
uint32_t getTypeOffset() const { return getHeader().getTypeOffset(); }

View File

@ -153,10 +153,10 @@ public:
private:
void addUnitsImpl(DWARFContext &Context, const DWARFObject &Obj,
const DWARFSection &Section, const DWARFDebugAbbrev *DA,
const DWARFSection *RS, StringRef SS,
const DWARFSection &SOS, const DWARFSection *AOS,
const DWARFSection &LS, bool LE, bool IsDWO, bool Lazy,
DWARFSectionKind SectionKind);
const DWARFSection *RS, const DWARFSection *LocSection,
StringRef SS, const DWARFSection &SOS,
const DWARFSection *AOS, const DWARFSection &LS, bool LE,
bool IsDWO, bool Lazy, DWARFSectionKind SectionKind);
};
/// Represents base address of the CU.
@ -198,6 +198,12 @@ class DWARFUnit {
const DWARFDebugAbbrev *Abbrev;
const DWARFSection *RangeSection;
uint32_t RangeSectionBase;
/// We either keep track of the location list section or its data, depending
/// on whether we are handling a split DWARF section or not.
union {
const DWARFSection *LocSection;
StringRef LocSectionData;
};
const DWARFSection &LineSection;
StringRef StringSection;
const DWARFSection &StringOffsetSection;
@ -258,16 +264,19 @@ protected:
public:
DWARFUnit(DWARFContext &Context, const DWARFSection &Section,
const DWARFUnitHeader &Header,
const DWARFDebugAbbrev *DA, const DWARFSection *RS, StringRef SS,
const DWARFSection &SOS, const DWARFSection *AOS,
const DWARFUnitHeader &Header, const DWARFDebugAbbrev *DA,
const DWARFSection *RS, const DWARFSection *LocSection,
StringRef SS, const DWARFSection &SOS, const DWARFSection *AOS,
const DWARFSection &LS, bool LE, bool IsDWO,
const DWARFUnitVector &UnitVector);
virtual ~DWARFUnit();
bool isDWOUnit() const { return isDWO; }
DWARFContext& getContext() const { return Context; }
const DWARFSection &getInfoSection() const { return InfoSection; }
const DWARFSection *getLocSection() const { return LocSection; }
StringRef getLocSectionData() const { return LocSectionData; }
uint32_t getOffset() const { return Header.getOffset(); }
const dwarf::FormParams &getFormParams() const {
return Header.getFormParams();

View File

@ -101,12 +101,10 @@ static void dumpLocation(raw_ostream &OS, DWARFFormValue &FormValue,
FormValue.dump(OS, DumpOpts);
if (FormValue.isFormClass(DWARFFormValue::FC_SectionOffset)) {
const DWARFSection &LocSection = Obj.getLocSection();
const DWARFSection &LocDWOSection = Obj.getLocDWOSection();
uint32_t Offset = *FormValue.getAsSectionOffset();
if (!LocSection.Data.empty()) {
if (!U->isDWOUnit()) {
DWARFDebugLoc DebugLoc;
DWARFDataExtractor Data(Obj, LocSection, Ctx.isLittleEndian(),
DWARFDataExtractor Data(Obj, *U->getLocSection(), Ctx.isLittleEndian(),
Obj.getAddressSize());
auto LL = DebugLoc.parseOneLocationList(Data, &Offset);
if (LL) {
@ -117,8 +115,8 @@ static void dumpLocation(raw_ostream &OS, DWARFFormValue &FormValue,
Indent);
} else
OS << "error extracting location list.";
} else if (!LocDWOSection.Data.empty()) {
DataExtractor Data(LocDWOSection.Data, Ctx.isLittleEndian(), 0);
} else {
DataExtractor Data(U->getLocSectionData(), Ctx.isLittleEndian(), 0);
auto LL = DWARFDebugLocDWO::parseOneLocationList(Data, &Offset);
if (LL)
LL->dump(OS, Ctx.isLittleEndian(), Obj.getAddressSize(), MRI, Indent);

View File

@ -39,9 +39,10 @@ void DWARFUnitVector::addUnitsForSection(DWARFContext &C,
DWARFSectionKind SectionKind) {
const DWARFObject &D = C.getDWARFObj();
addUnitsImpl(C, D, Section, C.getDebugAbbrev(), &D.getRangeSection(),
D.getStringSection(), D.getStringOffsetSection(),
&D.getAddrSection(), D.getLineSection(), D.isLittleEndian(),
false, false, SectionKind);
&D.getLocSection(), D.getStringSection(),
D.getStringOffsetSection(), &D.getAddrSection(),
D.getLineSection(), D.isLittleEndian(), false, false,
SectionKind);
}
void DWARFUnitVector::addUnitsForDWOSection(DWARFContext &C,
@ -50,16 +51,18 @@ void DWARFUnitVector::addUnitsForDWOSection(DWARFContext &C,
bool Lazy) {
const DWARFObject &D = C.getDWARFObj();
addUnitsImpl(C, D, DWOSection, C.getDebugAbbrevDWO(), &D.getRangeDWOSection(),
D.getStringDWOSection(), D.getStringOffsetDWOSection(),
&D.getAddrSection(), D.getLineDWOSection(), C.isLittleEndian(),
true, Lazy, SectionKind);
&D.getLocDWOSection(), D.getStringDWOSection(),
D.getStringOffsetDWOSection(), &D.getAddrSection(),
D.getLineDWOSection(), C.isLittleEndian(), true, Lazy,
SectionKind);
}
void DWARFUnitVector::addUnitsImpl(
DWARFContext &Context, const DWARFObject &Obj, const DWARFSection &Section,
const DWARFDebugAbbrev *DA, const DWARFSection *RS, StringRef SS,
const DWARFSection &SOS, const DWARFSection *AOS, const DWARFSection &LS,
bool LE, bool IsDWO, bool Lazy, DWARFSectionKind SectionKind) {
const DWARFDebugAbbrev *DA, const DWARFSection *RS,
const DWARFSection *LocSection, StringRef SS, const DWARFSection &SOS,
const DWARFSection *AOS, const DWARFSection &LS, bool LE, bool IsDWO,
bool Lazy, DWARFSectionKind SectionKind) {
DWARFDataExtractor Data(Obj, Section, LE, 0);
// Lazy initialization of Parser, now that we have all section info.
if (!Parser) {
@ -79,12 +82,12 @@ void DWARFUnitVector::addUnitsImpl(
std::unique_ptr<DWARFUnit> U;
if (Header.isTypeUnit())
U = llvm::make_unique<DWARFTypeUnit>(Context, InfoSection, Header, DA,
RS, SS, SOS, AOS, LS, LE, IsDWO,
*this);
RS, LocSection, SS, SOS, AOS, LS,
LE, IsDWO, *this);
else
U = llvm::make_unique<DWARFCompileUnit>(Context, InfoSection, Header,
DA, RS, SS, SOS, AOS, LS, LE,
IsDWO, *this);
DA, RS, LocSection, SS, SOS,
AOS, LS, LE, IsDWO, *this);
return U;
};
}
@ -164,16 +167,25 @@ DWARFUnitVector::getUnitForIndexEntry(const DWARFUnitIndex::Entry &E) {
}
DWARFUnit::DWARFUnit(DWARFContext &DC, const DWARFSection &Section,
const DWARFUnitHeader &Header,
const DWARFDebugAbbrev *DA, const DWARFSection *RS,
const DWARFUnitHeader &Header, const DWARFDebugAbbrev *DA,
const DWARFSection *RS, const DWARFSection *LocSection,
StringRef SS, const DWARFSection &SOS,
const DWARFSection *AOS, const DWARFSection &LS, bool LE,
bool IsDWO, const DWARFUnitVector &UnitVector)
: Context(DC), InfoSection(Section), Header(Header), Abbrev(DA),
RangeSection(RS), LineSection(LS), StringSection(SS),
StringOffsetSection(SOS), AddrOffsetSection(AOS), isLittleEndian(LE),
isDWO(IsDWO), UnitVector(UnitVector) {
RangeSection(RS), LocSection(LocSection), LineSection(LS),
StringSection(SS), StringOffsetSection(SOS), AddrOffsetSection(AOS),
isLittleEndian(LE), isDWO(IsDWO), UnitVector(UnitVector) {
clear();
// For split DWARF we only need to keep track of the location list section's
// data (no relocations), and if we are reading a package file, we need to
// adjust the location list data based on the index entries.
if (IsDWO) {
LocSectionData = LocSection->Data;
if (auto *IndexEntry = Header.getIndexEntry())
if (const auto *C = IndexEntry->getOffset(DW_SECT_LOC))
LocSectionData = LocSectionData.substr(C->Offset, C->Length);
}
}
DWARFUnit::~DWARFUnit() = default;

View File

@ -325,9 +325,10 @@ unsigned DWARFVerifier::verifyUnitSection(const DWARFSection &S,
case dwarf::DW_UT_split_type: {
Unit = TypeUnitVector.addUnit(llvm::make_unique<DWARFTypeUnit>(
DCtx, S, Header, DCtx.getDebugAbbrev(), &DObj.getRangeSection(),
DObj.getStringSection(), DObj.getStringOffsetSection(),
&DObj.getAppleObjCSection(), DObj.getLineSection(),
DCtx.isLittleEndian(), false, TypeUnitVector));
&DObj.getLocSection(), DObj.getStringSection(),
DObj.getStringOffsetSection(), &DObj.getAppleObjCSection(),
DObj.getLineSection(), DCtx.isLittleEndian(), false,
TypeUnitVector));
break;
}
case dwarf::DW_UT_skeleton:
@ -338,9 +339,10 @@ unsigned DWARFVerifier::verifyUnitSection(const DWARFSection &S,
case 0: {
Unit = CompileUnitVector.addUnit(llvm::make_unique<DWARFCompileUnit>(
DCtx, S, Header, DCtx.getDebugAbbrev(), &DObj.getRangeSection(),
DObj.getStringSection(), DObj.getStringOffsetSection(),
&DObj.getAppleObjCSection(), DObj.getLineSection(),
DCtx.isLittleEndian(), false, CompileUnitVector));
&DObj.getLocSection(), DObj.getStringSection(),
DObj.getStringOffsetSection(), &DObj.getAppleObjCSection(),
DObj.getLineSection(), DCtx.isLittleEndian(), false,
CompileUnitVector));
break;
}
default: { llvm_unreachable("Invalid UnitType."); }

View File

@ -0,0 +1,32 @@
target triple = "x86_64-unknown-linux-gnu"
define dso_local void @_Z1bi(i32 %i) local_unnamed_addr !dbg !7 {
entry:
call void @llvm.dbg.value(metadata i32 %i, metadata !12, metadata !DIExpression()), !dbg !13
tail call void asm sideeffect "", "~{rdi},~{dirflag},~{fpsr},~{flags}"() , !dbg !14, !srcloc !15
ret void, !dbg !16
}
declare void @llvm.dbg.value(metadata, metadata, metadata)
!llvm.dbg.cu = !{!0}
!llvm.module.flags = !{!3, !4, !5}
!llvm.ident = !{!6}
!0 = distinct !DICompileUnit(language: DW_LANG_C_plus_plus, file: !1, producer: "clang version 8.0.0 (https://git.llvm.org/git/clang.git/ 41055c6168135fe539801799e5c5636247cf0302) (https://git.llvm.org/git/llvm.git/ de0558be123ffbb5b5bd692c17dbd57a75fe684f)", isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug, enums: !2, nameTableKind: None)
!1 = !DIFile(filename: "b.cpp", directory: "/home/test/PRs/PR38990")
!2 = !{}
!3 = !{i32 2, !"Dwarf Version", i32 4}
!4 = !{i32 2, !"Debug Info Version", i32 3}
!5 = !{i32 1, !"wchar_size", i32 4}
!6 = !{!"clang version 8.0.0 (https://git.llvm.org/git/clang.git/ 41055c6168135fe539801799e5c5636247cf0302) (https://git.llvm.org/git/llvm.git/ de0558be123ffbb5b5bd692c17dbd57a75fe684f)"}
!7 = distinct !DISubprogram(name: "b", linkageName: "_Z1bi", scope: !1, file: !1, line: 1, type: !8, isLocal: false, isDefinition: true, scopeLine: 1, flags: DIFlagPrototyped, isOptimized: true, unit: !0, retainedNodes: !11)
!8 = !DISubroutineType(types: !9)
!9 = !{null, !10}
!10 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed)
!11 = !{!12}
!12 = !DILocalVariable(name: "i", arg: 1, scope: !7, file: !1, line: 1, type: !10)
!13 = !DILocation(line: 1, column: 12, scope: !7)
!14 = !DILocation(line: 1, column: 17, scope: !7)
!15 = !{i32 22}
!16 = !DILocation(line: 1, column: 38, scope: !7)

View File

@ -0,0 +1,62 @@
; RUN: llc -split-dwarf-file=%t1.dwo -filetype=obj -o %t1.o < %s
; RUN: llc -split-dwarf-file=%t2.dwo -filetype=obj -o %t2.o < %p/../Inputs/loclists-dwp-b.ll
; RUN: llvm-dwp %t1.o %t2.o -o %t.dwp
; RUN: llvm-dwarfdump -v %t.dwp | FileCheck %s
; Make sure that 2 location lists from different units within a dwp file are
; dumped correctly. The 2 location lists differ in the length of their address
; ranges.
;
; Generate both .ll files with clang -S -emit-llvm from the following sources:
; a.cpp:
; void y();
; void a(int i) {
; y();
; asm("" : : : "rdi");
; }
;
; b.cpp:
; void b(int i) { asm("" : : : "rdi"); }
; CHECK: DW_AT_location [DW_FORM_sec_offset] (0x00000000
; CHECK-NEXT: Addr idx 0 (w/ length 6): DW_OP_reg5 RDI)
; CHECK: DW_AT_location [DW_FORM_sec_offset] (0x00000000
; CHECK-NEXT: Addr idx 0 (w/ length 0): DW_OP_reg5 RDI)
target triple = "x86_64-unknown-linux-gnu"
define dso_local void @_Z1ai(i32 %i) local_unnamed_addr !dbg !7 {
entry:
call void @llvm.dbg.value(metadata i32 %i, metadata !12, metadata !DIExpression()), !dbg !13
tail call void @_Z1yv(), !dbg !14
tail call void asm sideeffect "", "~{rdi},~{dirflag},~{fpsr},~{flags}"(), !dbg !15, !srcloc !16
ret void, !dbg !17
}
declare dso_local void @_Z1yv() local_unnamed_addr
declare void @llvm.dbg.value(metadata, metadata, metadata)
!llvm.dbg.cu = !{!0}
!llvm.module.flags = !{!3, !4, !5}
!llvm.ident = !{!6}
!0 = distinct !DICompileUnit(language: DW_LANG_C_plus_plus, file: !1, producer: "clang version 8.0.0 (https://git.llvm.org/git/clang.git/ 41055c6168135fe539801799e5c5636247cf0302) (https://git.llvm.org/git/llvm.git/ de0558be123ffbb5b5bd692c17dbd57a75fe684f)", isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug, enums: !2, nameTableKind: None)
!1 = !DIFile(filename: "a.cpp", directory: "/home/test/PRs/PR38990")
!2 = !{}
!3 = !{i32 2, !"Dwarf Version", i32 4}
!4 = !{i32 2, !"Debug Info Version", i32 3}
!5 = !{i32 1, !"wchar_size", i32 4}
!6 = !{!"clang version 8.0.0 (https://git.llvm.org/git/clang.git/ 41055c6168135fe539801799e5c5636247cf0302) (https://git.llvm.org/git/llvm.git/ de0558be123ffbb5b5bd692c17dbd57a75fe684f)"}
!7 = distinct !DISubprogram(name: "a", linkageName: "_Z1ai", scope: !1, file: !1, line: 2, type: !8, isLocal: false, isDefinition: true, scopeLine: 2, flags: DIFlagPrototyped, isOptimized: true, unit: !0, retainedNodes: !11)
!8 = !DISubroutineType(types: !9)
!9 = !{null, !10}
!10 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed)
!11 = !{!12}
!12 = !DILocalVariable(name: "i", arg: 1, scope: !7, file: !1, line: 2, type: !10)
!13 = !DILocation(line: 2, column: 12, scope: !7)
!14 = !DILocation(line: 3, column: 3, scope: !7)
!15 = !DILocation(line: 4, column: 3, scope: !7)
!16 = !{i32 41}
!17 = !DILocation(line: 5, column: 1, scope: !7)