From ed0b17172ebb1d8ef290709f622ec0da3078a34b Mon Sep 17 00:00:00 2001 From: Chris Bieneman Date: Thu, 12 May 2016 17:44:48 +0000 Subject: [PATCH] [yaml2obj] Support for dumping mach_header from yaml With this change obj2yaml and yaml2obj can now round-trip mach_headers. This change also adds ObjectYAML/MachO tests. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@269314 91177308-0d34-0410-b5e6-96231b3b80d8 --- test/ObjectYAML/MachO/mach_header.yaml | 23 ++++++++++ test/ObjectYAML/MachO/mach_header_64.yaml | 23 ++++++++++ test/ObjectYAML/lit.local.cfg | 1 + tools/yaml2obj/yaml2macho.cpp | 70 +++++++++++++++++++++++++++++-- 4 files changed, 114 insertions(+), 3 deletions(-) create mode 100644 test/ObjectYAML/MachO/mach_header.yaml create mode 100644 test/ObjectYAML/MachO/mach_header_64.yaml create mode 100644 test/ObjectYAML/lit.local.cfg diff --git a/test/ObjectYAML/MachO/mach_header.yaml b/test/ObjectYAML/MachO/mach_header.yaml new file mode 100644 index 00000000000..722a00be6f8 --- /dev/null +++ b/test/ObjectYAML/MachO/mach_header.yaml @@ -0,0 +1,23 @@ +# RUN: yaml2obj -format=macho %s | obj2yaml | FileCheck %s + +--- !mach-o +FileHeader: + magic: 0xFEEDFACE + cputype: 0x00000007 + cpusubtype: 0x80000003 + filetype: 0x00000002 + ncmds: 0 + sizeofcmds: 0 + flags: 0x00218085 +... + +# CHECK: --- !mach-o +# CHECK: FileHeader: +# CHECK: magic: 0xFEEDFACE +# CHECK: cputype: 0x00000007 +# CHECK: cpusubtype: 0x80000003 +# CHECK: filetype: 0x00000002 +# CHECK: ncmds: 0 +# CHECK: sizeofcmds: 0 +# CHECK: flags: 0x00218085 +# CHECK: ... diff --git a/test/ObjectYAML/MachO/mach_header_64.yaml b/test/ObjectYAML/MachO/mach_header_64.yaml new file mode 100644 index 00000000000..a9ea82e1a84 --- /dev/null +++ b/test/ObjectYAML/MachO/mach_header_64.yaml @@ -0,0 +1,23 @@ +# RUN: yaml2obj -format=macho %s | obj2yaml | FileCheck %s + +--- !mach-o +FileHeader: + magic: 0xFEEDFACF + cputype: 0x01000007 + cpusubtype: 0x80000003 + filetype: 0x00000002 + ncmds: 0 + sizeofcmds: 0 + flags: 0x00218085 +... + +# CHECK: --- !mach-o +# CHECK: FileHeader: +# CHECK: magic: 0xFEEDFACF +# CHECK: cputype: 0x01000007 +# CHECK: cpusubtype: 0x80000003 +# CHECK: filetype: 0x00000002 +# CHECK: ncmds: 0 +# CHECK: sizeofcmds: 0 +# CHECK: flags: 0x00218085 +# CHECK: ... diff --git a/test/ObjectYAML/lit.local.cfg b/test/ObjectYAML/lit.local.cfg new file mode 100644 index 00000000000..8169b9f95e1 --- /dev/null +++ b/test/ObjectYAML/lit.local.cfg @@ -0,0 +1 @@ +config.suffixes = ['.yaml'] diff --git a/tools/yaml2obj/yaml2macho.cpp b/tools/yaml2obj/yaml2macho.cpp index 09a94ce2a40..ae391cc087b 100644 --- a/tools/yaml2obj/yaml2macho.cpp +++ b/tools/yaml2obj/yaml2macho.cpp @@ -13,11 +13,75 @@ //===----------------------------------------------------------------------===// #include "yaml2obj.h" +#include "llvm/ObjectYAML/MachOYAML.h" +#include "llvm/Support/Error.h" +#include "llvm/Support/MachO.h" +#include "llvm/Support/YAMLTraits.h" #include "llvm/Support/raw_ostream.h" using namespace llvm; -int yaml2macho(llvm::yaml::Input &YIn, llvm::raw_ostream &Out) { - errs() << "yaml2obj: Mach-O not implemented yet!\n"; - return 1; +namespace { + +class MachOWriter { +public: + MachOWriter(MachOYAML::Object &Obj) : Obj(Obj) { + is64Bit = Obj.Header.magic == MachO::MH_MAGIC_64 || + Obj.Header.magic == MachO::MH_CIGAM_64; + bzero(&Header64, sizeof(MachO::mach_header_64)); + } + + Error writeMachO(raw_ostream &OS); + +private: + Error writeHeader(raw_ostream &OS); + + MachOYAML::Object Obj; + bool is64Bit; + + union { + MachO::mach_header_64 Header64; + MachO::mach_header Header; + }; +}; + +Error MachOWriter::writeMachO(raw_ostream &OS) { + if (auto Err = writeHeader(OS)) + return Err; + return Error::success(); +} + +Error MachOWriter::writeHeader(raw_ostream &OS) { + Header.magic = Obj.Header.magic; + Header.cputype = Obj.Header.cputype; + Header.cpusubtype = Obj.Header.cpusubtype; + Header.filetype = Obj.Header.filetype; + Header.ncmds = Obj.Header.ncmds; + Header.sizeofcmds = Obj.Header.sizeofcmds; + Header.flags = Obj.Header.flags; + + if (is64Bit) + OS.write((const char *)&Header64, sizeof(MachO::mach_header_64)); + else + OS.write((const char *)&Header, sizeof(MachO::mach_header)); + + return Error::success(); +} + +} // end anonymous namespace + +int yaml2macho(yaml::Input &YIn, raw_ostream &Out) { + MachOYAML::Object Doc; + YIn >> Doc; + if (YIn.error()) { + errs() << "yaml2obj: Failed to parse YAML file!\n"; + return 1; + } + + MachOWriter Writer(Doc); + if (auto Err = Writer.writeMachO(Out)) { + errs() << toString(std::move(Err)); + return 1; + } + return 0; } -- 2.11.0