diff --git a/lldb/unittests/TestingSupport/Symbol/YAMLModuleTester.cpp b/lldb/unittests/TestingSupport/Symbol/YAMLModuleTester.cpp --- a/lldb/unittests/TestingSupport/Symbol/YAMLModuleTester.cpp +++ b/lldb/unittests/TestingSupport/Symbol/YAMLModuleTester.cpp @@ -93,7 +93,7 @@ YAMLModuleTester::YAMLModuleTester(llvm::StringRef yaml_data, llvm::StringRef triple) { - auto sections_map = llvm::DWARFYAML::emitDebugSections(yaml_data, true); + auto sections_map = llvm::DWARFYAML::emitDebugSections(yaml_data); if (!sections_map) return; m_sections_map = std::move(*sections_map); diff --git a/llvm/include/llvm/ObjectYAML/DWARFEmitter.h b/llvm/include/llvm/ObjectYAML/DWARFEmitter.h --- a/llvm/include/llvm/ObjectYAML/DWARFEmitter.h +++ b/llvm/include/llvm/ObjectYAML/DWARFEmitter.h @@ -42,7 +42,7 @@ Error emitDebugRnglists(raw_ostream &OS, const Data &DI); Expected>> -emitDebugSections(StringRef YAMLString, bool ApplyFixups = false, +emitDebugSections(StringRef YAMLString, bool IsLittleEndian = sys::IsLittleEndianHost); } // end namespace DWARFYAML } // end namespace llvm diff --git a/llvm/include/llvm/ObjectYAML/DWARFYAML.h b/llvm/include/llvm/ObjectYAML/DWARFYAML.h --- a/llvm/include/llvm/ObjectYAML/DWARFYAML.h +++ b/llvm/include/llvm/ObjectYAML/DWARFYAML.h @@ -120,7 +120,7 @@ struct Unit { dwarf::DwarfFormat Format; - yaml::Hex64 Length; + Optional Length; uint16_t Version; llvm::dwarf::UnitType Type; // Added in DWARF 5 yaml::Hex64 AbbrOffset; diff --git a/llvm/lib/ObjectYAML/CMakeLists.txt b/llvm/lib/ObjectYAML/CMakeLists.txt --- a/llvm/lib/ObjectYAML/CMakeLists.txt +++ b/llvm/lib/ObjectYAML/CMakeLists.txt @@ -6,7 +6,6 @@ COFFEmitter.cpp COFFYAML.cpp DWARFEmitter.cpp - DWARFVisitor.cpp DWARFYAML.cpp ELFEmitter.cpp ELFYAML.cpp diff --git a/llvm/lib/ObjectYAML/DWARFEmitter.cpp b/llvm/lib/ObjectYAML/DWARFEmitter.cpp --- a/llvm/lib/ObjectYAML/DWARFEmitter.cpp +++ b/llvm/lib/ObjectYAML/DWARFEmitter.cpp @@ -12,7 +12,6 @@ //===----------------------------------------------------------------------===// #include "llvm/ObjectYAML/DWARFEmitter.h" -#include "DWARFVisitor.h" #include "llvm/ADT/ArrayRef.h" #include "llvm/ADT/StringMap.h" #include "llvm/ADT/StringRef.h" @@ -205,79 +204,194 @@ return Error::success(); } -namespace { -/// An extension of the DWARFYAML::ConstVisitor which writes compile -/// units and DIEs to a stream. -class DumpVisitor : public DWARFYAML::ConstVisitor { - raw_ostream &OS; - -protected: - void onStartCompileUnit(const DWARFYAML::Unit &CU) override { - writeInitialLength(CU.Format, CU.Length, OS, DebugInfo.IsLittleEndian); - writeInteger((uint16_t)CU.Version, OS, DebugInfo.IsLittleEndian); - if (CU.Version >= 5) { - writeInteger((uint8_t)CU.Type, OS, DebugInfo.IsLittleEndian); - writeInteger((uint8_t)CU.AddrSize, OS, DebugInfo.IsLittleEndian); - cantFail(writeVariableSizedInteger(CU.AbbrOffset, - CU.Format == dwarf::DWARF64 ? 8 : 4, - OS, DebugInfo.IsLittleEndian)); - } else { - cantFail(writeVariableSizedInteger(CU.AbbrOffset, - CU.Format == dwarf::DWARF64 ? 8 : 4, - OS, DebugInfo.IsLittleEndian)); - writeInteger((uint8_t)CU.AddrSize, OS, DebugInfo.IsLittleEndian); - } - } - - void onStartDIE(const DWARFYAML::Unit &CU, - const DWARFYAML::Entry &DIE) override { - encodeULEB128(DIE.AbbrCode, OS); - } +static unsigned getOffsetSize(const DWARFYAML::Unit &Unit) { + return Unit.Format == dwarf::DWARF64 ? 8 : 4; +} - void onValue(const uint8_t U) override { - writeInteger(U, OS, DebugInfo.IsLittleEndian); - } +static unsigned getRefSize(const DWARFYAML::Unit &Unit) { + if (Unit.Version == 2) + return Unit.AddrSize; + return getOffsetSize(Unit); +} - void onValue(const uint16_t U) override { - writeInteger(U, OS, DebugInfo.IsLittleEndian); +static Expected writeDIE(ArrayRef AbbrevDecls, + const DWARFYAML::Unit &Unit, + const DWARFYAML::Entry &Entry, + raw_ostream &OS, bool IsLittleEndian) { + uint64_t EntryBegin = OS.tell(); + encodeULEB128(Entry.AbbrCode, OS); + uint32_t AbbrCode = Entry.AbbrCode; + if (AbbrCode == 0 || Entry.Values.empty()) + return OS.tell() - EntryBegin; + + if (AbbrCode > AbbrevDecls.size()) + return createStringError( + errc::invalid_argument, + "abbrev code must be less than or equal to the number of " + "entries in abbreviation table"); + const DWARFYAML::Abbrev &Abbrev = AbbrevDecls[AbbrCode - 1]; + auto FormVal = Entry.Values.begin(); + auto AbbrForm = Abbrev.Attributes.begin(); + for (; FormVal != Entry.Values.end() && AbbrForm != Abbrev.Attributes.end(); + ++FormVal, ++AbbrForm) { + dwarf::Form Form = AbbrForm->Form; + bool Indirect; + do { + Indirect = false; + switch (Form) { + case dwarf::DW_FORM_addr: + // TODO: Test this error. + if (Error Err = writeVariableSizedInteger(FormVal->Value, Unit.AddrSize, + OS, IsLittleEndian)) + return std::move(Err); + break; + case dwarf::DW_FORM_ref_addr: + // TODO: Test this error. + if (Error Err = writeVariableSizedInteger( + FormVal->Value, getRefSize(Unit), OS, IsLittleEndian)) + return std::move(Err); + break; + case dwarf::DW_FORM_exprloc: + case dwarf::DW_FORM_block: + encodeULEB128(FormVal->BlockData.size(), OS); + OS.write((const char *)FormVal->BlockData.data(), + FormVal->BlockData.size()); + break; + case dwarf::DW_FORM_block1: { + writeInteger((uint8_t)FormVal->BlockData.size(), OS, IsLittleEndian); + OS.write((const char *)FormVal->BlockData.data(), + FormVal->BlockData.size()); + break; + } + case dwarf::DW_FORM_block2: { + writeInteger((uint16_t)FormVal->BlockData.size(), OS, IsLittleEndian); + OS.write((const char *)FormVal->BlockData.data(), + FormVal->BlockData.size()); + break; + } + case dwarf::DW_FORM_block4: { + writeInteger((uint32_t)FormVal->BlockData.size(), OS, IsLittleEndian); + OS.write((const char *)FormVal->BlockData.data(), + FormVal->BlockData.size()); + break; + } + case dwarf::DW_FORM_strx: + case dwarf::DW_FORM_addrx: + case dwarf::DW_FORM_rnglistx: + case dwarf::DW_FORM_loclistx: + case dwarf::DW_FORM_udata: + case dwarf::DW_FORM_ref_udata: + case dwarf::DW_FORM_GNU_addr_index: + case dwarf::DW_FORM_GNU_str_index: + encodeULEB128(FormVal->Value, OS); + break; + case dwarf::DW_FORM_data1: + case dwarf::DW_FORM_ref1: + case dwarf::DW_FORM_flag: + case dwarf::DW_FORM_strx1: + case dwarf::DW_FORM_addrx1: + writeInteger((uint8_t)FormVal->Value, OS, IsLittleEndian); + break; + case dwarf::DW_FORM_data2: + case dwarf::DW_FORM_ref2: + case dwarf::DW_FORM_strx2: + case dwarf::DW_FORM_addrx2: + writeInteger((uint16_t)FormVal->Value, OS, IsLittleEndian); + break; + case dwarf::DW_FORM_data4: + case dwarf::DW_FORM_ref4: + case dwarf::DW_FORM_ref_sup4: + case dwarf::DW_FORM_strx4: + case dwarf::DW_FORM_addrx4: + writeInteger((uint32_t)FormVal->Value, OS, IsLittleEndian); + break; + case dwarf::DW_FORM_data8: + case dwarf::DW_FORM_ref8: + case dwarf::DW_FORM_ref_sup8: + case dwarf::DW_FORM_ref_sig8: + writeInteger((uint64_t)FormVal->Value, OS, IsLittleEndian); + break; + case dwarf::DW_FORM_sdata: + encodeSLEB128(FormVal->Value, OS); + break; + case dwarf::DW_FORM_string: + OS.write(FormVal->CStr.data(), FormVal->CStr.size()); + OS.write('\0'); + break; + case dwarf::DW_FORM_indirect: + encodeULEB128(FormVal->Value, OS); + Indirect = true; + Form = static_cast((uint64_t)FormVal->Value); + ++FormVal; + break; + case dwarf::DW_FORM_strp: + case dwarf::DW_FORM_sec_offset: + case dwarf::DW_FORM_GNU_ref_alt: + case dwarf::DW_FORM_GNU_strp_alt: + case dwarf::DW_FORM_line_strp: + case dwarf::DW_FORM_strp_sup: + // TODO: Test this error. + if (Error Err = writeVariableSizedInteger( + FormVal->Value, getOffsetSize(Unit), OS, IsLittleEndian)) + return std::move(Err); + break; + default: + break; + } + } while (Indirect); } - void onValue(const uint32_t U) override { - writeInteger(U, OS, DebugInfo.IsLittleEndian); - } + return OS.tell() - EntryBegin; +} - void onValue(const uint64_t U, const bool LEB = false) override { - if (LEB) - encodeULEB128(U, OS); - else - writeInteger(U, OS, DebugInfo.IsLittleEndian); - } +static void writeDWARFOffset(uint64_t Offset, dwarf::DwarfFormat Format, + raw_ostream &OS, bool IsLittleEndian) { + cantFail(writeVariableSizedInteger(Offset, Format == dwarf::DWARF64 ? 8 : 4, + OS, IsLittleEndian)); +} - void onValue(const int64_t S, const bool LEB = false) override { - if (LEB) - encodeSLEB128(S, OS); - else - writeInteger(S, OS, DebugInfo.IsLittleEndian); - } +Error DWARFYAML::emitDebugInfo(raw_ostream &OS, const DWARFYAML::Data &DI) { + for (const DWARFYAML::Unit &Unit : DI.CompileUnits) { + uint64_t Length = 3; // sizeof(version) + sizeof(address_size) + Length += Unit.Version >= 5 ? 1 : 0; // sizeof(unit_type) + Length += + Unit.Format == dwarf::DWARF64 ? 8 : 4; // sizeof(debug_abbrev_offset) + + // Since the length of the current compilation unit is undetermined yet, we + // firstly write the content of the compilation unit to a buffer to + // calculate it and then serialize the buffer content to the actual output + // stream. + std::string EntryBuffer; + raw_string_ostream EntryBufferOS(EntryBuffer); + + for (const DWARFYAML::Entry &Entry : Unit.Entries) { + if (Expected EntryLength = writeDIE( + DI.AbbrevDecls, Unit, Entry, EntryBufferOS, DI.IsLittleEndian)) + Length += *EntryLength; + else + return EntryLength.takeError(); + } - void onValue(const StringRef String) override { - OS.write(String.data(), String.size()); - OS.write('\0'); - } + // If the length is specified in the YAML description, we use it instead of + // the actual length. + if (Unit.Length) + Length = *Unit.Length; + + writeInitialLength(Unit.Format, Length, OS, DI.IsLittleEndian); + writeInteger((uint16_t)Unit.Version, OS, DI.IsLittleEndian); + if (Unit.Version >= 5) { + writeInteger((uint8_t)Unit.Type, OS, DI.IsLittleEndian); + writeInteger((uint8_t)Unit.AddrSize, OS, DI.IsLittleEndian); + writeDWARFOffset(Unit.AbbrOffset, Unit.Format, OS, DI.IsLittleEndian); + } else { + writeDWARFOffset(Unit.AbbrOffset, Unit.Format, OS, DI.IsLittleEndian); + writeInteger((uint8_t)Unit.AddrSize, OS, DI.IsLittleEndian); + } - void onValue(const MemoryBufferRef MBR) override { - OS.write(MBR.getBufferStart(), MBR.getBufferSize()); + OS.write(EntryBuffer.data(), EntryBuffer.size()); } -public: - DumpVisitor(const DWARFYAML::Data &DI, raw_ostream &Out) - : DWARFYAML::ConstVisitor(DI), OS(Out) {} -}; -} // namespace - -Error DWARFYAML::emitDebugInfo(raw_ostream &OS, const DWARFYAML::Data &DI) { - DumpVisitor Visitor(DI, OS); - return Visitor.traverseDebugInfo(); + return Error::success(); } static void emitFileEntry(raw_ostream &OS, const DWARFYAML::File &File) { @@ -634,51 +748,8 @@ return Error::success(); } -namespace { -class DIEFixupVisitor : public DWARFYAML::Visitor { - uint64_t Length; - -public: - DIEFixupVisitor(DWARFYAML::Data &DI) : DWARFYAML::Visitor(DI){}; - -protected: - void onStartCompileUnit(DWARFYAML::Unit &CU) override { - // Size of the unit header, excluding the length field itself. - Length = CU.Version >= 5 ? 8 : 7; - } - - void onEndCompileUnit(DWARFYAML::Unit &CU) override { CU.Length = Length; } - - void onStartDIE(DWARFYAML::Unit &CU, DWARFYAML::Entry &DIE) override { - Length += getULEB128Size(DIE.AbbrCode); - } - - void onValue(const uint8_t U) override { Length += 1; } - void onValue(const uint16_t U) override { Length += 2; } - void onValue(const uint32_t U) override { Length += 4; } - void onValue(const uint64_t U, const bool LEB = false) override { - if (LEB) - Length += getULEB128Size(U); - else - Length += 8; - } - void onValue(const int64_t S, const bool LEB = false) override { - if (LEB) - Length += getSLEB128Size(S); - else - Length += 8; - } - void onValue(const StringRef String) override { Length += String.size() + 1; } - - void onValue(const MemoryBufferRef MBR) override { - Length += MBR.getBufferSize(); - } -}; -} // namespace - Expected>> -DWARFYAML::emitDebugSections(StringRef YAMLString, bool ApplyFixups, - bool IsLittleEndian) { +DWARFYAML::emitDebugSections(StringRef YAMLString, bool IsLittleEndian) { auto CollectDiagnostic = [](const SMDiagnostic &Diag, void *DiagContext) { *static_cast(DiagContext) = Diag; }; @@ -693,12 +764,6 @@ if (YIn.error()) return createStringError(YIn.error(), GeneratedDiag.getMessage()); - if (ApplyFixups) { - DIEFixupVisitor DIFixer(DI); - if (Error Err = DIFixer.traverseDebugInfo()) - return std::move(Err); - } - StringMap> DebugSections; Error Err = emitDebugSectionImpl(DI, &DWARFYAML::emitDebugInfo, "debug_info", DebugSections); diff --git a/llvm/lib/ObjectYAML/DWARFVisitor.h b/llvm/lib/ObjectYAML/DWARFVisitor.h deleted file mode 100644 --- a/llvm/lib/ObjectYAML/DWARFVisitor.h +++ /dev/null @@ -1,97 +0,0 @@ -//===--- DWARFVisitor.h -----------------------------------------*- C++ -*-===// -// -// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. -// See https://llvm.org/LICENSE.txt for license information. -// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception -// -//===----------------------------------------------------------------------===// -// -//===----------------------------------------------------------------------===// - -#ifndef LLVM_OBJECTYAML_DWARFVISITOR_H -#define LLVM_OBJECTYAML_DWARFVISITOR_H - -#include "llvm/ADT/StringRef.h" -#include "llvm/BinaryFormat/Dwarf.h" -#include "llvm/Support/MemoryBuffer.h" - -namespace llvm { -class Error; - -namespace DWARFYAML { - -struct Data; -struct Unit; -struct Entry; -struct FormValue; -struct AttributeAbbrev; - -/// A class to visits DWARFYAML Compile Units and DIEs in preorder. -/// -/// Extensions of this class can either maintain const or non-const references -/// to the DWARFYAML::Data object. -template class VisitorImpl { -protected: - T &DebugInfo; - - /// Visitor Functions - /// @{ - virtual void onStartCompileUnit(Unit &CU) {} - virtual void onEndCompileUnit(Unit &CU) {} - virtual void onStartDIE(Unit &CU, Entry &DIE) {} - virtual void onEndDIE(Unit &CU, Entry &DIE) {} - virtual void onForm(AttributeAbbrev &AttAbbrev, FormValue &Value) {} - /// @} - - /// Const Visitor Functions - /// @{ - virtual void onStartCompileUnit(const Unit &CU) {} - virtual void onEndCompileUnit(const Unit &CU) {} - virtual void onStartDIE(const Unit &CU, const Entry &DIE) {} - virtual void onEndDIE(const Unit &CU, const Entry &DIE) {} - virtual void onForm(const AttributeAbbrev &AttAbbrev, - const FormValue &Value) {} - /// @} - - /// Value visitors - /// @{ - virtual void onValue(const uint8_t U) {} - virtual void onValue(const uint16_t U) {} - virtual void onValue(const uint32_t U) {} - virtual void onValue(const uint64_t U, const bool LEB = false) {} - virtual void onValue(const int64_t S, const bool LEB = false) {} - virtual void onValue(const StringRef String) {} - virtual void onValue(const MemoryBufferRef MBR) {} - /// @} - -public: - VisitorImpl(T &DI) : DebugInfo(DI) {} - - virtual ~VisitorImpl() {} - - Error traverseDebugInfo(); - -private: - void onVariableSizeValue(uint64_t U, unsigned Size); -}; - -// Making the visior instantiations extern and explicit in the cpp file. This -// prevents them from being instantiated in every compile unit that uses the -// visitors. -extern template class VisitorImpl; -extern template class VisitorImpl; - -class Visitor : public VisitorImpl { -public: - Visitor(Data &DI) : VisitorImpl(DI) {} -}; - -class ConstVisitor : public VisitorImpl { -public: - ConstVisitor(const Data &DI) : VisitorImpl(DI) {} -}; - -} // namespace DWARFYAML -} // namespace llvm - -#endif diff --git a/llvm/lib/ObjectYAML/DWARFVisitor.cpp b/llvm/lib/ObjectYAML/DWARFVisitor.cpp deleted file mode 100644 --- a/llvm/lib/ObjectYAML/DWARFVisitor.cpp +++ /dev/null @@ -1,188 +0,0 @@ -//===--- DWARFVisitor.cpp ---------------------------------------*- C++ -*-===// -// -// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. -// See https://llvm.org/LICENSE.txt for license information. -// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception -// -//===----------------------------------------------------------------------===// -// -//===----------------------------------------------------------------------===// - -#include "DWARFVisitor.h" -#include "llvm/BinaryFormat/Dwarf.h" -#include "llvm/ObjectYAML/DWARFYAML.h" -#include "llvm/Support/Errc.h" -#include "llvm/Support/Error.h" - -using namespace llvm; - -template -void DWARFYAML::VisitorImpl::onVariableSizeValue(uint64_t U, unsigned Size) { - switch (Size) { - case 8: - onValue((uint64_t)U); - break; - case 4: - onValue((uint32_t)U); - break; - case 2: - onValue((uint16_t)U); - break; - case 1: - onValue((uint8_t)U); - break; - default: - llvm_unreachable("Invalid integer write size."); - } -} - -static unsigned getOffsetSize(const DWARFYAML::Unit &Unit) { - return Unit.Format == dwarf::DWARF64 ? 8 : 4; -} - -static unsigned getRefSize(const DWARFYAML::Unit &Unit) { - if (Unit.Version == 2) - return Unit.AddrSize; - return getOffsetSize(Unit); -} - -template Error DWARFYAML::VisitorImpl::traverseDebugInfo() { - for (auto &Unit : DebugInfo.CompileUnits) { - onStartCompileUnit(Unit); - - for (auto &Entry : Unit.Entries) { - onStartDIE(Unit, Entry); - uint32_t AbbrCode = Entry.AbbrCode; - if (AbbrCode == 0 || Entry.Values.empty()) - continue; - - if (AbbrCode > DebugInfo.AbbrevDecls.size()) - return createStringError( - errc::invalid_argument, - "abbrev code must be less than or equal to the number of " - "entries in abbreviation table"); - const DWARFYAML::Abbrev &Abbrev = DebugInfo.AbbrevDecls[AbbrCode - 1]; - auto FormVal = Entry.Values.begin(); - auto AbbrForm = Abbrev.Attributes.begin(); - for (; - FormVal != Entry.Values.end() && AbbrForm != Abbrev.Attributes.end(); - ++FormVal, ++AbbrForm) { - onForm(*AbbrForm, *FormVal); - dwarf::Form Form = AbbrForm->Form; - bool Indirect; - do { - Indirect = false; - switch (Form) { - case dwarf::DW_FORM_addr: - onVariableSizeValue(FormVal->Value, Unit.AddrSize); - break; - case dwarf::DW_FORM_ref_addr: - onVariableSizeValue(FormVal->Value, getRefSize(Unit)); - break; - case dwarf::DW_FORM_exprloc: - case dwarf::DW_FORM_block: - onValue((uint64_t)FormVal->BlockData.size(), true); - onValue( - MemoryBufferRef(StringRef((const char *)&FormVal->BlockData[0], - FormVal->BlockData.size()), - "")); - break; - case dwarf::DW_FORM_block1: { - auto writeSize = FormVal->BlockData.size(); - onValue((uint8_t)writeSize); - onValue( - MemoryBufferRef(StringRef((const char *)&FormVal->BlockData[0], - FormVal->BlockData.size()), - "")); - break; - } - case dwarf::DW_FORM_block2: { - auto writeSize = FormVal->BlockData.size(); - onValue((uint16_t)writeSize); - onValue( - MemoryBufferRef(StringRef((const char *)&FormVal->BlockData[0], - FormVal->BlockData.size()), - "")); - break; - } - case dwarf::DW_FORM_block4: { - auto writeSize = FormVal->BlockData.size(); - onValue((uint32_t)writeSize); - onValue( - MemoryBufferRef(StringRef((const char *)&FormVal->BlockData[0], - FormVal->BlockData.size()), - "")); - break; - } - case dwarf::DW_FORM_strx: - case dwarf::DW_FORM_addrx: - case dwarf::DW_FORM_rnglistx: - case dwarf::DW_FORM_loclistx: - case dwarf::DW_FORM_udata: - case dwarf::DW_FORM_ref_udata: - case dwarf::DW_FORM_GNU_addr_index: - case dwarf::DW_FORM_GNU_str_index: - onValue((uint64_t)FormVal->Value, /*LEB=*/true); - break; - case dwarf::DW_FORM_data1: - case dwarf::DW_FORM_ref1: - case dwarf::DW_FORM_flag: - case dwarf::DW_FORM_strx1: - case dwarf::DW_FORM_addrx1: - onValue((uint8_t)FormVal->Value); - break; - case dwarf::DW_FORM_data2: - case dwarf::DW_FORM_ref2: - case dwarf::DW_FORM_strx2: - case dwarf::DW_FORM_addrx2: - onValue((uint16_t)FormVal->Value); - break; - case dwarf::DW_FORM_data4: - case dwarf::DW_FORM_ref4: - case dwarf::DW_FORM_ref_sup4: - case dwarf::DW_FORM_strx4: - case dwarf::DW_FORM_addrx4: - onValue((uint32_t)FormVal->Value); - break; - case dwarf::DW_FORM_data8: - case dwarf::DW_FORM_ref8: - case dwarf::DW_FORM_ref_sup8: - case dwarf::DW_FORM_ref_sig8: - onValue((uint64_t)FormVal->Value); - break; - case dwarf::DW_FORM_sdata: - onValue((int64_t)FormVal->Value, true); - break; - case dwarf::DW_FORM_string: - onValue(FormVal->CStr); - break; - case dwarf::DW_FORM_indirect: - onValue((uint64_t)FormVal->Value, true); - Indirect = true; - Form = static_cast((uint64_t)FormVal->Value); - ++FormVal; - break; - case dwarf::DW_FORM_strp: - case dwarf::DW_FORM_sec_offset: - case dwarf::DW_FORM_GNU_ref_alt: - case dwarf::DW_FORM_GNU_strp_alt: - case dwarf::DW_FORM_line_strp: - case dwarf::DW_FORM_strp_sup: - onVariableSizeValue(FormVal->Value, getOffsetSize(Unit)); - break; - default: - break; - } - } while (Indirect); - } - onEndDIE(Unit, Entry); - } - onEndCompileUnit(Unit); - } - - return Error::success(); -} - -// Explicitly instantiate the two template expansions. -template class DWARFYAML::VisitorImpl; -template class DWARFYAML::VisitorImpl; diff --git a/llvm/lib/ObjectYAML/DWARFYAML.cpp b/llvm/lib/ObjectYAML/DWARFYAML.cpp --- a/llvm/lib/ObjectYAML/DWARFYAML.cpp +++ b/llvm/lib/ObjectYAML/DWARFYAML.cpp @@ -143,7 +143,7 @@ void MappingTraits::mapping(IO &IO, DWARFYAML::Unit &Unit) { IO.mapOptional("Format", Unit.Format, dwarf::DWARF32); - IO.mapOptional("Length", Unit.Length, 0); + IO.mapOptional("Length", Unit.Length); IO.mapRequired("Version", Unit.Version); if (Unit.Version >= 5) IO.mapRequired("UnitType", Unit.Type); diff --git a/llvm/test/tools/yaml2obj/ELF/DWARF/debug-info.yaml b/llvm/test/tools/yaml2obj/ELF/DWARF/debug-info.yaml --- a/llvm/test/tools/yaml2obj/ELF/DWARF/debug-info.yaml +++ b/llvm/test/tools/yaml2obj/ELF/DWARF/debug-info.yaml @@ -735,3 +735,110 @@ AbbrOffset: 0x1234 AddrSize: 8 Entries: [] + +## k) Test that yaml2obj is able to emit a correct length for compilation units. + +# RUN: yaml2obj --docnum=13 %s -o %t13.o +# RUN: llvm-readelf --hex-dump=.debug_info %t13.o | \ +# RUN: FileCheck %s --check-prefix=INFER-LENGTH + +# INFER-LENGTH: Hex dump of section '.debug_info': +# INFER-LENGTH-NEXT: 0x00000000 37000000 04000000 00000801 00000000 7............... +## ^------- unit_length (0x37) +## ^--- version (2-byte) +## ^-------- debug_abbrev_offset (4-byte) +## ^- address_size (1-byte) +## ^- abbrev code (ULEB128) 0x01 +## ^------- Form: DW_FORM_strp (4-byte) +# INFER-LENGTH-NEXT: 0x00000010 0c001600 00000000 00001e00 00002011 .............. . +## ^--- Form: DW_FORM_data2 (2-byte) +## ^-------- Form: DW_FORM_strp (4-byte) +## ^-------- Form: DW_FORM_sec_offset (4-byte) +## ^-------- Form: DW_FORM_strp (4-byte) +## ^--- Form: DW_FORM_addr (8-byte) +# INFER-LENGTH-NEXT: 0x00000020 00000000 00003300 00000220 11000000 ......3.... .... +## ------------- +## ^-------- Form: DW_FORM_data4 (4-byte) +## ^- abbrev code (ULEB128) 0x02 +## ^---------- Form: DW_FORM_addr (8-byte) +# INFER-LENGTH-NEXT: 0x00000030 00000006 00000038 000000 .......8... +## ------ +## ^-------- Form: DW_FORM_data4 (4-byte) +## ^-------- Form: DW_FORM_strp (4-byte) + +## The handwritten DIEs should look like: + +## 0x0000000b: DW_TAG_compile_unit [1] * +## DW_AT_producer [DW_FORM_strp] ( .debug_str[0x00000000] = "clang version 10.0.0 ") +## DW_AT_language [DW_FORM_data2] (DW_LANG_C99) +## DW_AT_name [DW_FORM_strp] ( .debug_str[0x00000016] = "hello.c") +## DW_AT_stmt_list [DW_FORM_sec_offset] (0x00000000) +## DW_AT_comp_dir [DW_FORM_strp] ( .debug_str[0x0000001e] = "/home/v/x/llvm/playground") +## DW_AT_low_pc [DW_FORM_addr] (0x0000000000001120) +## DW_AT_high_pc [DW_FORM_data4] (0x00000033) +## +## 0x0000002a: DW_TAG_subprogram [2] +## DW_AT_low_pc [DW_FORM_addr] (0x0000000000001120) +## DW_AT_high_pc [DW_FORM_data4] (0x00000006) +## DW_AT_name [DW_FORM_strp] ( .debug_str[0x00000038] = "main") + +--- !ELF +FileHeader: + Class: ELFCLASS64 + Data: ELFDATA2LSB + Type: ET_EXEC + Machine: EM_X86_64 +DWARF: + debug_str: + - "clang version 10.0.0 " + - "hello.c" + - "/home/v/x/llvm/playground" + - "main" + debug_abbrev: + - Code: 1 + Tag: DW_TAG_compile_unit + Children: DW_CHILDREN_yes + Attributes: + - Attribute: DW_AT_producer + Form: DW_FORM_strp + - Attribute: DW_AT_language + Form: DW_FORM_data2 + - Attribute: DW_AT_name + Form: DW_FORM_strp + - Attribute: DW_AT_stmt_list + Form: DW_FORM_sec_offset + - Attribute: DW_AT_comp_dir + Form: DW_FORM_strp + - Attribute: DW_AT_low_pc + Form: DW_FORM_addr + - Attribute: DW_AT_high_pc + Form: DW_FORM_data4 + - Code: 2 + Tag: DW_TAG_subprogram + Children: DW_CHILDREN_no + Attributes: + - Attribute: DW_AT_low_pc + Form: DW_FORM_addr + - Attribute: DW_AT_high_pc + Form: DW_FORM_data4 + - Attribute: DW_AT_name + Form: DW_FORM_strp + debug_info: + - Version: 4 + AbbrOffset: 0x00 + AddrSize: 0x08 + Entries: + - AbbrCode: 1 + Values: + - Value: 0x00 ## DW_AT_producer [DW_FORM_strp] + - Value: 0x0c ## DW_LANG_C99, DW_AT_language [DW_FORM_data2] + - Value: 0x16 ## DW_AT_name [DW_FORM_strp] + - Value: 0x00 ## DW_AT_stmt_list [DW_FORM_sec_offset] + - Value: 0x1e ## DW_AT_comp_dir [DW_FORM_strp] + - Value: 0x1120 ## DW_AT_low_pc [DW_FORM_addr] + - Value: 0x33 ## DW_AT_high_pc [DW_FORM_data4] + - AbbrCode: 2 + Values: + - Value: 0x1120 ## DW_AT_low_pc [DW_FORM_addr] + - Value: 0x06 ## DW_AT_high_pc [DW_FORM_data4] + - Value: 0x38 ## DW_AT_name [DW_FORM_strp] diff --git a/llvm/unittests/DebugInfo/DWARF/DWARFDebugInfoTest.cpp b/llvm/unittests/DebugInfo/DWARF/DWARFDebugInfoTest.cpp --- a/llvm/unittests/DebugInfo/DWARF/DWARFDebugInfoTest.cpp +++ b/llvm/unittests/DebugInfo/DWARF/DWARFDebugInfoTest.cpp @@ -1377,7 +1377,7 @@ " - AbbrCode: 0x00000000\n" " Values:\n"; - auto ErrOrSections = DWARFYAML::emitDebugSections(StringRef(yamldata), true); + auto ErrOrSections = DWARFYAML::emitDebugSections(StringRef(yamldata)); ASSERT_TRUE((bool)ErrOrSections); std::unique_ptr DwarfContext = DWARFContext::create(*ErrOrSections, 8); diff --git a/llvm/unittests/DebugInfo/DWARF/DWARFDieTest.cpp b/llvm/unittests/DebugInfo/DWARF/DWARFDieTest.cpp --- a/llvm/unittests/DebugInfo/DWARF/DWARFDieTest.cpp +++ b/llvm/unittests/DebugInfo/DWARF/DWARFDieTest.cpp @@ -48,7 +48,7 @@ - Value: 25 )"; Expected>> Sections = - DWARFYAML::emitDebugSections(StringRef(yamldata), /*ApplyFixups=*/true, + DWARFYAML::emitDebugSections(StringRef(yamldata), /*IsLittleEndian=*/true); ASSERT_THAT_EXPECTED(Sections, Succeeded()); std::vector Loclists{