summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--llvm/test/ObjectYAML/MachO/out_of_order_linkedit.yaml266
-rw-r--r--llvm/tools/yaml2obj/yaml2macho.cpp90
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();
}
OpenPOWER on IntegriCloud