[llvm] 652713e - [MachO][ObjCopy] Handle exports trie in LC_DYLD_INFO and LC_DYLD_EXPORTS_TRIE
Daniel Rodríguez Troitiño via llvm-commits
llvm-commits at lists.llvm.org
Tue Nov 22 18:51:44 PST 2022
Author: Daniel Rodríguez Troitiño
Date: 2022-11-22T18:50:06-08:00
New Revision: 652713e268d86a79c9a2935fb4ed7207bd0f0d1c
URL: https://github.com/llvm/llvm-project/commit/652713e268d86a79c9a2935fb4ed7207bd0f0d1c
DIFF: https://github.com/llvm/llvm-project/commit/652713e268d86a79c9a2935fb4ed7207bd0f0d1c.diff
LOG: [MachO][ObjCopy] Handle exports trie in LC_DYLD_INFO and LC_DYLD_EXPORTS_TRIE
The exports trie used to be pointed by the information in LC_DYLD_INFO,
but when chained fixups are present, the exports trie is pointed by
LC_DYLD_EXPORTS_TRIE instead.
Modify ObjCopy code to calculate the right offset and size needed
depending on the existence of LC_DYLD_INFO or LC_DYLD_EXPORTS_TRIE, read
the exports from either of those places, and write the export
information as pointed to either of those places.
Depends on D134571.
Reviewed By: alexander-shaposhnikov
Differential Revision: https://reviews.llvm.org/D137879
Added:
llvm/test/tools/llvm-objdump/MachO/exports-trie-lc.test
Modified:
llvm/lib/ObjCopy/MachO/MachOLayoutBuilder.cpp
llvm/lib/ObjCopy/MachO/MachOReader.cpp
llvm/lib/ObjCopy/MachO/MachOWriter.cpp
Removed:
################################################################################
diff --git a/llvm/lib/ObjCopy/MachO/MachOLayoutBuilder.cpp b/llvm/lib/ObjCopy/MachO/MachOLayoutBuilder.cpp
index 30e25d05d76b5..067ef39d90522 100644
--- a/llvm/lib/ObjCopy/MachO/MachOLayoutBuilder.cpp
+++ b/llvm/lib/ObjCopy/MachO/MachOLayoutBuilder.cpp
@@ -235,6 +235,26 @@ Error MachOLayoutBuilder::layoutTail(uint64_t Offset) {
"Incorrect tail offset");
Offset = std::max(Offset, HeaderSize + O.Header.SizeOfCmds);
+ // The exports trie can be in either LC_DYLD_INFO or in
+ // LC_DYLD_EXPORTS_TRIE, but not both.
+ size_t DyldInfoExportsTrieSize = 0;
+ size_t DyldExportsTrieSize = 0;
+ for (const auto &LC : O.LoadCommands) {
+ switch (LC.MachOLoadCommand.load_command_data.cmd) {
+ case MachO::LC_DYLD_INFO:
+ case MachO::LC_DYLD_INFO_ONLY:
+ DyldInfoExportsTrieSize = O.Exports.Trie.size();
+ break;
+ case MachO::LC_DYLD_EXPORTS_TRIE:
+ DyldExportsTrieSize = O.Exports.Trie.size();
+ break;
+ default:
+ break;
+ }
+ }
+ assert((DyldInfoExportsTrieSize == 0 || DyldExportsTrieSize == 0) &&
+ "Export trie in both LCs");
+
uint64_t NListSize = Is64Bit ? sizeof(MachO::nlist_64) : sizeof(MachO::nlist);
uint64_t StartOfLinkEdit = Offset;
@@ -253,9 +273,9 @@ Error MachOLayoutBuilder::layoutTail(uint64_t Offset) {
uint64_t StartOfBindingInfo = updateOffset(O.Binds.Opcodes.size());
uint64_t StartOfWeakBindingInfo = updateOffset(O.WeakBinds.Opcodes.size());
uint64_t StartOfLazyBindingInfo = updateOffset(O.LazyBinds.Opcodes.size());
- uint64_t StartOfExportTrie = updateOffset(O.Exports.Trie.size());
+ uint64_t StartOfExportTrie = updateOffset(DyldInfoExportsTrieSize);
uint64_t StartOfChainedFixups = updateOffset(O.ChainedFixups.Data.size());
- uint64_t StartOfDyldExportsTrie = updateOffset(O.ExportsTrie.Data.size());
+ uint64_t StartOfDyldExportsTrie = updateOffset(DyldExportsTrieSize);
uint64_t StartOfFunctionStarts = updateOffset(O.FunctionStarts.Data.size());
uint64_t StartOfDataInCode = updateOffset(O.DataInCode.Data.size());
uint64_t StartOfLinkerOptimizationHint =
@@ -368,7 +388,7 @@ Error MachOLayoutBuilder::layoutTail(uint64_t Offset) {
break;
case MachO::LC_DYLD_EXPORTS_TRIE:
MLC.linkedit_data_command_data.dataoff = StartOfDyldExportsTrie;
- MLC.linkedit_data_command_data.datasize = O.ExportsTrie.Data.size();
+ MLC.linkedit_data_command_data.datasize = DyldExportsTrieSize;
break;
case MachO::LC_DYLD_INFO:
case MachO::LC_DYLD_INFO_ONLY:
@@ -386,7 +406,7 @@ Error MachOLayoutBuilder::layoutTail(uint64_t Offset) {
MLC.dyld_info_command_data.lazy_bind_size = O.LazyBinds.Opcodes.size();
MLC.dyld_info_command_data.export_off =
O.Exports.Trie.empty() ? 0 : StartOfExportTrie;
- MLC.dyld_info_command_data.export_size = O.Exports.Trie.size();
+ MLC.dyld_info_command_data.export_size = DyldInfoExportsTrieSize;
break;
// Note that LC_ENCRYPTION_INFO.cryptoff despite its name and the comment in
// <mach-o/loader.h> is not an offset in the binary file, instead, it is a
diff --git a/llvm/lib/ObjCopy/MachO/MachOReader.cpp b/llvm/lib/ObjCopy/MachO/MachOReader.cpp
index b9bb02db23920..e0fdd1ce4cfa2 100644
--- a/llvm/lib/ObjCopy/MachO/MachOReader.cpp
+++ b/llvm/lib/ObjCopy/MachO/MachOReader.cpp
@@ -284,7 +284,11 @@ void MachOReader::readLazyBindInfo(Object &O) const {
}
void MachOReader::readExportInfo(Object &O) const {
- O.Exports.Trie = MachOObj.getDyldInfoExportsTrie();
+ // This information can be in LC_DYLD_INFO or in LC_DYLD_EXPORTS_TRIE
+ ArrayRef<uint8_t> Trie = MachOObj.getDyldInfoExportsTrie();
+ if (Trie.empty())
+ Trie = MachOObj.getDyldExportsTrie();
+ O.Exports.Trie = Trie;
}
void MachOReader::readLinkData(Object &O, Optional<size_t> LCIndex,
diff --git a/llvm/lib/ObjCopy/MachO/MachOWriter.cpp b/llvm/lib/ObjCopy/MachO/MachOWriter.cpp
index 80a8b29047099..d0a9dc9e9c15c 100644
--- a/llvm/lib/ObjCopy/MachO/MachOWriter.cpp
+++ b/llvm/lib/ObjCopy/MachO/MachOWriter.cpp
@@ -569,7 +569,15 @@ void MachOWriter::writeChainedFixupsData() {
}
void MachOWriter::writeExportsTrieData() {
- return writeLinkData(O.ExportsTrieCommandIndex, O.ExportsTrie);
+ if (!O.ExportsTrieCommandIndex)
+ return;
+ const MachO::linkedit_data_command &ExportsTrieCmd =
+ O.LoadCommands[*O.ExportsTrieCommandIndex]
+ .MachOLoadCommand.linkedit_data_command_data;
+ char *Out = (char *)Buf->getBufferStart() + ExportsTrieCmd.dataoff;
+ assert((ExportsTrieCmd.datasize == O.Exports.Trie.size()) &&
+ "Incorrect export trie size");
+ memcpy(Out, O.Exports.Trie.data(), O.Exports.Trie.size());
}
void MachOWriter::writeTail() {
diff --git a/llvm/test/tools/llvm-objdump/MachO/exports-trie-lc.test b/llvm/test/tools/llvm-objdump/MachO/exports-trie-lc.test
new file mode 100644
index 0000000000000..08ebaeebfaba4
--- /dev/null
+++ b/llvm/test/tools/llvm-objdump/MachO/exports-trie-lc.test
@@ -0,0 +1,205 @@
+# RUN: yaml2obj %s | llvm-objdump --macho --exports-trie - | FileCheck %s
+
+# CHECK: Exports trie:
+# CHECK-NEXT: 0x100000000 __mh_execute_header
+# CHECK-NEXT: 0x100003F98 _main
+
+--- !mach-o
+FileHeader:
+ magic: 0xFEEDFACF
+ cputype: 0x1000007
+ cpusubtype: 0x3
+ filetype: 0x2
+ ncmds: 15
+ sizeofcmds: 728
+ flags: 0x200085
+ reserved: 0x0
+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: 232
+ segname: __TEXT
+ vmaddr: 4294967296
+ vmsize: 16384
+ fileoff: 0
+ filesize: 16384
+ maxprot: 5
+ initprot: 5
+ nsects: 2
+ flags: 0
+ Sections:
+ - sectname: __text
+ segname: __TEXT
+ addr: 0x100003FB0
+ size: 8
+ offset: 0x3FB0
+ align: 4
+ reloff: 0x0
+ nreloc: 0
+ flags: 0x80000400
+ reserved1: 0x0
+ reserved2: 0x0
+ reserved3: 0x0
+ content: C30F1F0000000000
+ - sectname: __unwind_info
+ segname: __TEXT
+ addr: 0x100003FB8
+ size: 72
+ offset: 0x3FB8
+ align: 2
+ reloff: 0x0
+ nreloc: 0
+ flags: 0x0
+ reserved1: 0x0
+ reserved2: 0x0
+ reserved3: 0x0
+ content: 010000001C000000000000001C000000000000001C00000002000000B03F00003400000034000000B93F00000000000034000000030000000C000100100001000000000000000000
+ - cmd: LC_SEGMENT_64
+ cmdsize: 72
+ segname: __LINKEDIT
+ vmaddr: 4294983680
+ vmsize: 16384
+ fileoff: 16384
+ filesize: 176
+ maxprot: 1
+ initprot: 1
+ nsects: 0
+ flags: 0
+ - cmd: LC_DYLD_CHAINED_FIXUPS
+ cmdsize: 16
+ dataoff: 16384
+ datasize: 56
+ - cmd: LC_DYLD_EXPORTS_TRIE
+ cmdsize: 16
+ dataoff: 16440
+ datasize: 48
+ - cmd: LC_SYMTAB
+ cmdsize: 24
+ symoff: 16504
+ nsyms: 2
+ stroff: 16536
+ strsize: 32
+ - cmd: LC_DYSYMTAB
+ cmdsize: 80
+ ilocalsym: 0
+ nlocalsym: 0
+ iextdefsym: 0
+ nextdefsym: 2
+ iundefsym: 2
+ nundefsym: 0
+ tocoff: 0
+ ntoc: 0
+ modtaboff: 0
+ nmodtab: 0
+ extrefsymoff: 0
+ nextrefsyms: 0
+ indirectsymoff: 0
+ nindirectsyms: 0
+ extreloff: 0
+ nextrel: 0
+ locreloff: 0
+ nlocrel: 0
+ - cmd: LC_LOAD_DYLINKER
+ cmdsize: 32
+ name: 12
+ Content: '/usr/lib/dyld'
+ ZeroPadBytes: 7
+ - cmd: LC_UUID
+ cmdsize: 24
+ uuid: 362D6303-E0AC-3074-B083-CF48B87DB35D
+ - cmd: LC_BUILD_VERSION
+ cmdsize: 32
+ platform: 1
+ minos: 786432
+ sdk: 787200
+ ntools: 1
+ Tools:
+ - tool: 3
+ version: 50069504
+ - cmd: LC_SOURCE_VERSION
+ cmdsize: 16
+ version: 0
+ - cmd: LC_MAIN
+ cmdsize: 24
+ entryoff: 16304
+ stacksize: 0
+ - cmd: LC_LOAD_DYLIB
+ cmdsize: 56
+ dylib:
+ name: 24
+ timestamp: 2
+ current_version: 85943299
+ compatibility_version: 65536
+ Content: '/usr/lib/libSystem.B.dylib'
+ ZeroPadBytes: 6
+ - cmd: LC_FUNCTION_STARTS
+ cmdsize: 16
+ dataoff: 16488
+ datasize: 8
+ - cmd: LC_DATA_IN_CODE
+ cmdsize: 16
+ dataoff: 0
+ datasize: 0
+LinkEditData:
+ ExportTrie:
+ TerminalSize: 0
+ NodeOffset: 0
+ Name: ''
+ Flags: 0x0
+ Address: 0x0
+ Other: 0x0
+ ImportName: ''
+ Children:
+ - TerminalSize: 0
+ NodeOffset: 5
+ Name: _
+ Flags: 0x0
+ Address: 0x0
+ Other: 0x0
+ ImportName: ''
+ Children:
+ - TerminalSize: 2
+ NodeOffset: 33
+ Name: _mh_execute_header
+ Flags: 0x0
+ Address: 0x0
+ Other: 0x0
+ ImportName: ''
+ - TerminalSize: 3
+ NodeOffset: 37
+ Name: main
+ Flags: 0x0
+ Address: 0x3F98
+ Other: 0x0
+ ImportName: ''
+ NameList:
+ - n_strx: 2
+ n_type: 0xF
+ n_sect: 1
+ n_desc: 16
+ n_value: 4294967296
+ - n_strx: 22
+ n_type: 0xF
+ n_sect: 1
+ n_desc: 0
+ n_value: 4294983600
+ StringTable:
+ - ' '
+ - __mh_execute_header
+ - _main
+ - ''
+ - ''
+ - ''
+ - ''
+ FunctionStarts: [ 0x3FB0 ]
+...
More information about the llvm-commits
mailing list