[llvm] r269442 - [obj2yaml] [yaml2obj] Basic support for MachO::load_command

Chris Bieneman via llvm-commits llvm-commits at lists.llvm.org
Fri May 13 10:41:41 PDT 2016


Author: cbieneman
Date: Fri May 13 12:41:41 2016
New Revision: 269442

URL: http://llvm.org/viewvc/llvm-project?rev=269442&view=rev
Log:
[obj2yaml] [yaml2obj] Basic support for MachO::load_command

This patch adds basic support for MachO::load_command. Load command types and sizes are encoded in the YAML and expanded back into MachO.

The YAML doesn't yet support load command structs, that is coming next. In the meantime as a temporary measure when writing MachO files the load commands are padded with zeros so that the generated binary is valid.

Added:
    llvm/trunk/test/ObjectYAML/MachO/load_commands.yaml
Modified:
    llvm/trunk/include/llvm/ObjectYAML/MachOYAML.h
    llvm/trunk/lib/ObjectYAML/MachOYAML.cpp
    llvm/trunk/tools/obj2yaml/macho2yaml.cpp
    llvm/trunk/tools/yaml2obj/yaml2macho.cpp

Modified: llvm/trunk/include/llvm/ObjectYAML/MachOYAML.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/ObjectYAML/MachOYAML.h?rev=269442&r1=269441&r2=269442&view=diff
==============================================================================
--- llvm/trunk/include/llvm/ObjectYAML/MachOYAML.h (original)
+++ llvm/trunk/include/llvm/ObjectYAML/MachOYAML.h Fri May 13 12:41:41 2016
@@ -33,12 +33,23 @@ struct FileHeader {
   llvm::yaml::Hex32 reserved;
 };
 
+struct LoadCommand {
+  virtual ~LoadCommand();
+  MachO::LoadCommandType cmd;
+  uint32_t cmdsize;
+};
+
 struct Object {
   FileHeader Header;
+  std::vector<std::unique_ptr<LoadCommand>> LoadCommands;
 };
 
 } // namespace llvm::MachOYAML
+} // namespace llvm
+
+LLVM_YAML_IS_SEQUENCE_VECTOR(std::unique_ptr<llvm::MachOYAML::LoadCommand>)
 
+namespace llvm {
 namespace yaml {
 
 template <> struct MappingTraits<MachOYAML::FileHeader> {
@@ -49,6 +60,22 @@ template <> struct MappingTraits<MachOYA
   static void mapping(IO &IO, MachOYAML::Object &Object);
 };
 
+template <> struct MappingTraits<std::unique_ptr<MachOYAML::LoadCommand>> {
+  static void mapping(IO &IO,
+                      std::unique_ptr<MachOYAML::LoadCommand> &LoadCommand);
+};
+
+#define HANDLE_LOAD_COMMAND(LoadCommandName, LoadCommandValue)                 \
+  io.enumCase(value, #LoadCommandName, MachO::LoadCommandName);
+
+template <> struct ScalarEnumerationTraits<MachO::LoadCommandType> {
+  static void enumeration(IO &io, MachO::LoadCommandType &value) {
+#include "llvm/Support/MachO.def"
+  }
+};
+
+#undef HANDLE_LOAD_COMMAND
+
 } // namespace llvm::yaml
 
 } // namespace llvm

Modified: llvm/trunk/lib/ObjectYAML/MachOYAML.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/ObjectYAML/MachOYAML.cpp?rev=269442&r1=269441&r2=269442&view=diff
==============================================================================
--- llvm/trunk/lib/ObjectYAML/MachOYAML.cpp (original)
+++ llvm/trunk/lib/ObjectYAML/MachOYAML.cpp Fri May 13 12:41:41 2016
@@ -16,6 +16,8 @@
 
 namespace llvm {
 
+MachOYAML::LoadCommand::~LoadCommand() {}
+
 namespace yaml {
 
 void MappingTraits<MachOYAML::FileHeader>::mapping(
@@ -40,9 +42,18 @@ void MappingTraits<MachOYAML::Object>::m
     IO.mapTag("!mach-o", true);
   }
   IO.mapRequired("FileHeader", Object.Header);
+  IO.mapOptional("LoadCommands", Object.LoadCommands);
   IO.setContext(nullptr);
 }
 
+void MappingTraits<std::unique_ptr<MachOYAML::LoadCommand>>::mapping(
+    IO &IO, std::unique_ptr<MachOYAML::LoadCommand> &LoadCommand) {
+  if (!IO.outputting())
+    LoadCommand.reset(new MachOYAML::LoadCommand());
+  IO.mapRequired("cmd", LoadCommand->cmd);
+  IO.mapRequired("cmdsize", LoadCommand->cmdsize);
+}
+
 } // namespace llvm::yaml
 
 } // namespace llvm

Added: llvm/trunk/test/ObjectYAML/MachO/load_commands.yaml
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/ObjectYAML/MachO/load_commands.yaml?rev=269442&view=auto
==============================================================================
--- llvm/trunk/test/ObjectYAML/MachO/load_commands.yaml (added)
+++ llvm/trunk/test/ObjectYAML/MachO/load_commands.yaml Fri May 13 12:41:41 2016
@@ -0,0 +1,81 @@
+# 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
+  - cmd:             LC_SEGMENT_64
+    cmdsize:         552
+  - cmd:             LC_SEGMENT_64
+    cmdsize:         312
+  - cmd:             LC_SEGMENT_64
+    cmdsize:         72
+  - cmd:             LC_DYLD_INFO_ONLY
+    cmdsize:         48
+  - cmd:             LC_SYMTAB
+    cmdsize:         24
+  - cmd:             LC_DYSYMTAB
+    cmdsize:         80
+  - cmd:             LC_LOAD_DYLINKER
+    cmdsize:         32
+  - cmd:             LC_UUID
+    cmdsize:         24
+  - cmd:             LC_VERSION_MIN_MACOSX
+    cmdsize:         16
+  - cmd:             LC_SOURCE_VERSION
+    cmdsize:         16
+  - cmd:             LC_MAIN
+    cmdsize:         24
+  - cmd:             LC_LOAD_DYLIB
+    cmdsize:         48
+  - cmd:             LC_LOAD_DYLIB
+    cmdsize:         56
+  - cmd:             LC_FUNCTION_STARTS
+    cmdsize:         16
+  - cmd:             LC_DATA_IN_CODE
+    cmdsize:         16
+...
+
+
+# CHECK: LoadCommands:    
+# CHECK:   - cmd:             LC_SEGMENT_64
+# CHECK:     cmdsize:         72
+# CHECK:   - cmd:             LC_SEGMENT_64
+# CHECK:     cmdsize:         552
+# CHECK:   - cmd:             LC_SEGMENT_64
+# CHECK:     cmdsize:         312
+# CHECK:   - cmd:             LC_SEGMENT_64
+# CHECK:     cmdsize:         72
+# CHECK:   - cmd:             LC_DYLD_INFO_ONLY
+# CHECK:     cmdsize:         48
+# CHECK:   - cmd:             LC_SYMTAB
+# CHECK:     cmdsize:         24
+# CHECK:   - cmd:             LC_DYSYMTAB
+# CHECK:     cmdsize:         80
+# CHECK:   - cmd:             LC_LOAD_DYLINKER
+# CHECK:     cmdsize:         32
+# CHECK:   - cmd:             LC_UUID
+# CHECK:     cmdsize:         24
+# CHECK:   - cmd:             LC_VERSION_MIN_MACOSX
+# CHECK:     cmdsize:         16
+# CHECK:   - cmd:             LC_SOURCE_VERSION
+# CHECK:     cmdsize:         16
+# CHECK:   - cmd:             LC_MAIN
+# CHECK:     cmdsize:         24
+# CHECK:   - cmd:             LC_LOAD_DYLIB
+# CHECK:     cmdsize:         48
+# CHECK:   - cmd:             LC_LOAD_DYLIB
+# CHECK:     cmdsize:         56
+# CHECK:   - cmd:             LC_FUNCTION_STARTS
+# CHECK:     cmdsize:         16
+# CHECK:   - cmd:             LC_DATA_IN_CODE
+# CHECK:     cmdsize:         16

Modified: llvm/trunk/tools/obj2yaml/macho2yaml.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/obj2yaml/macho2yaml.cpp?rev=269442&r1=269441&r2=269442&view=diff
==============================================================================
--- llvm/trunk/tools/obj2yaml/macho2yaml.cpp (original)
+++ llvm/trunk/tools/obj2yaml/macho2yaml.cpp Fri May 13 12:41:41 2016
@@ -21,10 +21,10 @@ class MachODumper {
 
 public:
   MachODumper(const object::MachOObjectFile &O) : Obj(O) {}
-  Expected<std::unique_ptr<MachOYAML::Object> > dump();
+  Expected<std::unique_ptr<MachOYAML::Object>> dump();
 };
 
-Expected<std::unique_ptr<MachOYAML::Object> > MachODumper::dump() {
+Expected<std::unique_ptr<MachOYAML::Object>> MachODumper::dump() {
   auto Y = make_unique<MachOYAML::Object>();
   Y->Header.magic = Obj.getHeader().magic;
   Y->Header.cputype = Obj.getHeader().cputype;
@@ -34,12 +34,19 @@ Expected<std::unique_ptr<MachOYAML::Obje
   Y->Header.sizeofcmds = Obj.getHeader().sizeofcmds;
   Y->Header.flags = Obj.getHeader().flags;
 
+  for (auto load_command : Obj.load_commands()) {
+    auto LC = make_unique<MachOYAML::LoadCommand>();
+    LC->cmd = static_cast<MachO::LoadCommandType>(load_command.C.cmd);
+    LC->cmdsize = load_command.C.cmdsize;
+    Y->LoadCommands.push_back(std::move(LC));
+  }
+
   return std::move(Y);
 }
 
 Error macho2yaml(raw_ostream &Out, const object::MachOObjectFile &Obj) {
   MachODumper Dumper(Obj);
-  Expected<std::unique_ptr<MachOYAML::Object> > YAML = Dumper.dump();
+  Expected<std::unique_ptr<MachOYAML::Object>> YAML = Dumper.dump();
   if (!YAML)
     return YAML.takeError();
 

Modified: llvm/trunk/tools/yaml2obj/yaml2macho.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/yaml2obj/yaml2macho.cpp?rev=269442&r1=269441&r2=269442&view=diff
==============================================================================
--- llvm/trunk/tools/yaml2obj/yaml2macho.cpp (original)
+++ llvm/trunk/tools/yaml2obj/yaml2macho.cpp Fri May 13 12:41:41 2016
@@ -40,8 +40,9 @@ public:
 
 private:
   Error writeHeader(raw_ostream &OS);
+  Error writeLoadCommands(raw_ostream &OS);
 
-  MachOYAML::Object Obj;
+  MachOYAML::Object &Obj;
   bool is64Bit;
 
   union {
@@ -53,6 +54,8 @@ private:
 Error MachOWriter::writeMachO(raw_ostream &OS) {
   if (auto Err = writeHeader(OS))
     return Err;
+  if (auto Err = writeLoadCommands(OS))
+    return Err;
   return Error::success();
 }
 
@@ -66,15 +69,32 @@ Error MachOWriter::writeHeader(raw_ostre
   Header.flags = Obj.Header.flags;
   Header64.reserved = Obj.Header.reserved;
 
-  if (is64Bit) {
+  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();
 }
 
+Error MachOWriter::writeLoadCommands(raw_ostream &OS) {
+  for (auto &LC : Obj.LoadCommands) {
+    MachO::load_command LCTemp;
+    LCTemp.cmd = LC->cmd;
+    LCTemp.cmdsize = LC->cmdsize;
+    OS.write(reinterpret_cast<const char *>(&LCTemp),
+             sizeof(MachO::load_command));
+    auto remaining_size = LC->cmdsize - sizeof(MachO::load_command);
+    if (remaining_size > 0) {
+      // TODO: Replace all this once the load command data is present in yaml.
+      std::vector<char> fill_data;
+      fill_data.insert(fill_data.begin(), remaining_size, 0);
+      OS.write(fill_data.data(), remaining_size);
+    }
+  }
+  return Error::success();
+}
+
 } // end anonymous namespace
 
 int yaml2macho(yaml::Input &YIn, raw_ostream &Out) {




More information about the llvm-commits mailing list