From d9430944f4bb423a15785a0cea2bc6a76c50ecdb Mon Sep 17 00:00:00 2001 From: Chris Bieneman Date: Mon, 19 Dec 2016 22:22:12 +0000 Subject: [PATCH] [ObjectYAML] Support for DWARF Pub Sections This patch adds support for YAML<->DWARF round tripping for pub* section data. The patch supports both GNU and non-GNU style entries. llvm-svn: 290139 --- llvm/include/llvm/ObjectYAML/DWARFYAML.h | 31 ++ llvm/lib/ObjectYAML/DWARFYAML.cpp | 30 ++ llvm/test/ObjectYAML/MachO/DWARF-pubsections.yaml | 355 ++++++++++++++++++++++ llvm/tools/obj2yaml/dwarf2yaml.cpp | 33 ++ llvm/tools/yaml2obj/yaml2dwarf.cpp | 14 + llvm/tools/yaml2obj/yaml2macho.cpp | 4 + llvm/tools/yaml2obj/yaml2obj.h | 3 + 7 files changed, 470 insertions(+) create mode 100644 llvm/test/ObjectYAML/MachO/DWARF-pubsections.yaml diff --git a/llvm/include/llvm/ObjectYAML/DWARFYAML.h b/llvm/include/llvm/ObjectYAML/DWARFYAML.h index 69e3ab4..b64d9f8 100644 --- a/llvm/include/llvm/ObjectYAML/DWARFYAML.h +++ b/llvm/include/llvm/ObjectYAML/DWARFYAML.h @@ -49,10 +49,32 @@ struct ARange { std::vector Descriptors; }; +struct PubEntry { + llvm::yaml::Hex32 DieOffset; + llvm::yaml::Hex8 Descriptor; + StringRef Name; +}; + +struct PubSection { + PubSection() : IsGNUStyle(false) {} + + uint32_t Length; + uint16_t Version; + uint32_t UnitOffset; + uint32_t UnitSize; + bool IsGNUStyle; + std::vector Entries; +}; + struct Data { std::vector AbbrevDecls; std::vector DebugStrings; std::vector ARanges; + PubSection PubNames; + PubSection PubTypes; + + PubSection GNUPubNames; + PubSection GNUPubTypes; bool isEmpty() const; }; @@ -65,6 +87,7 @@ 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) namespace llvm { namespace yaml { @@ -89,6 +112,14 @@ template <> struct MappingTraits { static void mapping(IO &IO, DWARFYAML::ARange &Range); }; +template <> struct MappingTraits { + static void mapping(IO &IO, DWARFYAML::PubEntry &Entry); +}; + +template <> struct MappingTraits { + static void mapping(IO &IO, DWARFYAML::PubSection &Section); +}; + #define HANDLE_DW_TAG(unused, name) \ io.enumCase(value, "DW_TAG_" #name, dwarf::DW_TAG_##name); diff --git a/llvm/lib/ObjectYAML/DWARFYAML.cpp b/llvm/lib/ObjectYAML/DWARFYAML.cpp index 0a463bd4..3d647b0 100644 --- a/llvm/lib/ObjectYAML/DWARFYAML.cpp +++ b/llvm/lib/ObjectYAML/DWARFYAML.cpp @@ -28,6 +28,14 @@ void MappingTraits::mapping( IO.mapOptional("debug_abbrev", DWARF.AbbrevDecls); if(!DWARF.ARanges.empty() || !IO.outputting()) IO.mapOptional("debug_aranges", DWARF.ARanges); + if(!DWARF.PubNames.Entries.empty() || !IO.outputting()) + IO.mapOptional("debug_pubnames", DWARF.PubNames); + if(!DWARF.PubTypes.Entries.empty() || !IO.outputting()) + IO.mapOptional("debug_pubtypes", DWARF.PubTypes); + if(!DWARF.GNUPubNames.Entries.empty() || !IO.outputting()) + IO.mapOptional("debug_gnu_pubnames", DWARF.GNUPubNames); + if(!DWARF.GNUPubTypes.Entries.empty() || !IO.outputting()) + IO.mapOptional("debug_gnu_pubtypes", DWARF.GNUPubTypes); } void MappingTraits::mapping( @@ -60,6 +68,28 @@ void MappingTraits::mapping(IO &IO, IO.mapRequired("Descriptors", Range.Descriptors); } +void MappingTraits::mapping(IO &IO, + DWARFYAML::PubEntry &Entry) { + IO.mapRequired("DieOffset", Entry.DieOffset); + if (reinterpret_cast(IO.getContext())->IsGNUStyle) + IO.mapRequired("Descriptor", Entry.Descriptor); + IO.mapRequired("Name", Entry.Name); +} + +void MappingTraits::mapping( + IO &IO, DWARFYAML::PubSection &Section) { + auto OldContext = IO.getContext(); + IO.setContext(&Section); + + IO.mapRequired("Length", Section.Length); + IO.mapRequired("Version", Section.Version); + IO.mapRequired("UnitOffset", Section.UnitOffset); + IO.mapRequired("UnitSize", Section.UnitSize); + IO.mapRequired("Entries", Section.Entries); + + IO.setContext(OldContext); +} + } // namespace llvm::yaml } // namespace llvm diff --git a/llvm/test/ObjectYAML/MachO/DWARF-pubsections.yaml b/llvm/test/ObjectYAML/MachO/DWARF-pubsections.yaml new file mode 100644 index 0000000..8535ed0 --- /dev/null +++ b/llvm/test/ObjectYAML/MachO/DWARF-pubsections.yaml @@ -0,0 +1,355 @@ +# 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_str: + - '' + - 'clang version 4.0.0 (trunk 288923) (llvm/trunk 288991)' + - hello_world.c + - /Users/cbieneman/dev/open-source/llvm-build-rel + - main + - argc + - argv + - int + - char + debug_pubnames: + Length: 23 + Version: 2 + UnitOffset: 0 + UnitSize: 121 + Entries: + - DieOffset: 0x0000002A + Name: main + debug_pubtypes: + Length: 31 + Version: 2 + UnitOffset: 0 + UnitSize: 121 + Entries: + - DieOffset: 0x00000060 + Name: int + - DieOffset: 0x00000071 + Name: char +... + +#CHECK: DWARF: +#CHECK: debug_pubnames: +#CHECK: Length: 23 +#CHECK: Version: 2 +#CHECK: UnitOffset: 0 +#CHECK: UnitSize: 121 +#CHECK: Entries: +#CHECK: - DieOffset: 0x0000002A +#CHECK: Name: main +#CHECK: debug_pubtypes: +#CHECK: Length: 31 +#CHECK: Version: 2 +#CHECK: UnitOffset: 0 +#CHECK: UnitSize: 121 +#CHECK: Entries: +#CHECK: - DieOffset: 0x00000060 +#CHECK: Name: int +#CHECK: - DieOffset: 0x00000071 +#CHECK: Name: char +#CHECK: ... diff --git a/llvm/tools/obj2yaml/dwarf2yaml.cpp b/llvm/tools/obj2yaml/dwarf2yaml.cpp index ca55702..0fd646e 100644 --- a/llvm/tools/obj2yaml/dwarf2yaml.cpp +++ b/llvm/tools/obj2yaml/dwarf2yaml.cpp @@ -67,11 +67,44 @@ void dumpDebugARanges(DWARFContextInMemory &DCtx, DWARFYAML::Data &Y) { } } +void dumpPubSection(DWARFContextInMemory &DCtx, DWARFYAML::PubSection &Y, + StringRef Section) { + DataExtractor PubSectionData(Section, DCtx.isLittleEndian(), 0); + uint32_t Offset = 0; + Y.Length = PubSectionData.getU32(&Offset); + Y.Version = PubSectionData.getU16(&Offset); + Y.UnitOffset = PubSectionData.getU32(&Offset); + Y.UnitSize = PubSectionData.getU32(&Offset); + while (Offset < Y.Length) { + DWARFYAML::PubEntry NewEntry; + NewEntry.DieOffset = PubSectionData.getU32(&Offset); + if (Y.IsGNUStyle) + NewEntry.Descriptor = PubSectionData.getU8(&Offset); + NewEntry.Name = PubSectionData.getCStr(&Offset); + Y.Entries.push_back(NewEntry); + } +} + +void dumpDebugPubSections(DWARFContextInMemory &DCtx, DWARFYAML::Data &Y) { + Y.PubNames.IsGNUStyle = false; + dumpPubSection(DCtx, Y.PubNames, DCtx.getPubNamesSection()); + + Y.PubTypes.IsGNUStyle = false; + dumpPubSection(DCtx, Y.PubTypes, DCtx.getPubTypesSection()); + + Y.GNUPubNames.IsGNUStyle = true; + dumpPubSection(DCtx, Y.GNUPubNames, DCtx.getGnuPubNamesSection()); + + Y.GNUPubTypes.IsGNUStyle = true; + dumpPubSection(DCtx, Y.GNUPubTypes, DCtx.getGnuPubTypesSection()); +} + std::error_code dwarf2yaml(DWARFContextInMemory &DCtx, DWARFYAML::Data &Y) { dumpDebugAbbrev(DCtx, Y); dumpDebugStrings(DCtx, Y); dumpDebugARanges(DCtx, Y); + dumpDebugPubSections(DCtx, Y); return obj2yaml_error::success; } diff --git a/llvm/tools/yaml2obj/yaml2dwarf.cpp b/llvm/tools/yaml2obj/yaml2dwarf.cpp index fcc5833..6096f4c 100644 --- a/llvm/tools/yaml2obj/yaml2dwarf.cpp +++ b/llvm/tools/yaml2obj/yaml2dwarf.cpp @@ -66,3 +66,17 @@ void yaml2debug_aranges(raw_ostream &OS, const DWARFYAML::Data &DI) { ZeroFillBytes(OS, Range.AddrSize * 2); } } + +void yaml2pubsection(raw_ostream &OS, const DWARFYAML::PubSection &Sect) { + OS.write(reinterpret_cast(&Sect.Length), 4); + OS.write(reinterpret_cast(&Sect.Version), 2); + OS.write(reinterpret_cast(&Sect.UnitOffset), 4); + OS.write(reinterpret_cast(&Sect.UnitSize), 4); + for (auto Entry : Sect.Entries) { + OS.write(reinterpret_cast(&Entry.DieOffset), 4); + if (Sect.IsGNUStyle) + OS.write(reinterpret_cast(&Entry.Descriptor), 4); + OS.write(Entry.Name.data(), Entry.Name.size()); + OS.write('\0'); + } +} diff --git a/llvm/tools/yaml2obj/yaml2macho.cpp b/llvm/tools/yaml2obj/yaml2macho.cpp index 9d70f58..3fdf3cf 100644 --- a/llvm/tools/yaml2obj/yaml2macho.cpp +++ b/llvm/tools/yaml2obj/yaml2macho.cpp @@ -394,6 +394,10 @@ Error MachOWriter::writeDWARFData(raw_ostream &OS, yaml2debug_abbrev(OS, Obj.DWARF); } else if (0 == strncmp(&Section.sectname[0], "__debug_aranges", 16)) { yaml2debug_aranges(OS, Obj.DWARF); + } else if (0 == strncmp(&Section.sectname[0], "__debug_pubnames", 16)) { + yaml2pubsection(OS, Obj.DWARF.PubNames); + } else if (0 == strncmp(&Section.sectname[0], "__debug_pubtypes", 16)) { + yaml2pubsection(OS, Obj.DWARF.PubTypes); } } return Error::success(); diff --git a/llvm/tools/yaml2obj/yaml2obj.h b/llvm/tools/yaml2obj/yaml2obj.h index cd481c0..f36166a 100644 --- a/llvm/tools/yaml2obj/yaml2obj.h +++ b/llvm/tools/yaml2obj/yaml2obj.h @@ -25,6 +25,7 @@ struct Object; namespace DWARFYAML { struct Data; +struct PubSection; } namespace yaml { @@ -43,5 +44,7 @@ void yaml2debug_str(llvm::raw_ostream &OS, const llvm::DWARFYAML::Data &DI); void yaml2debug_aranges(llvm::raw_ostream &OS, const llvm::DWARFYAML::Data &DI); +void yaml2pubsection(llvm::raw_ostream &OS, + const llvm::DWARFYAML::PubSection &Sect); #endif -- 2.7.4