forked from OSchip/llvm-project
[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:
parent
8365cc3a1f
commit
6214c11cb7
|
@ -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;
|
||||
|
|
|
@ -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(); }
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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."); }
|
||||
|
|
|
@ -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)
|
|
@ -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)
|
Loading…
Reference in New Issue