From ad76c97fd9bb5cdd96251d62939a2b22d1ea8c1f Mon Sep 17 00:00:00 2001 From: Chris Bieneman Date: Fri, 3 Mar 2017 21:11:55 +0000 Subject: [PATCH] [ObjectYAML] [DWARF] Abstract DWARF Initial Length values In the DWARF 4 Spec section 7.2.2, data in many DWARF sections, and some DWARF structures start with "Initial Length Values", which are a 32-bit length, and an optional 64-bit length if the 32 bit value == UINT32_MAX. This patch abstracts the Initial Length type in YAML, and extends its use to all the DWARF structures that are supported in the DWARFYAML code that have Initial Length values. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@296911 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/llvm/ObjectYAML/DWARFYAML.h | 38 +++++++++++++++---- lib/ObjectYAML/DWARFEmitter.cpp | 21 +++++----- lib/ObjectYAML/DWARFYAML.cpp | 11 ++++-- .../ObjectYAML/MachO/DWARF-debug_aranges.yaml | 6 ++- test/ObjectYAML/MachO/DWARF-debug_info.yaml | 12 ++++-- test/ObjectYAML/MachO/DWARF-debug_line.yaml | 18 ++++++--- test/ObjectYAML/MachO/DWARF-pubsections.yaml | 12 ++++-- tools/obj2yaml/dwarf2yaml.cpp | 26 +++++++------ .../DebugInfo/DWARF/DWARFDebugInfoTest.cpp | 3 +- 9 files changed, 98 insertions(+), 49 deletions(-) diff --git a/include/llvm/ObjectYAML/DWARFYAML.h b/include/llvm/ObjectYAML/DWARFYAML.h index d031b5ac404..f287f701004 100644 --- a/include/llvm/ObjectYAML/DWARFYAML.h +++ b/include/llvm/ObjectYAML/DWARFYAML.h @@ -13,7 +13,6 @@ /// //===----------------------------------------------------------------------===// - #ifndef LLVM_OBJECTYAML_DWARFYAML_H #define LLVM_OBJECTYAML_DWARFYAML_H @@ -23,6 +22,26 @@ namespace llvm { namespace DWARFYAML { +struct InitialLength { + uint32_t TotalLength; + uint64_t TotalLength64; + + bool isDWARF64() const { return TotalLength == UINT32_MAX; } + + uint64_t getLength() const { + return isDWARF64() ? TotalLength64 : TotalLength; + } + + void setLength(uint64_t Len) { + if (Len >= (uint64_t)UINT32_MAX) { + TotalLength64 = Len; + TotalLength = UINT32_MAX; + } else { + TotalLength = Len; + } + } +}; + struct AttributeAbbrev { llvm::dwarf::Attribute Attribute; llvm::dwarf::Form Form; @@ -41,7 +60,7 @@ struct ARangeDescriptor { }; struct ARange { - uint32_t Length; + InitialLength Length; uint16_t Version; uint32_t CuOffset; uint8_t AddrSize; @@ -58,7 +77,7 @@ struct PubEntry { struct PubSection { PubSection() : IsGNUStyle(false) {} - uint32_t Length; + InitialLength Length; uint16_t Version; uint32_t UnitOffset; uint32_t UnitSize; @@ -78,7 +97,7 @@ struct Entry { }; struct Unit { - uint32_t Length; + InitialLength Length; uint16_t Version; uint32_t AbbrOffset; uint8_t AddrSize; @@ -104,8 +123,7 @@ struct LineTableOpcode { }; struct LineTable { - uint32_t TotalLength; - uint64_t TotalLength64; + InitialLength Length; uint16_t Version; uint64_t PrologueLength; uint8_t MinInstLength; @@ -130,7 +148,7 @@ struct Data { PubSection GNUPubNames; PubSection GNUPubTypes; - + std::vector CompileUnits; std::vector DebugLines; @@ -203,7 +221,7 @@ template <> struct MappingTraits { template <> struct MappingTraits { static void mapping(IO &IO, DWARFYAML::File &File); }; - + template <> struct MappingTraits { static void mapping(IO &IO, DWARFYAML::LineTableOpcode &LineTableOpcode); }; @@ -212,6 +230,10 @@ template <> struct MappingTraits { static void mapping(IO &IO, DWARFYAML::LineTable &LineTable); }; +template <> struct MappingTraits { + static void mapping(IO &IO, DWARFYAML::InitialLength &DWARF); +}; + #define HANDLE_DW_TAG(unused, name) \ io.enumCase(value, "DW_TAG_" #name, dwarf::DW_TAG_##name); diff --git a/lib/ObjectYAML/DWARFEmitter.cpp b/lib/ObjectYAML/DWARFEmitter.cpp index 2c2d8958e53..69f7d368ddc 100644 --- a/lib/ObjectYAML/DWARFEmitter.cpp +++ b/lib/ObjectYAML/DWARFEmitter.cpp @@ -50,6 +50,13 @@ static void ZeroFillBytes(raw_ostream &OS, size_t Size) { OS.write(reinterpret_cast(FillData.data()), Size); } +void writeInitialLength(const DWARFYAML::InitialLength &Length, raw_ostream &OS, + bool IsLittleEndian) { + writeInteger((uint32_t)Length.TotalLength, OS, IsLittleEndian); + if (Length.isDWARF64()) + writeInteger((uint64_t)Length.TotalLength64, OS, IsLittleEndian); +} + void DWARFYAML::EmitDebugStr(raw_ostream &OS, const DWARFYAML::Data &DI) { for (auto Str : DI.DebugStrings) { OS.write(Str.data(), Str.size()); @@ -74,7 +81,7 @@ void DWARFYAML::EmitDebugAbbrev(raw_ostream &OS, const DWARFYAML::Data &DI) { void DWARFYAML::EmitDebugAranges(raw_ostream &OS, const DWARFYAML::Data &DI) { for (auto Range : DI.ARanges) { auto HeaderStart = OS.tell(); - writeInteger((uint32_t)Range.Length, OS, DI.IsLittleEndian); + writeInitialLength(Range.Length, OS, DI.IsLittleEndian); writeInteger((uint16_t)Range.Version, OS, DI.IsLittleEndian); writeInteger((uint32_t)Range.CuOffset, OS, DI.IsLittleEndian); writeInteger((uint8_t)Range.AddrSize, OS, DI.IsLittleEndian); @@ -97,7 +104,7 @@ void DWARFYAML::EmitDebugAranges(raw_ostream &OS, const DWARFYAML::Data &DI) { void DWARFYAML::EmitPubSection(raw_ostream &OS, const DWARFYAML::PubSection &Sect, bool IsLittleEndian) { - writeInteger((uint32_t)Sect.Length, OS, IsLittleEndian); + writeInitialLength(Sect.Length, OS, IsLittleEndian); writeInteger((uint16_t)Sect.Version, OS, IsLittleEndian); writeInteger((uint32_t)Sect.UnitOffset, OS, IsLittleEndian); writeInteger((uint32_t)Sect.UnitSize, OS, IsLittleEndian); @@ -113,7 +120,7 @@ void DWARFYAML::EmitPubSection(raw_ostream &OS, void DWARFYAML::EmitDebugInfo(raw_ostream &OS, const DWARFYAML::Data &DI) { for (auto CU : DI.CompileUnits) { - writeInteger((uint32_t)CU.Length, OS, DI.IsLittleEndian); + writeInitialLength(CU.Length, OS, DI.IsLittleEndian); writeInteger((uint16_t)CU.Version, OS, DI.IsLittleEndian); writeInteger((uint32_t)CU.AbbrOffset, OS, DI.IsLittleEndian); writeInteger((uint8_t)CU.AddrSize, OS, DI.IsLittleEndian); @@ -246,12 +253,8 @@ static void EmitFileEntry(raw_ostream &OS, const DWARFYAML::File &File) { void DWARFYAML::EmitDebugLine(raw_ostream &OS, const DWARFYAML::Data &DI) { for (const auto &LineTable : DI.DebugLines) { - writeInteger((uint32_t)LineTable.TotalLength, OS, DI.IsLittleEndian); - uint64_t SizeOfPrologueLength = 4; - if (LineTable.TotalLength == UINT32_MAX) { - writeInteger((uint64_t)LineTable.TotalLength64, OS, DI.IsLittleEndian); - SizeOfPrologueLength = 8; - } + writeInitialLength(LineTable.Length, OS, DI.IsLittleEndian); + uint64_t SizeOfPrologueLength = LineTable.Length.isDWARF64() ? 8 : 4; writeInteger((uint16_t)LineTable.Version, OS, DI.IsLittleEndian); writeVariableSizedInteger(LineTable.PrologueLength, SizeOfPrologueLength, OS, DI.IsLittleEndian); diff --git a/lib/ObjectYAML/DWARFYAML.cpp b/lib/ObjectYAML/DWARFYAML.cpp index 014e63fe7d3..f55d59aff04 100644 --- a/lib/ObjectYAML/DWARFYAML.cpp +++ b/lib/ObjectYAML/DWARFYAML.cpp @@ -144,9 +144,7 @@ void MappingTraits::mapping( void MappingTraits::mapping( IO &IO, DWARFYAML::LineTable &LineTable) { - IO.mapRequired("TotalLength", LineTable.TotalLength); - if (LineTable.TotalLength == UINT32_MAX) - IO.mapRequired("TotalLength64", LineTable.TotalLength64); + IO.mapRequired("Length", LineTable.Length); IO.mapRequired("Version", LineTable.Version); IO.mapRequired("PrologueLength", LineTable.PrologueLength); IO.mapRequired("MinInstLength", LineTable.MinInstLength); @@ -162,6 +160,13 @@ void MappingTraits::mapping( IO.mapRequired("Opcodes", LineTable.Opcodes); } +void MappingTraits::mapping( + IO &IO, DWARFYAML::InitialLength &InitialLength) { + IO.mapRequired("TotalLength", InitialLength.TotalLength); + if (InitialLength.isDWARF64()) + IO.mapRequired("TotalLength64", InitialLength.TotalLength64); +} + } // namespace llvm::yaml } // namespace llvm diff --git a/test/ObjectYAML/MachO/DWARF-debug_aranges.yaml b/test/ObjectYAML/MachO/DWARF-debug_aranges.yaml index 2822c94d775..0b0421d6a09 100644 --- a/test/ObjectYAML/MachO/DWARF-debug_aranges.yaml +++ b/test/ObjectYAML/MachO/DWARF-debug_aranges.yaml @@ -313,7 +313,8 @@ LinkEditData: - _main DWARF: debug_aranges: - - Length: 44 + - Length: + TotalLength: 44 Version: 2 CuOffset: 0 AddrSize: 8 @@ -325,7 +326,8 @@ DWARF: #CHECK: DWARF: #CHECK: debug_aranges: -#CHECK: - Length: 44 +#CHECK: - Length: +#CHECK: TotalLength: 44 #CHECK: Version: 2 #CHECK: CuOffset: 0 #CHECK: AddrSize: 8 diff --git a/test/ObjectYAML/MachO/DWARF-debug_info.yaml b/test/ObjectYAML/MachO/DWARF-debug_info.yaml index b1b6b8ad19e..0ede72bd1f4 100644 --- a/test/ObjectYAML/MachO/DWARF-debug_info.yaml +++ b/test/ObjectYAML/MachO/DWARF-debug_info.yaml @@ -375,7 +375,8 @@ DWARF: - Attribute: DW_AT_type Form: DW_FORM_ref4 debug_aranges: - - Length: 44 + - Length: + TotalLength: 44 Version: 2 CuOffset: 0 AddrSize: 8 @@ -384,7 +385,8 @@ DWARF: - Address: 0x0000000100000F50 Length: 52 debug_info: - - Length: 117 + - Length: + TotalLength: 117 Version: 4 AbbrOffset: 0 AddrSize: 8 @@ -452,7 +454,8 @@ DWARF: - AbbrCode: 0x00000000 Values: debug_line: - - TotalLength: 65 + - Length: + TotalLength: 65 Version: 2 PrologueLength: 36 MinInstLength: 1 @@ -508,7 +511,8 @@ DWARF: #CHECK: DWARF: #CHECK: debug_info: -#CHECK: - Length: 117 +#CHECK: - Length: +#CHECK: TotalLength: 117 #CHECK: Version: 4 #CHECK: AbbrOffset: 0 #CHECK: AddrSize: 8 diff --git a/test/ObjectYAML/MachO/DWARF-debug_line.yaml b/test/ObjectYAML/MachO/DWARF-debug_line.yaml index c1e015839f9..692b5014428 100644 --- a/test/ObjectYAML/MachO/DWARF-debug_line.yaml +++ b/test/ObjectYAML/MachO/DWARF-debug_line.yaml @@ -394,7 +394,8 @@ DWARF: - Attribute: DW_AT_type Form: DW_FORM_ref4 debug_aranges: - - Length: 44 + - Length: + TotalLength: 44 Version: 2 CuOffset: 0 AddrSize: 8 @@ -403,7 +404,8 @@ DWARF: - Address: 0x0000000100000F50 Length: 52 debug_pubnames: - Length: 23 + Length: + TotalLength: 23 Version: 2 UnitOffset: 0 UnitSize: 121 @@ -411,7 +413,8 @@ DWARF: - DieOffset: 0x0000002A Name: main debug_pubtypes: - Length: 31 + Length: + TotalLength: 31 Version: 2 UnitOffset: 0 UnitSize: 121 @@ -421,7 +424,8 @@ DWARF: - DieOffset: 0x00000071 Name: char debug_info: - - Length: 117 + - Length: + TotalLength: 117 Version: 4 AbbrOffset: 0 AddrSize: 8 @@ -489,7 +493,8 @@ DWARF: - AbbrCode: 0x00000000 Values: debug_line: - - TotalLength: 65 + - Length: + TotalLength: 65 Version: 2 PrologueLength: 36 MinInstLength: 1 @@ -542,7 +547,8 @@ DWARF: ... #CHECK: debug_line: -#CHECK: - TotalLength: 65 +#CHECK: - Length: +#CHECK: TotalLength: 65 #CHECK: Version: 2 #CHECK: PrologueLength: 36 #CHECK: MinInstLength: 1 diff --git a/test/ObjectYAML/MachO/DWARF-pubsections.yaml b/test/ObjectYAML/MachO/DWARF-pubsections.yaml index 8535ed0b5c4..a3c05ca5b35 100644 --- a/test/ObjectYAML/MachO/DWARF-pubsections.yaml +++ b/test/ObjectYAML/MachO/DWARF-pubsections.yaml @@ -314,7 +314,8 @@ DWARF: - int - char debug_pubnames: - Length: 23 + Length: + TotalLength: 23 Version: 2 UnitOffset: 0 UnitSize: 121 @@ -322,7 +323,8 @@ DWARF: - DieOffset: 0x0000002A Name: main debug_pubtypes: - Length: 31 + Length: + TotalLength: 31 Version: 2 UnitOffset: 0 UnitSize: 121 @@ -335,7 +337,8 @@ DWARF: #CHECK: DWARF: #CHECK: debug_pubnames: -#CHECK: Length: 23 +#CHECK: Length: +#CHECK: TotalLength: 23 #CHECK: Version: 2 #CHECK: UnitOffset: 0 #CHECK: UnitSize: 121 @@ -343,7 +346,8 @@ DWARF: #CHECK: - DieOffset: 0x0000002A #CHECK: Name: main #CHECK: debug_pubtypes: -#CHECK: Length: 31 +#CHECK: Length: +#CHECK: TotalLength: 31 #CHECK: Version: 2 #CHECK: UnitOffset: 0 #CHECK: UnitSize: 121 diff --git a/tools/obj2yaml/dwarf2yaml.cpp b/tools/obj2yaml/dwarf2yaml.cpp index 4e320cff441..7b45f8acc3c 100644 --- a/tools/obj2yaml/dwarf2yaml.cpp +++ b/tools/obj2yaml/dwarf2yaml.cpp @@ -17,6 +17,13 @@ using namespace llvm; +void dumpInitialLength(DataExtractor &Data, uint32_t &Offset, + DWARFYAML::InitialLength &InitialLength) { + InitialLength.TotalLength = Data.getU32(&Offset); + if (InitialLength.isDWARF64()) + InitialLength.TotalLength64 = Data.getU64(&Offset); +} + void dumpDebugAbbrev(DWARFContextInMemory &DCtx, DWARFYAML::Data &Y) { auto AbbrevSetPtr = DCtx.getDebugAbbrev(); if (AbbrevSetPtr) { @@ -55,7 +62,7 @@ void dumpDebugARanges(DWARFContextInMemory &DCtx, DWARFYAML::Data &Y) { while (Set.extract(ArangesData, &Offset)) { DWARFYAML::ARange Range; - Range.Length = Set.getHeader().Length; + Range.Length.setLength(Set.getHeader().Length); Range.Version = Set.getHeader().Version; Range.CuOffset = Set.getHeader().CuOffset; Range.AddrSize = Set.getHeader().AddrSize; @@ -74,11 +81,11 @@ void dumpPubSection(DWARFContextInMemory &DCtx, DWARFYAML::PubSection &Y, StringRef Section) { DataExtractor PubSectionData(Section, DCtx.isLittleEndian(), 0); uint32_t Offset = 0; - Y.Length = PubSectionData.getU32(&Offset); + dumpInitialLength(PubSectionData, Offset, Y.Length); Y.Version = PubSectionData.getU16(&Offset); Y.UnitOffset = PubSectionData.getU32(&Offset); Y.UnitSize = PubSectionData.getU32(&Offset); - while (Offset < Y.Length) { + while (Offset < Y.Length.getLength()) { DWARFYAML::PubEntry NewEntry; NewEntry.DieOffset = PubSectionData.getU32(&Offset); if (Y.IsGNUStyle) @@ -105,7 +112,7 @@ void dumpDebugPubSections(DWARFContextInMemory &DCtx, DWARFYAML::Data &Y) { void dumpDebugInfo(DWARFContextInMemory &DCtx, DWARFYAML::Data &Y) { for (const auto &CU : DCtx.compile_units()) { DWARFYAML::Unit NewUnit; - NewUnit.Length = CU->getLength(); + NewUnit.Length.setLength(CU->getLength()); NewUnit.Version = CU->getVersion(); NewUnit.AbbrOffset = CU->getAbbreviations()->getOffset(); NewUnit.AddrSize = CU->getAddressByteSize(); @@ -233,14 +240,9 @@ void dumpDebugLines(DWARFContextInMemory &DCtx, DWARFYAML::Data &Y) { DataExtractor LineData(DCtx.getLineSection().Data, DCtx.isLittleEndian(), CU->getAddressByteSize()); uint32_t Offset = *StmtOffset; - uint64_t SizeOfPrologueLength = 4; - DebugLines.TotalLength = LineData.getU32(&Offset); - uint64_t LineTableLength = DebugLines.TotalLength; - if (DebugLines.TotalLength == UINT32_MAX) { - DebugLines.TotalLength64 = LineData.getU64(&Offset); - LineTableLength = DebugLines.TotalLength64; - SizeOfPrologueLength = 8; - } + dumpInitialLength(LineData, Offset, DebugLines.Length); + uint64_t LineTableLength = DebugLines.Length.getLength(); + uint64_t SizeOfPrologueLength = DebugLines.Length.isDWARF64() ? 8 : 4; DebugLines.Version = LineData.getU16(&Offset); DebugLines.PrologueLength = LineData.getUnsigned(&Offset, SizeOfPrologueLength); diff --git a/unittests/DebugInfo/DWARF/DWARFDebugInfoTest.cpp b/unittests/DebugInfo/DWARF/DWARFDebugInfoTest.cpp index 90dd688d51f..b6111e71c1a 100644 --- a/unittests/DebugInfo/DWARF/DWARFDebugInfoTest.cpp +++ b/unittests/DebugInfo/DWARF/DWARFDebugInfoTest.cpp @@ -1172,7 +1172,8 @@ TEST(DWARFDebugInfo, TestEmptyChildren) { " Children: DW_CHILDREN_yes\n" " Attributes:\n" "debug_info:\n" - " - Length: 9\n" + " - Length:\n" + " TotalLength: 9\n" " Version: 4\n" " AbbrOffset: 0\n" " AddrSize: 8\n" -- 2.50.1