From e5400f8a6e601729da4aa6706cda3db37a06bf13 Mon Sep 17 00:00:00 2001 From: Paul Robinson Date: Tue, 7 Nov 2017 19:57:12 +0000 Subject: [PATCH] [DWARFv5] Support DW_FORM_strp in the .debug_line header. Supporting this form in .debug_line.dwo will be done as a follow-up. Differential Revision: https://reviews.llvm.org/D33155 llvm-svn: 317607 --- lld/ELF/InputFiles.cpp | 4 +++- llvm/include/llvm/DebugInfo/DWARF/DWARFDebugLine.h | 8 +++++--- llvm/include/llvm/DebugInfo/DWARF/DWARFFormValue.h | 14 +++++--------- .../DWARF/DWARFAbbreviationDeclaration.cpp | 2 +- llvm/lib/DebugInfo/DWARF/DWARFAcceleratorTable.cpp | 10 +++++++--- llvm/lib/DebugInfo/DWARF/DWARFContext.cpp | 8 ++++---- llvm/lib/DebugInfo/DWARF/DWARFDebugLine.cpp | 20 +++++++++++--------- llvm/lib/DebugInfo/DWARF/DWARFDie.cpp | 5 +++-- llvm/lib/DebugInfo/DWARF/DWARFFormValue.cpp | 13 +++++-------- .../DebugInfo/Inputs/dwarfdump-header.elf-x86-64 | Bin 3056 -> 3248 bytes llvm/test/DebugInfo/Inputs/dwarfdump-header.s | 10 +++++++--- llvm/tools/dsymutil/DwarfLinker.cpp | 6 +++--- .../DebugInfo/DWARF/DWARFFormValueTest.cpp | 6 +++--- 13 files changed, 57 insertions(+), 49 deletions(-) diff --git a/lld/ELF/InputFiles.cpp b/lld/ELF/InputFiles.cpp index 688c802..e2717c2 100644 --- a/lld/ELF/InputFiles.cpp +++ b/lld/ELF/InputFiles.cpp @@ -77,8 +77,10 @@ template void ObjFile::initializeDwarf() { // The second parameter is offset in .debug_line section // for compilation unit (CU) of interest. We have only one // CU (object file), so offset is always 0. + // FIXME: Provide the associated DWARFUnit if there is one. DWARF v5 + // needs it in order to find indirect strings. const DWARFDebugLine::LineTable *LT = - DwarfLine->getOrParseLineTable(LineData, 0); + DwarfLine->getOrParseLineTable(LineData, 0, nullptr); // Return if there is no debug information about CU available. if (!Dwarf.getNumCompileUnits()) diff --git a/llvm/include/llvm/DebugInfo/DWARF/DWARFDebugLine.h b/llvm/include/llvm/DebugInfo/DWARF/DWARFDebugLine.h index a4d8c0d..f89bcf8 100644 --- a/llvm/include/llvm/DebugInfo/DWARF/DWARFDebugLine.h +++ b/llvm/include/llvm/DebugInfo/DWARF/DWARFDebugLine.h @@ -22,6 +22,7 @@ namespace llvm { +class DWARFUnit; class raw_ostream; class DWARFDebugLine { @@ -95,7 +96,8 @@ public: void clear(); void dump(raw_ostream &OS) const; - bool parse(const DWARFDataExtractor &DebugLineData, uint32_t *OffsetPtr); + bool parse(const DWARFDataExtractor &DebugLineData, uint32_t *OffsetPtr, + const DWARFUnit *U = nullptr); }; /// Standard .debug_line state machine structure. @@ -218,7 +220,7 @@ public: /// Parse prologue and all rows. bool parse(const DWARFDataExtractor &DebugLineData, uint32_t *OffsetPtr, - raw_ostream *OS = nullptr); + const DWARFUnit *U, raw_ostream *OS = nullptr); using RowVector = std::vector; using RowIter = RowVector::const_iterator; @@ -236,7 +238,7 @@ public: const LineTable *getLineTable(uint32_t Offset) const; const LineTable *getOrParseLineTable(const DWARFDataExtractor &DebugLineData, - uint32_t Offset); + uint32_t Offset, const DWARFUnit *U); private: struct ParsingState { diff --git a/llvm/include/llvm/DebugInfo/DWARF/DWARFFormValue.h b/llvm/include/llvm/DebugInfo/DWARF/DWARFFormValue.h index 497fe59..d320535 100644 --- a/llvm/include/llvm/DebugInfo/DWARF/DWARFFormValue.h +++ b/llvm/include/llvm/DebugInfo/DWARF/DWARFFormValue.h @@ -104,16 +104,12 @@ public: const DWARFUnit *getUnit() const { return U; } void dump(raw_ostream &OS, DIDumpOptions DumpOpts = DIDumpOptions()) const; - /// Extracts a value in \p Data at offset \p *OffsetPtr. - /// - /// The passed DWARFUnit is allowed to be nullptr, in which case some - /// kind of forms that depend on Unit information are disallowed. - /// \param Data The DWARFDataExtractor to use. - /// \param OffsetPtr The offset within \p Data where the data starts. - /// \param U The optional DWARFUnit supplying information for some forms. - /// \returns whether the extraction succeeded. + /// Extracts a value in \p Data at offset \p *OffsetPtr. The information + /// in \p FormParams is needed to interpret some forms. The optional + /// \p Unit allows extracting information if the form refers to other + /// sections (e.g., .debug_str). bool extractValue(const DWARFDataExtractor &Data, uint32_t *OffsetPtr, - const DWARFUnit *U); + DWARFFormParams FormParams, const DWARFUnit *U = nullptr); bool isInlinedCStr() const { return Value.data != nullptr && Value.data == (const uint8_t *)Value.cstr; diff --git a/llvm/lib/DebugInfo/DWARF/DWARFAbbreviationDeclaration.cpp b/llvm/lib/DebugInfo/DWARF/DWARFAbbreviationDeclaration.cpp index a88dcfc..f593953 100644 --- a/llvm/lib/DebugInfo/DWARF/DWARFAbbreviationDeclaration.cpp +++ b/llvm/lib/DebugInfo/DWARF/DWARFAbbreviationDeclaration.cpp @@ -184,7 +184,7 @@ Optional DWARFAbbreviationDeclaration::getAttributeValue( FormValue.setSValue(Spec.getImplicitConstValue()); return FormValue; } - if (FormValue.extractValue(DebugInfoData, &Offset, &U)) + if (FormValue.extractValue(DebugInfoData, &Offset, U.getFormParams(), &U)) return FormValue; } // March Offset along until we get to the attribute we want. diff --git a/llvm/lib/DebugInfo/DWARF/DWARFAcceleratorTable.cpp b/llvm/lib/DebugInfo/DWARF/DWARFAcceleratorTable.cpp index dbe6fe5..f04ec77 100644 --- a/llvm/lib/DebugInfo/DWARF/DWARFAcceleratorTable.cpp +++ b/llvm/lib/DebugInfo/DWARF/DWARFAcceleratorTable.cpp @@ -90,10 +90,11 @@ std::pair DWARFAcceleratorTable::readAtoms(uint32_t &HashDataOffset) { uint32_t DieOffset = dwarf::DW_INVALID_OFFSET; dwarf::Tag DieTag = dwarf::DW_TAG_null; + DWARFFormParams FormParams = {Hdr.Version, 0, dwarf::DwarfFormat::DWARF32}; for (auto Atom : getAtomsDesc()) { DWARFFormValue FormValue(Atom.second); - FormValue.extractValue(AccelSection, &HashDataOffset, NULL); + FormValue.extractValue(AccelSection, &HashDataOffset, FormParams); switch (Atom.first) { case dwarf::DW_ATOM_die_offset: DieOffset = *FormValue.getAsUnsignedConstant(); @@ -145,6 +146,7 @@ LLVM_DUMP_METHOD void DWARFAcceleratorTable::dump(raw_ostream &OS) const { uint32_t Offset = sizeof(Hdr) + Hdr.HeaderDataLength; unsigned HashesBase = Offset + Hdr.NumBuckets * 4; unsigned OffsetsBase = HashesBase + Hdr.NumHashes * 4; + DWARFFormParams FormParams = {Hdr.Version, 0, dwarf::DwarfFormat::DWARF32}; for (unsigned Bucket = 0; Bucket < Hdr.NumBuckets; ++Bucket) { unsigned Index = AccelSection.getU32(&Offset); @@ -181,7 +183,7 @@ LLVM_DUMP_METHOD void DWARFAcceleratorTable::dump(raw_ostream &OS) const { unsigned i = 0; for (auto &Atom : AtomForms) { OS << format("{Atom[%d]: ", i++); - if (Atom.extractValue(AccelSection, &DataOffset, nullptr)) + if (Atom.extractValue(AccelSection, &DataOffset, FormParams)) Atom.dump(OS); else OS << "Error extracting the value"; @@ -216,8 +218,10 @@ void DWARFAcceleratorTable::ValueIterator::Next() { NumData = 0; return; } + DWARFFormParams FormParams = {AccelTable->Hdr.Version, 0, + dwarf::DwarfFormat::DWARF32}; for (auto &Atom : AtomForms) - Atom.extractValue(AccelSection, &DataOffset, nullptr); + Atom.extractValue(AccelSection, &DataOffset, FormParams); ++Data; } diff --git a/llvm/lib/DebugInfo/DWARF/DWARFContext.cpp b/llvm/lib/DebugInfo/DWARF/DWARFContext.cpp index 24aa666..881cd1d 100644 --- a/llvm/lib/DebugInfo/DWARF/DWARFContext.cpp +++ b/llvm/lib/DebugInfo/DWARF/DWARFContext.cpp @@ -329,9 +329,9 @@ void DWARFContext::dump( // representation. OS << "debug_line[" << format("0x%8.8x", Offset) << "]\n"; if (DumpOpts.Verbose) { - LineTable.parse(lineData, &Offset, &OS); + LineTable.parse(lineData, &Offset, &*CU, &OS); } else { - LineTable.parse(lineData, &Offset); + LineTable.parse(lineData, &Offset, &*CU); LineTable.dump(OS); } } @@ -349,7 +349,7 @@ void DWARFContext::dump( DWARFDataExtractor lineData(*DObj, DObj->getLineDWOSection(), isLittleEndian(), savedAddressByteSize); DWARFDebugLine::LineTable LineTable; - while (LineTable.Prologue.parse(lineData, &stmtOffset)) { + while (LineTable.Prologue.parse(lineData, &stmtOffset, nullptr)) { LineTable.dump(OS); LineTable.clear(); } @@ -681,7 +681,7 @@ DWARFContext::getLineTableForUnit(DWARFUnit *U) { // We have to parse it first. DWARFDataExtractor lineData(*DObj, U->getLineSection(), isLittleEndian(), U->getAddressByteSize()); - return Line->getOrParseLineTable(lineData, stmtOffset); + return Line->getOrParseLineTable(lineData, stmtOffset, U); } void DWARFContext::parseCompileUnits() { diff --git a/llvm/lib/DebugInfo/DWARF/DWARFDebugLine.cpp b/llvm/lib/DebugInfo/DWARF/DWARFDebugLine.cpp index bd8dd0d..c99c7a9 100644 --- a/llvm/lib/DebugInfo/DWARF/DWARFDebugLine.cpp +++ b/llvm/lib/DebugInfo/DWARF/DWARFDebugLine.cpp @@ -144,7 +144,7 @@ parseV5EntryFormat(const DWARFDataExtractor &DebugLineData, uint32_t *OffsetPtr, static bool parseV5DirFileTables(const DWARFDataExtractor &DebugLineData, uint32_t *OffsetPtr, uint64_t EndPrologueOffset, - const DWARFFormParams &FormParams, + const DWARFFormParams &FormParams, const DWARFUnit *U, std::vector &IncludeDirectories, std::vector &FileNames) { // Get the directory entry description. @@ -162,7 +162,7 @@ parseV5DirFileTables(const DWARFDataExtractor &DebugLineData, DWARFFormValue Value(Descriptor.Form); switch (Descriptor.Type) { case DW_LNCT_path: - if (!Value.extractValue(DebugLineData, OffsetPtr, nullptr)) + if (!Value.extractValue(DebugLineData, OffsetPtr, FormParams, U)) return false; IncludeDirectories.push_back(Value.getAsCString().getValue()); break; @@ -187,7 +187,7 @@ parseV5DirFileTables(const DWARFDataExtractor &DebugLineData, DWARFDebugLine::FileNameEntry FileEntry; for (auto Descriptor : FileDescriptors) { DWARFFormValue Value(Descriptor.Form); - if (!Value.extractValue(DebugLineData, OffsetPtr, nullptr)) + if (!Value.extractValue(DebugLineData, OffsetPtr, FormParams, U)) return false; switch (Descriptor.Type) { case DW_LNCT_path: @@ -213,7 +213,7 @@ parseV5DirFileTables(const DWARFDataExtractor &DebugLineData, } bool DWARFDebugLine::Prologue::parse(const DWARFDataExtractor &DebugLineData, - uint32_t *OffsetPtr) { + uint32_t *OffsetPtr, const DWARFUnit *U) { const uint64_t PrologueOffset = *OffsetPtr; clear(); @@ -253,7 +253,8 @@ bool DWARFDebugLine::Prologue::parse(const DWARFDataExtractor &DebugLineData, if (getVersion() >= 5) { if (!parseV5DirFileTables(DebugLineData, OffsetPtr, EndPrologueOffset, - getFormParams(), IncludeDirectories, FileNames)) { + getFormParams(), U, IncludeDirectories, + FileNames)) { fprintf(stderr, "warning: parsing line table prologue at 0x%8.8" PRIx64 " found an invalid directory or file table description at" @@ -382,24 +383,25 @@ DWARFDebugLine::getLineTable(uint32_t Offset) const { const DWARFDebugLine::LineTable * DWARFDebugLine::getOrParseLineTable(const DWARFDataExtractor &DebugLineData, - uint32_t Offset) { + uint32_t Offset, const DWARFUnit *U) { std::pair Pos = LineTableMap.insert(LineTableMapTy::value_type(Offset, LineTable())); LineTable *LT = &Pos.first->second; if (Pos.second) { - if (!LT->parse(DebugLineData, &Offset)) + if (!LT->parse(DebugLineData, &Offset, U)) return nullptr; } return LT; } bool DWARFDebugLine::LineTable::parse(const DWARFDataExtractor &DebugLineData, - uint32_t *OffsetPtr, raw_ostream *OS) { + uint32_t *OffsetPtr, const DWARFUnit *U, + raw_ostream *OS) { const uint32_t DebugLineOffset = *OffsetPtr; clear(); - if (!Prologue.parse(DebugLineData, OffsetPtr)) { + if (!Prologue.parse(DebugLineData, OffsetPtr, U)) { // Restore our offset and return false to indicate failure! *OffsetPtr = DebugLineOffset; return false; diff --git a/llvm/lib/DebugInfo/DWARF/DWARFDie.cpp b/llvm/lib/DebugInfo/DWARF/DWARFDie.cpp index d20eabf..a579c06 100644 --- a/llvm/lib/DebugInfo/DWARF/DWARFDie.cpp +++ b/llvm/lib/DebugInfo/DWARF/DWARFDie.cpp @@ -208,7 +208,8 @@ static void dumpAttribute(raw_ostream &OS, const DWARFDie &Die, DWARFUnit *U = Die.getDwarfUnit(); DWARFFormValue formValue(Form); - if (!formValue.extractValue(U->getDebugInfoExtractor(), OffsetPtr, U)) + if (!formValue.extractValue(U->getDebugInfoExtractor(), OffsetPtr, + U->getFormParams(), U)) return; OS << "\t("; @@ -550,7 +551,7 @@ void DWARFDie::attribute_iterator::updateForIndex( auto U = Die.getDwarfUnit(); assert(U && "Die must have valid DWARF unit"); bool b = AttrValue.Value.extractValue(U->getDebugInfoExtractor(), - &ParseOffset, U); + &ParseOffset, U->getFormParams(), U); (void)b; assert(b && "extractValue cannot fail on fully parsed DWARF"); AttrValue.ByteSize = ParseOffset - AttrValue.Offset; diff --git a/llvm/lib/DebugInfo/DWARF/DWARFFormValue.cpp b/llvm/lib/DebugInfo/DWARF/DWARFFormValue.cpp index d63e84e..c4abd49 100644 --- a/llvm/lib/DebugInfo/DWARF/DWARFFormValue.cpp +++ b/llvm/lib/DebugInfo/DWARF/DWARFFormValue.cpp @@ -276,7 +276,8 @@ bool DWARFFormValue::isFormClass(DWARFFormValue::FormClass FC) const { } bool DWARFFormValue::extractValue(const DWARFDataExtractor &Data, - uint32_t *OffsetPtr, const DWARFUnit *CU) { + uint32_t *OffsetPtr, DWARFFormParams FP, + const DWARFUnit *CU) { U = CU; bool Indirect = false; bool IsBlock = false; @@ -288,10 +289,8 @@ bool DWARFFormValue::extractValue(const DWARFDataExtractor &Data, switch (Form) { case DW_FORM_addr: case DW_FORM_ref_addr: { - if (!U) - return false; - uint16_t Size = (Form == DW_FORM_addr) ? U->getAddressByteSize() - : U->getRefAddrByteSize(); + uint16_t Size = + (Form == DW_FORM_addr) ? FP.AddrSize : FP.getRefAddrByteSize(); Value.uval = Data.getRelocatedValue(Size, OffsetPtr, &Value.SectionIndex); break; } @@ -360,10 +359,8 @@ bool DWARFFormValue::extractValue(const DWARFDataExtractor &Data, case DW_FORM_GNU_strp_alt: case DW_FORM_line_strp: case DW_FORM_strp_sup: { - if (!U) - return false; Value.uval = - Data.getRelocatedValue(U->getDwarfOffsetByteSize(), OffsetPtr); + Data.getRelocatedValue(FP.getDwarfOffsetByteSize(), OffsetPtr); break; } case DW_FORM_flag_present: diff --git a/llvm/test/DebugInfo/Inputs/dwarfdump-header.elf-x86-64 b/llvm/test/DebugInfo/Inputs/dwarfdump-header.elf-x86-64 index 21c1eacd07141b963047c81a51aa3984a961448c..e65f34f2a216f128086fb879c55932dbe4aa9003 100644 GIT binary patch delta 779 zcmZvaKS&!<9LL}9a+ls+ywo7!C4)(NCyXpPAv)r*Q~BC4jo!b!FT6-;Rqhw@B7~O^S-~|9e4M@+JyCxf6 z6@OJ>qK+rz?R+Du`6Y)a0p(pAMVmeRW`8>oDDj;=$H##r;kaTf`UP`|{ z;@@IL?^6bj!7*lxIpdPsLQ_~Uc=AOcF%_U0e36-%fSbap%)FCsI6yP_C1^@GCFxEE zXbS%YRWm%04A3-QhIuh99Zxm`)a$9&Cw~AtTJ_RDC#w?M7@P&mt!U4anyG?@i|uPycQ=M z*{@@NB&-eLz|K<%R-~M($RR@}&P2qmen0hbtJsckYt{dFjCJ5zX`?K5I$V7s*Opyo b)dZo=6J5Tc7vb4^*`*eGJnn6$pE&&hh-hF- delta 607 zcmZuuO)ErE7(Va4?sd<-Gc=)NYKF1V*ccYVf@?uO7ZwVk2`RGBNQsRkMNy_FWy8Y8 zl3^hWHCr~yPX2%;KR`M6%$bjcQ|Eo3`+U4__ujkcw>V2SbU3VZ1{4}#wb{Or+$ASI zB?*f;Yy!6=qK+}Rwz;yrwXwO=waChN32)R(=io+)cF`;A74{85bF!ve4k(x!X4h(X zxr`TikU32!m^IV1jwds1J`zLDZJ>8_R*7g{`An89M-_TOw(0@%Rwx|OiYt2z3zmq+ zBx=-beTAC9sU=jVwStY|*%I*}Q{2&Bp(Z3AL#I`za>c2IU2$84gItgHJIL4qGj=E* z*G$lwG!8O~f5_Rxgx~6I96757yTOkm_@rI1eImm5Xb4%}O^0~lK3#yjKHXzf)>j<6 zenkEhb@GMAYVhHvj9&)V>yPBMI8qX4y%Z&I?D=huUQ*Je$CKC5-s0=|`0)fERG*%) YYed{;x .debug_str) # Directory table entries .byte 2 # Two directories - .asciz "Directory5a" - .asciz "Directory5b" + .long str_LT_5a + .long str_LT_5b # File table format .byte 4 # Four elements per file entry .byte 1 # DW_LNCT_path diff --git a/llvm/tools/dsymutil/DwarfLinker.cpp b/llvm/tools/dsymutil/DwarfLinker.cpp index 9fb968c..0fdc690 100644 --- a/llvm/tools/dsymutil/DwarfLinker.cpp +++ b/llvm/tools/dsymutil/DwarfLinker.cpp @@ -2366,7 +2366,7 @@ void DwarfLinker::keepDIEAndDependencies(RelocationManager &RelocMgr, continue; } - Val.extractValue(Data, &Offset, &Unit); + Val.extractValue(Data, &Offset, Unit.getFormParams(), &Unit); CompileUnit *ReferencedCU; if (auto RefDie = resolveDIEReference(*this, Units, Val, Unit, Die, ReferencedCU)) { @@ -2965,7 +2965,7 @@ DIE *DwarfLinker::DIECloner::cloneDIE( DWARFFormValue Val(AttrSpec.Form); uint32_t AttrSize = Offset; - Val.extractValue(Data, &Offset, &U); + Val.extractValue(Data, &Offset, U.getFormParams(), &U); AttrSize = Offset - AttrSize; OutOffset += @@ -3158,7 +3158,7 @@ void DwarfLinker::patchLineTableForUnit(CompileUnit &Unit, DWARFDataExtractor LineExtractor( OrigDwarf.getDWARFObj(), OrigDwarf.getDWARFObj().getLineSection(), OrigDwarf.isLittleEndian(), Unit.getOrigUnit().getAddressByteSize()); - LineTable.parse(LineExtractor, &StmtOffset); + LineTable.parse(LineExtractor, &StmtOffset, &Unit.getOrigUnit()); // This vector is the output line table. std::vector NewRows; diff --git a/llvm/unittests/DebugInfo/DWARF/DWARFFormValueTest.cpp b/llvm/unittests/DebugInfo/DWARF/DWARFFormValueTest.cpp index f283ac0..14550b90 100644 --- a/llvm/unittests/DebugInfo/DWARF/DWARFFormValueTest.cpp +++ b/llvm/unittests/DebugInfo/DWARF/DWARFFormValueTest.cpp @@ -99,7 +99,7 @@ DWARFFormValue createDataXFormValue(dwarf::Form Form, RawTypeT Value) { DWARFFormValue Result(Form); DWARFDataExtractor Data(StringRef(Raw, sizeof(RawTypeT)), sys::IsLittleEndianHost, sizeof(void *)); - Result.extractValue(Data, &Offset, nullptr); + Result.extractValue(Data, &Offset, {0, 0, dwarf::DwarfFormat::DWARF32}); return Result; } @@ -110,7 +110,7 @@ DWARFFormValue createULEBFormValue(uint64_t Value) { uint32_t Offset = 0; DWARFFormValue Result(DW_FORM_udata); DWARFDataExtractor Data(OS.str(), sys::IsLittleEndianHost, sizeof(void *)); - Result.extractValue(Data, &Offset, nullptr); + Result.extractValue(Data, &Offset, {0, 0, dwarf::DwarfFormat::DWARF32}); return Result; } @@ -121,7 +121,7 @@ DWARFFormValue createSLEBFormValue(int64_t Value) { uint32_t Offset = 0; DWARFFormValue Result(DW_FORM_sdata); DWARFDataExtractor Data(OS.str(), sys::IsLittleEndianHost, sizeof(void *)); - Result.extractValue(Data, &Offset, nullptr); + Result.extractValue(Data, &Offset, {0, 0, dwarf::DwarfFormat::DWARF32}); return Result; } -- 2.7.4