[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