[DWARFv5] Support DW_FORM_line_strp in llvm-dwarfdump.

This form is like DW_FORM_strp, but points to .debug_line_str instead
of .debug_str as the string section.  It's intended to be used from
the line-table header, and allows string-pooling of directory and
filenames across compilation units.

Differential Revision: https://reviews.llvm.org/D42553

llvm-svn: 323476
This commit is contained in:
Paul Robinson 2018-01-25 22:02:36 +00:00
parent 8410c37465
commit b6aa01ca99
10 changed files with 60 additions and 26 deletions

View File

@ -840,6 +840,7 @@ HANDLE_DWARF_SECTION(DebugAranges, ".debug_aranges", "debug-aranges")
HANDLE_DWARF_SECTION(DebugInfo, ".debug_info", "debug-info") HANDLE_DWARF_SECTION(DebugInfo, ".debug_info", "debug-info")
HANDLE_DWARF_SECTION(DebugTypes, ".debug_types", "debug-types") HANDLE_DWARF_SECTION(DebugTypes, ".debug_types", "debug-types")
HANDLE_DWARF_SECTION(DebugLine, ".debug_line", "debug-line") HANDLE_DWARF_SECTION(DebugLine, ".debug_line", "debug-line")
HANDLE_DWARF_SECTION(DebugLineStr, ".debug_line_str", "debug-line-str")
HANDLE_DWARF_SECTION(DebugLoc, ".debug_loc", "debug-loc") HANDLE_DWARF_SECTION(DebugLoc, ".debug_loc", "debug-loc")
HANDLE_DWARF_SECTION(DebugFrame, ".debug_frame", "debug-frame") HANDLE_DWARF_SECTION(DebugFrame, ".debug_frame", "debug-frame")
HANDLE_DWARF_SECTION(DebugMacro, ".debug_macro", "debug-macro") HANDLE_DWARF_SECTION(DebugMacro, ".debug_macro", "debug-macro")

View File

@ -20,10 +20,11 @@ public:
DWARFCompileUnit(DWARFContext &Context, const DWARFSection &Section, DWARFCompileUnit(DWARFContext &Context, const DWARFSection &Section,
const DWARFDebugAbbrev *DA, const DWARFSection *RS, const DWARFDebugAbbrev *DA, const DWARFSection *RS,
StringRef SS, const DWARFSection &SOS, StringRef SS, const DWARFSection &SOS,
const DWARFSection *AOS, const DWARFSection &LS, bool LE, const DWARFSection *AOS, const DWARFSection &LS,
bool IsDWO, const DWARFUnitSectionBase &UnitSection, StringRef LSS, bool LE, bool IsDWO,
const DWARFUnitSectionBase &UnitSection,
const DWARFUnitIndex::Entry *Entry) const DWARFUnitIndex::Entry *Entry)
: DWARFUnit(Context, Section, DA, RS, SS, SOS, AOS, LS, LE, IsDWO, : DWARFUnit(Context, Section, DA, RS, SS, SOS, AOS, LS, LSS, LE, IsDWO,
UnitSection, Entry) {} UnitSection, Entry) {}
// VTable anchor. // VTable anchor.

View File

@ -42,6 +42,7 @@ public:
virtual StringRef getDebugFrameSection() const { return ""; } virtual StringRef getDebugFrameSection() const { return ""; }
virtual StringRef getEHFrameSection() const { return ""; } virtual StringRef getEHFrameSection() const { return ""; }
virtual const DWARFSection &getLineSection() const { return Dummy; } virtual const DWARFSection &getLineSection() const { return Dummy; }
virtual StringRef getLineStringSection() const { return ""; }
virtual StringRef getStringSection() const { return ""; } virtual StringRef getStringSection() const { return ""; }
virtual const DWARFSection &getRangeSection() const { return Dummy; } virtual const DWARFSection &getRangeSection() const { return Dummy; }
virtual StringRef getMacinfoSection() const { return ""; } virtual StringRef getMacinfoSection() const { return ""; }

View File

@ -32,10 +32,10 @@ public:
DWARFTypeUnit(DWARFContext &Context, const DWARFSection &Section, DWARFTypeUnit(DWARFContext &Context, const DWARFSection &Section,
const DWARFDebugAbbrev *DA, const DWARFSection *RS, const DWARFDebugAbbrev *DA, const DWARFSection *RS,
StringRef SS, const DWARFSection &SOS, const DWARFSection *AOS, StringRef SS, const DWARFSection &SOS, const DWARFSection *AOS,
const DWARFSection &LS, bool LE, bool IsDWO, const DWARFSection &LS, StringRef LSS, bool LE, bool IsDWO,
const DWARFUnitSectionBase &UnitSection, const DWARFUnitSectionBase &UnitSection,
const DWARFUnitIndex::Entry *Entry) const DWARFUnitIndex::Entry *Entry)
: DWARFUnit(Context, Section, DA, RS, SS, SOS, AOS, LS, LE, IsDWO, : DWARFUnit(Context, Section, DA, RS, SS, SOS, AOS, LS, LSS, LE, IsDWO,
UnitSection, Entry) {} UnitSection, Entry) {}
uint32_t getHeaderSize() const override { uint32_t getHeaderSize() const override {

View File

@ -60,7 +60,8 @@ protected:
const DWARFDebugAbbrev *DA, const DWARFSection *RS, const DWARFDebugAbbrev *DA, const DWARFSection *RS,
StringRef SS, const DWARFSection &SOS, StringRef SS, const DWARFSection &SOS,
const DWARFSection *AOS, const DWARFSection &LS, const DWARFSection *AOS, const DWARFSection &LS,
bool isLittleEndian, bool isDWO, bool Lazy) = 0; StringRef LSS, bool isLittleEndian, bool isDWO,
bool Lazy) = 0;
}; };
const DWARFUnitIndex &getDWARFUnitIndex(DWARFContext &Context, const DWARFUnitIndex &getDWARFUnitIndex(DWARFContext &Context,
@ -119,7 +120,7 @@ private:
void parseImpl(DWARFContext &Context, const DWARFSection &Section, void parseImpl(DWARFContext &Context, const DWARFSection &Section,
const DWARFDebugAbbrev *DA, const DWARFSection *RS, const DWARFDebugAbbrev *DA, const DWARFSection *RS,
StringRef SS, const DWARFSection &SOS, const DWARFSection *AOS, StringRef SS, const DWARFSection &SOS, const DWARFSection *AOS,
const DWARFSection &LS, bool LE, bool IsDWO, const DWARFSection &LS, StringRef LSS, bool LE, bool IsDWO,
bool Lazy) override { bool Lazy) override {
if (Parsed) if (Parsed)
return; return;
@ -133,7 +134,7 @@ private:
if (!Data.isValidOffset(Offset)) if (!Data.isValidOffset(Offset))
return nullptr; return nullptr;
auto U = llvm::make_unique<UnitType>( auto U = llvm::make_unique<UnitType>(
Context, Section, DA, RS, SS, SOS, AOS, LS, LE, IsDWO, *this, Context, Section, DA, RS, SS, SOS, AOS, LS, LSS, LE, IsDWO, *this,
Index ? Index->getFromOffset(Offset) : nullptr); Index ? Index->getFromOffset(Offset) : nullptr);
if (!U->extract(Data, &Offset)) if (!U->extract(Data, &Offset))
return nullptr; return nullptr;
@ -197,6 +198,7 @@ class DWARFUnit {
const DWARFSection *RangeSection; const DWARFSection *RangeSection;
uint32_t RangeSectionBase; uint32_t RangeSectionBase;
const DWARFSection &LineSection; const DWARFSection &LineSection;
StringRef LineStringSection;
StringRef StringSection; StringRef StringSection;
const DWARFSection &StringOffsetSection; const DWARFSection &StringOffsetSection;
const DWARFSection *AddrOffsetSection; const DWARFSection *AddrOffsetSection;
@ -293,7 +295,7 @@ public:
DWARFUnit(DWARFContext &Context, const DWARFSection &Section, DWARFUnit(DWARFContext &Context, const DWARFSection &Section,
const DWARFDebugAbbrev *DA, const DWARFSection *RS, StringRef SS, const DWARFDebugAbbrev *DA, const DWARFSection *RS, StringRef SS,
const DWARFSection &SOS, const DWARFSection *AOS, const DWARFSection &SOS, const DWARFSection *AOS,
const DWARFSection &LS, bool LE, bool IsDWO, const DWARFSection &LS, StringRef LSS, bool LE, bool IsDWO,
const DWARFUnitSectionBase &UnitSection, const DWARFUnitSectionBase &UnitSection,
const DWARFUnitIndex::Entry *IndexEntry = nullptr); const DWARFUnitIndex::Entry *IndexEntry = nullptr);
@ -302,6 +304,7 @@ public:
DWARFContext& getContext() const { return Context; } DWARFContext& getContext() const { return Context; }
const DWARFSection &getLineSection() const { return LineSection; } const DWARFSection &getLineSection() const { return LineSection; }
StringRef getLineStringSection() const { return LineStringSection; }
StringRef getStringSection() const { return StringSection; } StringRef getStringSection() const { return StringSection; }
const DWARFSection &getStringOffsetSection() const { const DWARFSection &getStringOffsetSection() const {
return StringOffsetSection; return StringOffsetSection;
@ -322,11 +325,13 @@ public:
DWARFDataExtractor getDebugInfoExtractor() const; DWARFDataExtractor getDebugInfoExtractor() const;
DataExtractor getLineStringExtractor() const {
return DataExtractor(LineStringSection, false, 0);
}
DataExtractor getStringExtractor() const { DataExtractor getStringExtractor() const {
return DataExtractor(StringSection, false, 0); return DataExtractor(StringSection, false, 0);
} }
bool extract(DataExtractor debug_info, uint32_t* offset_ptr); bool extract(DataExtractor debug_info, uint32_t* offset_ptr);
/// extractRangeList - extracts the range list referenced by this compile /// extractRangeList - extracts the range list referenced by this compile

View File

@ -459,6 +459,16 @@ void DWARFContext::dump(
strDWOOffset = offset; strDWOOffset = offset;
} }
} }
if (shouldDump(Explicit, ".debug_line_str", DIDT_ID_DebugLineStr,
DObj->getLineStringSection())) {
DataExtractor strData(DObj->getLineStringSection(), isLittleEndian(), 0);
uint32_t offset = 0;
uint32_t strOffset = 0;
while (const char *s = strData.getCStr(&offset)) {
OS << format("0x%8.8x: \"%s\"\n", strOffset, s);
strOffset = offset;
}
}
if (shouldDump(Explicit, ".debug_ranges", DIDT_ID_DebugRanges, if (shouldDump(Explicit, ".debug_ranges", DIDT_ID_DebugRanges,
DObj->getRangeSection().Data)) { DObj->getRangeSection().Data)) {
@ -1193,6 +1203,7 @@ class DWARFObjInMemory final : public DWARFObject {
StringRef CUIndexSection; StringRef CUIndexSection;
StringRef GdbIndexSection; StringRef GdbIndexSection;
StringRef TUIndexSection; StringRef TUIndexSection;
StringRef LineStringSection;
SmallVector<SmallString<32>, 4> UncompressedSections; SmallVector<SmallString<32>, 4> UncompressedSections;
@ -1215,6 +1226,7 @@ class DWARFObjInMemory final : public DWARFObject {
.Case("debug_cu_index", &CUIndexSection) .Case("debug_cu_index", &CUIndexSection)
.Case("debug_tu_index", &TUIndexSection) .Case("debug_tu_index", &TUIndexSection)
.Case("gdb_index", &GdbIndexSection) .Case("gdb_index", &GdbIndexSection)
.Case("debug_line_str", &LineStringSection)
// Any more debug info sections go here. // Any more debug info sections go here.
.Default(nullptr); .Default(nullptr);
} }
@ -1433,6 +1445,7 @@ public:
const DWARFSection &getStringOffsetSection() const override { const DWARFSection &getStringOffsetSection() const override {
return StringOffsetSection; return StringOffsetSection;
} }
StringRef getLineStringSection() const override { return LineStringSection; }
// Sections for DWARF5 split dwarf proposal. // Sections for DWARF5 split dwarf proposal.
const DWARFSection &getInfoDWOSection() const override { const DWARFSection &getInfoDWOSection() const override {

View File

@ -264,6 +264,7 @@ bool DWARFFormValue::isFormClass(DWARFFormValue::FormClass FC) const {
case DW_FORM_strx2: case DW_FORM_strx2:
case DW_FORM_strx3: case DW_FORM_strx3:
case DW_FORM_strx4: case DW_FORM_strx4:
case DW_FORM_line_strp:
return (FC == FC_String); return (FC == FC_String);
case DW_FORM_implicit_const: case DW_FORM_implicit_const:
return (FC == FC_Constant); return (FC == FC_Constant);
@ -582,6 +583,11 @@ Optional<const char *> DWARFFormValue::getAsCString() const {
if (Form == DW_FORM_GNU_strp_alt || U == nullptr) if (Form == DW_FORM_GNU_strp_alt || U == nullptr)
return None; return None;
uint32_t Offset = Value.uval; uint32_t Offset = Value.uval;
if (Form == DW_FORM_line_strp) {
if (const char *Str = U->getLineStringExtractor().getCStr(&Offset))
return Str;
return None;
}
if (Form == DW_FORM_GNU_str_index || Form == DW_FORM_strx || if (Form == DW_FORM_GNU_str_index || Form == DW_FORM_strx ||
Form == DW_FORM_strx1 || Form == DW_FORM_strx2 || Form == DW_FORM_strx3 || Form == DW_FORM_strx1 || Form == DW_FORM_strx2 || Form == DW_FORM_strx3 ||
Form == DW_FORM_strx4) { Form == DW_FORM_strx4) {

View File

@ -34,8 +34,8 @@ void DWARFUnitSectionBase::parse(DWARFContext &C, const DWARFSection &Section) {
const DWARFObject &D = C.getDWARFObj(); const DWARFObject &D = C.getDWARFObj();
parseImpl(C, Section, C.getDebugAbbrev(), &D.getRangeSection(), parseImpl(C, Section, C.getDebugAbbrev(), &D.getRangeSection(),
D.getStringSection(), D.getStringOffsetSection(), D.getStringSection(), D.getStringOffsetSection(),
&D.getAddrSection(), D.getLineSection(), D.isLittleEndian(), false, &D.getAddrSection(), D.getLineSection(), D.getLineStringSection(),
false); D.isLittleEndian(), false, false);
} }
void DWARFUnitSectionBase::parseDWO(DWARFContext &C, void DWARFUnitSectionBase::parseDWO(DWARFContext &C,
@ -43,20 +43,21 @@ void DWARFUnitSectionBase::parseDWO(DWARFContext &C,
const DWARFObject &D = C.getDWARFObj(); const DWARFObject &D = C.getDWARFObj();
parseImpl(C, DWOSection, C.getDebugAbbrevDWO(), &D.getRangeDWOSection(), parseImpl(C, DWOSection, C.getDebugAbbrevDWO(), &D.getRangeDWOSection(),
D.getStringDWOSection(), D.getStringOffsetDWOSection(), D.getStringDWOSection(), D.getStringOffsetDWOSection(),
&D.getAddrSection(), D.getLineDWOSection(), C.isLittleEndian(), &D.getAddrSection(), D.getLineDWOSection(), StringRef(),
true, Lazy); C.isLittleEndian(), true, Lazy);
} }
DWARFUnit::DWARFUnit(DWARFContext &DC, const DWARFSection &Section, DWARFUnit::DWARFUnit(DWARFContext &DC, const DWARFSection &Section,
const DWARFDebugAbbrev *DA, const DWARFSection *RS, const DWARFDebugAbbrev *DA, const DWARFSection *RS,
StringRef SS, const DWARFSection &SOS, StringRef SS, const DWARFSection &SOS,
const DWARFSection *AOS, const DWARFSection &LS, bool LE, const DWARFSection *AOS, const DWARFSection &LS,
bool IsDWO, const DWARFUnitSectionBase &UnitSection, StringRef LSS, bool LE, bool IsDWO,
const DWARFUnitSectionBase &UnitSection,
const DWARFUnitIndex::Entry *IndexEntry) const DWARFUnitIndex::Entry *IndexEntry)
: Context(DC), InfoSection(Section), Abbrev(DA), RangeSection(RS), : Context(DC), InfoSection(Section), Abbrev(DA), RangeSection(RS),
LineSection(LS), StringSection(SS), StringOffsetSection(SOS), LineSection(LS), LineStringSection(LSS), StringSection(SS),
AddrOffsetSection(AOS), isLittleEndian(LE), isDWO(IsDWO), StringOffsetSection(SOS), AddrOffsetSection(AOS), isLittleEndian(LE),
UnitSection(UnitSection), IndexEntry(IndexEntry) { isDWO(IsDWO), UnitSection(UnitSection), IndexEntry(IndexEntry) {
clear(); clear();
} }

View File

@ -282,8 +282,8 @@ bool DWARFVerifier::handleDebugInfo() {
DCtx, DObj.getInfoSection(), DCtx.getDebugAbbrev(), DCtx, DObj.getInfoSection(), DCtx.getDebugAbbrev(),
&DObj.getRangeSection(), DObj.getStringSection(), &DObj.getRangeSection(), DObj.getStringSection(),
DObj.getStringOffsetSection(), &DObj.getAppleObjCSection(), DObj.getStringOffsetSection(), &DObj.getAppleObjCSection(),
DObj.getLineSection(), DCtx.isLittleEndian(), false, TUSection, DObj.getLineSection(), DObj.getLineStringSection(),
nullptr)); DCtx.isLittleEndian(), false, TUSection, nullptr));
break; break;
} }
case dwarf::DW_UT_skeleton: case dwarf::DW_UT_skeleton:
@ -297,8 +297,8 @@ bool DWARFVerifier::handleDebugInfo() {
DCtx, DObj.getInfoSection(), DCtx.getDebugAbbrev(), DCtx, DObj.getInfoSection(), DCtx.getDebugAbbrev(),
&DObj.getRangeSection(), DObj.getStringSection(), &DObj.getRangeSection(), DObj.getStringSection(),
DObj.getStringOffsetSection(), &DObj.getAppleObjCSection(), DObj.getStringOffsetSection(), &DObj.getAppleObjCSection(),
DObj.getLineSection(), DCtx.isLittleEndian(), false, CUSection, DObj.getLineSection(), DObj.getLineStringSection(),
nullptr)); DCtx.isLittleEndian(), false, CUSection, nullptr));
break; break;
} }
default: { llvm_unreachable("Invalid UnitType."); } default: { llvm_unreachable("Invalid UnitType."); }

View File

@ -300,18 +300,18 @@ LH_5_params:
# File table format # File table format
.byte 3 # Three elements per file entry .byte 3 # Three elements per file entry
.byte 1 # DW_LNCT_path .byte 1 # DW_LNCT_path
.byte 0x08 # DW_FORM_string .byte 0x1f # DW_FORM_line_strp (-> .debug_line_str)
.byte 2 # DW_LNCT_directory_index .byte 2 # DW_LNCT_directory_index
.byte 0x0b # DW_FORM_data1 .byte 0x0b # DW_FORM_data1
.byte 5 # DW_LNCT_MD5 .byte 5 # DW_LNCT_MD5
.byte 0x1e # DW_FORM_data16 .byte 0x1e # DW_FORM_data16
# File table entries # File table entries
.byte 2 # Two files .byte 2 # Two files
.asciz "File5a" .long lstr_LT_5a
.byte 0 .byte 0
.quad 0x7766554433221100 .quad 0x7766554433221100
.quad 0xffeeddccbbaa9988 .quad 0xffeeddccbbaa9988
.asciz "File5b" .long lstr_LT_5b
.byte 1 .byte 1
.quad 0x8899aabbccddeeff .quad 0x8899aabbccddeeff
.quad 0x0011223344556677 .quad 0x0011223344556677
@ -332,6 +332,12 @@ LH_5_end:
# CHECK: file_names[ 2] 1 ffeeddccbbaa99887766554433221100 File5b{{$}} # CHECK: file_names[ 2] 1 ffeeddccbbaa99887766554433221100 File5b{{$}}
# CHECK-NOT: file_names # CHECK-NOT: file_names
.section .debug_line_str,"MS",@progbits,1
lstr_LT_5a:
.asciz "File5a"
lstr_LT_5b:
.asciz "File5b"
.section .debug_line.dwo,"",@progbits .section .debug_line.dwo,"",@progbits
# CHECK-LABEL: .debug_line.dwo # CHECK-LABEL: .debug_line.dwo