diff --git a/include/llvm/DebugInfo/DWARF/DWARFDebugAbbrev.h b/include/llvm/DebugInfo/DWARF/DWARFDebugAbbrev.h index 67c4a2bb3e6..f732deef548 100644 --- a/include/llvm/DebugInfo/DWARF/DWARFDebugAbbrev.h +++ b/include/llvm/DebugInfo/DWARF/DWARFDebugAbbrev.h @@ -23,6 +23,9 @@ class DWARFAbbreviationDeclarationSet { uint32_t FirstAbbrCode; std::vector Decls; + typedef std::vector::const_iterator + const_iterator; + public: DWARFAbbreviationDeclarationSet(); @@ -33,6 +36,14 @@ public: const DWARFAbbreviationDeclaration * getAbbreviationDeclaration(uint32_t AbbrCode) const; + const_iterator begin() const { + return Decls.begin(); + } + + const_iterator end() const { + return Decls.end(); + } + private: void clear(); }; @@ -53,6 +64,14 @@ public: void dump(raw_ostream &OS) const; void extract(DataExtractor Data); + DWARFAbbreviationDeclarationSetMap::const_iterator begin() const { + return AbbrDeclSets.begin(); + } + + DWARFAbbreviationDeclarationSetMap::const_iterator end() const { + return AbbrDeclSets.end(); + } + private: void clear(); }; diff --git a/include/llvm/ObjectYAML/MachOYAML.h b/include/llvm/ObjectYAML/MachOYAML.h index 4de495beb86..f56c12a6594 100644 --- a/include/llvm/ObjectYAML/MachOYAML.h +++ b/include/llvm/ObjectYAML/MachOYAML.h @@ -18,6 +18,7 @@ #include "llvm/ObjectYAML/YAML.h" #include "llvm/Support/MachO.h" +#include "llvm/Support/Dwarf.h" namespace llvm { namespace MachOYAML { @@ -104,7 +105,20 @@ struct LinkEditData { bool isEmpty() const; }; +struct DWARFAttributeAbbrev { + llvm::dwarf::Attribute Attribute; + llvm::dwarf::Form Form; +}; + +struct DWARFAbbrev { + llvm::yaml::Hex32 Code; + llvm::dwarf::Tag Tag; + llvm::dwarf::Constants Children; + std::vector Attributes; +}; + struct DWARFData { + std::vector AbbrevDecls; std::vector DebugStrings; bool isEmpty() const; @@ -153,6 +167,8 @@ LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::MachOYAML::NListEntry) LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::StringRef) LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::MachOYAML::Object) LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::MachOYAML::FatArch) +LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::MachOYAML::DWARFAttributeAbbrev) +LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::MachOYAML::DWARFAbbrev) namespace llvm { namespace yaml { @@ -209,6 +225,14 @@ template <> struct MappingTraits { static void mapping(IO &IO, MachOYAML::DWARFData &DWARF); }; +template <> struct MappingTraits { + static void mapping(IO &IO, MachOYAML::DWARFAbbrev &Abbrev); +}; + +template <> struct MappingTraits { + static void mapping(IO &IO, MachOYAML::DWARFAttributeAbbrev &AttAbbrev); +}; + #define HANDLE_LOAD_COMMAND(LCName, LCValue, LCStruct) \ io.enumCase(value, #LCName, MachO::LCName); @@ -255,6 +279,44 @@ template <> struct ScalarEnumerationTraits { } }; +#define HANDLE_DW_TAG(unused, name) \ + io.enumCase(value, "DW_TAG_" #name, dwarf::DW_TAG_##name); + +template <> struct ScalarEnumerationTraits { + static void enumeration(IO &io, dwarf::Tag &value) { +#include "llvm/Support/Dwarf.def" + io.enumFallback(value); + } +}; + +#define HANDLE_DW_AT(unused, name) \ + io.enumCase(value, "DW_AT_" #name, dwarf::DW_AT_##name); + +template <> struct ScalarEnumerationTraits { + static void enumeration(IO &io, dwarf::Attribute &value) { +#include "llvm/Support/Dwarf.def" + io.enumFallback(value); + } +}; + +#define HANDLE_DW_FORM(unused, name) \ + io.enumCase(value, "DW_FORM_" #name, dwarf::DW_FORM_##name); + +template <> struct ScalarEnumerationTraits { + static void enumeration(IO &io, dwarf::Form &value) { +#include "llvm/Support/Dwarf.def" + io.enumFallback(value); + } +}; + +template <> struct ScalarEnumerationTraits { + static void enumeration(IO &io, dwarf::Constants &value) { + io.enumCase(value, "DW_CHILDREN_no", dwarf::DW_CHILDREN_no); + io.enumCase(value, "DW_CHILDREN_yes", dwarf::DW_CHILDREN_yes); + io.enumFallback(value); + } +}; + // This trait is used for 16-byte chars in Mach structures used for strings typedef char char_16[16]; diff --git a/lib/ObjectYAML/MachOYAML.cpp b/lib/ObjectYAML/MachOYAML.cpp index d3f8ea47e59..45554304d10 100644 --- a/lib/ObjectYAML/MachOYAML.cpp +++ b/lib/ObjectYAML/MachOYAML.cpp @@ -30,7 +30,7 @@ bool MachOYAML::LinkEditData::isEmpty() const { } bool MachOYAML::DWARFData::isEmpty() const { - return 0 == DebugStrings.size(); + return 0 == DebugStrings.size() + AbbrevDecls.size(); } namespace yaml { @@ -559,7 +559,22 @@ void MappingTraits::mapping( void MappingTraits::mapping( IO &IO, MachOYAML::DWARFData &DWARF) { - IO.mapRequired("DebugStrings", DWARF.DebugStrings); + IO.mapOptional("DebugStrings", DWARF.DebugStrings); + IO.mapOptional("AbbrevDecls", DWARF.AbbrevDecls); +} + +void MappingTraits::mapping( + IO &IO, MachOYAML::DWARFAbbrev &Abbrev) { + IO.mapRequired("Code", Abbrev.Code); + IO.mapRequired("Tag", Abbrev.Tag); + IO.mapRequired("Children", Abbrev.Children); + IO.mapRequired("Attributes", Abbrev.Attributes); +} + +void MappingTraits::mapping( + IO &IO, MachOYAML::DWARFAttributeAbbrev &AttAbbrev) { + IO.mapRequired("Attribute", AttAbbrev.Attribute); + IO.mapRequired("Form", AttAbbrev.Form); } } // namespace llvm::yaml diff --git a/test/ObjectYAML/MachO/DWARF-debug_abbrev.yaml b/test/ObjectYAML/MachO/DWARF-debug_abbrev.yaml new file mode 100644 index 00000000000..b874c27612a --- /dev/null +++ b/test/ObjectYAML/MachO/DWARF-debug_abbrev.yaml @@ -0,0 +1,433 @@ +# 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 +DWARF: + AbbrevDecls: + - 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 +... + +#CHECK: DWARF: +#CHECK: AbbrevDecls: +#CHECK: - Code: 0x00000001 +#CHECK: Tag: DW_TAG_compile_unit +#CHECK: Children: DW_CHILDREN_yes +#CHECK: Attributes: +#CHECK: - Attribute: DW_AT_producer +#CHECK: Form: DW_FORM_strp +#CHECK: - Attribute: DW_AT_language +#CHECK: Form: DW_FORM_data2 +#CHECK: - Attribute: DW_AT_name +#CHECK: Form: DW_FORM_strp +#CHECK: - Attribute: DW_AT_stmt_list +#CHECK: Form: DW_FORM_sec_offset +#CHECK: - Attribute: DW_AT_comp_dir +#CHECK: Form: DW_FORM_strp +#CHECK: - Attribute: DW_AT_low_pc +#CHECK: Form: DW_FORM_addr +#CHECK: - Attribute: DW_AT_high_pc +#CHECK: Form: DW_FORM_data4 +#CHECK: - Code: 0x00000002 +#CHECK: Tag: DW_TAG_subprogram +#CHECK: Children: DW_CHILDREN_yes +#CHECK: Attributes: +#CHECK: - Attribute: DW_AT_low_pc +#CHECK: Form: DW_FORM_addr +#CHECK: - Attribute: DW_AT_high_pc +#CHECK: Form: DW_FORM_data4 +#CHECK: - Attribute: DW_AT_frame_base +#CHECK: Form: DW_FORM_exprloc +#CHECK: - Attribute: DW_AT_name +#CHECK: Form: DW_FORM_strp +#CHECK: - Attribute: DW_AT_decl_file +#CHECK: Form: DW_FORM_data1 +#CHECK: - Attribute: DW_AT_decl_line +#CHECK: Form: DW_FORM_data1 +#CHECK: - Attribute: DW_AT_prototyped +#CHECK: Form: DW_FORM_flag_present +#CHECK: - Attribute: DW_AT_type +#CHECK: Form: DW_FORM_ref4 +#CHECK: - Attribute: DW_AT_external +#CHECK: Form: DW_FORM_flag_present +#CHECK: - Code: 0x00000003 +#CHECK: Tag: DW_TAG_formal_parameter +#CHECK: Children: DW_CHILDREN_no +#CHECK: Attributes: +#CHECK: - Attribute: DW_AT_location +#CHECK: Form: DW_FORM_exprloc +#CHECK: - Attribute: DW_AT_name +#CHECK: Form: DW_FORM_strp +#CHECK: - Attribute: DW_AT_decl_file +#CHECK: Form: DW_FORM_data1 +#CHECK: - Attribute: DW_AT_decl_line +#CHECK: Form: DW_FORM_data1 +#CHECK: - Attribute: DW_AT_type +#CHECK: Form: DW_FORM_ref4 +#CHECK: - Code: 0x00000004 +#CHECK: Tag: DW_TAG_base_type +#CHECK: Children: DW_CHILDREN_no +#CHECK: Attributes: +#CHECK: - Attribute: DW_AT_name +#CHECK: Form: DW_FORM_strp +#CHECK: - Attribute: DW_AT_encoding +#CHECK: Form: DW_FORM_data1 +#CHECK: - Attribute: DW_AT_byte_size +#CHECK: Form: DW_FORM_data1 +#CHECK: - Code: 0x00000005 +#CHECK: Tag: DW_TAG_pointer_type +#CHECK: Children: DW_CHILDREN_no +#CHECK: Attributes: +#CHECK: - Attribute: DW_AT_type +#CHECK: Form: DW_FORM_ref4 diff --git a/tools/obj2yaml/macho2yaml.cpp b/tools/obj2yaml/macho2yaml.cpp index 0953d284e11..16f25fc4668 100644 --- a/tools/obj2yaml/macho2yaml.cpp +++ b/tools/obj2yaml/macho2yaml.cpp @@ -36,7 +36,10 @@ class MachODumper { void dumpExportTrie(std::unique_ptr &Y); void dumpSymbols(std::unique_ptr &Y); void dumpDWARF(std::unique_ptr &Y); - void dumpDebugStrings(DWARFContextInMemory &DCtx, std::unique_ptr &Y); + void dumpDebugAbbrev(DWARFContextInMemory &DCtx, + std::unique_ptr &Y); + void dumpDebugStrings(DWARFContextInMemory &DCtx, + std::unique_ptr &Y); public: MachODumper(const object::MachOObjectFile &O) : Obj(O) {} @@ -466,6 +469,7 @@ void MachODumper::dumpSymbols(std::unique_ptr &Y) { void MachODumper::dumpDWARF(std::unique_ptr &Y) { DWARFContextInMemory DICtx(Obj); dumpDebugStrings(DICtx, Y); + dumpDebugAbbrev(DICtx, Y); } void MachODumper::dumpDebugStrings(DWARFContextInMemory &DICtx, @@ -478,6 +482,29 @@ void MachODumper::dumpDebugStrings(DWARFContextInMemory &DICtx, } } +void MachODumper::dumpDebugAbbrev(DWARFContextInMemory &DCtx, + std::unique_ptr &Y) { + auto AbbrevSetPtr = DCtx.getDebugAbbrev(); + if(AbbrevSetPtr) { + for(auto AbbrvDeclSet : *AbbrevSetPtr) { + for(auto AbbrvDecl : AbbrvDeclSet.second) { + MachOYAML::DWARFAbbrev Abbrv; + Abbrv.Code = AbbrvDecl.getCode(); + Abbrv.Tag = AbbrvDecl.getTag(); + Abbrv.Children = AbbrvDecl.hasChildren() ? dwarf::DW_CHILDREN_yes + : dwarf::DW_CHILDREN_no; + for(auto Attribute : AbbrvDecl.attributes()) { + MachOYAML::DWARFAttributeAbbrev AttAbrv; + AttAbrv.Attribute = Attribute.Attr; + AttAbrv.Form = Attribute.Form; + Abbrv.Attributes.push_back(AttAbrv); + } + Y->DWARF.AbbrevDecls.push_back(Abbrv); + } + } + } +} + Error macho2yaml(raw_ostream &Out, const object::MachOObjectFile &Obj) { MachODumper Dumper(Obj); Expected> YAML = Dumper.dump(); diff --git a/tools/yaml2obj/yaml2macho.cpp b/tools/yaml2obj/yaml2macho.cpp index 3312cd45fb7..48bd9e83ad3 100644 --- a/tools/yaml2obj/yaml2macho.cpp +++ b/tools/yaml2obj/yaml2macho.cpp @@ -393,6 +393,18 @@ Error MachOWriter::writeDWARFData(raw_ostream &OS, OS.write(Str.data(), Str.size()); OS.write('\0'); } + } else if (0 == strncmp(&Section.sectname[0], "__debug_abbrev", 16)) { + for (auto AbbrevDecl : Obj.DWARF.AbbrevDecls) { + encodeULEB128(AbbrevDecl.Code, OS); + encodeULEB128(AbbrevDecl.Tag, OS); + OS.write(AbbrevDecl.Children); + for (auto Attr : AbbrevDecl.Attributes) { + encodeULEB128(Attr.Attribute, OS); + encodeULEB128(Attr.Form, OS); + } + encodeULEB128(0, OS); + encodeULEB128(0, OS); + } } } return Error::success();