diff options
author | Chris Bieneman <beanz@apple.com> | 2016-05-17 21:31:02 +0000 |
---|---|---|
committer | Chris Bieneman <beanz@apple.com> | 2016-05-17 21:31:02 +0000 |
commit | 7b504b75312ec0a02f20aba47d59e254f76d2e56 (patch) | |
tree | d993365a431d4cd4682ef0fb2c001d10b651965a | |
parent | e3ec688df598f3ff052776b72a9f4601838a2d1a (diff) | |
download | bcm5719-llvm-7b504b75312ec0a02f20aba47d59e254f76d2e56.tar.gz bcm5719-llvm-7b504b75312ec0a02f20aba47d59e254f76d2e56.zip |
[obj2yaml] [yaml2obj] Support MachO section and section_64 structs
This patch adds round trip support for MachO section structs.
llvm-svn: 269845
-rw-r--r-- | llvm/include/llvm/ObjectYAML/MachOYAML.h | 22 | ||||
-rw-r--r-- | llvm/lib/ObjectYAML/MachOYAML.cpp | 20 | ||||
-rw-r--r-- | llvm/test/ObjectYAML/MachO/sections.yaml | 282 | ||||
-rw-r--r-- | llvm/tools/obj2yaml/macho2yaml.cpp | 54 | ||||
-rw-r--r-- | llvm/tools/yaml2obj/yaml2macho.cpp | 32 |
5 files changed, 410 insertions, 0 deletions
diff --git a/llvm/include/llvm/ObjectYAML/MachOYAML.h b/llvm/include/llvm/ObjectYAML/MachOYAML.h index 21558f00cc0..3c79a20c55a 100644 --- a/llvm/include/llvm/ObjectYAML/MachOYAML.h +++ b/llvm/include/llvm/ObjectYAML/MachOYAML.h @@ -22,6 +22,21 @@ namespace llvm { namespace MachOYAML { +struct Section { + char sectname[16]; + char segname[16]; + llvm::yaml::Hex64 addr; + uint64_t size; + llvm::yaml::Hex32 offset; + uint32_t align; + llvm::yaml::Hex32 reloff; + uint32_t nreloc; + llvm::yaml::Hex32 flags; + llvm::yaml::Hex32 reserved1; + llvm::yaml::Hex32 reserved2; + llvm::yaml::Hex32 reserved3; +}; + struct FileHeader { llvm::yaml::Hex32 magic; llvm::yaml::Hex32 cputype; @@ -36,17 +51,20 @@ struct FileHeader { struct LoadCommand { virtual ~LoadCommand(); llvm::MachO::macho_load_command Data; + std::vector<Section> Sections; }; struct Object { FileHeader Header; std::vector<LoadCommand> LoadCommands; + std::vector<Section> Sections; }; } // namespace llvm::MachOYAML } // namespace llvm LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::MachOYAML::LoadCommand) +LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::MachOYAML::Section) namespace llvm { namespace yaml { @@ -63,6 +81,10 @@ template <> struct MappingTraits<MachOYAML::LoadCommand> { static void mapping(IO &IO, MachOYAML::LoadCommand &LoadCommand); }; +template <> struct MappingTraits<MachOYAML::Section> { + static void mapping(IO &IO, MachOYAML::Section &Section); +}; + #define HANDLE_LOAD_COMMAND(LCName, LCValue, LCStruct) \ io.enumCase(value, #LCName, MachO::LCName); diff --git a/llvm/lib/ObjectYAML/MachOYAML.cpp b/llvm/lib/ObjectYAML/MachOYAML.cpp index b98d4622a36..6724b24dd33 100644 --- a/llvm/lib/ObjectYAML/MachOYAML.cpp +++ b/llvm/lib/ObjectYAML/MachOYAML.cpp @@ -110,6 +110,10 @@ void MappingTraits<MachOYAML::LoadCommand>::mapping( switch (LoadCommand.Data.load_command_data.cmd) { #include "llvm/Support/MachO.def" } + if (LoadCommand.Data.load_command_data.cmd == MachO::LC_SEGMENT || + LoadCommand.Data.load_command_data.cmd == MachO::LC_SEGMENT_64) { + IO.mapOptional("Sections", LoadCommand.Sections); + } } void MappingTraits<MachO::dyld_info_command>::mapping( @@ -124,6 +128,22 @@ void MappingTraits<MachO::dyld_info_command>::mapping( IO.mapRequired("export_size", LoadCommand.export_size); } +void MappingTraits<MachOYAML::Section>::mapping(IO &IO, + MachOYAML::Section &Section) { + IO.mapRequired("sectname", Section.sectname); + IO.mapRequired("segname", Section.segname); + IO.mapRequired("addr", Section.addr); + IO.mapRequired("size", Section.size); + IO.mapRequired("offset", Section.offset); + IO.mapRequired("align", Section.align); + IO.mapRequired("reloff", Section.reloff); + IO.mapRequired("nreloc", Section.nreloc); + IO.mapRequired("flags", Section.flags); + IO.mapRequired("reserved1", Section.reserved1); + IO.mapRequired("reserved2", Section.reserved2); + IO.mapOptional("reserved3", Section.reserved3); +} + void MappingTraits<MachO::dylib>::mapping(IO &IO, MachO::dylib &DylibStruct) { IO.mapRequired("name", DylibStruct.name); IO.mapRequired("timestamp", DylibStruct.timestamp); diff --git a/llvm/test/ObjectYAML/MachO/sections.yaml b/llvm/test/ObjectYAML/MachO/sections.yaml new file mode 100644 index 00000000000..9e4adb0d52d --- /dev/null +++ b/llvm/test/ObjectYAML/MachO/sections.yaml @@ -0,0 +1,282 @@ +# RUN: yaml2obj -format=macho %s | obj2yaml | FileCheck %s + +--- !mach-o +FileHeader: + magic: 0xFEEDFACF + cputype: 0x01000007 + cpusubtype: 0x80000003 + filetype: 0x00000002 + ncmds: 16 + sizeofcmds: 1408 + flags: 0x00218085 + 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: 552 + segname: __TEXT + vmaddr: 4294967296 + vmsize: 8192 + fileoff: 0 + filesize: 8192 + maxprot: 7 + initprot: 5 + nsects: 6 + flags: 0 + Sections: + - sectname: __text + segname: __TEXT + addr: 0x0000000100001160 + size: 3099 + offset: 0x00001160 + align: 4 + reloff: 0x00000000 + nreloc: 0 + flags: 0x80000400 + reserved1: 0x00000000 + reserved2: 0x00000000 + reserved3: 0x00000000 + - sectname: __stubs + segname: __TEXT + addr: 0x0000000100001D7C + size: 90 + offset: 0x00001D7C + align: 1 + reloff: 0x00000000 + nreloc: 0 + flags: 0x80000408 + reserved1: 0x00000000 + reserved2: 0x00000006 + reserved3: 0x00000000 + - sectname: __stub_helper + segname: __TEXT + addr: 0x0000000100001DD8 + size: 166 + offset: 0x00001DD8 + align: 2 + reloff: 0x00000000 + nreloc: 0 + flags: 0x80000400 + reserved1: 0x00000000 + reserved2: 0x00000000 + reserved3: 0x00000000 + - sectname: __gcc_except_tab__TEXT + segname: __TEXT + addr: 0x0000000100001E80 + size: 240 + offset: 0x00001E80 + align: 2 + reloff: 0x00000000 + nreloc: 0 + flags: 0x00000000 + reserved1: 0x00000000 + reserved2: 0x00000000 + reserved3: 0x00000000 + - sectname: __cstring + segname: __TEXT + addr: 0x0000000100001F70 + size: 15 + offset: 0x00001F70 + align: 0 + reloff: 0x00000000 + nreloc: 0 + flags: 0x00000002 + reserved1: 0x00000000 + reserved2: 0x00000000 + reserved3: 0x00000000 + - sectname: __unwind_info + segname: __TEXT + addr: 0x0000000100001F80 + size: 120 + offset: 0x00001F80 + align: 2 + reloff: 0x00000000 + nreloc: 0 + flags: 0x00000000 + reserved1: 0x00000000 + reserved2: 0x00000000 + reserved3: 0x00000000 + - cmd: LC_SEGMENT_64 + cmdsize: 312 + segname: __DATA + vmaddr: 4294975488 + vmsize: 4096 + fileoff: 8192 + filesize: 4096 + maxprot: 7 + initprot: 3 + nsects: 3 + flags: 0 + Sections: + - sectname: __got + segname: __DATA + addr: 0x0000000100002000 + size: 24 + offset: 0x00002000 + align: 3 + reloff: 0x00000000 + nreloc: 0 + flags: 0x00000006 + reserved1: 0x0000000F + reserved2: 0x00000000 + reserved3: 0x00000000 + - sectname: __nl_symbol_ptr + segname: __DATA + addr: 0x0000000100002018 + size: 16 + offset: 0x00002018 + align: 3 + reloff: 0x00000000 + nreloc: 0 + flags: 0x00000006 + reserved1: 0x00000012 + reserved2: 0x00000000 + reserved3: 0x00000000 + - sectname: __la_symbol_ptr + segname: __DATA + addr: 0x0000000100002028 + size: 120 + offset: 0x00002028 + align: 3 + reloff: 0x00000000 + nreloc: 0 + flags: 0x00000007 + reserved1: 0x00000014 + reserved2: 0x00000000 + reserved3: 0x00000000 + - cmd: LC_SEGMENT_64 + cmdsize: 72 + segname: __LINKEDIT + vmaddr: 4294979584 + vmsize: 4096 + fileoff: 12288 + filesize: 2508 + maxprot: 7 + initprot: 1 + nsects: 0 + flags: 0 + - cmd: LC_DYLD_INFO_ONLY + cmdsize: 48 + rebase_off: 12288 + rebase_size: 8 + bind_off: 96 + weak_bind_off: 0 + weak_bind_size: 0 + lazy_bind_off: 624 + export_off: 13016 + export_size: 48 + - cmd: LC_SYMTAB + cmdsize: 24 + symoff: 13080 + nsyms: 30 + stroff: 13700 + strsize: 1096 + - cmd: LC_DYSYMTAB + cmdsize: 80 + ilocalsym: 0 + nlocalsym: 9 + iextdefsym: 9 + nextdefsym: 2 + iundefsym: 11 + nundefsym: 19 + tocoff: 0 + ntoc: 0 + modtaboff: 0 + nmodtab: 0 + extrefsymoff: 0 + nextrefsyms: 0 + indirectsymoff: 13560 + nindirectsyms: 35 + extreloff: 0 + nextrel: 0 + locreloff: 0 + nlocrel: 0 + - cmd: LC_LOAD_DYLINKER + cmdsize: 32 + name: 12 + - cmd: LC_UUID + cmdsize: 24 + cmdsize: 24 + uuid: 461A1B28-822F-3F38-B670-645419E636F5 + - cmd: LC_VERSION_MIN_MACOSX + cmdsize: 16 + version: 658176 + sdk: 658176 + - cmd: LC_SOURCE_VERSION + cmdsize: 16 + version: 0 + - cmd: LC_MAIN + cmdsize: 24 + entryoff: 4448 + stacksize: 0 + - cmd: LC_LOAD_DYLIB + cmdsize: 48 + dylib: + name: 24 + timestamp: 2 + current_version: 7864576 + compatibility_version: 65536 + - cmd: LC_LOAD_DYLIB + cmdsize: 56 + dylib: + name: 24 + timestamp: 2 + current_version: 80349697 + compatibility_version: 65536 + - cmd: LC_FUNCTION_STARTS + cmdsize: 16 + dataoff: 13064 + datasize: 16 + - cmd: LC_DATA_IN_CODE + cmdsize: 16 + dataoff: 13080 + datasize: 0 +... + + +#CHECK: - cmd: LC_SEGMENT_64 +#CHECK: segname: __PAGEZERO +#CHECK: - cmd: LC_SEGMENT_64 +#CHECK: segname: __TEXT +#CHECK: Sections: +#CHECK: - sectname: __text +#CHECK: segname: __TEXT +#CHECK: addr: 0x0000000100001160 +#CHECK: size: 3099 +#CHECK: offset: 0x00001160 +#CHECK: align: 4 +#CHECK: reloff: 0x00000000 +#CHECK: nreloc: 0 +#CHECK: flags: 0x80000400 +#CHECK: reserved1: 0x00000000 +#CHECK: reserved2: 0x00000000 +#CHECK: reserved3: 0x00000000 +#CHECK: - sectname: __stubs +#CHECK: segname: __TEXT +#CHECK: - sectname: __stub_helper +#CHECK: segname: __TEXT +#CHECK: - sectname: __gcc_except_tab__TEXT +#CHECK: segname: __TEXT +#CHECK: - sectname: __cstring +#CHECK: segname: __TEXT +#CHECK: - sectname: __unwind_info +#CHECK: segname: __TEXT +#CHECK: - cmd: LC_SEGMENT_64 +#CHECK: segname: __DATA +#CHECK: Sections: +#CHECK: - sectname: __got +#CHECK: segname: __DATA +#CHECK: - sectname: __nl_symbol_ptr +#CHECK: segname: __DATA +#CHECK: - sectname: __la_symbol_ptr +#CHECK: segname: __DATA diff --git a/llvm/tools/obj2yaml/macho2yaml.cpp b/llvm/tools/obj2yaml/macho2yaml.cpp index cbf55ba35a5..66244c30e40 100644 --- a/llvm/tools/obj2yaml/macho2yaml.cpp +++ b/llvm/tools/obj2yaml/macho2yaml.cpp @@ -13,6 +13,8 @@ #include "llvm/ObjectYAML/MachOYAML.h" #include "llvm/Support/ErrorHandling.h" +#include <string.h> // for memcpy + using namespace llvm; class MachODumper { @@ -32,6 +34,24 @@ public: MachO::swapStruct(LC.Data.LCStruct##_data); \ break; +template <typename SectionType> +MachOYAML::Section constructSection(SectionType Sec) { + MachOYAML::Section TempSec; + memcpy(reinterpret_cast<void *>(&TempSec.sectname[0]), &Sec.sectname[0], 16); + memcpy(reinterpret_cast<void *>(&TempSec.segname[0]), &Sec.segname[0], 16); + TempSec.addr = Sec.addr; + TempSec.size = Sec.size; + TempSec.offset = Sec.offset; + TempSec.align = Sec.align; + TempSec.reloff = Sec.reloff; + TempSec.nreloc = Sec.nreloc; + TempSec.flags = Sec.flags; + TempSec.reserved1 = Sec.reserved1; + TempSec.reserved2 = Sec.reserved2; + TempSec.reserved3 = 0; + return TempSec; +} + Expected<std::unique_ptr<MachOYAML::Object>> MachODumper::dump() { auto Y = make_unique<MachOYAML::Object>(); Y->Header.magic = Obj.getHeader().magic; @@ -54,6 +74,40 @@ Expected<std::unique_ptr<MachOYAML::Object>> MachODumper::dump() { break; #include "llvm/Support/MachO.def" } + if (LoadCmd.C.cmd == MachO::LC_SEGMENT) { + auto End = LoadCmd.Ptr + LoadCmd.C.cmdsize; + const MachO::section *Curr = reinterpret_cast<const MachO::section *>( + LoadCmd.Ptr + sizeof(MachO::segment_command)); + for (; reinterpret_cast<const void *>(Curr) < End; Curr++) { + if (Obj.isLittleEndian() != sys::IsLittleEndianHost) { + MachO::section Sec; + memcpy((void *)&Sec, Curr, sizeof(MachO::section)); + MachO::swapStruct(Sec); + LC.Sections.push_back(constructSection(Sec)); + } else { + LC.Sections.push_back(constructSection(*Curr)); + } + } + } else if (LoadCmd.C.cmd == MachO::LC_SEGMENT_64) { + auto End = LoadCmd.Ptr + LoadCmd.C.cmdsize; + const MachO::section_64 *Curr = + reinterpret_cast<const MachO::section_64 *>( + LoadCmd.Ptr + sizeof(MachO::segment_command_64)); + for (; reinterpret_cast<const void *>(Curr) < End; Curr++) { + MachOYAML::Section TempSec; + if (Obj.isLittleEndian() != sys::IsLittleEndianHost) { + MachO::section_64 Sec; + memcpy((void *)&Sec, Curr, sizeof(MachO::section_64)); + MachO::swapStruct(Sec); + LC.Sections.push_back(constructSection(Sec)); + TempSec = constructSection(Sec); + } else { + TempSec = constructSection(*Curr); + } + TempSec.reserved3 = Curr->reserved3; + LC.Sections.push_back(TempSec); + } + } Y->LoadCommands.push_back(std::move(LC)); } diff --git a/llvm/tools/yaml2obj/yaml2macho.cpp b/llvm/tools/yaml2obj/yaml2macho.cpp index 772c710c098..0e8799e2ce1 100644 --- a/llvm/tools/yaml2obj/yaml2macho.cpp +++ b/llvm/tools/yaml2obj/yaml2macho.cpp @@ -77,6 +77,23 @@ Error MachOWriter::writeHeader(raw_ostream &OS) { return Error::success(); } +template <typename SectionType> +SectionType constructSection(MachOYAML::Section Sec) { + SectionType TempSec; + memcpy(reinterpret_cast<void *>(&TempSec.sectname[0]), &Sec.sectname[0], 16); + memcpy(reinterpret_cast<void *>(&TempSec.segname[0]), &Sec.segname[0], 16); + TempSec.addr = Sec.addr; + TempSec.size = Sec.size; + TempSec.offset = Sec.offset; + TempSec.align = Sec.align; + TempSec.reloff = Sec.reloff; + TempSec.nreloc = Sec.nreloc; + TempSec.flags = Sec.flags; + TempSec.reserved1 = Sec.reserved1; + TempSec.reserved2 = Sec.reserved2; + return TempSec; +} + Error MachOWriter::writeLoadCommands(raw_ostream &OS) { for (auto &LC : Obj.LoadCommands) { size_t BytesWritten = 0; @@ -96,6 +113,21 @@ Error MachOWriter::writeLoadCommands(raw_ostream &OS) { #include "llvm/Support/MachO.def" } + if(LC.Data.load_command_data.cmd == MachO::LC_SEGMENT) { + for(auto Sec : LC.Sections) { + auto TempSec = constructSection<MachO::section>(Sec); + OS.write(reinterpret_cast<const char *>(&(TempSec)), sizeof(MachO::section)); + BytesWritten += sizeof(MachO::section); + } + } else if(LC.Data.load_command_data.cmd == MachO::LC_SEGMENT_64) { + for(auto Sec : LC.Sections) { + auto TempSec = constructSection<MachO::section_64>(Sec); + TempSec.reserved3 = Sec.reserved3; + OS.write(reinterpret_cast<const char *>(&(TempSec)), sizeof(MachO::section_64)); + BytesWritten += sizeof(MachO::section_64); + } + } + auto BytesRemaining = LC.Data.load_command_data.cmdsize - BytesWritten; if (BytesRemaining > 0) { |