diff --git a/test/ObjectYAML/MachO/out_of_order_linkedit.yaml b/test/ObjectYAML/MachO/out_of_order_linkedit.yaml deleted file mode 100644 index 2d8bd24d508..00000000000 --- a/test/ObjectYAML/MachO/out_of_order_linkedit.yaml +++ /dev/null @@ -1,266 +0,0 @@ -# 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/tools/yaml2obj/yaml2macho.cpp b/tools/yaml2obj/yaml2macho.cpp index 533811507df..d65aabc5c86 100644 --- a/tools/yaml2obj/yaml2macho.cpp +++ b/tools/yaml2obj/yaml2macho.cpp @@ -46,15 +46,8 @@ private: Error writeLoadCommands(raw_ostream &OS); Error writeSectionData(raw_ostream &OS); Error writeLinkEditData(raw_ostream &OS); - void writeBindOpcodes(raw_ostream &OS, + void writeBindOpcodes(raw_ostream &OS, uint64_t offset, std::vector &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); @@ -282,7 +275,9 @@ Error MachOWriter::writeSectionData(raw_ostream &OS) { } void MachOWriter::writeBindOpcodes( - raw_ostream &OS, std::vector &BindOpcodes) { + raw_ostream &OS, uint64_t offset, + std::vector &BindOpcodes) { + ZeroToOffset(OS, offset); for (auto Opcode : BindOpcodes) { uint8_t OpByte = Opcode.Opcode | Opcode.Imm; @@ -342,55 +337,21 @@ void writeNListEntry(MachOYAML::NListEntry &NLE, raw_ostream &OS) { } Error MachOWriter::writeLinkEditData(raw_ostream &OS) { - typedef Error (MachOWriter::*writeHandler)(raw_ostream &); - typedef std::pair writeOperation; - std::vector WriteQueue; - + MachOYAML::LinkEditData &LinkEdit = Obj.LinkEdit; 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; } } - std::sort( - WriteQueue.begin(), WriteQueue.end(), - [](writeOperation &a, writeOperation &b) { return a.first < b.first; }); - - for (auto writeOp : WriteQueue) { - ZeroToOffset(OS, writeOp.first); - if (auto Err = (this->*writeOp.second)(OS)) - return Err; - } - - // Fill to the end of the string table - ZeroToOffset(OS, SymtabCmd->stroff + SymtabCmd->strsize); - - return Error::success(); -} - -Error MachOWriter::writeRebaseOpcodes(raw_ostream &OS) { - MachOYAML::LinkEditData &LinkEdit = Obj.LinkEdit; + ZeroToOffset(OS, DyldInfoOnlyCmd->rebase_off); for (auto Opcode : LinkEdit.RebaseOpcodes) { uint8_t OpByte = Opcode.Opcode | Opcode.Imm; @@ -399,39 +360,38 @@ Error MachOWriter::writeRebaseOpcodes(raw_ostream &OS) { encodeULEB128(Data, OS); } } - return Error::success(); -} -Error MachOWriter::writeBasicBindOpcodes(raw_ostream &OS) { - writeBindOpcodes(OS, Obj.LinkEdit.BindOpcodes); - 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::writeWeakBindOpcodes(raw_ostream &OS) { - writeBindOpcodes(OS, Obj.LinkEdit.WeakBindOpcodes); - return Error::success(); -} + ZeroToOffset(OS, DyldInfoOnlyCmd->export_off); + if (auto Err = writeExportTrie(OS)) + return Err; -Error MachOWriter::writeLazyBindOpcodes(raw_ostream &OS) { - writeBindOpcodes(OS, Obj.LinkEdit.LazyBindOpcodes); - return Error::success(); -} - -Error MachOWriter::writeNameList(raw_ostream &OS) { - for (auto NLE : Obj.LinkEdit.NameList) { + ZeroToOffset(OS, SymtabCmd->symoff); + + for (auto NLE : LinkEdit.NameList) { if (is64Bit) writeNListEntry(NLE, OS); else writeNListEntry(NLE, OS); } - return Error::success(); -} -Error MachOWriter::writeStringTable(raw_ostream &OS) { - for (auto Str : Obj.LinkEdit.StringTable) { + auto currOffset = OS.tell() - fileStart; + if (currOffset < SymtabCmd->stroff) + Fill(OS, SymtabCmd->stroff - currOffset, 0xDEADBEEFu); + + for (auto Str : 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(); }