diff --git a/llvm/include/llvm/DebugInfo/DWARF/DWARFFormValue.h b/llvm/include/llvm/DebugInfo/DWARF/DWARFFormValue.h index a6228b531cea..920880cea10c 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 78bbe098b2d3..db7b59be90c2 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 d73ff6c3eb7f..222cad61a992 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 0cbf585f0322..6b7a924f5143 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 b3f1a52e6b7c..e48a6f0981b7 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 3d647b0b0b14..42a448a7bdfd 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 000000000000..9a616e9afb9d --- /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 0fd646e23b98..cf8b3e5b9273 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 525c44ce7abc..283b0df0f625 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 13414502c031..a41ec55d73be 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 756fe4961969..7cad4ca8675f 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