From e0e451d9278e12f5d6411565e0cb17b9c57362ce Mon Sep 17 00:00:00 2001 From: Chris Bieneman Date: Thu, 22 Dec 2016 22:44:27 +0000 Subject: [PATCH] [ObjectYAML] Support for DWARF debug_info section This patch adds support for YAML<->DWARF for debug_info sections. This re-lands r290147, reverted in 290148, re-landed in r290204 after fixing the issue that caused bots to fail (thank you UBSan!), and reverted again in r290209 due to failures on big endian systems. After adding support for preserving endianness, this should be good now. llvm-svn: 290386 --- llvm/include/llvm/DebugInfo/DWARF/DWARFFormValue.h | 2 + llvm/include/llvm/DebugInfo/DWARF/DWARFUnit.h | 8 + llvm/include/llvm/ObjectYAML/DWARFYAML.h | 38 ++ llvm/include/llvm/ObjectYAML/MachOYAML.h | 1 - llvm/lib/DebugInfo/DWARF/DWARFFormValue.cpp | 12 + llvm/lib/ObjectYAML/DWARFYAML.cpp | 33 +- llvm/test/ObjectYAML/MachO/DWARF-debug_info.yaml | 525 +++++++++++++++++++++ llvm/tools/obj2yaml/dwarf2yaml.cpp | 117 ++++- llvm/tools/yaml2obj/yaml2dwarf.cpp | 130 ++++- llvm/tools/yaml2obj/yaml2macho.cpp | 2 + llvm/tools/yaml2obj/yaml2obj.h | 1 + 11 files changed, 860 insertions(+), 9 deletions(-) create mode 100644 llvm/test/ObjectYAML/MachO/DWARF-debug_info.yaml diff --git a/llvm/include/llvm/DebugInfo/DWARF/DWARFFormValue.h b/llvm/include/llvm/DebugInfo/DWARF/DWARFFormValue.h index a6228b5..920880c 100644 --- a/llvm/include/llvm/DebugInfo/DWARF/DWARFFormValue.h +++ b/llvm/include/llvm/DebugInfo/DWARF/DWARFFormValue.h @@ -82,6 +82,8 @@ public: Optional getAsAddress() const; Optional getAsSectionOffset() const; Optional> getAsBlock() const; + Optional getAsCStringOffset() const; + Optional getAsReferenceUVal() const; /// Get the fixed byte size for a given form. /// /// If the form always has a fixed valid byte size that doesn't depend on a diff --git a/llvm/include/llvm/DebugInfo/DWARF/DWARFUnit.h b/llvm/include/llvm/DebugInfo/DWARF/DWARFUnit.h index 78bbe09..db7b59b 100644 --- a/llvm/include/llvm/DebugInfo/DWARF/DWARFUnit.h +++ b/llvm/include/llvm/DebugInfo/DWARF/DWARFUnit.h @@ -11,6 +11,7 @@ #define LLVM_LIB_DEBUGINFO_DWARFUNIT_H #include "llvm/ADT/Optional.h" +#include "llvm/ADT/iterator_range.h" #include "llvm/ADT/STLExtras.h" #include "llvm/DebugInfo/DWARF/DWARFDebugAbbrev.h" #include "llvm/DebugInfo/DWARF/DWARFDebugInfoEntry.h" @@ -127,6 +128,8 @@ class DWARFUnit { uint64_t BaseAddr; // The compile unit debug information entry items. std::vector DieArray; + typedef iterator_range::iterator> + die_iterator_range; class DWOHolder { object::OwningBinary DWOFile; @@ -293,6 +296,11 @@ public: return 0; } + die_iterator_range dies() { + extractDIEsIfNeeded(false); + return die_iterator_range(DieArray.begin(), DieArray.end()); + } + private: /// Size in bytes of the .debug_info data associated with this compile unit. size_t getDebugInfoSize() const { return Length + 4 - getHeaderSize(); } diff --git a/llvm/include/llvm/ObjectYAML/DWARFYAML.h b/llvm/include/llvm/ObjectYAML/DWARFYAML.h index d73ff6c..222cad6 100644 --- a/llvm/include/llvm/ObjectYAML/DWARFYAML.h +++ b/llvm/include/llvm/ObjectYAML/DWARFYAML.h @@ -66,6 +66,25 @@ struct PubSection { std::vector Entries; }; +struct FormValue { + llvm::yaml::Hex64 Value; + StringRef CStr; + std::vector BlockData; +}; + +struct Entry { + llvm::yaml::Hex32 AbbrCode; + std::vector Values; +}; + +struct Unit { + uint32_t Length; + uint16_t Version; + uint32_t AbbrOffset; + uint8_t AddrSize; + std::vector Entries; +}; + struct Data { bool IsLittleEndian; std::vector AbbrevDecls; @@ -76,6 +95,8 @@ struct Data { PubSection GNUPubNames; PubSection GNUPubTypes; + + std::vector CompileUnits; bool isEmpty() const; }; @@ -83,12 +104,17 @@ struct Data { } // namespace llvm::DWARFYAML } // namespace llvm +LLVM_YAML_IS_SEQUENCE_VECTOR(uint8_t) LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::StringRef) +LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::yaml::Hex8) LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::DWARFYAML::AttributeAbbrev) LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::DWARFYAML::Abbrev) LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::DWARFYAML::ARangeDescriptor) LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::DWARFYAML::ARange) LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::DWARFYAML::PubEntry) +LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::DWARFYAML::Unit) +LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::DWARFYAML::FormValue) +LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::DWARFYAML::Entry) namespace llvm { namespace yaml { @@ -121,6 +147,18 @@ template <> struct MappingTraits { static void mapping(IO &IO, DWARFYAML::PubSection &Section); }; +template <> struct MappingTraits { + static void mapping(IO &IO, DWARFYAML::Unit &Unit); +}; + +template <> struct MappingTraits { + static void mapping(IO &IO, DWARFYAML::Entry &Entry); +}; + +template <> struct MappingTraits { + static void mapping(IO &IO, DWARFYAML::FormValue &FormValue); +}; + #define HANDLE_DW_TAG(unused, name) \ io.enumCase(value, "DW_TAG_" #name, dwarf::DW_TAG_##name); diff --git a/llvm/include/llvm/ObjectYAML/MachOYAML.h b/llvm/include/llvm/ObjectYAML/MachOYAML.h index 0cbf585..6b7a924 100644 --- a/llvm/include/llvm/ObjectYAML/MachOYAML.h +++ b/llvm/include/llvm/ObjectYAML/MachOYAML.h @@ -139,7 +139,6 @@ struct UniversalBinary { LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::MachOYAML::LoadCommand) LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::MachOYAML::Section) -LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::yaml::Hex8) LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::yaml::Hex64) LLVM_YAML_IS_SEQUENCE_VECTOR(int64_t) LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::MachOYAML::RebaseOpcode) diff --git a/llvm/lib/DebugInfo/DWARF/DWARFFormValue.cpp b/llvm/lib/DebugInfo/DWARF/DWARFFormValue.cpp index b3f1a52..e48a6f0 100644 --- a/llvm/lib/DebugInfo/DWARF/DWARFFormValue.cpp +++ b/llvm/lib/DebugInfo/DWARF/DWARFFormValue.cpp @@ -661,3 +661,15 @@ Optional> DWARFFormValue::getAsBlock() const { return makeArrayRef(Value.data, Value.uval); } +Optional DWARFFormValue::getAsCStringOffset() const { + if (!isFormClass(FC_String) && Form == DW_FORM_string) + return None; + return Value.uval; +} + +Optional DWARFFormValue::getAsReferenceUVal() const { + if (!isFormClass(FC_Reference)) + return None; + return Value.uval; +} + diff --git a/llvm/lib/ObjectYAML/DWARFYAML.cpp b/llvm/lib/ObjectYAML/DWARFYAML.cpp index 3d647b0..42a448a 100644 --- a/llvm/lib/ObjectYAML/DWARFYAML.cpp +++ b/llvm/lib/ObjectYAML/DWARFYAML.cpp @@ -22,8 +22,9 @@ bool DWARFYAML::Data::isEmpty() const { namespace yaml { -void MappingTraits::mapping( - IO &IO, DWARFYAML::Data &DWARF) { +void MappingTraits::mapping(IO &IO, DWARFYAML::Data &DWARF) { + auto oldContext = IO.getContext(); + IO.setContext(&DWARF); IO.mapOptional("debug_str", DWARF.DebugStrings); IO.mapOptional("debug_abbrev", DWARF.AbbrevDecls); if(!DWARF.ARanges.empty() || !IO.outputting()) @@ -36,10 +37,12 @@ void MappingTraits::mapping( IO.mapOptional("debug_gnu_pubnames", DWARF.GNUPubNames); if(!DWARF.GNUPubTypes.Entries.empty() || !IO.outputting()) IO.mapOptional("debug_gnu_pubtypes", DWARF.GNUPubTypes); + IO.mapOptional("debug_info", DWARF.CompileUnits); + IO.setContext(&oldContext); } -void MappingTraits::mapping( - IO &IO, DWARFYAML::Abbrev &Abbrev) { +void MappingTraits::mapping(IO &IO, + DWARFYAML::Abbrev &Abbrev) { IO.mapRequired("Code", Abbrev.Code); IO.mapRequired("Tag", Abbrev.Tag); IO.mapRequired("Children", Abbrev.Children); @@ -90,6 +93,28 @@ void MappingTraits::mapping( IO.setContext(OldContext); } +void MappingTraits::mapping(IO &IO, DWARFYAML::Unit &Unit) { + IO.mapRequired("Length", Unit.Length); + IO.mapRequired("Version", Unit.Version); + IO.mapRequired("AbbrOffset", Unit.AbbrOffset); + IO.mapRequired("AddrSize", Unit.AddrSize); + IO.mapOptional("Entries", Unit.Entries); +} + +void MappingTraits::mapping(IO &IO, DWARFYAML::Entry &Entry) { + IO.mapRequired("AbbrCode", Entry.AbbrCode); + IO.mapRequired("Values", Entry.Values); +} + +void MappingTraits::mapping(IO &IO, + DWARFYAML::FormValue &FormValue) { + IO.mapOptional("Value", FormValue.Value); + if(!FormValue.CStr.empty() || !IO.outputting()) + IO.mapOptional("CStr", FormValue.CStr); + if(!FormValue.BlockData.empty() || !IO.outputting()) + IO.mapOptional("BlockData", FormValue.BlockData); +} + } // namespace llvm::yaml } // namespace llvm diff --git a/llvm/test/ObjectYAML/MachO/DWARF-debug_info.yaml b/llvm/test/ObjectYAML/MachO/DWARF-debug_info.yaml new file mode 100644 index 0000000..9a616e9 --- /dev/null +++ b/llvm/test/ObjectYAML/MachO/DWARF-debug_info.yaml @@ -0,0 +1,525 @@ +# RUN: yaml2obj %s | obj2yaml | FileCheck %s + +--- !mach-o +FileHeader: + magic: 0xFEEDFACF + cputype: 0x01000007 + cpusubtype: 0x00000003 + filetype: 0x0000000A + ncmds: 5 + sizeofcmds: 1800 + flags: 0x00000000 + reserved: 0x00000000 +LoadCommands: + - cmd: LC_SEGMENT_64 + cmdsize: 72 + segname: __PAGEZERO + vmaddr: 0 + vmsize: 4294967296 + fileoff: 0 + filesize: 0 + maxprot: 0 + initprot: 0 + nsects: 0 + flags: 0 + - cmd: LC_SEGMENT_64 + cmdsize: 472 + segname: __TEXT + vmaddr: 4294967296 + vmsize: 4096 + fileoff: 0 + filesize: 0 + maxprot: 7 + initprot: 5 + nsects: 5 + flags: 0 + Sections: + - sectname: __text + segname: __TEXT + addr: 0x0000000100000F50 + size: 52 + offset: 0x00000000 + align: 4 + reloff: 0x00000000 + nreloc: 0 + flags: 0x80000400 + reserved1: 0x00000000 + reserved2: 0x00000000 + reserved3: 0x00000000 + - sectname: __stubs + segname: __TEXT + addr: 0x0000000100000F84 + size: 6 + offset: 0x00000000 + align: 1 + reloff: 0x00000000 + nreloc: 0 + flags: 0x80000408 + reserved1: 0x00000000 + reserved2: 0x00000006 + reserved3: 0x00000000 + - sectname: __stub_helper + segname: __TEXT + addr: 0x0000000100000F8C + size: 26 + offset: 0x00000000 + align: 2 + reloff: 0x00000000 + nreloc: 0 + flags: 0x80000400 + reserved1: 0x00000000 + reserved2: 0x00000000 + reserved3: 0x00000000 + - sectname: __cstring + segname: __TEXT + addr: 0x0000000100000FA6 + size: 14 + offset: 0x00000000 + align: 0 + reloff: 0x00000000 + nreloc: 0 + flags: 0x00000002 + reserved1: 0x00000000 + reserved2: 0x00000000 + reserved3: 0x00000000 + - sectname: __unwind_info + segname: __TEXT + addr: 0x0000000100000FB4 + size: 72 + offset: 0x00000000 + align: 2 + reloff: 0x00000000 + nreloc: 0 + flags: 0x00000000 + reserved1: 0x00000000 + reserved2: 0x00000000 + reserved3: 0x00000000 + - cmd: LC_SEGMENT_64 + cmdsize: 232 + segname: __DATA + vmaddr: 4294971392 + vmsize: 4096 + fileoff: 0 + filesize: 0 + maxprot: 7 + initprot: 3 + nsects: 2 + flags: 0 + Sections: + - sectname: __nl_symbol_ptr + segname: __DATA + addr: 0x0000000100001000 + size: 16 + offset: 0x00000000 + align: 3 + reloff: 0x00000000 + nreloc: 0 + flags: 0x00000006 + reserved1: 0x00000001 + reserved2: 0x00000000 + reserved3: 0x00000000 + - sectname: __la_symbol_ptr + segname: __DATA + addr: 0x0000000100001010 + size: 8 + offset: 0x00000000 + align: 3 + reloff: 0x00000000 + nreloc: 0 + flags: 0x00000007 + reserved1: 0x00000003 + reserved2: 0x00000000 + reserved3: 0x00000000 + - cmd: LC_SEGMENT_64 + cmdsize: 72 + segname: __LINKEDIT + vmaddr: 4294975488 + vmsize: 4096 + fileoff: 4096 + filesize: 60 + maxprot: 7 + initprot: 1 + nsects: 0 + flags: 0 + - cmd: LC_SEGMENT_64 + cmdsize: 952 + segname: __DWARF + vmaddr: 4294979584 + vmsize: 4096 + fileoff: 8192 + filesize: 764 + maxprot: 7 + initprot: 3 + nsects: 11 + flags: 0 + Sections: + - sectname: __debug_line + segname: __DWARF + addr: 0x0000000100003000 + size: 69 + offset: 0x00002000 + align: 0 + reloff: 0x00000000 + nreloc: 0 + flags: 0x00000000 + reserved1: 0x00000000 + reserved2: 0x00000000 + reserved3: 0x00000000 + - sectname: __debug_pubnames + segname: __DWARF + addr: 0x0000000100003045 + size: 27 + offset: 0x00002045 + align: 0 + reloff: 0x00000000 + nreloc: 0 + flags: 0x00000000 + reserved1: 0x00000000 + reserved2: 0x00000000 + reserved3: 0x00000000 + - sectname: __debug_pubtypes + segname: __DWARF + addr: 0x0000000100003060 + size: 35 + offset: 0x00002060 + align: 0 + reloff: 0x00000000 + nreloc: 0 + flags: 0x00000000 + reserved1: 0x00000000 + reserved2: 0x00000000 + reserved3: 0x00000000 + - sectname: __debug_aranges + segname: __DWARF + addr: 0x0000000100003083 + size: 48 + offset: 0x00002083 + align: 0 + reloff: 0x00000000 + nreloc: 0 + flags: 0x00000000 + reserved1: 0x00000000 + reserved2: 0x00000000 + reserved3: 0x00000000 + - sectname: __debug_info + segname: __DWARF + addr: 0x00000001000030B3 + size: 121 + offset: 0x000020B3 + align: 0 + reloff: 0x00000000 + nreloc: 0 + flags: 0x00000000 + reserved1: 0x00000000 + reserved2: 0x00000000 + reserved3: 0x00000000 + - sectname: __debug_abbrev + segname: __DWARF + addr: 0x000000010000312C + size: 76 + offset: 0x0000212C + align: 0 + reloff: 0x00000000 + nreloc: 0 + flags: 0x00000000 + reserved1: 0x00000000 + reserved2: 0x00000000 + reserved3: 0x00000000 + - sectname: __debug_str + segname: __DWARF + addr: 0x0000000100003178 + size: 142 + offset: 0x00002178 + align: 0 + reloff: 0x00000000 + nreloc: 0 + flags: 0x00000000 + reserved1: 0x00000000 + reserved2: 0x00000000 + reserved3: 0x00000000 + - sectname: __apple_names + segname: __DWARF + addr: 0x0000000100003206 + size: 60 + offset: 0x00002206 + align: 0 + reloff: 0x00000000 + nreloc: 0 + flags: 0x00000000 + reserved1: 0x00000000 + reserved2: 0x00000000 + reserved3: 0x00000000 + - sectname: __apple_namespac + segname: __DWARF + addr: 0x0000000100003242 + size: 36 + offset: 0x00002242 + align: 0 + reloff: 0x00000000 + nreloc: 0 + flags: 0x00000000 + reserved1: 0x00000000 + reserved2: 0x00000000 + reserved3: 0x00000000 + - sectname: __apple_types + segname: __DWARF + addr: 0x0000000100003266 + size: 114 + offset: 0x00002266 + align: 0 + reloff: 0x00000000 + nreloc: 0 + flags: 0x00000000 + reserved1: 0x00000000 + reserved2: 0x00000000 + reserved3: 0x00000000 + - sectname: __apple_objc + segname: __DWARF + addr: 0x00000001000032D8 + size: 36 + offset: 0x000022D8 + align: 0 + reloff: 0x00000000 + nreloc: 0 + flags: 0x00000000 + reserved1: 0x00000000 + reserved2: 0x00000000 + reserved3: 0x00000000 +LinkEditData: + NameList: + - n_strx: 2 + n_type: 0x0F + n_sect: 1 + n_desc: 16 + n_value: 4294967296 + - n_strx: 22 + n_type: 0x0F + n_sect: 1 + n_desc: 0 + n_value: 4294971216 + StringTable: + - '' + - '' + - __mh_execute_header + - _main +DWARF: + debug_abbrev: + - Code: 0x00000001 + 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: 0x00000002 + Tag: DW_TAG_subprogram + Children: DW_CHILDREN_yes + Attributes: + - Attribute: DW_AT_low_pc + Form: DW_FORM_addr + - Attribute: DW_AT_high_pc + Form: DW_FORM_data4 + - Attribute: DW_AT_frame_base + Form: DW_FORM_exprloc + - Attribute: DW_AT_name + Form: DW_FORM_strp + - Attribute: DW_AT_decl_file + Form: DW_FORM_data1 + - Attribute: DW_AT_decl_line + Form: DW_FORM_data1 + - Attribute: DW_AT_prototyped + Form: DW_FORM_flag_present + - Attribute: DW_AT_type + Form: DW_FORM_ref4 + - Attribute: DW_AT_external + Form: DW_FORM_flag_present + - Code: 0x00000003 + Tag: DW_TAG_formal_parameter + Children: DW_CHILDREN_no + Attributes: + - Attribute: DW_AT_location + Form: DW_FORM_exprloc + - Attribute: DW_AT_name + Form: DW_FORM_strp + - Attribute: DW_AT_decl_file + Form: DW_FORM_data1 + - Attribute: DW_AT_decl_line + Form: DW_FORM_data1 + - Attribute: DW_AT_type + Form: DW_FORM_ref4 + - Code: 0x00000004 + Tag: DW_TAG_base_type + Children: DW_CHILDREN_no + Attributes: + - Attribute: DW_AT_name + Form: DW_FORM_strp + - Attribute: DW_AT_encoding + Form: DW_FORM_data1 + - Attribute: DW_AT_byte_size + Form: DW_FORM_data1 + - Code: 0x00000005 + Tag: DW_TAG_pointer_type + Children: DW_CHILDREN_no + Attributes: + - Attribute: DW_AT_type + Form: DW_FORM_ref4 + debug_aranges: + - Length: 44 + Version: 2 + CuOffset: 0 + AddrSize: 8 + SegSize: 0 + Descriptors: + - Address: 0x0000000100000F50 + Length: 52 + debug_info: + - Length: 117 + Version: 4 + AbbrOffset: 0 + AddrSize: 8 + Entries: + - AbbrCode: 0x00000001 + Values: + - Value: 0x0000000000000001 + - Value: 0x000000000000000C + - Value: 0x0000000000000038 + - Value: 0x0000000000000000 + - Value: 0x0000000000000046 + - Value: 0x0000000100000F50 + - Value: 0x0000000000000034 + - AbbrCode: 0x00000002 + Values: + - Value: 0x0000000100000F50 + - Value: 0x0000000000000034 + - Value: 0x0000000000000001 + BlockData: + - 0x56 + - Value: 0x0000000000000076 + - Value: 0x0000000000000001 + - Value: 0x0000000000000003 + - Value: 0x0000000000000001 + - Value: 0x0000000000000060 + - Value: 0x0000000000000001 + - AbbrCode: 0x00000003 + Values: + - Value: 0x0000000000000002 + BlockData: + - 0x91 + - 0x78 + - Value: 0x000000000000007B + - Value: 0x0000000000000001 + - Value: 0x0000000000000003 + - Value: 0x0000000000000060 + - AbbrCode: 0x00000003 + Values: + - Value: 0x0000000000000002 + BlockData: + - 0x91 + - 0x70 + - Value: 0x0000000000000080 + - Value: 0x0000000000000001 + - Value: 0x0000000000000003 + - Value: 0x0000000000000067 + - AbbrCode: 0x00000000 + Values: + - AbbrCode: 0x00000004 + Values: + - Value: 0x0000000000000085 + - Value: 0x0000000000000005 + - Value: 0x0000000000000004 + - AbbrCode: 0x00000005 + Values: + - Value: 0x000000000000006C + - AbbrCode: 0x00000005 + Values: + - Value: 0x0000000000000071 + - AbbrCode: 0x00000004 + Values: + - Value: 0x0000000000000089 + - Value: 0x0000000000000006 + - Value: 0x0000000000000001 + - AbbrCode: 0x00000000 + Values: +... + + +#CHECK: DWARF: +#CHECK: debug_info: +#CHECK: - Length: 117 +#CHECK: Version: 4 +#CHECK: AbbrOffset: 0 +#CHECK: AddrSize: 8 +#CHECK: Entries: +#CHECK: - AbbrCode: 0x00000001 +#CHECK: Values: +#CHECK: - Value: 0x0000000000000001 +#CHECK: - Value: 0x000000000000000C +#CHECK: - Value: 0x0000000000000038 +#CHECK: - Value: 0x0000000000000000 +#CHECK: - Value: 0x0000000000000046 +#CHECK: - Value: 0x0000000100000F50 +#CHECK: - Value: 0x0000000000000034 +#CHECK: - AbbrCode: 0x00000002 +#CHECK: Values: +#CHECK: - Value: 0x0000000100000F50 +#CHECK: - Value: 0x0000000000000034 +#CHECK: - Value: 0x0000000000000001 +#CHECK: BlockData: +#CHECK: - 0x56 +#CHECK: - Value: 0x0000000000000076 +#CHECK: - Value: 0x0000000000000001 +#CHECK: - Value: 0x0000000000000003 +#CHECK: - Value: 0x0000000000000001 +#CHECK: - Value: 0x0000000000000060 +#CHECK: - Value: 0x0000000000000001 +#CHECK: - AbbrCode: 0x00000003 +#CHECK: Values: +#CHECK: - Value: 0x0000000000000002 +#CHECK: BlockData: +#CHECK: - 0x91 +#CHECK: - 0x78 +#CHECK: - Value: 0x000000000000007B +#CHECK: - Value: 0x0000000000000001 +#CHECK: - Value: 0x0000000000000003 +#CHECK: - Value: 0x0000000000000060 +#CHECK: - AbbrCode: 0x00000003 +#CHECK: Values: +#CHECK: - Value: 0x0000000000000002 +#CHECK: BlockData: +#CHECK: - 0x91 +#CHECK: - 0x70 +#CHECK: - Value: 0x0000000000000080 +#CHECK: - Value: 0x0000000000000001 +#CHECK: - Value: 0x0000000000000003 +#CHECK: - Value: 0x0000000000000067 +#CHECK: - AbbrCode: 0x00000000 +#CHECK: Values: +#CHECK: - AbbrCode: 0x00000004 +#CHECK: Values: +#CHECK: - Value: 0x0000000000000085 +#CHECK: - Value: 0x0000000000000005 +#CHECK: - Value: 0x0000000000000004 +#CHECK: - AbbrCode: 0x00000005 +#CHECK: Values: +#CHECK: - Value: 0x000000000000006C +#CHECK: - AbbrCode: 0x00000005 +#CHECK: Values: +#CHECK: - Value: 0x0000000000000071 +#CHECK: - AbbrCode: 0x00000004 +#CHECK: Values: +#CHECK: - Value: 0x0000000000000089 +#CHECK: - Value: 0x0000000000000006 +#CHECK: - Value: 0x0000000000000001 +#CHECK: - AbbrCode: 0x00000000 +#CHECK: Values: diff --git a/llvm/tools/obj2yaml/dwarf2yaml.cpp b/llvm/tools/obj2yaml/dwarf2yaml.cpp index 0fd646e..cf8b3e5 100644 --- a/llvm/tools/obj2yaml/dwarf2yaml.cpp +++ b/llvm/tools/obj2yaml/dwarf2yaml.cpp @@ -10,8 +10,11 @@ #include "Error.h" #include "llvm/DebugInfo/DWARF/DWARFContext.h" #include "llvm/DebugInfo/DWARF/DWARFDebugArangeSet.h" +#include "llvm/DebugInfo/DWARF/DWARFFormValue.h" #include "llvm/ObjectYAML/DWARFYAML.h" +#include + using namespace llvm; void dumpDebugAbbrev(DWARFContextInMemory &DCtx, DWARFYAML::Data &Y) { @@ -99,12 +102,120 @@ void dumpDebugPubSections(DWARFContextInMemory &DCtx, DWARFYAML::Data &Y) { dumpPubSection(DCtx, Y.GNUPubTypes, DCtx.getGnuPubTypesSection()); } -std::error_code dwarf2yaml(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.Version = CU->getVersion(); + NewUnit.AbbrOffset = CU->getAbbreviations()->getOffset(); + NewUnit.AddrSize = CU->getAddressByteSize(); + for (auto DIE : CU->dies()) { + DWARFYAML::Entry NewEntry; + DataExtractor EntryData = CU->getDebugInfoExtractor(); + uint32_t offset = DIE.getOffset(); + + assert(EntryData.isValidOffset(offset) && "Invalid DIE Offset"); + if (!EntryData.isValidOffset(offset)) + continue; + + NewEntry.AbbrCode = EntryData.getULEB128(&offset); + + auto AbbrevDecl = DIE.getAbbreviationDeclarationPtr(); + if (AbbrevDecl) { + for (const auto &AttrSpec : AbbrevDecl->attributes()) { + DWARFYAML::FormValue NewValue; + NewValue.Value = 0xDEADBEEFDEADBEEF; + DWARFDie DIEWrapper(CU.get(), &DIE); + auto FormValue = DIEWrapper.getAttributeValue(AttrSpec.Attr); + if(!FormValue) + return; + auto Form = FormValue.getValue().getForm(); + bool indirect = false; + do { + indirect = false; + switch (Form) { + case dwarf::DW_FORM_addr: + case dwarf::DW_FORM_GNU_addr_index: + if (auto Val = FormValue.getValue().getAsAddress()) + NewValue.Value = Val.getValue(); + break; + case dwarf::DW_FORM_ref_addr: + case dwarf::DW_FORM_ref1: + case dwarf::DW_FORM_ref2: + case dwarf::DW_FORM_ref4: + case dwarf::DW_FORM_ref8: + case dwarf::DW_FORM_ref_udata: + case dwarf::DW_FORM_ref_sig8: + if (auto Val = FormValue.getValue().getAsReferenceUVal()) + NewValue.Value = Val.getValue(); + break; + case dwarf::DW_FORM_exprloc: + case dwarf::DW_FORM_block: + case dwarf::DW_FORM_block1: + case dwarf::DW_FORM_block2: + case dwarf::DW_FORM_block4: + if (auto Val = FormValue.getValue().getAsBlock()) { + auto BlockData = Val.getValue(); + std::copy(BlockData.begin(), BlockData.end(), + std::back_inserter(NewValue.BlockData)); + } + NewValue.Value = NewValue.BlockData.size(); + break; + case dwarf::DW_FORM_data1: + case dwarf::DW_FORM_flag: + case dwarf::DW_FORM_data2: + case dwarf::DW_FORM_data4: + case dwarf::DW_FORM_data8: + case dwarf::DW_FORM_sdata: + case dwarf::DW_FORM_udata: + if (auto Val = FormValue.getValue().getAsUnsignedConstant()) + NewValue.Value = Val.getValue(); + break; + case dwarf::DW_FORM_string: + if (auto Val = FormValue.getValue().getAsCString()) + NewValue.CStr = Val.getValue(); + break; + case dwarf::DW_FORM_indirect: + indirect = true; + if (auto Val = FormValue.getValue().getAsUnsignedConstant()) { + NewValue.Value = Val.getValue(); + NewEntry.Values.push_back(NewValue); + Form = static_cast(Val.getValue()); + } + 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: + case dwarf::DW_FORM_ref_sup: + case dwarf::DW_FORM_GNU_str_index: + if (auto Val = FormValue.getValue().getAsCStringOffset()) + NewValue.Value = Val.getValue(); + break; + case dwarf::DW_FORM_flag_present: + NewValue.Value = 1; + break; + default: + break; + } + } while (indirect); + NewEntry.Values.push_back(NewValue); + } + } + + NewUnit.Entries.push_back(NewEntry); + } + Y.CompileUnits.push_back(NewUnit); + } +} + +std::error_code dwarf2yaml(DWARFContextInMemory &DCtx, DWARFYAML::Data &Y) { dumpDebugAbbrev(DCtx, Y); dumpDebugStrings(DCtx, Y); dumpDebugARanges(DCtx, Y); dumpDebugPubSections(DCtx, Y); - + dumpDebugInfo(DCtx, Y); return obj2yaml_error::success; } diff --git a/llvm/tools/yaml2obj/yaml2dwarf.cpp b/llvm/tools/yaml2obj/yaml2dwarf.cpp index 525c44c..283b0df 100644 --- a/llvm/tools/yaml2obj/yaml2dwarf.cpp +++ b/llvm/tools/yaml2obj/yaml2dwarf.cpp @@ -18,6 +18,8 @@ #include "llvm/Support/raw_ostream.h" #include "llvm/Support/SwapByteOrder.h" +#include + using namespace llvm; template @@ -104,4 +106,130 @@ void yaml2pubsection(raw_ostream &OS, const DWARFYAML::PubSection &Sect, OS.write(Entry.Name.data(), Entry.Name.size()); OS.write('\0'); } -} \ No newline at end of file +} + +void yaml2debug_info(raw_ostream &OS, const DWARFYAML::Data &DI) { + + for (auto CU : DI.CompileUnits) { + writeInteger((uint32_t)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); + + auto FirstAbbrevCode = CU.Entries[0].AbbrCode; + + for (auto Entry : CU.Entries) { + encodeULEB128(Entry.AbbrCode, OS); + if (Entry.AbbrCode == 0u) + continue; + bool Indirect = false; + assert(Entry.AbbrCode - FirstAbbrevCode < DI.AbbrevDecls.size() && + "Out of range AbbCode"); + auto &Abbrev = DI.AbbrevDecls[Entry.AbbrCode - FirstAbbrevCode]; + + 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; + do { + bool Indirect = false; + switch (Form) { + case dwarf::DW_FORM_addr: + writeVariableSizedInteger(FormVal->Value, CU.AddrSize, OS, + DI.IsLittleEndian); + break; + case dwarf::DW_FORM_ref_addr: { + // TODO: Handle DWARF32/DWARF64 after Line Table data is done + auto writeSize = CU.Version == 2 ? CU.AddrSize : 4; + writeVariableSizedInteger(FormVal->Value, writeSize, OS, + DI.IsLittleEndian); + break; + } + case dwarf::DW_FORM_exprloc: + case dwarf::DW_FORM_block: + encodeULEB128(FormVal->BlockData.size(), OS); + OS.write(reinterpret_cast(&FormVal->BlockData[0]), + FormVal->BlockData.size()); + break; + case dwarf::DW_FORM_block1: { + auto writeSize = FormVal->BlockData.size(); + writeInteger((uint8_t)writeSize, OS, DI.IsLittleEndian); + OS.write(reinterpret_cast(&FormVal->BlockData[0]), + FormVal->BlockData.size()); + break; + } + case dwarf::DW_FORM_block2: { + auto writeSize = FormVal->BlockData.size(); + writeInteger((uint16_t)writeSize, OS, DI.IsLittleEndian); + OS.write(reinterpret_cast(&FormVal->BlockData[0]), + FormVal->BlockData.size()); + break; + } + case dwarf::DW_FORM_block4: { + auto writeSize = FormVal->BlockData.size(); + writeInteger((uint32_t)writeSize, OS, DI.IsLittleEndian); + OS.write(reinterpret_cast(&FormVal->BlockData[0]), + FormVal->BlockData.size()); + break; + } + case dwarf::DW_FORM_data1: + case dwarf::DW_FORM_ref1: + case dwarf::DW_FORM_flag: + writeInteger((uint8_t)FormVal->Value, OS, DI.IsLittleEndian); + break; + case dwarf::DW_FORM_data2: + case dwarf::DW_FORM_ref2: + writeInteger((uint16_t)FormVal->Value, OS, DI.IsLittleEndian); + break; + case dwarf::DW_FORM_data4: + case dwarf::DW_FORM_ref4: + writeInteger((uint32_t)FormVal->Value, OS, DI.IsLittleEndian); + break; + case dwarf::DW_FORM_data8: + case dwarf::DW_FORM_ref8: + writeInteger((uint64_t)FormVal->Value, OS, DI.IsLittleEndian); + break; + case dwarf::DW_FORM_sdata: + encodeSLEB128(FormVal->Value, OS); + break; + case dwarf::DW_FORM_udata: + case dwarf::DW_FORM_ref_udata: + encodeULEB128(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: + case dwarf::DW_FORM_ref_sup: + // TODO: Handle DWARF32/64 + writeInteger((uint32_t)FormVal->Value, OS, DI.IsLittleEndian); + break; + case dwarf::DW_FORM_ref_sig8: + writeInteger((uint64_t)FormVal->Value, OS, DI.IsLittleEndian); + break; + case dwarf::DW_FORM_GNU_addr_index: + case dwarf::DW_FORM_GNU_str_index: + encodeULEB128(FormVal->Value, OS); + break; + default: + break; + } + } while (Indirect); + } + } + } +} diff --git a/llvm/tools/yaml2obj/yaml2macho.cpp b/llvm/tools/yaml2obj/yaml2macho.cpp index 1341450..a41ec55 100644 --- a/llvm/tools/yaml2obj/yaml2macho.cpp +++ b/llvm/tools/yaml2obj/yaml2macho.cpp @@ -278,6 +278,8 @@ Error MachOWriter::writeSectionData(raw_ostream &OS) { yaml2pubsection(OS, Obj.DWARF.PubNames, Obj.IsLittleEndian); } else if (0 == strncmp(&Sec.sectname[0], "__debug_pubtypes", 16)) { yaml2pubsection(OS, Obj.DWARF.PubTypes, Obj.IsLittleEndian); + } else if (0 == strncmp(&Sec.sectname[0], "__debug_info", 16)) { + yaml2debug_info(OS, Obj.DWARF); } } else { // Fills section data with 0xDEADBEEF diff --git a/llvm/tools/yaml2obj/yaml2obj.h b/llvm/tools/yaml2obj/yaml2obj.h index 756fe49..7cad4ca 100644 --- a/llvm/tools/yaml2obj/yaml2obj.h +++ b/llvm/tools/yaml2obj/yaml2obj.h @@ -45,5 +45,6 @@ void yaml2debug_aranges(llvm::raw_ostream &OS, const llvm::DWARFYAML::Data &DI); void yaml2pubsection(llvm::raw_ostream &OS, const llvm::DWARFYAML::PubSection &Sect, bool IsLittleEndian); +void yaml2debug_info(llvm::raw_ostream &OS, const llvm::DWARFYAML::Data &DI); #endif -- 2.7.4