mirror of
https://github.com/RPCSX/llvm.git
synced 2024-11-23 11:49:50 +00:00
[DWARF] Adding support for the DWARF v5 string offsets table (consumer/reader part only).
Reviewers: dblaikie, aprantl Differential Revision: https://reviews.llvm.org/D32779 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@304759 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
2144c5262f
commit
c9977b6aa4
@ -135,6 +135,7 @@ enum DIDumpType {
|
||||
DIDT_GnuPubnames,
|
||||
DIDT_GnuPubtypes,
|
||||
DIDT_Str,
|
||||
DIDT_StrOffsets,
|
||||
DIDT_StrDwo,
|
||||
DIDT_StrOffsetsDwo,
|
||||
DIDT_AppleNames,
|
||||
|
@ -19,8 +19,8 @@ class DWARFCompileUnit : public DWARFUnit {
|
||||
public:
|
||||
DWARFCompileUnit(DWARFContext &Context, const DWARFSection &Section,
|
||||
const DWARFDebugAbbrev *DA, const DWARFSection *RS,
|
||||
StringRef SS, StringRef SOS, const DWARFSection *AOS,
|
||||
StringRef LS, bool LE, bool IsDWO,
|
||||
StringRef SS, const DWARFSection &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,
|
||||
|
@ -72,6 +72,9 @@ class DWARFContext : public DIContext {
|
||||
std::unique_ptr<DWARFDebugAbbrev> AbbrevDWO;
|
||||
std::unique_ptr<DWARFDebugLocDWO> LocDWO;
|
||||
|
||||
/// The maximum DWARF version of all units.
|
||||
unsigned MaxVersion;
|
||||
|
||||
struct DWOFile {
|
||||
object::OwningBinary<object::ObjectFile> File;
|
||||
std::unique_ptr<DWARFContext> Context;
|
||||
@ -97,7 +100,7 @@ class DWARFContext : public DIContext {
|
||||
void parseDWOTypeUnits();
|
||||
|
||||
public:
|
||||
DWARFContext() : DIContext(CK_DWARF) {}
|
||||
DWARFContext() : DIContext(CK_DWARF), MaxVersion(0) {}
|
||||
DWARFContext(DWARFContext &) = delete;
|
||||
DWARFContext &operator=(DWARFContext &) = delete;
|
||||
|
||||
@ -178,6 +181,13 @@ public:
|
||||
/// Get a DIE given an exact offset.
|
||||
DWARFDie getDIEForOffset(uint32_t Offset);
|
||||
|
||||
unsigned getMaxVersion() const { return MaxVersion; }
|
||||
|
||||
void setMaxVersionIfGreater(unsigned Version) {
|
||||
if (Version > MaxVersion)
|
||||
MaxVersion = Version;
|
||||
}
|
||||
|
||||
const DWARFUnitIndex &getCUIndex();
|
||||
DWARFGdbIndex &getGdbIndex();
|
||||
const DWARFUnitIndex &getTUIndex();
|
||||
@ -237,6 +247,11 @@ public:
|
||||
virtual StringRef getGnuPubNamesSection() = 0;
|
||||
virtual StringRef getGnuPubTypesSection() = 0;
|
||||
|
||||
/// DWARF v5
|
||||
/// @{
|
||||
virtual const DWARFSection &getStringOffsetSection() = 0;
|
||||
/// @}
|
||||
|
||||
// Sections for DWARF5 split dwarf proposal.
|
||||
virtual const DWARFSection &getInfoDWOSection() = 0;
|
||||
virtual const TypeSectionMap &getTypesDWOSections() = 0;
|
||||
@ -244,7 +259,7 @@ public:
|
||||
virtual const DWARFSection &getLineDWOSection() = 0;
|
||||
virtual const DWARFSection &getLocDWOSection() = 0;
|
||||
virtual StringRef getStringDWOSection() = 0;
|
||||
virtual StringRef getStringOffsetDWOSection() = 0;
|
||||
virtual const DWARFSection &getStringOffsetDWOSection() = 0;
|
||||
virtual const DWARFSection &getRangeDWOSection() = 0;
|
||||
virtual const DWARFSection &getAddrSection() = 0;
|
||||
virtual const DWARFSection& getAppleNamesSection() = 0;
|
||||
@ -295,6 +310,11 @@ class DWARFContextInMemory : public DWARFContext {
|
||||
StringRef GnuPubNamesSection;
|
||||
StringRef GnuPubTypesSection;
|
||||
|
||||
/// DWARF v5
|
||||
/// @{
|
||||
DWARFSection StringOffsetSection;
|
||||
/// @}
|
||||
|
||||
// Sections for DWARF5 split dwarf proposal.
|
||||
DWARFSection InfoDWOSection;
|
||||
TypeSectionMap TypesDWOSections;
|
||||
@ -302,7 +322,7 @@ class DWARFContextInMemory : public DWARFContext {
|
||||
DWARFSection LineDWOSection;
|
||||
DWARFSection LocDWOSection;
|
||||
StringRef StringDWOSection;
|
||||
StringRef StringOffsetDWOSection;
|
||||
DWARFSection StringOffsetDWOSection;
|
||||
DWARFSection RangeDWOSection;
|
||||
DWARFSection AddrSection;
|
||||
DWARFSection AppleNamesSection;
|
||||
@ -353,6 +373,11 @@ public:
|
||||
const DWARFSection& getAppleNamespacesSection() override { return AppleNamespacesSection; }
|
||||
const DWARFSection& getAppleObjCSection() override { return AppleObjCSection; }
|
||||
|
||||
// DWARF v5
|
||||
const DWARFSection &getStringOffsetSection() override {
|
||||
return StringOffsetSection;
|
||||
}
|
||||
|
||||
// Sections for DWARF5 split dwarf proposal.
|
||||
const DWARFSection &getInfoDWOSection() override { return InfoDWOSection; }
|
||||
|
||||
@ -365,7 +390,7 @@ public:
|
||||
const DWARFSection &getLocDWOSection() override { return LocDWOSection; }
|
||||
StringRef getStringDWOSection() override { return StringDWOSection; }
|
||||
|
||||
StringRef getStringOffsetDWOSection() override {
|
||||
const DWARFSection &getStringOffsetDWOSection() override {
|
||||
return StringOffsetDWOSection;
|
||||
}
|
||||
|
||||
|
@ -31,7 +31,7 @@ private:
|
||||
public:
|
||||
DWARFTypeUnit(DWARFContext &Context, const DWARFSection &Section,
|
||||
const DWARFDebugAbbrev *DA, const DWARFSection *RS,
|
||||
StringRef SS, StringRef SOS, const DWARFSection *AOS,
|
||||
StringRef SS, const DWARFSection &SOS, const DWARFSection *AOS,
|
||||
StringRef LS, bool LE, bool IsDWO,
|
||||
const DWARFUnitSectionBase &UnitSection,
|
||||
const DWARFUnitIndex::Entry *Entry)
|
||||
|
@ -57,8 +57,9 @@ protected:
|
||||
|
||||
virtual void parseImpl(DWARFContext &Context, const DWARFSection &Section,
|
||||
const DWARFDebugAbbrev *DA, const DWARFSection *RS,
|
||||
StringRef SS, StringRef SOS, const DWARFSection *AOS,
|
||||
StringRef LS, bool isLittleEndian, bool isDWO) = 0;
|
||||
StringRef SS, const DWARFSection &SOS,
|
||||
const DWARFSection *AOS, StringRef LS,
|
||||
bool isLittleEndian, bool isDWO) = 0;
|
||||
};
|
||||
|
||||
const DWARFUnitIndex &getDWARFUnitIndex(DWARFContext &Context,
|
||||
@ -89,7 +90,7 @@ public:
|
||||
private:
|
||||
void parseImpl(DWARFContext &Context, const DWARFSection &Section,
|
||||
const DWARFDebugAbbrev *DA, const DWARFSection *RS,
|
||||
StringRef SS, StringRef SOS, const DWARFSection *AOS,
|
||||
StringRef SS, const DWARFSection &SOS, const DWARFSection *AOS,
|
||||
StringRef LS, bool LE, bool IsDWO) override {
|
||||
if (Parsed)
|
||||
return;
|
||||
@ -119,7 +120,8 @@ class DWARFUnit {
|
||||
uint32_t RangeSectionBase;
|
||||
StringRef LineSection;
|
||||
StringRef StringSection;
|
||||
StringRef StringOffsetSection;
|
||||
const DWARFSection &StringOffsetSection;
|
||||
uint64_t StringOffsetSectionBase = 0;
|
||||
const DWARFSection *AddrOffsetSection;
|
||||
uint32_t AddrOffsetSectionBase;
|
||||
bool isLittleEndian;
|
||||
@ -162,8 +164,8 @@ protected:
|
||||
public:
|
||||
DWARFUnit(DWARFContext &Context, const DWARFSection &Section,
|
||||
const DWARFDebugAbbrev *DA, const DWARFSection *RS, StringRef SS,
|
||||
StringRef SOS, const DWARFSection *AOS, StringRef LS, bool LE,
|
||||
bool IsDWO, const DWARFUnitSectionBase &UnitSection,
|
||||
const DWARFSection &SOS, const DWARFSection *AOS, StringRef LS,
|
||||
bool LE, bool IsDWO, const DWARFUnitSectionBase &UnitSection,
|
||||
const DWARFUnitIndex::Entry *IndexEntry = nullptr);
|
||||
|
||||
virtual ~DWARFUnit();
|
||||
@ -172,7 +174,9 @@ public:
|
||||
|
||||
StringRef getLineSection() const { return LineSection; }
|
||||
StringRef getStringSection() const { return StringSection; }
|
||||
StringRef getStringOffsetSection() const { return StringOffsetSection; }
|
||||
const DWARFSection &getStringOffsetSection() const {
|
||||
return StringOffsetSection;
|
||||
}
|
||||
|
||||
void setAddrOffsetSection(const DWARFSection *AOS, uint32_t Base) {
|
||||
AddrOffsetSection = AOS;
|
||||
@ -189,7 +193,8 @@ public:
|
||||
|
||||
bool getAddrOffsetSectionItem(uint32_t Index, uint64_t &Result) const;
|
||||
// FIXME: Result should be uint64_t in DWARF64.
|
||||
bool getStringOffsetSectionItem(uint32_t Index, uint32_t &Result) const;
|
||||
bool getStringOffsetSectionItem(uint32_t Index, uint64_t &Result) const;
|
||||
uint64_t getStringOffsetSectionRelocation(uint32_t Index) const;
|
||||
|
||||
DataExtractor getDebugInfoExtractor() const {
|
||||
return DataExtractor(InfoSection.Data, isLittleEndian, AddrSize);
|
||||
@ -200,6 +205,9 @@ public:
|
||||
}
|
||||
|
||||
const RelocAddrMap *getRelocMap() const { return &InfoSection.Relocs; }
|
||||
const RelocAddrMap &getStringOffsetsRelocMap() const {
|
||||
return StringOffsetSection.Relocs;
|
||||
}
|
||||
|
||||
bool extract(DataExtractor debug_info, uint32_t* offset_ptr);
|
||||
|
||||
|
@ -109,6 +109,9 @@ protected:
|
||||
MCSection *DwarfLineDWOSection;
|
||||
MCSection *DwarfLocDWOSection;
|
||||
MCSection *DwarfStrOffDWOSection;
|
||||
|
||||
/// The DWARF v5 string offset and address table sections.
|
||||
MCSection *DwarfStrOffSection;
|
||||
MCSection *DwarfAddrSection;
|
||||
|
||||
// These are for Fission DWP files.
|
||||
@ -260,6 +263,7 @@ public:
|
||||
MCSection *getDwarfLineDWOSection() const { return DwarfLineDWOSection; }
|
||||
MCSection *getDwarfLocDWOSection() const { return DwarfLocDWOSection; }
|
||||
MCSection *getDwarfStrOffDWOSection() const { return DwarfStrOffDWOSection; }
|
||||
MCSection *getDwarfStrOffSection() const { return DwarfStrOffSection; }
|
||||
MCSection *getDwarfAddrSection() const { return DwarfAddrSection; }
|
||||
MCSection *getDwarfCUIndexSection() const { return DwarfCUIndexSection; }
|
||||
MCSection *getDwarfTUIndexSection() const { return DwarfTUIndexSection; }
|
||||
|
@ -550,6 +550,8 @@ public:
|
||||
|
||||
bool isRelocatableObject() const override;
|
||||
|
||||
StringRef mapDebugSectionName(StringRef Name) const override;
|
||||
|
||||
bool hasPageZeroSegment() const { return HasPageZeroSegment; }
|
||||
|
||||
static bool classof(const Binary *v) {
|
||||
|
@ -292,6 +292,9 @@ public:
|
||||
return std::error_code();
|
||||
}
|
||||
|
||||
/// Maps a debug section name to a standard DWARF section name.
|
||||
virtual StringRef mapDebugSectionName(StringRef Name) const { return Name; }
|
||||
|
||||
/// True if this is a relocatable object (.o/.obj).
|
||||
virtual bool isRelocatableObject() const = 0;
|
||||
|
||||
|
@ -84,6 +84,123 @@ static void dumpAccelSection(raw_ostream &OS, StringRef Name,
|
||||
Accel.dump(OS);
|
||||
}
|
||||
|
||||
static void
|
||||
dumpDWARFv5StringOffsetsSection(raw_ostream &OS, StringRef SectionName,
|
||||
const DWARFSection &StringOffsetsSection,
|
||||
StringRef StringSection, bool LittleEndian) {
|
||||
DataExtractor StrOffsetExt(StringOffsetsSection.Data, LittleEndian, 0);
|
||||
uint32_t Offset = 0;
|
||||
uint64_t SectionSize = StringOffsetsSection.Data.size();
|
||||
|
||||
while (Offset < SectionSize) {
|
||||
unsigned Version = 0;
|
||||
DwarfFormat Format = DWARF32;
|
||||
unsigned EntrySize = 4;
|
||||
// Perform validation and extract the segment size from the header.
|
||||
if (!StrOffsetExt.isValidOffsetForDataOfSize(Offset, 4)) {
|
||||
OS << "error: invalid contribution to string offsets table in section ."
|
||||
<< SectionName << ".\n";
|
||||
return;
|
||||
}
|
||||
uint32_t ContributionStart = Offset;
|
||||
uint64_t ContributionSize = StrOffsetExt.getU32(&Offset);
|
||||
// A contribution size of 0xffffffff indicates DWARF64, with the actual size
|
||||
// in the following 8 bytes. Otherwise, the DWARF standard mandates that
|
||||
// the contribution size must be at most 0xfffffff0.
|
||||
if (ContributionSize == 0xffffffff) {
|
||||
if (!StrOffsetExt.isValidOffsetForDataOfSize(Offset, 8)) {
|
||||
OS << "error: invalid contribution to string offsets table in section ."
|
||||
<< SectionName << ".\n";
|
||||
return;
|
||||
}
|
||||
Format = DWARF64;
|
||||
EntrySize = 8;
|
||||
ContributionSize = StrOffsetExt.getU64(&Offset);
|
||||
} else if (ContributionSize > 0xfffffff0) {
|
||||
OS << "error: invalid contribution to string offsets table in section ."
|
||||
<< SectionName << ".\n";
|
||||
return;
|
||||
}
|
||||
|
||||
// We must ensure that we don't read a partial record at the end, so we
|
||||
// validate for a multiple of EntrySize. Also, we're expecting a version
|
||||
// number and padding, which adds an additional 4 bytes.
|
||||
uint64_t ValidationSize =
|
||||
4 + ((ContributionSize + EntrySize - 1) & (-(uint64_t)EntrySize));
|
||||
if (!StrOffsetExt.isValidOffsetForDataOfSize(Offset, ValidationSize)) {
|
||||
OS << "error: contribution to string offsets table in section ."
|
||||
<< SectionName << " has invalid length.\n";
|
||||
return;
|
||||
}
|
||||
|
||||
Version = StrOffsetExt.getU16(&Offset);
|
||||
Offset += 2;
|
||||
OS << format("0x%8.8x: ", ContributionStart);
|
||||
OS << "Contribution size = " << ContributionSize
|
||||
<< ", Version = " << Version << "\n";
|
||||
|
||||
uint32_t ContributionBase = Offset;
|
||||
DataExtractor StrData(StringSection, LittleEndian, 0);
|
||||
while (Offset - ContributionBase < ContributionSize) {
|
||||
OS << format("0x%8.8x: ", Offset);
|
||||
// FIXME: We can only extract strings in DWARF32 format at the moment.
|
||||
uint64_t StringOffset = getRelocatedValue(
|
||||
StrOffsetExt, EntrySize, &Offset, &StringOffsetsSection.Relocs);
|
||||
if (Format == DWARF32) {
|
||||
OS << format("%8.8x ", StringOffset);
|
||||
uint32_t StringOffset32 = (uint32_t)StringOffset;
|
||||
const char *S = StrData.getCStr(&StringOffset32);
|
||||
if (S)
|
||||
OS << format("\"%s\"", S);
|
||||
} else
|
||||
OS << format("%16.16x ", StringOffset);
|
||||
OS << "\n";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Dump a DWARF string offsets section. This may be a DWARF v5 formatted
|
||||
// string offsets section, where each compile or type unit contributes a
|
||||
// number of entries (string offsets), with each contribution preceded by
|
||||
// a header containing size and version number. Alternatively, it may be a
|
||||
// monolithic series of string offsets, as generated by the pre-DWARF v5
|
||||
// implementation of split DWARF.
|
||||
static void dumpStringOffsetsSection(raw_ostream &OS, StringRef SectionName,
|
||||
const DWARFSection &StringOffsetsSection,
|
||||
StringRef StringSection, bool LittleEndian,
|
||||
unsigned MaxVersion) {
|
||||
if (StringOffsetsSection.Data.empty())
|
||||
return;
|
||||
OS << "\n." << SectionName << " contents:\n";
|
||||
// If we have at least one (compile or type) unit with DWARF v5 or greater,
|
||||
// we assume that the section is formatted like a DWARF v5 string offsets
|
||||
// section.
|
||||
if (MaxVersion >= 5)
|
||||
dumpDWARFv5StringOffsetsSection(OS, SectionName, StringOffsetsSection,
|
||||
StringSection, LittleEndian);
|
||||
else {
|
||||
DataExtractor strOffsetExt(StringOffsetsSection.Data, LittleEndian, 0);
|
||||
uint32_t offset = 0;
|
||||
uint64_t size = StringOffsetsSection.Data.size();
|
||||
// Ensure that size is a multiple of the size of an entry.
|
||||
if (size & ((uint64_t)(sizeof(uint32_t) - 1))) {
|
||||
OS << "error: size of ." << SectionName << " is not a multiple of "
|
||||
<< sizeof(uint32_t) << ".\n";
|
||||
size &= -(uint64_t)sizeof(uint32_t);
|
||||
}
|
||||
DataExtractor StrData(StringSection, LittleEndian, 0);
|
||||
while (offset < size) {
|
||||
OS << format("0x%8.8x: ", offset);
|
||||
uint32_t StringOffset = strOffsetExt.getU32(&offset);
|
||||
OS << format("%8.8x ", StringOffset);
|
||||
const char *S = StrData.getCStr(&StringOffset);
|
||||
if (S)
|
||||
OS << format("\"%s\"", S);
|
||||
OS << "\n";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void DWARFContext::dump(raw_ostream &OS, DIDumpOptions DumpOpts){
|
||||
|
||||
DIDumpType DumpType = DumpOpts.DumpType;
|
||||
@ -258,17 +375,15 @@ void DWARFContext::dump(raw_ostream &OS, DIDumpOptions DumpOpts){
|
||||
true /* GnuStyle */)
|
||||
.dump("debug_gnu_pubtypes", OS);
|
||||
|
||||
if ((DumpType == DIDT_All || DumpType == DIDT_StrOffsetsDwo) &&
|
||||
!getStringOffsetDWOSection().empty()) {
|
||||
OS << "\n.debug_str_offsets.dwo contents:\n";
|
||||
DataExtractor strOffsetExt(getStringOffsetDWOSection(), isLittleEndian(),
|
||||
0);
|
||||
offset = 0;
|
||||
uint64_t size = getStringOffsetDWOSection().size();
|
||||
while (offset < size) {
|
||||
OS << format("0x%8.8x: ", offset);
|
||||
OS << format("%8.8x\n", strOffsetExt.getU32(&offset));
|
||||
}
|
||||
if (DumpType == DIDT_All || DumpType == DIDT_StrOffsets)
|
||||
dumpStringOffsetsSection(OS, "debug_str_offsets", getStringOffsetSection(),
|
||||
getStringSection(), isLittleEndian(),
|
||||
getMaxVersion());
|
||||
|
||||
if (DumpType == DIDT_All || DumpType == DIDT_StrOffsetsDwo) {
|
||||
dumpStringOffsetsSection(OS, "debug_str_offsets.dwo",
|
||||
getStringOffsetDWOSection(), getStringDWOSection(),
|
||||
isLittleEndian(), getMaxVersion());
|
||||
}
|
||||
|
||||
if ((DumpType == DIDT_All || DumpType == DIDT_GdbIndex) &&
|
||||
@ -1109,6 +1224,10 @@ DWARFContextInMemory::DWARFContextInMemory(const object::ObjectFile &Obj,
|
||||
TypesDWOSections[Section].Data = data;
|
||||
}
|
||||
|
||||
// Map platform specific debug section names to DWARF standard section
|
||||
// names.
|
||||
name = Obj.mapDebugSectionName(name);
|
||||
|
||||
if (RelocatedSection == Obj.section_end())
|
||||
continue;
|
||||
|
||||
@ -1141,6 +1260,7 @@ DWARFContextInMemory::DWARFContextInMemory(const object::ObjectFile &Obj,
|
||||
.Case("debug_loc", &LocSection.Relocs)
|
||||
.Case("debug_info.dwo", &InfoDWOSection.Relocs)
|
||||
.Case("debug_line", &LineSection.Relocs)
|
||||
.Case("debug_str_offsets", &StringOffsetSection.Relocs)
|
||||
.Case("debug_ranges", &RangeSection.Relocs)
|
||||
.Case("debug_addr", &AddrSection.Relocs)
|
||||
.Case("apple_names", &AppleNamesSection.Relocs)
|
||||
@ -1211,6 +1331,7 @@ StringRef *DWARFContextInMemory::MapSectionToMember(StringRef Name) {
|
||||
.Case("debug_frame", &DebugFrameSection)
|
||||
.Case("eh_frame", &EHFrameSection)
|
||||
.Case("debug_str", &StringSection)
|
||||
.Case("debug_str_offsets", &StringOffsetSection.Data)
|
||||
.Case("debug_ranges", &RangeSection.Data)
|
||||
.Case("debug_macinfo", &MacinfoSection)
|
||||
.Case("debug_pubnames", &PubNamesSection)
|
||||
@ -1222,7 +1343,7 @@ StringRef *DWARFContextInMemory::MapSectionToMember(StringRef Name) {
|
||||
.Case("debug_loc.dwo", &LocDWOSection.Data)
|
||||
.Case("debug_line.dwo", &LineDWOSection.Data)
|
||||
.Case("debug_str.dwo", &StringDWOSection)
|
||||
.Case("debug_str_offsets.dwo", &StringOffsetDWOSection)
|
||||
.Case("debug_str_offsets.dwo", &StringOffsetDWOSection.Data)
|
||||
.Case("debug_addr", &AddrSection.Data)
|
||||
.Case("apple_names", &AppleNamesSection.Data)
|
||||
.Case("apple_types", &AppleTypesSection.Data)
|
||||
|
@ -301,6 +301,7 @@ bool DWARFFormValue::isFormClass(DWARFFormValue::FormClass FC) const {
|
||||
return (FC == FC_Address);
|
||||
case DW_FORM_GNU_str_index:
|
||||
case DW_FORM_GNU_strp_alt:
|
||||
case DW_FORM_strx:
|
||||
return (FC == FC_String);
|
||||
case DW_FORM_implicit_const:
|
||||
return (FC == FC_Constant);
|
||||
@ -415,6 +416,7 @@ bool DWARFFormValue::extractValue(const DataExtractor &Data,
|
||||
break;
|
||||
case DW_FORM_GNU_addr_index:
|
||||
case DW_FORM_GNU_str_index:
|
||||
case DW_FORM_strx:
|
||||
Value.uval = Data.getULEB128(OffsetPtr);
|
||||
break;
|
||||
default:
|
||||
@ -542,6 +544,7 @@ void DWARFFormValue::dump(raw_ostream &OS) const {
|
||||
OS << format(" .debug_str[0x%8.8x] = ", (uint32_t)UValue);
|
||||
dumpString(OS);
|
||||
break;
|
||||
case DW_FORM_strx:
|
||||
case DW_FORM_GNU_str_index:
|
||||
OS << format(" indexed (%8.8x) string = ", (uint32_t)UValue);
|
||||
dumpString(OS);
|
||||
@ -620,10 +623,11 @@ Optional<const char *> DWARFFormValue::getAsCString() const {
|
||||
if (Form == DW_FORM_GNU_strp_alt || U == nullptr)
|
||||
return None;
|
||||
uint32_t Offset = Value.uval;
|
||||
if (Form == DW_FORM_GNU_str_index) {
|
||||
uint32_t StrOffset;
|
||||
if (Form == DW_FORM_GNU_str_index || Form == DW_FORM_strx) {
|
||||
uint64_t StrOffset;
|
||||
if (!U->getStringOffsetSectionItem(Offset, StrOffset))
|
||||
return None;
|
||||
StrOffset += U->getStringOffsetSectionRelocation(Offset);
|
||||
Offset = StrOffset;
|
||||
}
|
||||
if (const char *Str = U->getStringExtractor().getCStr(&Offset)) {
|
||||
|
@ -33,8 +33,9 @@ using namespace dwarf;
|
||||
|
||||
void DWARFUnitSectionBase::parse(DWARFContext &C, const DWARFSection &Section) {
|
||||
parseImpl(C, Section, C.getDebugAbbrev(), &C.getRangeSection(),
|
||||
C.getStringSection(), StringRef(), &C.getAddrSection(),
|
||||
C.getLineSection().Data, C.isLittleEndian(), false);
|
||||
C.getStringSection(), C.getStringOffsetSection(),
|
||||
&C.getAddrSection(), C.getLineSection().Data, C.isLittleEndian(),
|
||||
false);
|
||||
}
|
||||
|
||||
void DWARFUnitSectionBase::parseDWO(DWARFContext &C,
|
||||
@ -48,19 +49,14 @@ void DWARFUnitSectionBase::parseDWO(DWARFContext &C,
|
||||
|
||||
DWARFUnit::DWARFUnit(DWARFContext &DC, const DWARFSection &Section,
|
||||
const DWARFDebugAbbrev *DA, const DWARFSection *RS,
|
||||
StringRef SS, StringRef SOS, const DWARFSection *AOS,
|
||||
StringRef LS, bool LE, bool IsDWO,
|
||||
StringRef SS, const DWARFSection &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),
|
||||
LineSection(LS), StringSection(SS), StringOffsetSection([&]() {
|
||||
if (IndexEntry)
|
||||
if (const auto *C = IndexEntry->getOffset(DW_SECT_STR_OFFSETS))
|
||||
return SOS.slice(C->Offset, C->Offset + C->Length);
|
||||
return SOS;
|
||||
}()),
|
||||
AddrOffsetSection(AOS), isLittleEndian(LE), isDWO(IsDWO),
|
||||
UnitSection(UnitSection), IndexEntry(IndexEntry) {
|
||||
LineSection(LS), StringSection(SS), StringOffsetSection(SOS),
|
||||
StringOffsetSectionBase(0), AddrOffsetSection(AOS), isLittleEndian(LE),
|
||||
isDWO(IsDWO), UnitSection(UnitSection), IndexEntry(IndexEntry) {
|
||||
clear();
|
||||
}
|
||||
|
||||
@ -77,17 +73,25 @@ bool DWARFUnit::getAddrOffsetSectionItem(uint32_t Index,
|
||||
}
|
||||
|
||||
bool DWARFUnit::getStringOffsetSectionItem(uint32_t Index,
|
||||
uint32_t &Result) const {
|
||||
// FIXME: string offset section entries are 8-byte for DWARF64.
|
||||
const uint32_t ItemSize = 4;
|
||||
uint32_t Offset = Index * ItemSize;
|
||||
if (StringOffsetSection.size() < Offset + ItemSize)
|
||||
uint64_t &Result) const {
|
||||
unsigned ItemSize = getFormat() == DWARF64 ? 8 : 4;
|
||||
uint32_t Offset = StringOffsetSectionBase + Index * ItemSize;
|
||||
if (StringOffsetSection.Data.size() < Offset + ItemSize)
|
||||
return false;
|
||||
DataExtractor DA(StringOffsetSection, isLittleEndian, 0);
|
||||
Result = DA.getU32(&Offset);
|
||||
DataExtractor DA(StringOffsetSection.Data, isLittleEndian, 0);
|
||||
Result = ItemSize == 4 ? DA.getU32(&Offset) : DA.getU64(&Offset);
|
||||
return true;
|
||||
}
|
||||
|
||||
uint64_t DWARFUnit::getStringOffsetSectionRelocation(uint32_t Index) const {
|
||||
unsigned ItemSize = getFormat() == DWARF64 ? 8 : 4;
|
||||
uint64_t ByteOffset = StringOffsetSectionBase + Index * ItemSize;
|
||||
RelocAddrMap::const_iterator AI = getStringOffsetsRelocMap().find(ByteOffset);
|
||||
if (AI != getStringOffsetsRelocMap().end())
|
||||
return AI->second.Value;
|
||||
return 0;
|
||||
}
|
||||
|
||||
bool DWARFUnit::extractImpl(DataExtractor debug_info, uint32_t *offset_ptr) {
|
||||
Length = debug_info.getU32(offset_ptr);
|
||||
Version = debug_info.getU16(offset_ptr);
|
||||
@ -119,6 +123,9 @@ bool DWARFUnit::extractImpl(DataExtractor debug_info, uint32_t *offset_ptr) {
|
||||
if (!LengthOK || !VersionOK || !AddrSizeOK)
|
||||
return false;
|
||||
|
||||
// Keep track of the highest DWARF version we encounter across all units.
|
||||
Context.setMaxVersionIfGreater(Version);
|
||||
|
||||
Abbrevs = Abbrev->getAbbreviationDeclarationSet(AbbrOffset);
|
||||
return Abbrevs != nullptr;
|
||||
}
|
||||
@ -242,6 +249,17 @@ size_t DWARFUnit::extractDIEsIfNeeded(bool CUDieOnly) {
|
||||
setBaseAddress(*BaseAddr);
|
||||
AddrOffsetSectionBase = toSectionOffset(UnitDie.find(DW_AT_GNU_addr_base), 0);
|
||||
RangeSectionBase = toSectionOffset(UnitDie.find(DW_AT_rnglists_base), 0);
|
||||
|
||||
// In general, we derive the offset of the unit's contibution to the
|
||||
// debug_str_offsets{.dwo} section from the unit DIE's
|
||||
// DW_AT_str_offsets_base attribute. In dwp files we add to it the offset
|
||||
// we get from the index table.
|
||||
StringOffsetSectionBase =
|
||||
toSectionOffset(UnitDie.find(DW_AT_str_offsets_base), 0);
|
||||
if (IndexEntry)
|
||||
if (const auto *C = IndexEntry->getOffset(DW_SECT_STR_OFFSETS))
|
||||
StringOffsetSectionBase += C->Offset;
|
||||
|
||||
// Don't fall back to DW_AT_GNU_ranges_base: it should be ignored for
|
||||
// skeleton CU DIE, so that DWARF users not aware of it are not broken.
|
||||
}
|
||||
|
@ -241,6 +241,9 @@ void MCObjectFileInfo::initMachOMCObjectFileInfo(const Triple &T) {
|
||||
DwarfStrSection =
|
||||
Ctx->getMachOSection("__DWARF", "__debug_str", MachO::S_ATTR_DEBUG,
|
||||
SectionKind::getMetadata(), "info_string");
|
||||
DwarfStrOffSection =
|
||||
Ctx->getMachOSection("__DWARF", "__debug_str_offs", MachO::S_ATTR_DEBUG,
|
||||
SectionKind::getMetadata(), "section_str_off");
|
||||
DwarfLocSection =
|
||||
Ctx->getMachOSection("__DWARF", "__debug_loc", MachO::S_ATTR_DEBUG,
|
||||
SectionKind::getMetadata(), "section_debug_loc");
|
||||
@ -557,6 +560,11 @@ void MCObjectFileInfo::initELFMCObjectFileInfo(const Triple &T) {
|
||||
DwarfAccelTypesSection =
|
||||
Ctx->getELFSection(".apple_types", ELF::SHT_PROGBITS, 0);
|
||||
|
||||
// String Offset and Address Sections
|
||||
DwarfStrOffSection =
|
||||
Ctx->getELFSection(".debug_str_offsets", DebugSecType, 0);
|
||||
DwarfAddrSection = Ctx->getELFSection(".debug_addr", DebugSecType, 0);
|
||||
|
||||
// Fission Sections
|
||||
DwarfInfoDWOSection =
|
||||
Ctx->getELFSection(".debug_info.dwo", DebugSecType, 0);
|
||||
@ -573,7 +581,6 @@ void MCObjectFileInfo::initELFMCObjectFileInfo(const Triple &T) {
|
||||
Ctx->getELFSection(".debug_loc.dwo", DebugSecType, 0);
|
||||
DwarfStrOffDWOSection =
|
||||
Ctx->getELFSection(".debug_str_offsets.dwo", DebugSecType, 0);
|
||||
DwarfAddrSection = Ctx->getELFSection(".debug_addr", DebugSecType, 0);
|
||||
|
||||
// DWP Sections
|
||||
DwarfCUIndexSection =
|
||||
@ -695,6 +702,11 @@ void MCObjectFileInfo::initCOFFMCObjectFileInfo(const Triple &T) {
|
||||
COFF::IMAGE_SCN_MEM_DISCARDABLE | COFF::IMAGE_SCN_CNT_INITIALIZED_DATA |
|
||||
COFF::IMAGE_SCN_MEM_READ,
|
||||
SectionKind::getMetadata(), "info_string");
|
||||
DwarfStrOffSection = Ctx->getCOFFSection(
|
||||
".debug_str_offsets",
|
||||
COFF::IMAGE_SCN_MEM_DISCARDABLE | COFF::IMAGE_SCN_CNT_INITIALIZED_DATA |
|
||||
COFF::IMAGE_SCN_MEM_READ,
|
||||
SectionKind::getMetadata(), "section_str_off");
|
||||
DwarfLocSection = Ctx->getCOFFSection(
|
||||
".debug_loc",
|
||||
COFF::IMAGE_SCN_MEM_DISCARDABLE | COFF::IMAGE_SCN_CNT_INITIALIZED_DATA |
|
||||
@ -749,7 +761,7 @@ void MCObjectFileInfo::initCOFFMCObjectFileInfo(const Triple &T) {
|
||||
".debug_str_offsets.dwo",
|
||||
COFF::IMAGE_SCN_MEM_DISCARDABLE | COFF::IMAGE_SCN_CNT_INITIALIZED_DATA |
|
||||
COFF::IMAGE_SCN_MEM_READ,
|
||||
SectionKind::getMetadata());
|
||||
SectionKind::getMetadata(), "section_str_off_dwo");
|
||||
DwarfAddrSection = Ctx->getCOFFSection(
|
||||
".debug_addr",
|
||||
COFF::IMAGE_SCN_MEM_DISCARDABLE | COFF::IMAGE_SCN_CNT_INITIALIZED_DATA |
|
||||
|
@ -4314,3 +4314,9 @@ ObjectFile::createMachOObjectFile(MemoryBufferRef Buffer,
|
||||
return make_error<GenericBinaryError>("Unrecognized MachO magic number",
|
||||
object_error::invalid_file_type);
|
||||
}
|
||||
|
||||
StringRef MachOObjectFile::mapDebugSectionName(StringRef Name) const {
|
||||
return StringSwitch<StringRef>(Name)
|
||||
.Case("debug_str_offs", "debug_str_offsets")
|
||||
.Default(Name);
|
||||
}
|
||||
|
277
test/DebugInfo/Inputs/dwarfdump-str-offsets-dwp.s
Normal file
277
test/DebugInfo/Inputs/dwarfdump-str-offsets-dwp.s
Normal file
@ -0,0 +1,277 @@
|
||||
# Test object to verify that dwarfdump handles dwp files with DWARF v5 string
|
||||
# offset tables. We have 2 CUs and 2 TUs, where it is assumed that
|
||||
# CU1 and TU1 came from one object file, CU2 and TU2 from a second object
|
||||
# file.
|
||||
#
|
||||
# To generate the test object:
|
||||
# llvm-mc -triple x86_64-unknown-linux dwarfdump-str-offsets-dwp.s -filetype=obj \
|
||||
# -o dwarfdump-str_offsets-dwp.x86_64.o
|
||||
|
||||
.section .debug_str.dwo,"MS",@progbits,1
|
||||
str_producer:
|
||||
.asciz "Handmade DWARF producer"
|
||||
str_CU1:
|
||||
.asciz "Compile_Unit_1"
|
||||
str_CU1_dir:
|
||||
.asciz "/home/test/CU1"
|
||||
str_CU2:
|
||||
.asciz "Compile_Unit_2"
|
||||
str_CU2_dir:
|
||||
.asciz "/home/test/CU2"
|
||||
str_TU1:
|
||||
.asciz "Type_Unit_1"
|
||||
str_TU1_type:
|
||||
.asciz "MyStruct_1"
|
||||
str_TU2:
|
||||
.asciz "Type_Unit_2"
|
||||
str_TU2_type:
|
||||
.asciz "MyStruct_2"
|
||||
|
||||
.section .debug_str_offsets.dwo,"",@progbits
|
||||
# Object files 1's portion of the .debug_str_offsets.dwo section.
|
||||
.debug_str_offsets_object_file1:
|
||||
|
||||
# CU1's contribution (from object file 1)
|
||||
.debug_str_offsets_start_CU1:
|
||||
.long .debug_str_offsets_end_CU1-.debug_str_offsets_base_CU1
|
||||
.short 5 # DWARF version
|
||||
.short 0 # Padding
|
||||
.debug_str_offsets_base_CU1:
|
||||
.long str_producer-.debug_str.dwo
|
||||
.long str_CU1-.debug_str.dwo
|
||||
.long str_CU1_dir-.debug_str.dwo
|
||||
.debug_str_offsets_end_CU1:
|
||||
|
||||
# TU1's contribution (from object file 1)
|
||||
.debug_str_offsets_start_TU1:
|
||||
.long .debug_str_offsets_end_TU1-.debug_str_offsets_base_TU1
|
||||
.short 5 # DWARF version
|
||||
.short 0 # Padding
|
||||
.debug_str_offsets_base_TU1:
|
||||
.long str_TU1-.debug_str.dwo
|
||||
.long str_TU1_type-.debug_str.dwo
|
||||
.debug_str_offsets_end_TU1:
|
||||
|
||||
# Object files 2's portion of the .debug_str_offsets.dwo section.
|
||||
.debug_str_offsets_object_file2:
|
||||
|
||||
# CU2's contribution (from object file 2)
|
||||
.debug_str_offsets_start_CU2:
|
||||
.long .debug_str_offsets_end_CU2-.debug_str_offsets_base_CU2
|
||||
.short 5 # DWARF version
|
||||
.short 0 # Padding
|
||||
.debug_str_offsets_base_CU2:
|
||||
.long str_producer-.debug_str.dwo
|
||||
.long str_CU2-.debug_str.dwo
|
||||
.long str_CU2_dir-.debug_str.dwo
|
||||
.debug_str_offsets_end_CU2:
|
||||
|
||||
# TU2's contribution (from object file 2)
|
||||
.debug_str_offsets_start_TU2:
|
||||
.long .debug_str_offsets_end_TU2-.debug_str_offsets_base_TU2
|
||||
.short 5 # DWARF version
|
||||
.short 0 # Padding
|
||||
.debug_str_offsets_base_TU2:
|
||||
.long str_TU2-.debug_str.dwo
|
||||
.long str_TU2_type-.debug_str.dwo
|
||||
.debug_str_offsets_end_TU2:
|
||||
|
||||
|
||||
# Abbrevs are shared for all compile and type units
|
||||
.section .debug_abbrev.dwo,"",@progbits
|
||||
.byte 0x01 # Abbrev code
|
||||
.byte 0x11 # DW_TAG_compile_unit
|
||||
.byte 0x00 # DW_CHILDREN_no
|
||||
.byte 0x25 # DW_AT_producer
|
||||
.byte 0x1a # DW_FORM_strx
|
||||
.byte 0x03 # DW_AT_name
|
||||
.byte 0x1a # DW_FORM_strx
|
||||
.byte 0x72 # DW_AT_str_offsets_base
|
||||
.byte 0x17 # DW_FORM_sec_offset
|
||||
.byte 0x03 # DW_AT_name
|
||||
.byte 0x1a # DW_FORM_strx
|
||||
.byte 0x00 # EOM(1)
|
||||
.byte 0x00 # EOM(2)
|
||||
.byte 0x02 # Abbrev code
|
||||
.byte 0x41 # DW_TAG_type_unit
|
||||
.byte 0x01 # DW_CHILDREN_yes
|
||||
.byte 0x03 # DW_AT_name
|
||||
.byte 0x1a # DW_FORM_strx
|
||||
.byte 0x72 # DW_AT_str_offsets_base
|
||||
.byte 0x17 # DW_FORM_sec_offset
|
||||
.byte 0x00 # EOM(1)
|
||||
.byte 0x00 # EOM(2)
|
||||
.byte 0x03 # Abbrev code
|
||||
.byte 0x13 # DW_TAG_structure_type
|
||||
.byte 0x00 # DW_CHILDREN_no (no members)
|
||||
.byte 0x03 # DW_AT_name
|
||||
.byte 0x1a # DW_FORM_strx
|
||||
.byte 0x00 # EOM(1)
|
||||
.byte 0x00 # EOM(2)
|
||||
.byte 0x00 # EOM(3)
|
||||
abbrev_end:
|
||||
|
||||
.section .debug_info.dwo,"",@progbits
|
||||
|
||||
# DWARF v5 CU header.
|
||||
CU1_5_start:
|
||||
.long CU1_5_end-CU1_5_version # Length of Unit
|
||||
CU1_5_version:
|
||||
.short 5 # DWARF version number
|
||||
.byte 1 # DWARF Unit Type
|
||||
.byte 8 # Address Size (in bytes)
|
||||
.long .debug_abbrev.dwo # Offset Into Abbrev. Section
|
||||
# The compile-unit DIE, which has a DW_AT_producer, DW_AT_name,
|
||||
# DW_AT_str_offsets and DW_AT_compdir.
|
||||
.byte 1 # Abbreviation code
|
||||
.byte 0 # The index of the producer string
|
||||
.byte 1 # The index of the CU name string
|
||||
# The DW_AT_str_offsets_base attribute for CU1 contains the offset of CU1's
|
||||
# contribution relative to the start of object file 1's portion of the
|
||||
# .debug_str_offsets section.
|
||||
.long .debug_str_offsets_base_CU1-.debug_str_offsets_object_file1
|
||||
.byte 2 # The index of the comp dir string
|
||||
.byte 0 # NULL
|
||||
CU1_5_end:
|
||||
|
||||
CU2_5_start:
|
||||
.long CU2_5_end-CU2_5_version # Length of Unit
|
||||
CU2_5_version:
|
||||
.short 5 # DWARF version number
|
||||
.byte 1 # DWARF Unit Type
|
||||
.byte 8 # Address Size (in bytes)
|
||||
.long .debug_abbrev.dwo # Offset Into Abbrev. Section
|
||||
# The compile-unit DIE, which has a DW_AT_producer, DW_AT_name,
|
||||
# DW_AT_str_offsets and DW_AT_compdir.
|
||||
.byte 1 # Abbreviation code
|
||||
.byte 0 # The index of the producer string
|
||||
.byte 1 # The index of the CU name string
|
||||
# The DW_AT_str_offsets_base attribute for CU2 contains the offset of CU2's
|
||||
# contribution relative to the start of object file 2's portion of the
|
||||
# .debug_str_offsets section.
|
||||
.long .debug_str_offsets_base_CU2-.debug_str_offsets_object_file2
|
||||
.byte 2 # The index of the comp dir string
|
||||
.byte 0 # NULL
|
||||
CU2_5_end:
|
||||
|
||||
.section .debug_types.dwo,"",@progbits
|
||||
# DWARF v5 Type unit header.
|
||||
TU1_5_start:
|
||||
.long TU1_5_end-TU1_5_version # Length of Unit
|
||||
TU1_5_version:
|
||||
.short 5 # DWARF version number
|
||||
.byte 2 # DWARF Unit Type
|
||||
.byte 8 # Address Size (in bytes)
|
||||
.long .debug_abbrev.dwo # Offset Into Abbrev. Section
|
||||
.quad 0x0011223344556677 # Type Signature
|
||||
.long TU1_5_type-TU1_5_start # Type offset
|
||||
# The type-unit DIE, which has a name.
|
||||
.byte 2 # Abbreviation code
|
||||
.byte 0 # Index of the unit type name string
|
||||
# The DW_AT_str_offsets_base attribute for TU1 contains the offset of TU1's
|
||||
# contribution relative to the start of object file 1's portion of the
|
||||
# .debug_str_offsets section.
|
||||
.long .debug_str_offsets_base_TU1-.debug_str_offsets_object_file1
|
||||
# The type DIE, which has a name.
|
||||
TU1_5_type:
|
||||
.byte 3 # Abbreviation code
|
||||
.byte 1 # Index of the type name string
|
||||
.byte 0 # NULL
|
||||
.byte 0 # NULL
|
||||
TU1_5_end:
|
||||
|
||||
TU2_5_start:
|
||||
.long TU2_5_end-TU2_5_version # Length of Unit
|
||||
TU2_5_version:
|
||||
.short 5 # DWARF version number
|
||||
.byte 2 # DWARF Unit Type
|
||||
.byte 8 # Address Size (in bytes)
|
||||
.long .debug_abbrev.dwo # Offset Into Abbrev. Section
|
||||
.quad 0x00aabbccddeeff99 # Type Signature
|
||||
.long TU2_5_type-TU2_5_start # Type offset
|
||||
# The type-unit DIE, which has a name.
|
||||
.byte 2 # Abbreviation code
|
||||
.byte 0 # Index of the unit type name string
|
||||
# The DW_AT_str_offsets_base attribute for TU2 contains the offset of TU2's
|
||||
# contribution relative to the start of object file 2's portion of the
|
||||
# .debug_str_offsets section.
|
||||
.long .debug_str_offsets_base_TU2-.debug_str_offsets_object_file2
|
||||
# The type DIE, which has a name.
|
||||
TU2_5_type:
|
||||
.byte 3 # Abbreviation code
|
||||
.byte 1 # Index of the type name string
|
||||
.byte 0 # NULL
|
||||
.byte 0 # NULL
|
||||
TU2_5_end:
|
||||
|
||||
.section .debug_cu_index,"",@progbits
|
||||
# The index header
|
||||
.long 2 # Version
|
||||
.long 3 # Columns of contribution matrix
|
||||
.long 2 # number of units
|
||||
.long 2 # number of hash buckets in table
|
||||
|
||||
# The signatures for both CUs.
|
||||
.quad 0xddeeaaddbbaabbee # signature 1
|
||||
.quad 0xff00ffeeffaaff00 # signature 2
|
||||
# The indexes for both CUs.
|
||||
.long 1 # index 1
|
||||
.long 2 # index 2
|
||||
# The sections to which both CUs contribute.
|
||||
.long 1 # DW_SECT_INFO
|
||||
.long 3 # DW_SECT_ABBREV
|
||||
.long 6 # DW_SECT_STR_OFFSETS
|
||||
|
||||
# The starting offsets of both CU's contributions to info,
|
||||
# abbrev and string offsets table.
|
||||
.long CU1_5_start-.debug_info.dwo
|
||||
.long 0
|
||||
.long .debug_str_offsets_object_file1-.debug_str_offsets.dwo
|
||||
.long CU2_5_start-.debug_info.dwo
|
||||
.long 0
|
||||
.long .debug_str_offsets_object_file2-.debug_str_offsets.dwo
|
||||
|
||||
# The lengths of both CU's contributions to info, abbrev and
|
||||
# string offsets table.
|
||||
.long CU1_5_end-CU1_5_start
|
||||
.long abbrev_end-.debug_abbrev.dwo
|
||||
.long .debug_str_offsets_end_CU1-.debug_str_offsets_start_CU1
|
||||
.long CU2_5_end-CU2_5_start
|
||||
.long abbrev_end-.debug_abbrev.dwo
|
||||
.long .debug_str_offsets_end_CU2-.debug_str_offsets_start_CU2
|
||||
|
||||
.section .debug_tu_index,"",@progbits
|
||||
# The index header
|
||||
.long 2 # Version
|
||||
.long 3 # Columns of contribution matrix
|
||||
.long 2 # number of units
|
||||
.long 2 # number of hash buckets in table
|
||||
|
||||
# The signatures for both TUs.
|
||||
.quad 0xeeaaddbbaabbeedd # signature 1
|
||||
.quad 0x00ffeeffaaff00ff # signature 2
|
||||
# The indexes for both TUs.
|
||||
.long 1 # index 1
|
||||
.long 2 # index 2
|
||||
# The sections to which both TUs contribute.
|
||||
.long 2 # DW_SECT_TYPES
|
||||
.long 3 # DW_SECT_ABBREV
|
||||
.long 6 # DW_SECT_STR_OFFSETS
|
||||
|
||||
# The starting offsets of both TU's contributions to info,
|
||||
# abbrev and string offsets table.
|
||||
.long TU1_5_start-.debug_types.dwo
|
||||
.long 0
|
||||
.long .debug_str_offsets_object_file1-.debug_str_offsets.dwo
|
||||
.long TU2_5_start-.debug_types.dwo
|
||||
.long 0
|
||||
.long .debug_str_offsets_object_file2-.debug_str_offsets.dwo
|
||||
|
||||
# The lengths of both TU's contributions to info, abbrev and
|
||||
# string offsets table.
|
||||
.long TU1_5_end-TU1_5_start
|
||||
.long abbrev_end-.debug_abbrev.dwo
|
||||
.long .debug_str_offsets_end_TU1-.debug_str_offsets_start_TU1
|
||||
.long TU2_5_end-TU2_5_start
|
||||
.long abbrev_end-.debug_abbrev.dwo
|
||||
.long .debug_str_offsets_end_TU2-.debug_str_offsets_start_TU2
|
34
test/DebugInfo/Inputs/dwarfdump-str-offsets-invalid-1.s
Normal file
34
test/DebugInfo/Inputs/dwarfdump-str-offsets-invalid-1.s
Normal file
@ -0,0 +1,34 @@
|
||||
# Test object to verify that llvm-dwarfdump handles an invalid string offsets
|
||||
# table.
|
||||
#
|
||||
# To generate the test object:
|
||||
# llvm-mc -triple x86_64-unknown-linux dwarfdump-str-offsets-invalid-1.s -filetype=obj \
|
||||
# -o dwarfdump-str-offsets-invalid-1.x86_64.o
|
||||
#
|
||||
# A rudimentary abbrev section.
|
||||
.section .debug_abbrev,"",@progbits
|
||||
.byte 0x01 # Abbrev code
|
||||
.byte 0x11 # DW_TAG_compile_unit
|
||||
.byte 0x00 # DW_CHILDREN_no
|
||||
.byte 0x00 # EOM(1)
|
||||
.byte 0x00 # EOM(2)
|
||||
.byte 0x00 # EOM(3)
|
||||
|
||||
# A rudimentary compile unit to convince dwarfdump that we are dealing with a
|
||||
# DWARF v5 string offsets table.
|
||||
.section .debug_info,"",@progbits
|
||||
|
||||
# DWARF v5 CU header.
|
||||
.long CU1_5_end-CU1_5_version # Length of Unit
|
||||
CU1_5_version:
|
||||
.short 5 # DWARF version number
|
||||
.byte 1 # DWARF Unit Type
|
||||
.byte 8 # Address Size (in bytes)
|
||||
.long .debug_abbrev # Offset Into Abbrev. Section
|
||||
# A compile-unit DIE, which has no attributes.
|
||||
.byte 1 # Abbreviation code
|
||||
CU1_5_end:
|
||||
|
||||
.section .debug_str_offsets,"",@progbits
|
||||
# A degenerate section, not enough for a single contribution size.
|
||||
.byte 2
|
BIN
test/DebugInfo/Inputs/dwarfdump-str-offsets-invalid-1.x86_64.o
Normal file
BIN
test/DebugInfo/Inputs/dwarfdump-str-offsets-invalid-1.x86_64.o
Normal file
Binary file not shown.
36
test/DebugInfo/Inputs/dwarfdump-str-offsets-invalid-2.s
Normal file
36
test/DebugInfo/Inputs/dwarfdump-str-offsets-invalid-2.s
Normal file
@ -0,0 +1,36 @@
|
||||
# Test object to verify that llvm-dwarfdump handles an invalid string offsets
|
||||
# table.
|
||||
#
|
||||
# To generate the test object:
|
||||
# llvm-mc -triple x86_64-unknown-linux dwarfdump-str-offsets-invalid-2.s -filetype=obj \
|
||||
# -o dwarfdump-str-offsets-invalid-2.x86_64.o
|
||||
|
||||
# A rudimentary abbrev section.
|
||||
.section .debug_abbrev,"",@progbits
|
||||
.byte 0x01 # Abbrev code
|
||||
.byte 0x11 # DW_TAG_compile_unit
|
||||
.byte 0x00 # DW_CHILDREN_no
|
||||
.byte 0x00 # EOM(1)
|
||||
.byte 0x00 # EOM(2)
|
||||
.byte 0x00 # EOM(3)
|
||||
|
||||
# A rudimentary compile unit to convince dwarfdump that we are dealing with a
|
||||
# DWARF v5 string offsets table.
|
||||
.section .debug_info,"",@progbits
|
||||
|
||||
# DWARF v5 CU header.
|
||||
.long CU1_5_end-CU1_5_version # Length of Unit
|
||||
CU1_5_version:
|
||||
.short 5 # DWARF version number
|
||||
.byte 1 # DWARF Unit Type
|
||||
.byte 8 # Address Size (in bytes)
|
||||
.long .debug_abbrev # Offset Into Abbrev. Section
|
||||
# A compile-unit DIE, which has no attributes.
|
||||
.byte 1 # Abbreviation code
|
||||
CU1_5_end:
|
||||
|
||||
.section .debug_str_offsets,"",@progbits
|
||||
# A degenerate section with fewer bytes than required for a DWARF64 size.
|
||||
.long 0xffffffff
|
||||
.long 0
|
||||
.short 4
|
BIN
test/DebugInfo/Inputs/dwarfdump-str-offsets-invalid-2.x86_64.o
Normal file
BIN
test/DebugInfo/Inputs/dwarfdump-str-offsets-invalid-2.x86_64.o
Normal file
Binary file not shown.
88
test/DebugInfo/Inputs/dwarfdump-str-offsets-invalid-3.s
Normal file
88
test/DebugInfo/Inputs/dwarfdump-str-offsets-invalid-3.s
Normal file
@ -0,0 +1,88 @@
|
||||
# Test object to verify that llvm-dwarfdump handles an invalid string offsets
|
||||
# table.
|
||||
#
|
||||
# To generate the test object:
|
||||
# llvm-mc -triple x86_64-unknown-linux dwarfdump-str-offsets-invalid-3.s -filetype=obj \
|
||||
# -o dwarfdump-str-offsets-invalid-3.x86_64.o
|
||||
|
||||
.section .debug_str,"MS",@progbits,1
|
||||
str_producer:
|
||||
.asciz "Handmade DWARF producer"
|
||||
str_CU1:
|
||||
.asciz "Compile_Unit_1"
|
||||
str_CU1_dir:
|
||||
.asciz "/home/test/CU1"
|
||||
str_CU2:
|
||||
.asciz "Compile_Unit_2"
|
||||
str_CU2_dir:
|
||||
.asciz "/home/test/CU2"
|
||||
str_TU:
|
||||
.asciz "Type_Unit"
|
||||
str_TU_type:
|
||||
.asciz "MyStruct"
|
||||
|
||||
.section .debug_str.dwo,"MS",@progbits,1
|
||||
dwo_str_CU_5_producer:
|
||||
.asciz "Handmade split DWARF producer"
|
||||
dwo_str_CU_5_name:
|
||||
.asciz "V5_split_compile_unit"
|
||||
dwo_str_CU_5_comp_dir:
|
||||
.asciz "/home/test/splitCU"
|
||||
dwo_str_TU_5:
|
||||
.asciz "V5_split_type_unit"
|
||||
dwo_str_TU_5_type:
|
||||
.asciz "V5_split_Mystruct"
|
||||
|
||||
# A rudimentary abbrev section.
|
||||
.section .debug_abbrev,"",@progbits
|
||||
.byte 0x01 # Abbrev code
|
||||
.byte 0x11 # DW_TAG_compile_unit
|
||||
.byte 0x00 # DW_CHILDREN_no
|
||||
.byte 0x00 # EOM(1)
|
||||
.byte 0x00 # EOM(2)
|
||||
.byte 0x00 # EOM(3)
|
||||
|
||||
# A rudimentary compile unit to convince dwarfdump that we are dealing with a
|
||||
# DWARF v5 string offsets table.
|
||||
.section .debug_info,"",@progbits
|
||||
|
||||
# DWARF v5 CU header.
|
||||
.long CU1_5_end-CU1_5_version # Length of Unit
|
||||
CU1_5_version:
|
||||
.short 5 # DWARF version number
|
||||
.byte 1 # DWARF Unit Type
|
||||
.byte 8 # Address Size (in bytes)
|
||||
.long .debug_abbrev # Offset Into Abbrev. Section
|
||||
# A compile-unit DIE, which has no attributes.
|
||||
.byte 1 # Abbreviation code
|
||||
CU1_5_end:
|
||||
|
||||
.section .debug_str_offsets,"",@progbits
|
||||
# CU1's contribution
|
||||
# Invalid length
|
||||
.long 0xfffffffe
|
||||
.long .debug_str_offsets_segment0_end-.debug_str_offsets_base0
|
||||
.short 5 # DWARF version
|
||||
.short 0 # Padding
|
||||
.debug_str_offsets_base0:
|
||||
.long str_producer
|
||||
.long str_CU1
|
||||
.long str_CU1_dir
|
||||
.debug_str_offsets_segment0_end:
|
||||
# CU2's contribution
|
||||
.long .debug_str_offsets_segment1_end-.debug_str_offsets_base1
|
||||
.short 5 # DWARF version
|
||||
.short 0 # Padding
|
||||
.debug_str_offsets_base1:
|
||||
.long str_producer
|
||||
.long str_CU2
|
||||
.long str_CU2_dir
|
||||
.debug_str_offsets_segment1_end:
|
||||
# The TU's contribution
|
||||
.long .debug_str_offsets_segment2_end-.debug_str_offsets_base2
|
||||
.short 5 # DWARF version
|
||||
.short 0 # Padding
|
||||
.debug_str_offsets_base2:
|
||||
.long str_TU
|
||||
.long str_TU_type
|
||||
.debug_str_offsets_segment2_end:
|
BIN
test/DebugInfo/Inputs/dwarfdump-str-offsets-invalid-3.x86_64.o
Normal file
BIN
test/DebugInfo/Inputs/dwarfdump-str-offsets-invalid-3.x86_64.o
Normal file
Binary file not shown.
50
test/DebugInfo/Inputs/dwarfdump-str-offsets-invalid-4.s
Normal file
50
test/DebugInfo/Inputs/dwarfdump-str-offsets-invalid-4.s
Normal file
@ -0,0 +1,50 @@
|
||||
# Test object to verify that llvm-dwarfdump handles an invalid string offsets
|
||||
# table.
|
||||
#
|
||||
# To generate the test object:
|
||||
# llvm-mc -triple x86_64-unknown-linux dwarfdump-str-offsets-invalid-4.s -filetype=obj \
|
||||
# -o dwarfdump-str-offsets-invalid-4.x86_64.o
|
||||
|
||||
.section .debug_str,"MS",@progbits,1
|
||||
str_producer:
|
||||
.asciz "Handmade DWARF producer"
|
||||
str_CU1:
|
||||
.asciz "Compile_Unit_1"
|
||||
|
||||
# A rudimentary abbrev section.
|
||||
.section .debug_abbrev,"",@progbits
|
||||
.byte 0x01 # Abbrev code
|
||||
.byte 0x11 # DW_TAG_compile_unit
|
||||
.byte 0x00 # DW_CHILDREN_no
|
||||
.byte 0x00 # EOM(1)
|
||||
.byte 0x00 # EOM(2)
|
||||
.byte 0x00 # EOM(3)
|
||||
|
||||
# A rudimentary compile unit to convince dwarfdump that we are dealing with a
|
||||
# DWARF v5 string offsets table.
|
||||
.section .debug_info,"",@progbits
|
||||
|
||||
# DWARF v5 CU header.
|
||||
.long CU1_5_end-CU1_5_version # Length of Unit
|
||||
CU1_5_version:
|
||||
.short 5 # DWARF version number
|
||||
.byte 1 # DWARF Unit Type
|
||||
.byte 8 # Address Size (in bytes)
|
||||
.long .debug_abbrev # Offset Into Abbrev. Section
|
||||
# A compile-unit DIE, which has no attributes.
|
||||
.byte 1 # Abbreviation code
|
||||
CU1_5_end:
|
||||
|
||||
# Every unit contributes to the string_offsets table.
|
||||
.section .debug_str_offsets,"",@progbits
|
||||
# CU1's contribution
|
||||
# The length is not a multiple of 4. Check that we don't read off the
|
||||
# end.
|
||||
.long .debug_str_offsets_segment0_end-.debug_str_offsets_base0
|
||||
.short 5 # DWARF version
|
||||
.short 0 # Padding
|
||||
.debug_str_offsets_base0:
|
||||
.long str_producer
|
||||
.long str_CU1
|
||||
.byte 0
|
||||
.debug_str_offsets_segment0_end:
|
BIN
test/DebugInfo/Inputs/dwarfdump-str-offsets-invalid-4.x86_64.o
Normal file
BIN
test/DebugInfo/Inputs/dwarfdump-str-offsets-invalid-4.x86_64.o
Normal file
Binary file not shown.
10
test/DebugInfo/Inputs/dwarfdump-str-offsets-invalid-5.s
Normal file
10
test/DebugInfo/Inputs/dwarfdump-str-offsets-invalid-5.s
Normal file
@ -0,0 +1,10 @@
|
||||
# Test object to verify that llvm-dwarfdump handles a degenerate string offsets
|
||||
# section.
|
||||
#
|
||||
# To generate the test object:
|
||||
# llvm-mc -triple x86_64-unknown-linux dwarfdump-str-offsets-invalid-5.s -filetype=obj \
|
||||
# -o dwarfdump-str-offsets-invalid-5.x86_64.o
|
||||
# Every unit contributes to the string_offsets table.
|
||||
.section .debug_str_offsets,"",@progbits
|
||||
# A degenerate section, not enough for a single entry.
|
||||
.byte 2
|
BIN
test/DebugInfo/Inputs/dwarfdump-str-offsets-invalid-5.x86_64.o
Normal file
BIN
test/DebugInfo/Inputs/dwarfdump-str-offsets-invalid-5.x86_64.o
Normal file
Binary file not shown.
500
test/DebugInfo/Inputs/dwarfdump-str-offsets.s
Normal file
500
test/DebugInfo/Inputs/dwarfdump-str-offsets.s
Normal file
@ -0,0 +1,500 @@
|
||||
# Test object to verify dwarfdump handles v5 string offset tables.
|
||||
# We have 2 v5 CUs, a v5 TU, and a split v5 CU and TU.
|
||||
#
|
||||
# To generate the test object:
|
||||
# llvm-mc -triple x86_64-unknown-linux dwarfdump-str-offsets.s -filetype=obj \
|
||||
# -o dwarfdump-str-offsets.x86_64.o
|
||||
|
||||
.section .debug_str,"MS",@progbits,1
|
||||
str_producer:
|
||||
.asciz "Handmade DWARF producer"
|
||||
str_CU1:
|
||||
.asciz "Compile_Unit_1"
|
||||
str_CU1_dir:
|
||||
.asciz "/home/test/CU1"
|
||||
str_CU2:
|
||||
.asciz "Compile_Unit_2"
|
||||
str_CU2_dir:
|
||||
.asciz "/home/test/CU2"
|
||||
str_TU:
|
||||
.asciz "Type_Unit"
|
||||
str_TU_type:
|
||||
.asciz "MyStruct"
|
||||
|
||||
# Every unit contributes to the string_offsets table.
|
||||
.section .debug_str_offsets,"",@progbits
|
||||
# CU1's contribution
|
||||
.long .debug_str_offsets_segment0_end-.debug_str_offsets_base0
|
||||
.short 5 # DWARF version
|
||||
.short 0 # Padding
|
||||
.debug_str_offsets_base0:
|
||||
.long str_producer
|
||||
.long str_CU1
|
||||
.long str_CU1_dir
|
||||
.debug_str_offsets_segment0_end:
|
||||
# CU2's contribution
|
||||
.long .debug_str_offsets_segment1_end-.debug_str_offsets_base1
|
||||
.short 5 # DWARF version
|
||||
.short 0 # Padding
|
||||
.debug_str_offsets_base1:
|
||||
.long str_producer
|
||||
.long str_CU2
|
||||
.long str_CU2_dir
|
||||
.debug_str_offsets_segment1_end:
|
||||
# The TU's contribution
|
||||
.long .debug_str_offsets_segment2_end-.debug_str_offsets_base2
|
||||
.short 5 # DWARF version
|
||||
.short 0 # Padding
|
||||
.debug_str_offsets_base2:
|
||||
.long str_TU
|
||||
.long str_TU_type
|
||||
.debug_str_offsets_segment2_end:
|
||||
|
||||
.section .debug_str.dwo,"MS",@progbits,1
|
||||
dwo_str_CU_5_producer:
|
||||
.asciz "Handmade split DWARF producer"
|
||||
dwo_str_CU_5_name:
|
||||
.asciz "V5_split_compile_unit"
|
||||
dwo_str_CU_5_comp_dir:
|
||||
.asciz "/home/test/splitCU"
|
||||
dwo_str_TU_5:
|
||||
.asciz "V5_split_type_unit"
|
||||
dwo_str_TU_5_type:
|
||||
.asciz "V5_split_Mystruct"
|
||||
|
||||
.section .debug_str_offsets.dwo,"",@progbits
|
||||
# The split CU's contribution
|
||||
.long .debug_dwo_str_offsets_segment0_end-.debug_dwo_str_offsets_base0
|
||||
.short 5 # DWARF version
|
||||
.short 0 # Padding
|
||||
.debug_dwo_str_offsets_base0:
|
||||
.long dwo_str_CU_5_producer-.debug_str.dwo
|
||||
.long dwo_str_CU_5_name-.debug_str.dwo
|
||||
.long dwo_str_CU_5_comp_dir-.debug_str.dwo
|
||||
.debug_dwo_str_offsets_segment0_end:
|
||||
# The split TU's contribution
|
||||
.long .debug_dwo_str_offsets_segment1_end-.debug_dwo_str_offsets_base1
|
||||
.short 5 # DWARF version
|
||||
.short 0 # Padding
|
||||
.debug_dwo_str_offsets_base1:
|
||||
.long dwo_str_TU_5-.debug_str.dwo
|
||||
.long dwo_str_TU_5_type-.debug_str.dwo
|
||||
.debug_dwo_str_offsets_segment1_end:
|
||||
|
||||
# All CUs/TUs use the same abbrev section for simplicity.
|
||||
.section .debug_abbrev,"",@progbits
|
||||
.byte 0x01 # Abbrev code
|
||||
.byte 0x11 # DW_TAG_compile_unit
|
||||
.byte 0x00 # DW_CHILDREN_no
|
||||
.byte 0x25 # DW_AT_producer
|
||||
.byte 0x1a # DW_FORM_strx
|
||||
.byte 0x03 # DW_AT_name
|
||||
.byte 0x1a # DW_FORM_strx
|
||||
.byte 0x72 # DW_AT_str_offsets_base
|
||||
.byte 0x17 # DW_FORM_sec_offset
|
||||
.byte 0x1b # DW_AT_comp_dir
|
||||
.byte 0x1a # DW_FORM_strx
|
||||
.byte 0x00 # EOM(1)
|
||||
.byte 0x00 # EOM(2)
|
||||
.byte 0x02 # Abbrev code
|
||||
.byte 0x41 # DW_TAG_type_unit
|
||||
.byte 0x01 # DW_CHILDREN_yes
|
||||
.byte 0x03 # DW_AT_name
|
||||
.byte 0x1a # DW_FORM_strx
|
||||
.byte 0x72 # DW_AT_str_offsets_base
|
||||
.byte 0x17 # DW_FORM_sec_offset
|
||||
.byte 0x00 # EOM(1)
|
||||
.byte 0x00 # EOM(2)
|
||||
.byte 0x03 # Abbrev code
|
||||
.byte 0x13 # DW_TAG_structure_type
|
||||
.byte 0x00 # DW_CHILDREN_no (no members)
|
||||
.byte 0x03 # DW_AT_name
|
||||
.byte 0x1a # DW_FORM_strx
|
||||
.byte 0x00 # EOM(1)
|
||||
.byte 0x00 # EOM(2)
|
||||
.byte 0x00 # EOM(3)
|
||||
|
||||
# And a .dwo copy for the .dwo sections.
|
||||
.section .debug_abbrev.dwo,"",@progbits
|
||||
.byte 0x01 # Abbrev code
|
||||
.byte 0x11 # DW_TAG_compile_unit
|
||||
.byte 0x00 # DW_CHILDREN_no
|
||||
.byte 0x25 # DW_AT_producer
|
||||
.byte 0x1a # DW_FORM_strx
|
||||
.byte 0x03 # DW_AT_name
|
||||
.byte 0x1a # DW_FORM_strx
|
||||
.byte 0x72 # DW_AT_str_offsets_base
|
||||
.byte 0x17 # DW_FORM_sec_offset
|
||||
.byte 0x1b # DW_AT_comp_dir
|
||||
.byte 0x1a # DW_FORM_strx
|
||||
.byte 0x00 # EOM(1)
|
||||
.byte 0x00 # EOM(2)
|
||||
.byte 0x02 # Abbrev code
|
||||
.byte 0x41 # DW_TAG_type_unit
|
||||
.byte 0x01 # DW_CHILDREN_yes
|
||||
.byte 0x03 # DW_AT_name
|
||||
.byte 0x1a # DW_FORM_strx
|
||||
.byte 0x72 # DW_AT_str_offsets_base
|
||||
.byte 0x17 # DW_FORM_sec_offset
|
||||
.byte 0x00 # EOM(1)
|
||||
.byte 0x00 # EOM(2)
|
||||
.byte 0x03 # Abbrev code
|
||||
.byte 0x13 # DW_TAG_structure_type
|
||||
.byte 0x00 # DW_CHILDREN_no (no members)
|
||||
.byte 0x03 # DW_AT_name
|
||||
.byte 0x1a # DW_FORM_strx
|
||||
.byte 0x00 # EOM(1)
|
||||
.byte 0x00 # EOM(2)
|
||||
.byte 0x00 # EOM(3)
|
||||
|
||||
.section .debug_info,"",@progbits
|
||||
|
||||
# DWARF v5 CU header.
|
||||
.long CU1_5_end-CU1_5_version # Length of Unit
|
||||
CU1_5_version:
|
||||
.short 5 # DWARF version number
|
||||
.byte 1 # DWARF Unit Type
|
||||
.byte 8 # Address Size (in bytes)
|
||||
.long .debug_abbrev # Offset Into Abbrev. Section
|
||||
# The compile-unit DIE, which has a DW_AT_producer, DW_AT_name,
|
||||
# DW_AT_str_offsets and DW_AT_compdir.
|
||||
.byte 1 # Abbreviation code
|
||||
.byte 0 # The index of the producer string
|
||||
.byte 1 # The index of the CU name string
|
||||
.long .debug_str_offsets_base0
|
||||
.byte 2 # The index of the comp dir string
|
||||
.byte 0 # NULL
|
||||
CU1_5_end:
|
||||
|
||||
# DWARF v5 CU header
|
||||
.long CU2_5_end-CU2_5_version # Length of Unit
|
||||
CU2_5_version:
|
||||
.short 5 # DWARF version number
|
||||
.byte 1 # DWARF Unit Type
|
||||
.byte 8 # Address Size (in bytes)
|
||||
.long .debug_abbrev # Offset Into Abbrev. Section
|
||||
# The compile-unit DIE, which has a DW_AT_producer, DW_AT_name,
|
||||
# DW_AT_str_offsets and DW_AT_compdir.
|
||||
.byte 1 # Abbreviation code
|
||||
.byte 0 # The index of the producer string
|
||||
.byte 1 # The index of the CU name string
|
||||
.long .debug_str_offsets_base1
|
||||
.byte 2 # The index of the comp dir string
|
||||
.byte 0 # NULL
|
||||
CU2_5_end:
|
||||
|
||||
.section .debug_types,"",@progbits
|
||||
# DWARF v5 Type unit header.
|
||||
TU_5_start:
|
||||
.long TU_5_end-TU_5_version # Length of Unit
|
||||
TU_5_version:
|
||||
.short 5 # DWARF version number
|
||||
.byte 2 # DWARF Unit Type
|
||||
.byte 8 # Address Size (in bytes)
|
||||
.long .debug_abbrev # Offset Into Abbrev. Section
|
||||
.quad 0x0011223344556677 # Type Signature
|
||||
.long TU_5_type-TU_5_start # Type offset
|
||||
# The type-unit DIE, which has a name.
|
||||
.byte 2 # Abbreviation code
|
||||
.byte 0 # Index of the unit type name string
|
||||
.long .debug_str_offsets_base2 # offset into the str_offsets section
|
||||
# The type DIE, which has a name.
|
||||
TU_5_type:
|
||||
.byte 3 # Abbreviation code
|
||||
.byte 1 # Index of the type name string
|
||||
.byte 0 # NULL
|
||||
.byte 0 # NULL
|
||||
TU_5_end:
|
||||
|
||||
.section .debug_info.dwo,"",@progbits
|
||||
|
||||
# DWARF v5 split CU header.
|
||||
.long CU_split_5_end-CU_split_5_version # Length of Unit
|
||||
CU_split_5_version:
|
||||
.short 5 # DWARF version number
|
||||
.byte 1 # DWARF Unit Type
|
||||
.byte 8 # Address Size (in bytes)
|
||||
.long .debug_abbrev.dwo # Offset Into Abbrev Section
|
||||
# The compile-unit DIE, which has a DW_AT_producer, DW_AT_name,
|
||||
# DW_AT_str_offsets and DW_AT_compdir.
|
||||
.byte 1 # Abbreviation code
|
||||
.byte 0 # The index of the producer string
|
||||
.byte 1 # The index of the CU name string
|
||||
.long .debug_dwo_str_offsets_base0-.debug_str_offsets.dwo
|
||||
.byte 2 # The index of the comp dir string
|
||||
.byte 0 # NULL
|
||||
CU_split_5_end:
|
||||
|
||||
.section .debug_types.dwo,"",@progbits
|
||||
|
||||
# DWARF v5 split type unit header.
|
||||
TU_split_5_start:
|
||||
.long TU_split_5_end-TU_split_5_version # Length of Unit
|
||||
TU_split_5_version:
|
||||
.short 5 # DWARF version number
|
||||
.byte 6 # DWARF Unit Type
|
||||
.byte 8 # Address Size (in bytes)
|
||||
.long .debug_abbrev.dwo # Offset Into Abbrev Section
|
||||
.quad 0x8899aabbccddeeff # Type Signature
|
||||
.long TU_split_5_type-TU_split_5_start # Type offset
|
||||
# The type-unit DIE, which has a name.
|
||||
.byte 2 # Abbreviation code
|
||||
.byte 0 # The index of the type unit name string
|
||||
.long .debug_dwo_str_offsets_base1-.debug_str_offsets.dwo
|
||||
# The type DIE, which has a name.
|
||||
TU_split_5_type:
|
||||
.byte 3 # Abbreviation code
|
||||
.byte 1 # The index of the type name string
|
||||
.byte 0 # NULL
|
||||
.byte 0 # NULL
|
||||
TU_split_5_end:
|
||||
# Test object to verify dwarfdump handles v5 string offset tables.
|
||||
# We have 2 v5 CUs, a v5 TU, and a split v5 CU and TU.
|
||||
#
|
||||
# To generate the test object:
|
||||
# llvm-mc -triple x86_64-unknown-linux dwarfdump-str-offsets.s -filetype=obj \
|
||||
# -o dwarfdump-str-offsets.elf-x86-64
|
||||
|
||||
.section .debug_str,"MS",@progbits,1
|
||||
str_producer:
|
||||
.asciz "Handmade DWARF producer"
|
||||
str_CU1:
|
||||
.asciz "Compile_Unit_1"
|
||||
str_CU1_dir:
|
||||
.asciz "/home/test/CU1"
|
||||
str_CU2:
|
||||
.asciz "Compile_Unit_2"
|
||||
str_CU2_dir:
|
||||
.asciz "/home/test/CU2"
|
||||
str_TU:
|
||||
.asciz "Type_Unit"
|
||||
str_TU_type:
|
||||
.asciz "MyStruct"
|
||||
|
||||
# Every unit contributes to the string_offsets table.
|
||||
.section .debug_str_offsets,"",@progbits
|
||||
# CU1's contribution
|
||||
.long .debug_str_offsets_segment0_end-.debug_str_offsets_base0
|
||||
.short 5 # DWARF version
|
||||
.short 0 # Padding
|
||||
.debug_str_offsets_base0:
|
||||
.long str_producer
|
||||
.long str_CU1
|
||||
.long str_CU1_dir
|
||||
.debug_str_offsets_segment0_end:
|
||||
# CU2's contribution
|
||||
.long .debug_str_offsets_segment1_end-.debug_str_offsets_base1
|
||||
.short 5 # DWARF version
|
||||
.short 0 # Padding
|
||||
.debug_str_offsets_base1:
|
||||
.long str_producer
|
||||
.long str_CU2
|
||||
.long str_CU2_dir
|
||||
.debug_str_offsets_segment1_end:
|
||||
# The TU's contribution
|
||||
.long .debug_str_offsets_segment2_end-.debug_str_offsets_base2
|
||||
.short 5 # DWARF version
|
||||
.short 0 # Padding
|
||||
.debug_str_offsets_base2:
|
||||
.long str_TU
|
||||
.long str_TU_type
|
||||
.debug_str_offsets_segment2_end:
|
||||
|
||||
.section .debug_str.dwo,"MS",@progbits,1
|
||||
dwo_str_CU_5_producer:
|
||||
.asciz "Handmade split DWARF producer"
|
||||
dwo_str_CU_5_name:
|
||||
.asciz "V5_split_compile_unit"
|
||||
dwo_str_CU_5_comp_dir:
|
||||
.asciz "/home/test/splitCU"
|
||||
dwo_str_TU_5:
|
||||
.asciz "V5_split_type_unit"
|
||||
dwo_str_TU_5_type:
|
||||
.asciz "V5_split_Mystruct"
|
||||
|
||||
.section .debug_str_offsets.dwo,"",@progbits
|
||||
# The split CU's contribution
|
||||
.long .debug_dwo_str_offsets_segment0_end-.debug_dwo_str_offsets_base0
|
||||
.short 5 # DWARF version
|
||||
.short 0 # Padding
|
||||
.debug_dwo_str_offsets_base0:
|
||||
.long dwo_str_CU_5_producer-.debug_str.dwo
|
||||
.long dwo_str_CU_5_name-.debug_str.dwo
|
||||
.long dwo_str_CU_5_comp_dir-.debug_str.dwo
|
||||
.debug_dwo_str_offsets_segment0_end:
|
||||
# The split TU's contribution
|
||||
.long .debug_dwo_str_offsets_segment1_end-.debug_dwo_str_offsets_base1
|
||||
.short 5 # DWARF version
|
||||
.short 0 # Padding
|
||||
.debug_dwo_str_offsets_base1:
|
||||
.long dwo_str_TU_5-.debug_str.dwo
|
||||
.long dwo_str_TU_5_type-.debug_str.dwo
|
||||
.debug_dwo_str_offsets_segment1_end:
|
||||
|
||||
# All CUs/TUs use the same abbrev section for simplicity.
|
||||
.section .debug_abbrev,"",@progbits
|
||||
.byte 0x01 # Abbrev code
|
||||
.byte 0x11 # DW_TAG_compile_unit
|
||||
.byte 0x00 # DW_CHILDREN_no
|
||||
.byte 0x25 # DW_AT_producer
|
||||
.byte 0x1a # DW_FORM_strx
|
||||
.byte 0x03 # DW_AT_name
|
||||
.byte 0x1a # DW_FORM_strx
|
||||
.byte 0x72 # DW_AT_str_offsets_base
|
||||
.byte 0x17 # DW_FORM_sec_offset
|
||||
.byte 0x1b # DW_AT_comp_dir
|
||||
.byte 0x1a # DW_FORM_strx
|
||||
.byte 0x00 # EOM(1)
|
||||
.byte 0x00 # EOM(2)
|
||||
.byte 0x02 # Abbrev code
|
||||
.byte 0x41 # DW_TAG_type_unit
|
||||
.byte 0x01 # DW_CHILDREN_yes
|
||||
.byte 0x03 # DW_AT_name
|
||||
.byte 0x1a # DW_FORM_strx
|
||||
.byte 0x72 # DW_AT_str_offsets_base
|
||||
.byte 0x17 # DW_FORM_sec_offset
|
||||
.byte 0x00 # EOM(1)
|
||||
.byte 0x00 # EOM(2)
|
||||
.byte 0x03 # Abbrev code
|
||||
.byte 0x13 # DW_TAG_structure_type
|
||||
.byte 0x00 # DW_CHILDREN_no (no members)
|
||||
.byte 0x03 # DW_AT_name
|
||||
.byte 0x1a # DW_FORM_strx
|
||||
.byte 0x00 # EOM(1)
|
||||
.byte 0x00 # EOM(2)
|
||||
.byte 0x00 # EOM(3)
|
||||
|
||||
# And a .dwo copy for the .dwo sections.
|
||||
.section .debug_abbrev.dwo,"",@progbits
|
||||
.byte 0x01 # Abbrev code
|
||||
.byte 0x11 # DW_TAG_compile_unit
|
||||
.byte 0x00 # DW_CHILDREN_no
|
||||
.byte 0x25 # DW_AT_producer
|
||||
.byte 0x1a # DW_FORM_strx
|
||||
.byte 0x03 # DW_AT_name
|
||||
.byte 0x1a # DW_FORM_strx
|
||||
.byte 0x72 # DW_AT_str_offsets_base
|
||||
.byte 0x17 # DW_FORM_sec_offset
|
||||
.byte 0x1b # DW_AT_comp_dir
|
||||
.byte 0x1a # DW_FORM_strx
|
||||
.byte 0x00 # EOM(1)
|
||||
.byte 0x00 # EOM(2)
|
||||
.byte 0x02 # Abbrev code
|
||||
.byte 0x41 # DW_TAG_type_unit
|
||||
.byte 0x01 # DW_CHILDREN_yes
|
||||
.byte 0x03 # DW_AT_name
|
||||
.byte 0x1a # DW_FORM_strx
|
||||
.byte 0x72 # DW_AT_str_offsets_base
|
||||
.byte 0x17 # DW_FORM_sec_offset
|
||||
.byte 0x00 # EOM(1)
|
||||
.byte 0x00 # EOM(2)
|
||||
.byte 0x03 # Abbrev code
|
||||
.byte 0x13 # DW_TAG_structure_type
|
||||
.byte 0x00 # DW_CHILDREN_no (no members)
|
||||
.byte 0x03 # DW_AT_name
|
||||
.byte 0x1a # DW_FORM_strx
|
||||
.byte 0x00 # EOM(1)
|
||||
.byte 0x00 # EOM(2)
|
||||
.byte 0x00 # EOM(3)
|
||||
|
||||
.section .debug_info,"",@progbits
|
||||
|
||||
# DWARF v5 CU header.
|
||||
.long CU1_5_end-CU1_5_version # Length of Unit
|
||||
CU1_5_version:
|
||||
.short 5 # DWARF version number
|
||||
.byte 1 # DWARF Unit Type
|
||||
.byte 8 # Address Size (in bytes)
|
||||
.long .debug_abbrev # Offset Into Abbrev. Section
|
||||
# The compile-unit DIE, which has a DW_AT_producer, DW_AT_name,
|
||||
# DW_AT_str_offsets and DW_AT_compdir.
|
||||
.byte 1 # Abbreviation code
|
||||
.byte 0 # The index of the producer string
|
||||
.byte 1 # The index of the CU name string
|
||||
.long .debug_str_offsets_base0
|
||||
.byte 2 # The index of the comp dir string
|
||||
.byte 0 # NULL
|
||||
CU1_5_end:
|
||||
|
||||
# DWARF v5 CU header
|
||||
.long CU2_5_end-CU2_5_version # Length of Unit
|
||||
CU2_5_version:
|
||||
.short 5 # DWARF version number
|
||||
.byte 1 # DWARF Unit Type
|
||||
.byte 8 # Address Size (in bytes)
|
||||
.long .debug_abbrev # Offset Into Abbrev. Section
|
||||
# The compile-unit DIE, which has a DW_AT_producer, DW_AT_name,
|
||||
# DW_AT_str_offsets and DW_AT_compdir.
|
||||
.byte 1 # Abbreviation code
|
||||
.byte 0 # The index of the producer string
|
||||
.byte 1 # The index of the CU name string
|
||||
.long .debug_str_offsets_base1
|
||||
.byte 2 # The index of the comp dir string
|
||||
.byte 0 # NULL
|
||||
CU2_5_end:
|
||||
|
||||
.section .debug_types,"",@progbits
|
||||
# DWARF v5 Type unit header.
|
||||
TU_5_start:
|
||||
.long TU_5_end-TU_5_version # Length of Unit
|
||||
TU_5_version:
|
||||
.short 5 # DWARF version number
|
||||
.byte 2 # DWARF Unit Type
|
||||
.byte 8 # Address Size (in bytes)
|
||||
.long .debug_abbrev # Offset Into Abbrev. Section
|
||||
.quad 0x0011223344556677 # Type Signature
|
||||
.long TU_5_type-TU_5_start # Type offset
|
||||
# The type-unit DIE, which has a name.
|
||||
.byte 2 # Abbreviation code
|
||||
.byte 0 # Index of the unit type name string
|
||||
.long .debug_str_offsets_base2 # offset into the str_offsets section
|
||||
# The type DIE, which has a name.
|
||||
TU_5_type:
|
||||
.byte 3 # Abbreviation code
|
||||
.byte 1 # Index of the type name string
|
||||
.byte 0 # NULL
|
||||
.byte 0 # NULL
|
||||
TU_5_end:
|
||||
|
||||
.section .debug_info.dwo,"",@progbits
|
||||
|
||||
# DWARF v5 split CU header.
|
||||
.long CU_split_5_end-CU_split_5_version # Length of Unit
|
||||
CU_split_5_version:
|
||||
.short 5 # DWARF version number
|
||||
.byte 1 # DWARF Unit Type
|
||||
.byte 8 # Address Size (in bytes)
|
||||
.long .debug_abbrev.dwo # Offset Into Abbrev Section
|
||||
# The compile-unit DIE, which has a DW_AT_producer, DW_AT_name,
|
||||
# DW_AT_str_offsets and DW_AT_compdir.
|
||||
.byte 1 # Abbreviation code
|
||||
.byte 0 # The index of the producer string
|
||||
.byte 1 # The index of the CU name string
|
||||
.long .debug_dwo_str_offsets_base0-.debug_str_offsets.dwo
|
||||
.byte 2 # The index of the comp dir string
|
||||
.byte 0 # NULL
|
||||
CU_split_5_end:
|
||||
|
||||
.section .debug_types.dwo,"",@progbits
|
||||
|
||||
# DWARF v5 split type unit header.
|
||||
TU_split_5_start:
|
||||
.long TU_split_5_end-TU_split_5_version # Length of Unit
|
||||
TU_split_5_version:
|
||||
.short 5 # DWARF version number
|
||||
.byte 6 # DWARF Unit Type
|
||||
.byte 8 # Address Size (in bytes)
|
||||
.long .debug_abbrev.dwo # Offset Into Abbrev Section
|
||||
.quad 0x8899aabbccddeeff # Type Signature
|
||||
.long TU_split_5_type-TU_split_5_start # Type offset
|
||||
# The type-unit DIE, which has a name.
|
||||
.byte 2 # Abbreviation code
|
||||
.byte 0 # The index of the type unit name string
|
||||
.long .debug_dwo_str_offsets_base1-.debug_str_offsets.dwo
|
||||
# The type DIE, which has a name.
|
||||
TU_split_5_type:
|
||||
.byte 3 # Abbreviation code
|
||||
.byte 1 # The index of the type name string
|
||||
.byte 0 # NULL
|
||||
.byte 0 # NULL
|
||||
TU_split_5_end:
|
BIN
test/DebugInfo/Inputs/dwarfdump-str-offsets.x86_64.o
Normal file
BIN
test/DebugInfo/Inputs/dwarfdump-str-offsets.x86_64.o
Normal file
Binary file not shown.
24
test/DebugInfo/dwarfdump-str-offsets-invalid.test
Normal file
24
test/DebugInfo/dwarfdump-str-offsets-invalid.test
Normal file
@ -0,0 +1,24 @@
|
||||
; Verify that llvm-dwarfdump handles invalid string offset tables.
|
||||
|
||||
RUN: llvm-dwarfdump %p/Inputs/dwarfdump-str-offsets-invalid-1.x86_64.o | \
|
||||
RUN: FileCheck --check-prefix=INVALIDCONTRIB %s
|
||||
RUN: llvm-dwarfdump %p/Inputs/dwarfdump-str-offsets-invalid-2.x86_64.o | \
|
||||
RUN: FileCheck --check-prefix=INVALIDCONTRIB %s
|
||||
RUN: llvm-dwarfdump %p/Inputs/dwarfdump-str-offsets-invalid-3.x86_64.o | \
|
||||
RUN: FileCheck --check-prefix=INVALIDCONTRIB %s
|
||||
RUN: llvm-dwarfdump %p/Inputs/dwarfdump-str-offsets-invalid-4.x86_64.o | \
|
||||
RUN: FileCheck --check-prefix=INVALIDLENGTH %s
|
||||
RUN: llvm-dwarfdump %p/Inputs/dwarfdump-str-offsets-invalid-5.x86_64.o | \
|
||||
RUN: FileCheck --check-prefix=INVALIDSECTIONLENGTH %s
|
||||
|
||||
INVALIDCONTRIB: .debug_str_offsets contents:
|
||||
INVALIDCONTRIB-NOT: contents:
|
||||
INVALIDCONTRIB: error: invalid contribution to string offsets table in section .debug_str_offsets.
|
||||
|
||||
INVALIDLENGTH: .debug_str_offsets contents:
|
||||
INVALIDLENGTH-NOT: contents:
|
||||
INVALIDLENGTH: error: contribution to string offsets table in section .debug_str_offsets has invalid length.
|
||||
|
||||
INVALIDSECTIONLENGTH: .debug_str_offsets contents:
|
||||
INVALIDSECTIONLENGTH-NOT: contents:
|
||||
INVALIDSECTIONLENGTH: error: size of .debug_str_offsets is not a multiple of 4.
|
76
test/DebugInfo/dwarfdump-str-offsets.test
Normal file
76
test/DebugInfo/dwarfdump-str-offsets.test
Normal file
@ -0,0 +1,76 @@
|
||||
RUN: llvm-dwarfdump %p/Inputs/dwarfdump-str-offsets.x86_64.o | FileCheck %s
|
||||
|
||||
; We are using a hand-constructed object file and are interest in the correct
|
||||
; diplay of the DW_str_offsetsbase attribute, the correct display of strings
|
||||
; and the dump of the .debug_str_offsets[.dwo] table.
|
||||
;
|
||||
; Abbreviation for DW_AT_str_offsets_base
|
||||
CHECK: .debug_abbrev contents:
|
||||
CHECK-NOT: contents:
|
||||
CHECK: DW_TAG_compile_unit
|
||||
CHECK-NOT: DW_TAG
|
||||
CHECK: DW_AT_str_offsets_base DW_FORM_sec_offset
|
||||
|
||||
; Verify that strings are displayed correctly as indexed strings
|
||||
CHECK: .debug_info contents:
|
||||
CHECK-NOT: contents:
|
||||
CHECK: DW_TAG_compile_unit
|
||||
CHECK-NEXT: DW_AT_producer [DW_FORM_strx] ( indexed (00000000) string = "Handmade DWARF producer")
|
||||
CHECK-NEXT: DW_AT_name [DW_FORM_strx] ( indexed (00000001) string = "Compile_Unit_1")
|
||||
CHECK-NEXT: DW_AT_str_offsets_base [DW_FORM_sec_offset] (0x00000008)
|
||||
CHECK-NEXT: DW_AT_comp_dir [DW_FORM_strx] ( indexed (00000002) string = "/home/test/CU1")
|
||||
|
||||
; Second compile unit (b.cpp)
|
||||
CHECK: DW_TAG_compile_unit
|
||||
CHECK-NEXT: DW_AT_producer [DW_FORM_strx] ( indexed (00000000) string = "Handmade DWARF producer")
|
||||
CHECK-NEXT: DW_AT_name [DW_FORM_strx] ( indexed (00000001) string = "Compile_Unit_2")
|
||||
CHECK-NEXT: DW_AT_str_offsets_base [DW_FORM_sec_offset] (0x0000001c)
|
||||
CHECK-NEXT: DW_AT_comp_dir [DW_FORM_strx] ( indexed (00000002) string = "/home/test/CU2")
|
||||
|
||||
; The split CU
|
||||
CHECK: .debug_info.dwo contents:
|
||||
CHECK-NOT: contents:
|
||||
CHECK: DW_TAG_compile_unit
|
||||
CHECK-NEXT: DW_AT_producer [DW_FORM_strx] ( indexed (00000000) string = "Handmade split DWARF producer")
|
||||
CHECK-NEXT: DW_AT_name [DW_FORM_strx] ( indexed (00000001) string = "V5_split_compile_unit")
|
||||
CHECK-NEXT: DW_AT_str_offsets_base [DW_FORM_sec_offset] (0x00000008)
|
||||
CHECK-NEXT: DW_AT_comp_dir [DW_FORM_strx] ( indexed (00000002) string = "/home/test/splitCU")
|
||||
|
||||
; The type unit
|
||||
CHECK: .debug_types contents:
|
||||
CHECK: DW_TAG_type_unit
|
||||
CHECK-NEXT: DW_AT_name [DW_FORM_strx] ( indexed (00000000) string = "Type_Unit")
|
||||
CHECK-NEXT: DW_AT_str_offsets_base [DW_FORM_sec_offset] (0x00000030)
|
||||
CHECK: DW_TAG_structure_type
|
||||
CHECK-NEXT: DW_AT_name [DW_FORM_strx] ( indexed (00000001) string = "MyStruct")
|
||||
|
||||
; The split type unit
|
||||
CHECK: .debug_types.dwo contents:
|
||||
CHECK: DW_TAG_type_unit
|
||||
CHECK-NEXT: DW_AT_name [DW_FORM_strx] ( indexed (00000000) string = "V5_split_type_unit")
|
||||
CHECK-NEXT: DW_AT_str_offsets_base [DW_FORM_sec_offset] (0x0000001c)
|
||||
CHECK: DW_TAG_structure_type
|
||||
CHECK-NEXT: DW_AT_name [DW_FORM_strx] ( indexed (00000001) string = "V5_split_Mystruct")
|
||||
|
||||
; The .debug_str_offsets section
|
||||
CHECK: .debug_str_offsets contents:
|
||||
CHECK-NEXT: 0x00000000: Contribution size = 12, Version = 5
|
||||
CHECK-NEXT: 0x00000008: 00000000 "Handmade DWARF producer"
|
||||
CHECK-NEXT: 0x0000000c: 00000018 "Compile_Unit_1"
|
||||
CHECK-NEXT: 0x00000010: 00000027 "/home/test/CU1"
|
||||
CHECK-NEXT: 0x00000014: Contribution size = 12, Version = 5
|
||||
CHECK-NEXT: 0x0000001c: 00000000 "Handmade DWARF producer"
|
||||
CHECK-NEXT: 0x00000020: 00000036 "Compile_Unit_2"
|
||||
CHECK-NEXT: 0x00000024: 00000045 "/home/test/CU2"
|
||||
CHECK-NEXT: 0x00000028: Contribution size = 8, Version = 5
|
||||
CHECK-NEXT: 0x00000030: 00000054 "Type_Unit"
|
||||
CHECK-NEXT: 0x00000034: 0000005e "MyStruct"
|
||||
|
||||
CHECK: .debug_str_offsets.dwo contents:
|
||||
CHECK-NEXT: 0x00000000: Contribution size = 12, Version = 5
|
||||
CHECK-NEXT: 0x00000008: 00000000 "Handmade split DWARF producer"
|
||||
CHECK-NEXT: 0x0000000c: 0000001e "V5_split_compile_unit"
|
||||
CHECK-NEXT: 0x00000010: 00000034 "/home/test/splitCU"
|
||||
CHECK-NEXT: 0x00000014: Contribution size = 8, Version = 5
|
||||
CHECK-NEXT: 0x0000001c: 00000047 "V5_split_type_unit"
|
||||
CHECK-NEXT: 0x00000020: 0000005a "V5_split_Mystruct"
|
@ -67,6 +67,7 @@ static cl::opt<DIDumpType> DumpType(
|
||||
clEnumValN(DIDT_GnuPubnames, "gnu_pubnames", ".debug_gnu_pubnames"),
|
||||
clEnumValN(DIDT_GnuPubtypes, "gnu_pubtypes", ".debug_gnu_pubtypes"),
|
||||
clEnumValN(DIDT_Str, "str", ".debug_str"),
|
||||
clEnumValN(DIDT_StrOffsets, "str_offsets", ".debug_str_offsets"),
|
||||
clEnumValN(DIDT_StrDwo, "str.dwo", ".debug_str.dwo"),
|
||||
clEnumValN(DIDT_StrOffsetsDwo, "str_offsets.dwo",
|
||||
".debug_str_offsets.dwo"),
|
||||
|
@ -203,6 +203,7 @@ void dumpDebugInfo(DWARFContextInMemory &DCtx, DWARFYAML::Data &Y) {
|
||||
case dwarf::DW_FORM_line_strp:
|
||||
case dwarf::DW_FORM_strp_sup:
|
||||
case dwarf::DW_FORM_GNU_str_index:
|
||||
case dwarf::DW_FORM_strx:
|
||||
if (auto Val = FormValue.getValue().getAsCStringOffset())
|
||||
NewValue.Value = Val.getValue();
|
||||
break;
|
||||
|
Loading…
Reference in New Issue
Block a user