diff options
Diffstat (limited to 'llvm/tools/obj2yaml/macho2yaml.cpp')
-rw-r--r-- | llvm/tools/obj2yaml/macho2yaml.cpp | 54 |
1 files changed, 53 insertions, 1 deletions
diff --git a/llvm/tools/obj2yaml/macho2yaml.cpp b/llvm/tools/obj2yaml/macho2yaml.cpp index eae15533d07..d3dfdbbf8da 100644 --- a/llvm/tools/obj2yaml/macho2yaml.cpp +++ b/llvm/tools/obj2yaml/macho2yaml.cpp @@ -12,6 +12,7 @@ #include "llvm/Object/MachOUniversal.h" #include "llvm/ObjectYAML/MachOYAML.h" #include "llvm/Support/ErrorHandling.h" +#include "llvm/Support/LEB128.h" #include <string.h> // for memcpy @@ -25,6 +26,9 @@ class MachODumper { const llvm::object::MachOObjectFile::LoadCommandInfo &LoadCmd); const object::MachOObjectFile &Obj; + void dumpHeader(std::unique_ptr<MachOYAML::Object> &Y); + void dumpLoadCommands(std::unique_ptr<MachOYAML::Object> &Y); + void dumpLinkEdit(std::unique_ptr<MachOYAML::Object> &Y); public: MachODumper(const object::MachOObjectFile &O) : Obj(O) {} @@ -144,6 +148,13 @@ const char *MachODumper::processLoadCommandData<MachO::dylinker_command>( Expected<std::unique_ptr<MachOYAML::Object>> MachODumper::dump() { auto Y = make_unique<MachOYAML::Object>(); + dumpHeader(Y); + dumpLoadCommands(Y); + dumpLinkEdit(Y); + return std::move(Y); +} + +void MachODumper::dumpHeader(std::unique_ptr<MachOYAML::Object> &Y) { Y->Header.magic = Obj.getHeader().magic; Y->Header.cputype = Obj.getHeader().cputype; Y->Header.cpusubtype = Obj.getHeader().cpusubtype; @@ -152,7 +163,9 @@ Expected<std::unique_ptr<MachOYAML::Object>> MachODumper::dump() { Y->Header.sizeofcmds = Obj.getHeader().sizeofcmds; Y->Header.flags = Obj.getHeader().flags; Y->Header.reserved = 0; +} +void MachODumper::dumpLoadCommands(std::unique_ptr<MachOYAML::Object> &Y) { for (auto LoadCmd : Obj.load_commands()) { MachOYAML::LoadCommand LC; const char *EndPtr = LoadCmd.Ptr; @@ -176,8 +189,47 @@ Expected<std::unique_ptr<MachOYAML::Object>> MachODumper::dump() { LC.ZeroPadBytes = RemainingBytes; Y->LoadCommands.push_back(std::move(LC)); } +} - return std::move(Y); +void MachODumper::dumpLinkEdit(std::unique_ptr<MachOYAML::Object> &Y) { + MachOYAML::LinkEditData &LEData = Y->LinkEdit; + + auto RebaseOpcodes = Obj.getDyldInfoRebaseOpcodes(); + for (auto OpCode = RebaseOpcodes.begin(); OpCode != RebaseOpcodes.end(); + ++OpCode) { + MachOYAML::RebaseOpcode RebaseOp; + RebaseOp.Opcode = + static_cast<MachO::RebaseOpcode>(*OpCode & MachO::REBASE_OPCODE_MASK); + RebaseOp.Imm = *OpCode & MachO::REBASE_IMMEDIATE_MASK; + + unsigned Count; + uint64_t ULEB = 0; + + switch (RebaseOp.Opcode) { + case MachO::REBASE_OPCODE_DO_REBASE_ULEB_TIMES_SKIPPING_ULEB: + + ULEB = decodeULEB128(OpCode + 1, &Count); + RebaseOp.ExtraData.push_back(ULEB); + OpCode += Count; + // Intentionally no break here -- This opcode has two ULEB values + case MachO::REBASE_OPCODE_SET_SEGMENT_AND_OFFSET_ULEB: + case MachO::REBASE_OPCODE_ADD_ADDR_ULEB: + case MachO::REBASE_OPCODE_DO_REBASE_ULEB_TIMES: + case MachO::REBASE_OPCODE_DO_REBASE_ADD_ADDR_ULEB: + + ULEB = decodeULEB128(OpCode + 1, &Count); + RebaseOp.ExtraData.push_back(ULEB); + OpCode += Count; + break; + default: + break; + } + + LEData.RebaseOpcodes.push_back(RebaseOp); + + if (RebaseOp.Opcode == MachO::REBASE_OPCODE_DONE) + break; + } } Error macho2yaml(raw_ostream &Out, const object::MachOObjectFile &Obj) { |