diff options
| -rw-r--r-- | llvm/test/ObjectYAML/MachO/out_of_order_linkedit.yaml | 266 | ||||
| -rw-r--r-- | llvm/tools/yaml2obj/yaml2macho.cpp | 90 |
2 files changed, 330 insertions, 26 deletions
diff --git a/llvm/test/ObjectYAML/MachO/out_of_order_linkedit.yaml b/llvm/test/ObjectYAML/MachO/out_of_order_linkedit.yaml new file mode 100644 index 00000000000..2d8bd24d508 --- /dev/null +++ b/llvm/test/ObjectYAML/MachO/out_of_order_linkedit.yaml @@ -0,0 +1,266 @@ +# 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 + - cmd: LC_SEGMENT_64 + cmdsize: 312 + segname: __DATA + vmaddr: 4294975488 + vmsize: 4096 + fileoff: 8192 + filesize: 4096 + maxprot: 7 + initprot: 3 + nsects: 3 + flags: 0 + - 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: 12384 + rebase_size: 8 + bind_off: 12288 + bind_size: 96 + weak_bind_off: 0 + weak_bind_size: 0 + lazy_bind_off: 12392 + lazy_bind_size: 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 + PayloadString: /usr/lib/dyld + ZeroPadBytes: 7 + - cmd: LC_UUID + 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 + PayloadString: '/usr/lib/libc++.1.dylib' + ZeroPadBytes: 1 + - cmd: LC_LOAD_DYLIB + cmdsize: 56 + dylib: + name: 24 + timestamp: 2 + current_version: 80349697 + compatibility_version: 65536 + PayloadString: /usr/lib/libSystem.B.dylib + ZeroPadBytes: 6 + - cmd: LC_FUNCTION_STARTS + cmdsize: 16 + dataoff: 13064 + datasize: 16 + - cmd: LC_DATA_IN_CODE + cmdsize: 16 + dataoff: 13080 + datasize: 0 +LinkEditData: + RebaseOpcodes: + - Opcode: REBASE_OPCODE_SET_TYPE_IMM + Imm: 1 + - Opcode: REBASE_OPCODE_SET_SEGMENT_AND_OFFSET_ULEB + Imm: 2 + ExtraData: + - 0x0000000000000028 + - Opcode: REBASE_OPCODE_DO_REBASE_ULEB_TIMES + Imm: 0 + ExtraData: + - 0x000000000000000F + - Opcode: REBASE_OPCODE_DONE + Imm: 0 + BindOpcodes: + - Opcode: BIND_OPCODE_SET_DYLIB_ORDINAL_IMM + Imm: 1 + Symbol: '' + - Opcode: BIND_OPCODE_SET_SYMBOL_TRAILING_FLAGS_IMM + Imm: 0 + Symbol: __ZNSt3__14coutE + - Opcode: BIND_OPCODE_SET_TYPE_IMM + Imm: 1 + Symbol: '' + - Opcode: BIND_OPCODE_SET_SEGMENT_AND_OFFSET_ULEB + Imm: 2 + ULEBExtraData: + - 0x0000000000000000 + Symbol: '' + - Opcode: BIND_OPCODE_DO_BIND + Imm: 0 + Symbol: '' + - Opcode: BIND_OPCODE_SET_SYMBOL_TRAILING_FLAGS_IMM + Imm: 0 + Symbol: __ZNSt3__15ctypeIcE2idE + - Opcode: BIND_OPCODE_DO_BIND + Imm: 0 + Symbol: '' + - Opcode: BIND_OPCODE_SET_SYMBOL_TRAILING_FLAGS_IMM + Imm: 0 + Symbol: ___gxx_personality_v0 + - Opcode: BIND_OPCODE_DO_BIND + Imm: 0 + Symbol: '' + - Opcode: BIND_OPCODE_SET_DYLIB_ORDINAL_IMM + Imm: 2 + Symbol: '' + - Opcode: BIND_OPCODE_SET_SYMBOL_TRAILING_FLAGS_IMM + Imm: 0 + Symbol: dyld_stub_binder + - Opcode: BIND_OPCODE_DO_BIND + Imm: 0 + Symbol: '' + - Opcode: BIND_OPCODE_DONE + Imm: 0 + Symbol: '' +... + +#CHECK: - cmd: LC_DYLD_INFO_ONLY +#CHECK: cmdsize: 48 +#CHECK: rebase_off: 12384 +#CHECK: rebase_size: 8 +#CHECK: bind_off: 12288 +#CHECK: bind_size: 96 +#CHECK: weak_bind_off: 0 +#CHECK: weak_bind_size: 0 +#CHECK: lazy_bind_off: 12392 +#CHECK: lazy_bind_size: 624 +#CHECK: export_off: 13016 +#CHECK: export_size: 48 +#CHECK: LinkEditData: +#CHECK: RebaseOpcodes: +#CHECK: - Opcode: REBASE_OPCODE_SET_TYPE_IMM +#CHECK: Imm: 1 +#CHECK: - Opcode: REBASE_OPCODE_SET_SEGMENT_AND_OFFSET_ULEB +#CHECK: Imm: 2 +#CHECK: ExtraData: +#CHECK: - 0x0000000000000028 +#CHECK: - Opcode: REBASE_OPCODE_DO_REBASE_ULEB_TIMES +#CHECK: Imm: 0 +#CHECK: ExtraData: +#CHECK: - 0x000000000000000F +#CHECK: - Opcode: REBASE_OPCODE_DONE +#CHECK: Imm: 0 +#CHECK: BindOpcodes: +#CHECK: - Opcode: BIND_OPCODE_SET_DYLIB_ORDINAL_IMM +#CHECK: Imm: 1 +#CHECK: Symbol: '' +#CHECK: - Opcode: BIND_OPCODE_SET_SYMBOL_TRAILING_FLAGS_IMM +#CHECK: Imm: 0 +#CHECK: Symbol: __ZNSt3__14coutE +#CHECK: - Opcode: BIND_OPCODE_SET_TYPE_IMM +#CHECK: Imm: 1 +#CHECK: Symbol: '' +#CHECK: - Opcode: BIND_OPCODE_SET_SEGMENT_AND_OFFSET_ULEB +#CHECK: Imm: 2 +#CHECK: ULEBExtraData: +#CHECK: - 0x0000000000000000 +#CHECK: Symbol: '' +#CHECK: - Opcode: BIND_OPCODE_DO_BIND +#CHECK: Imm: 0 +#CHECK: Symbol: '' +#CHECK: - Opcode: BIND_OPCODE_SET_SYMBOL_TRAILING_FLAGS_IMM +#CHECK: Imm: 0 +#CHECK: Symbol: __ZNSt3__15ctypeIcE2idE +#CHECK: - Opcode: BIND_OPCODE_DO_BIND +#CHECK: Imm: 0 +#CHECK: Symbol: '' +#CHECK: - Opcode: BIND_OPCODE_SET_SYMBOL_TRAILING_FLAGS_IMM +#CHECK: Imm: 0 +#CHECK: Symbol: ___gxx_personality_v0 +#CHECK: - Opcode: BIND_OPCODE_DO_BIND +#CHECK: Imm: 0 +#CHECK: Symbol: '' +#CHECK: - Opcode: BIND_OPCODE_SET_DYLIB_ORDINAL_IMM +#CHECK: Imm: 2 +#CHECK: Symbol: '' +#CHECK: - Opcode: BIND_OPCODE_SET_SYMBOL_TRAILING_FLAGS_IMM +#CHECK: Imm: 0 +#CHECK: Symbol: dyld_stub_binder +#CHECK: - Opcode: BIND_OPCODE_DO_BIND +#CHECK: Imm: 0 +#CHECK: Symbol: '' +#CHECK: - Opcode: BIND_OPCODE_DONE +#CHECK: Imm: 0 +#CHECK: Symbol: '' diff --git a/llvm/tools/yaml2obj/yaml2macho.cpp b/llvm/tools/yaml2obj/yaml2macho.cpp index d65aabc5c86..e08a3f2b9f9 100644 --- a/llvm/tools/yaml2obj/yaml2macho.cpp +++ b/llvm/tools/yaml2obj/yaml2macho.cpp @@ -46,8 +46,15 @@ private: Error writeLoadCommands(raw_ostream &OS); Error writeSectionData(raw_ostream &OS); Error writeLinkEditData(raw_ostream &OS); - void writeBindOpcodes(raw_ostream &OS, uint64_t offset, + void writeBindOpcodes(raw_ostream &OS, std::vector<MachOYAML::BindOpcode> &BindOpcodes); + // LinkEdit writers + Error writeRebaseOpcodes(raw_ostream &OS); + Error writeBasicBindOpcodes(raw_ostream &OS); + Error writeWeakBindOpcodes(raw_ostream &OS); + Error writeLazyBindOpcodes(raw_ostream &OS); + Error writeNameList(raw_ostream &OS); + Error writeStringTable(raw_ostream &OS); Error writeExportTrie(raw_ostream &OS); void dumpExportEntry(raw_ostream &OS, MachOYAML::ExportEntry &Entry); @@ -275,9 +282,7 @@ Error MachOWriter::writeSectionData(raw_ostream &OS) { } void MachOWriter::writeBindOpcodes( - raw_ostream &OS, uint64_t offset, - std::vector<MachOYAML::BindOpcode> &BindOpcodes) { - ZeroToOffset(OS, offset); + raw_ostream &OS, std::vector<MachOYAML::BindOpcode> &BindOpcodes) { for (auto Opcode : BindOpcodes) { uint8_t OpByte = Opcode.Opcode | Opcode.Imm; @@ -337,21 +342,53 @@ void writeNListEntry(MachOYAML::NListEntry &NLE, raw_ostream &OS) { } Error MachOWriter::writeLinkEditData(raw_ostream &OS) { - MachOYAML::LinkEditData &LinkEdit = Obj.LinkEdit; + typedef Error (MachOWriter::*writeHandler)(raw_ostream &); + typedef std::pair<uint64_t, writeHandler> writeOperation; + std::vector<writeOperation> WriteQueue; + MachO::dyld_info_command *DyldInfoOnlyCmd = 0; MachO::symtab_command *SymtabCmd = 0; for (auto &LC : Obj.LoadCommands) { switch (LC.Data.load_command_data.cmd) { case MachO::LC_SYMTAB: SymtabCmd = &LC.Data.symtab_command_data; + WriteQueue.push_back( + std::make_pair(SymtabCmd->symoff, &MachOWriter::writeNameList)); + WriteQueue.push_back( + std::make_pair(SymtabCmd->stroff, &MachOWriter::writeStringTable)); break; case MachO::LC_DYLD_INFO_ONLY: DyldInfoOnlyCmd = &LC.Data.dyld_info_command_data; + WriteQueue.push_back(std::make_pair(DyldInfoOnlyCmd->rebase_off, + &MachOWriter::writeRebaseOpcodes)); + WriteQueue.push_back(std::make_pair(DyldInfoOnlyCmd->bind_off, + &MachOWriter::writeBasicBindOpcodes)); + WriteQueue.push_back(std::make_pair(DyldInfoOnlyCmd->weak_bind_off, + &MachOWriter::writeWeakBindOpcodes)); + WriteQueue.push_back(std::make_pair(DyldInfoOnlyCmd->lazy_bind_off, + &MachOWriter::writeLazyBindOpcodes)); + WriteQueue.push_back(std::make_pair(DyldInfoOnlyCmd->export_off, + &MachOWriter::writeExportTrie)); break; } } - ZeroToOffset(OS, DyldInfoOnlyCmd->rebase_off); + std::sort(WriteQueue.begin(), WriteQueue.end(), + [](const writeOperation &a, const writeOperation &b) { + return a.first < b.first; + }); + + for (auto writeOp : WriteQueue) { + ZeroToOffset(OS, writeOp.first); + if (auto Err = (this->*writeOp.second)(OS)) + return Err; + } + + return Error::success(); +} + +Error MachOWriter::writeRebaseOpcodes(raw_ostream &OS) { + MachOYAML::LinkEditData &LinkEdit = Obj.LinkEdit; for (auto Opcode : LinkEdit.RebaseOpcodes) { uint8_t OpByte = Opcode.Opcode | Opcode.Imm; @@ -360,38 +397,39 @@ Error MachOWriter::writeLinkEditData(raw_ostream &OS) { encodeULEB128(Data, OS); } } + return Error::success(); +} - writeBindOpcodes(OS, DyldInfoOnlyCmd->bind_off, LinkEdit.BindOpcodes); - writeBindOpcodes(OS, DyldInfoOnlyCmd->weak_bind_off, - LinkEdit.WeakBindOpcodes); - writeBindOpcodes(OS, DyldInfoOnlyCmd->lazy_bind_off, - LinkEdit.LazyBindOpcodes); +Error MachOWriter::writeBasicBindOpcodes(raw_ostream &OS) { + writeBindOpcodes(OS, Obj.LinkEdit.BindOpcodes); + return Error::success(); +} - ZeroToOffset(OS, DyldInfoOnlyCmd->export_off); - if (auto Err = writeExportTrie(OS)) - return Err; +Error MachOWriter::writeWeakBindOpcodes(raw_ostream &OS) { + writeBindOpcodes(OS, Obj.LinkEdit.WeakBindOpcodes); + return Error::success(); +} + +Error MachOWriter::writeLazyBindOpcodes(raw_ostream &OS) { + writeBindOpcodes(OS, Obj.LinkEdit.LazyBindOpcodes); + return Error::success(); +} - ZeroToOffset(OS, SymtabCmd->symoff); - - for (auto NLE : LinkEdit.NameList) { +Error MachOWriter::writeNameList(raw_ostream &OS) { + for (auto NLE : Obj.LinkEdit.NameList) { if (is64Bit) writeNListEntry<MachO::nlist_64>(NLE, OS); else writeNListEntry<MachO::nlist>(NLE, OS); } + return Error::success(); +} - auto currOffset = OS.tell() - fileStart; - if (currOffset < SymtabCmd->stroff) - Fill(OS, SymtabCmd->stroff - currOffset, 0xDEADBEEFu); - - for (auto Str : LinkEdit.StringTable) { +Error MachOWriter::writeStringTable(raw_ostream &OS) { + for (auto Str : Obj.LinkEdit.StringTable) { OS.write(Str.data(), Str.size()); OS.write('\0'); } - - // Fill to the end of the string table - ZeroToOffset(OS, SymtabCmd->stroff + SymtabCmd->strsize); - return Error::success(); } |

