Higuoxing created this revision.
Higuoxing added reviewers: jhenderson, grimar, MaskRay.
Herald added subscribers: llvm-commits, lldb-commits, hiraditya, mgorny.
Herald added projects: LLDB, LLVM.
This patch refactors `emitDebugInfo()` to make the length field be
inferred from its content. Besides, the `Visitor` class is removed in
this patch. The original `Visitor` class helps us determine an
appropriate length and emit the .debug_info section. These two
processes can be merged into one process. Besides, the length field
should be inferred when it's missing rather than when it's zero.
Repository:
rG LLVM Github Monorepo
https://reviews.llvm.org/D84008
Files:
lldb/unittests/Expression/DWARFExpressionTest.cpp
lldb/unittests/SymbolFile/DWARF/DWARFASTParserClangTests.cpp
lldb/unittests/TestingSupport/Symbol/YAMLModuleTester.cpp
llvm/include/llvm/ObjectYAML/DWARFEmitter.h
llvm/include/llvm/ObjectYAML/DWARFYAML.h
llvm/lib/ObjectYAML/CMakeLists.txt
llvm/lib/ObjectYAML/DWARFEmitter.cpp
llvm/lib/ObjectYAML/DWARFVisitor.cpp
llvm/lib/ObjectYAML/DWARFVisitor.h
llvm/lib/ObjectYAML/DWARFYAML.cpp
llvm/test/ObjectYAML/MachO/DWARF-debug_info.yaml
llvm/test/ObjectYAML/MachO/DWARF2-AddrSize8-FormValues.yaml
llvm/test/ObjectYAML/MachO/DWARF5-debug_info.yaml
llvm/unittests/DebugInfo/DWARF/DWARFDebugInfoTest.cpp
llvm/unittests/DebugInfo/DWARF/DWARFDieTest.cpp
Index: llvm/unittests/DebugInfo/DWARF/DWARFDieTest.cpp
===================================================================
--- llvm/unittests/DebugInfo/DWARF/DWARFDieTest.cpp
+++ llvm/unittests/DebugInfo/DWARF/DWARFDieTest.cpp
@@ -34,8 +34,7 @@
- Attribute: DW_AT_call_data_location
Form: DW_FORM_sec_offset
debug_info:
- - Length: 0
- Version: 5
+ - Version: 5
UnitType: DW_UT_compile
AbbrOffset: 0
AddrSize: 4
@@ -49,7 +48,7 @@
- Value: 25
)";
Expected<StringMap<std::unique_ptr<MemoryBuffer>>> Sections =
- DWARFYAML::emitDebugSections(StringRef(yamldata), /*ApplyFixups=*/true,
+ DWARFYAML::emitDebugSections(StringRef(yamldata),
/*IsLittleEndian=*/true);
ASSERT_THAT_EXPECTED(Sections, Succeeded());
std::vector<uint8_t> Loclists{
Index: llvm/unittests/DebugInfo/DWARF/DWARFDebugInfoTest.cpp
===================================================================
--- llvm/unittests/DebugInfo/DWARF/DWARFDebugInfoTest.cpp
+++ llvm/unittests/DebugInfo/DWARF/DWARFDebugInfoTest.cpp
@@ -1368,8 +1368,7 @@
" Children: DW_CHILDREN_yes\n"
" Attributes:\n"
"debug_info:\n"
- " - Length: 0\n"
- " Version: 4\n"
+ " - Version: 4\n"
" AbbrOffset: 0\n"
" AddrSize: 8\n"
" Entries:\n"
@@ -1378,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 =
DWARFContext::create(*ErrOrSections, 8);
Index: llvm/test/ObjectYAML/MachO/DWARF5-debug_info.yaml
===================================================================
--- llvm/test/ObjectYAML/MachO/DWARF5-debug_info.yaml
+++ llvm/test/ObjectYAML/MachO/DWARF5-debug_info.yaml
@@ -513,7 +513,7 @@
# DWARF32: DWARF:
# DWARF32: debug_info:
-# DWARF32-NEXT: - Length: 118
+# DWARF32-NEXT: - Length: 0x0000000000000076
# DWARF32-NEXT: Version: 5
# DWARF32-NEXT: UnitType: DW_UT_compile
# DWARF32-NEXT: AbbrOffset: 0
@@ -585,7 +585,7 @@
# RUN: obj2yaml | FileCheck %s --check-prefix=DWARF32-YAML
# DWARF32-YAML: debug_info:
-# DWARF32-YAML-NEXT: - Length: 12
+# DWARF32-YAML-NEXT: - Length: 0x000000000000000C
# DWARF32-YAML-NEXT: Version: 5
# DWARF32-YAML-NEXT: UnitType: DW_UT_compile
# DWARF32-YAML-NEXT: AbbrOffset: 0x0000000000000000
@@ -669,7 +669,7 @@
# DWARF64-YAML: debug_info:
# DWARF64-YAML-NEXT: - Format: DWARF64
-# DWARF64-YAML-NEXT: Length: 20
+# DWARF64-YAML-NEXT: Length: 0x0000000000000014
# DWARF64-YAML-NEXT: Version: 5
# DWARF64-YAML-NEXT: UnitType: DW_UT_compile
# DWARF64-YAML-NEXT: AbbrOffset: 0x0000000000000000
Index: llvm/test/ObjectYAML/MachO/DWARF2-AddrSize8-FormValues.yaml
===================================================================
--- llvm/test/ObjectYAML/MachO/DWARF2-AddrSize8-FormValues.yaml
+++ llvm/test/ObjectYAML/MachO/DWARF2-AddrSize8-FormValues.yaml
@@ -415,7 +415,7 @@
...
#CHECK: debug_info:
-#CHECK: - Length: 168
+#CHECK: - Length: 0x00000000000000A8
#CHECK: Version: 2
#CHECK: AbbrOffset: 0
#CHECK: AddrSize: 8
Index: llvm/test/ObjectYAML/MachO/DWARF-debug_info.yaml
===================================================================
--- llvm/test/ObjectYAML/MachO/DWARF-debug_info.yaml
+++ llvm/test/ObjectYAML/MachO/DWARF-debug_info.yaml
@@ -513,7 +513,7 @@
# DWARF32: DWARF:
# DWARF32: debug_info:
-# DWARF32-NEXT: - Length: 117
+# DWARF32-NEXT: - Length: 0x0000000000000075
# DWARF32-NEXT: Version: 4
# DWARF32-NEXT: AbbrOffset: 0
# DWARF32-NEXT: AddrSize: 8
@@ -584,7 +584,7 @@
# RUN: obj2yaml | FileCheck %s --check-prefix=DWARF32-YAML
# DWARF32-YAML: debug_info:
-# DWARF32-YAML-NEXT: - Length: 12
+# DWARF32-YAML-NEXT: - Length: 0x000000000000000C
# DWARF32-YAML-NEXT: Version: 4
# DWARF32-YAML-NEXT: AbbrOffset: 0
# DWARF32-YAML-NEXT: AddrSize: 8
@@ -666,7 +666,7 @@
# DWARF64-YAML: debug_info:
# DWARF64-YAML-NEXT: - Format: DWARF64
-# DWARF64-YAML-NEXT: Length: 12
+# DWARF64-YAML-NEXT: Length: 0x000000000000000C
# DWARF64-YAML-NEXT: Version: 4
# DWARF64-YAML-NEXT: AbbrOffset: 0
# DWARF64-YAML-NEXT: AddrSize: 8
Index: llvm/lib/ObjectYAML/DWARFYAML.cpp
===================================================================
--- llvm/lib/ObjectYAML/DWARFYAML.cpp
+++ llvm/lib/ObjectYAML/DWARFYAML.cpp
@@ -140,7 +140,7 @@
void MappingTraits<DWARFYAML::Unit>::mapping(IO &IO, DWARFYAML::Unit &Unit) {
IO.mapOptional("Format", Unit.Format, dwarf::DWARF32);
- IO.mapRequired("Length", Unit.Length);
+ IO.mapOptional("Length", Unit.Length);
IO.mapRequired("Version", Unit.Version);
if (Unit.Version >= 5)
IO.mapRequired("UnitType", Unit.Type);
Index: llvm/lib/ObjectYAML/DWARFVisitor.h
===================================================================
--- 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 <typename T> 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<DWARFYAML::Data>;
-extern template class VisitorImpl<const DWARFYAML::Data>;
-
-class Visitor : public VisitorImpl<Data> {
-public:
- Visitor(Data &DI) : VisitorImpl<Data>(DI) {}
-};
-
-class ConstVisitor : public VisitorImpl<const Data> {
-public:
- ConstVisitor(const Data &DI) : VisitorImpl<const Data>(DI) {}
-};
-
-} // namespace DWARFYAML
-} // namespace llvm
-
-#endif
Index: llvm/lib/ObjectYAML/DWARFVisitor.cpp
===================================================================
--- 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 <typename T>
-void DWARFYAML::VisitorImpl<T>::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 <typename T> Error DWARFYAML::VisitorImpl<T>::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<dwarf::Form>((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<DWARFYAML::Data>;
-template class DWARFYAML::VisitorImpl<const DWARFYAML::Data>;
Index: llvm/lib/ObjectYAML/DWARFEmitter.cpp
===================================================================
--- llvm/lib/ObjectYAML/DWARFEmitter.cpp
+++ llvm/lib/ObjectYAML/DWARFEmitter.cpp
@@ -12,7 +12,6 @@
//===----------------------------------------------------------------------===//
#include "llvm/ObjectYAML/DWARFEmitter.h"
-#include "DWARFVisitor.h"
#include "llvm/ADT/StringMap.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/BinaryFormat/Dwarf.h"
@@ -204,79 +203,193 @@
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);
- }
-
- void onValue(const uint8_t U) override {
- writeInteger(U, OS, DebugInfo.IsLittleEndian);
- }
+static unsigned getOffsetSize(const DWARFYAML::Unit &Unit) {
+ return Unit.Format == dwarf::DWARF64 ? 8 : 4;
+}
- void onValue(const uint16_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 uint32_t U) override {
- writeInteger(U, OS, DebugInfo.IsLittleEndian);
+static Expected<uint64_t> writeDIE(ArrayRef<DWARFYAML::Abbrev> 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<dwarf::Form>((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 uint64_t U, const bool LEB = false) override {
- if (LEB)
- encodeULEB128(U, OS);
- else
- writeInteger(U, OS, DebugInfo.IsLittleEndian);
- }
+ return OS.tell() - EntryBegin;
+}
- 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) {
+ // sizeof(version) 2 + sizeof(address_size) 1 = 3
+ // sizeof(unit_type) = 1 (DWARFv5) or 0
+ // sizeof(debug_abbrev_offset) = 4 (DWARF32) or 8 (DWARF64)
+ uint64_t Length = 3 + (Unit.Version >= 5 ? 1 : 0) +
+ (Unit.Format == dwarf::DWARF64 ? 8 : 4);
+
+ // 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<uint64_t> 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);
+ cantFail(writeVariableSizedInteger(Unit.AbbrOffset,
+ Unit.Format == dwarf::DWARF64 ? 8 : 4,
+ OS, DI.IsLittleEndian));
+ } else {
+ cantFail(writeVariableSizedInteger(Unit.AbbrOffset,
+ Unit.Format == dwarf::DWARF64 ? 8 : 4,
+ 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) {
@@ -458,51 +571,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<StringMap<std::unique_ptr<MemoryBuffer>>>
-DWARFYAML::emitDebugSections(StringRef YAMLString, bool ApplyFixups,
- bool IsLittleEndian) {
+DWARFYAML::emitDebugSections(StringRef YAMLString, bool IsLittleEndian) {
auto CollectDiagnostic = [](const SMDiagnostic &Diag, void *DiagContext) {
*static_cast<SMDiagnostic *>(DiagContext) = Diag;
};
@@ -517,12 +587,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<std::unique_ptr<MemoryBuffer>> DebugSections;
Error Err = emitDebugSectionImpl(DI, &DWARFYAML::emitDebugInfo, "debug_info",
DebugSections);
Index: llvm/lib/ObjectYAML/CMakeLists.txt
===================================================================
--- llvm/lib/ObjectYAML/CMakeLists.txt
+++ llvm/lib/ObjectYAML/CMakeLists.txt
@@ -6,7 +6,6 @@
COFFEmitter.cpp
COFFYAML.cpp
DWARFEmitter.cpp
- DWARFVisitor.cpp
DWARFYAML.cpp
ELFEmitter.cpp
ELFYAML.cpp
Index: llvm/include/llvm/ObjectYAML/DWARFYAML.h
===================================================================
--- llvm/include/llvm/ObjectYAML/DWARFYAML.h
+++ llvm/include/llvm/ObjectYAML/DWARFYAML.h
@@ -120,7 +120,7 @@
struct Unit {
dwarf::DwarfFormat Format;
- uint64_t Length;
+ Optional<yaml::Hex64> Length;
uint16_t Version;
llvm::dwarf::UnitType Type; // Added in DWARF 5
yaml::Hex64 AbbrOffset;
Index: llvm/include/llvm/ObjectYAML/DWARFEmitter.h
===================================================================
--- llvm/include/llvm/ObjectYAML/DWARFEmitter.h
+++ llvm/include/llvm/ObjectYAML/DWARFEmitter.h
@@ -41,7 +41,7 @@
Error emitDebugStrOffsets(raw_ostream &OS, const Data &DI);
Expected<StringMap<std::unique_ptr<MemoryBuffer>>>
-emitDebugSections(StringRef YAMLString, bool ApplyFixups = false,
+emitDebugSections(StringRef YAMLString,
bool IsLittleEndian = sys::IsLittleEndianHost);
} // end namespace DWARFYAML
} // end namespace llvm
Index: lldb/unittests/TestingSupport/Symbol/YAMLModuleTester.cpp
===================================================================
--- lldb/unittests/TestingSupport/Symbol/YAMLModuleTester.cpp
+++ 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);
Index: lldb/unittests/SymbolFile/DWARF/DWARFASTParserClangTests.cpp
===================================================================
--- lldb/unittests/SymbolFile/DWARF/DWARFASTParserClangTests.cpp
+++ lldb/unittests/SymbolFile/DWARF/DWARFASTParserClangTests.cpp
@@ -56,8 +56,7 @@
" - Attribute: DW_AT_byte_size\n"
" Form: DW_FORM_data1\n"
"debug_info:\n"
- " - Length: 0\n"
- " Version: 4\n"
+ " - Version: 4\n"
" AbbrOffset: 0\n"
" AddrSize: 8\n"
" Entries:\n"
Index: lldb/unittests/Expression/DWARFExpressionTest.cpp
===================================================================
--- lldb/unittests/Expression/DWARFExpressionTest.cpp
+++ lldb/unittests/Expression/DWARFExpressionTest.cpp
@@ -94,8 +94,7 @@
" - Attribute: DW_AT_byte_size\n"
" Form: DW_FORM_data1\n"
"debug_info:\n"
- " - Length: 0\n"
- " Version: 4\n"
+ " - Version: 4\n"
" AbbrOffset: 0\n"
" AddrSize: 8\n"
" Entries:\n"
_______________________________________________
lldb-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits