diff --git a/llvm/test/tools/llvm-objcopy/MachO/Inputs/strip-chained-fixups.yaml b/llvm/test/tools/llvm-objcopy/MachO/Inputs/strip-chained-fixups.yaml new file mode 100644 --- /dev/null +++ b/llvm/test/tools/llvm-objcopy/MachO/Inputs/strip-chained-fixups.yaml @@ -0,0 +1,238 @@ +--- !mach-o +FileHeader: + magic: 0xFEEDFACF + cputype: 0x100000C + cpusubtype: 0x0 + filetype: 0x2 + ncmds: 16 + sizeofcmds: 744 + 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: 0x100003F98 + size: 24 + offset: 0x3F98 + align: 2 + reloff: 0x0 + nreloc: 0 + flags: 0x80000400 + reserved1: 0x0 + reserved2: 0x0 + reserved3: 0x0 + content: C0035FD6FF4300D100008052FF0F00B9FF430091C0035FD6 + - sectname: __unwind_info + segname: __TEXT + addr: 0x100003FB0 + size: 80 + offset: 0x3FB0 + align: 2 + reloff: 0x0 + nreloc: 0 + flags: 0x0 + reserved1: 0x0 + reserved2: 0x0 + reserved3: 0x0 + content: 010000001C000000000000001C000000000000001C00000002000000983F00003400000034000000B13F00000000000034000000030000000C0002001400020000000001040000000010000200000002 + - cmd: LC_SEGMENT_64 + cmdsize: 72 + segname: __LINKEDIT + vmaddr: 4294983680 + vmsize: 16384 + fileoff: 16384 + filesize: 753 + 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: 56 + - cmd: LC_SYMTAB + cmdsize: 24 + symoff: 16504 + nsyms: 15 + stroff: 16744 + strsize: 120 + - cmd: LC_DYSYMTAB + cmdsize: 80 + ilocalsym: 0 + nlocalsym: 12 + iextdefsym: 12 + nextdefsym: 3 + iundefsym: 15 + 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: F445529E-643C-3A38-8F59-AB64566BCAFF + - cmd: LC_BUILD_VERSION + cmdsize: 32 + platform: 1 + minos: 786432 + sdk: 786432 + ntools: 1 + Tools: + - tool: 3 + version: 46596096 + - cmd: LC_SOURCE_VERSION + cmdsize: 16 + version: 0 + - cmd: LC_MAIN + cmdsize: 24 + entryoff: 16284 + stacksize: 0 + - cmd: LC_LOAD_DYLIB + cmdsize: 56 + dylib: + name: 24 + timestamp: 2 + current_version: 85917696 + compatibility_version: 65536 + Content: '/usr/lib/libSystem.B.dylib' + ZeroPadBytes: 6 + - cmd: LC_FUNCTION_STARTS + cmdsize: 16 + dataoff: 16496 + datasize: 8 + - cmd: LC_DATA_IN_CODE + cmdsize: 16 + dataoff: 16504 + datasize: 0 + - cmd: LC_CODE_SIGNATURE + cmdsize: 16 + dataoff: 16864 + datasize: 273 +LinkEditData: + NameList: + - n_strx: 33 + n_type: 0x64 + n_sect: 0 + n_desc: 0 + n_value: 0 + - n_strx: 39 + n_type: 0x64 + n_sect: 0 + n_desc: 0 + n_value: 0 + - n_strx: 46 + n_type: 0x66 + n_sect: 0 + n_desc: 1 + n_value: 1636754403 + - n_strx: 1 + n_type: 0x2E + n_sect: 1 + n_desc: 0 + n_value: 4294983576 + - n_strx: 109 + n_type: 0x24 + n_sect: 1 + n_desc: 0 + n_value: 4294983576 + - n_strx: 1 + n_type: 0x24 + n_sect: 0 + n_desc: 0 + n_value: 4 + - n_strx: 1 + n_type: 0x4E + n_sect: 1 + n_desc: 0 + n_value: 4 + - n_strx: 1 + n_type: 0x2E + n_sect: 1 + n_desc: 0 + n_value: 4294983580 + - n_strx: 114 + n_type: 0x24 + n_sect: 1 + n_desc: 0 + n_value: 4294983580 + - n_strx: 1 + n_type: 0x24 + n_sect: 0 + n_desc: 0 + n_value: 20 + - n_strx: 1 + n_type: 0x4E + n_sect: 1 + n_desc: 0 + n_value: 20 + - n_strx: 1 + n_type: 0x64 + n_sect: 1 + n_desc: 0 + n_value: 0 + - 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: 4294983576 + - n_strx: 27 + n_type: 0xF + n_sect: 1 + n_desc: 0 + n_value: 4294983580 + StringTable: + - ' ' + - __mh_execute_header + - _foo + - _main + - '/tmp/' + - main.c + - '/var/folders/gj/wf3swl0x215b2sq1qy84kzkm0000gn/T/main-e32fe7.o' + - _foo + - _main +... diff --git a/llvm/test/tools/llvm-objcopy/MachO/strip-all.test b/llvm/test/tools/llvm-objcopy/MachO/strip-all.test --- a/llvm/test/tools/llvm-objcopy/MachO/strip-all.test +++ b/llvm/test/tools/llvm-objcopy/MachO/strip-all.test @@ -2,6 +2,7 @@ # RUN: yaml2obj %p/Inputs/strip-all.yaml -o %t.exec # RUN: yaml2obj %p/Inputs/strip-all-with-dwarf.yaml -o %t.dwarf +# RUN: yaml2obj %p/Inputs/strip-chained-fixups.yaml -o %t.fixups ## Check that the symbol list satisfies the order: local / defined external / ## undefined external, otherwise llvm-objcopy will fail. @@ -15,6 +16,10 @@ # RUN: llvm-readobj --sections --relocations --symbols %t.dwarf.stripped \ # RUN: | FileCheck --check-prefixes=COMMON,DWARF %s +# RUN: llvm-objcopy --strip-all %t.fixups %t.fixups.stripped +# RUN: llvm-readobj --sections --relocations --symbols %t.fixups.stripped \ +# RUN: | FileCheck --check-prefix=COMMON %s + ## The output of "llvm-strip" should be identical with that of ## "llvm-strip --strip-all" and "llvm-objcopy --strip-all". # RUN: llvm-strip %t.exec -o %t2 @@ -32,6 +37,11 @@ # RUN: llvm-lipo %t.dwarf.universal.stripped -thin x86_64 -output %t6 # RUN: cmp %t6 %t.dwarf.stripped +# RUN: llvm-strip %t.exec -o %t7 +# RUN: llvm-strip --strip-all %t.exec -o %t8 +# cmp %t7 %t.fixups.stripped +# cmp %t8 %t.fixups.stripped + ## Make sure that debug sections are removed. # DWARF: Sections [ # DWARF-NOT: Name: __debug_str diff --git a/llvm/tools/llvm-objcopy/MachO/MachOLayoutBuilder.cpp b/llvm/tools/llvm-objcopy/MachO/MachOLayoutBuilder.cpp --- a/llvm/tools/llvm-objcopy/MachO/MachOLayoutBuilder.cpp +++ b/llvm/tools/llvm-objcopy/MachO/MachOLayoutBuilder.cpp @@ -249,8 +249,12 @@ uint64_t StartOfExportTrie = StartOfLazyBindingInfo + O.LazyBinds.Opcodes.size(); uint64_t StartOfFunctionStarts = StartOfExportTrie + O.Exports.Trie.size(); - uint64_t StartOfDataInCode = + uint64_t StartOfDyldExportsTrie = StartOfFunctionStarts + O.FunctionStarts.Data.size(); + uint64_t StartOfChainedFixups = + StartOfDyldExportsTrie + O.ExportsTrie.Data.size(); + uint64_t StartOfDataInCode = + StartOfChainedFixups + O.ChainedFixups.Data.size(); uint64_t StartOfLinkerOptimizationHint = StartOfDataInCode + O.DataInCode.Data.size(); uint64_t StartOfSymbols = @@ -353,6 +357,14 @@ MLC.linkedit_data_command_data.dataoff = StartOfFunctionStarts; MLC.linkedit_data_command_data.datasize = O.FunctionStarts.Data.size(); break; + case MachO::LC_DYLD_CHAINED_FIXUPS: + MLC.linkedit_data_command_data.dataoff = StartOfChainedFixups; + MLC.linkedit_data_command_data.datasize = O.ChainedFixups.Data.size(); + break; + case MachO::LC_DYLD_EXPORTS_TRIE: + MLC.linkedit_data_command_data.dataoff = StartOfDyldExportsTrie; + MLC.linkedit_data_command_data.datasize = O.ExportsTrie.Data.size(); + break; case MachO::LC_DYLD_INFO: case MachO::LC_DYLD_INFO_ONLY: MLC.dyld_info_command_data.rebase_off = diff --git a/llvm/tools/llvm-objcopy/MachO/MachOReader.h b/llvm/tools/llvm-objcopy/MachO/MachOReader.h --- a/llvm/tools/llvm-objcopy/MachO/MachOReader.h +++ b/llvm/tools/llvm-objcopy/MachO/MachOReader.h @@ -41,6 +41,8 @@ void readDataInCodeData(Object &O) const; void readLinkerOptimizationHint(Object &O) const; void readFunctionStartsData(Object &O) const; + void readExportsTrie(Object &O) const; + void readChainedFixups(Object &O) const; void readIndirectSymbolTable(Object &O) const; void readSwiftVersion(Object &O) const; diff --git a/llvm/tools/llvm-objcopy/MachO/MachOReader.cpp b/llvm/tools/llvm-objcopy/MachO/MachOReader.cpp --- a/llvm/tools/llvm-objcopy/MachO/MachOReader.cpp +++ b/llvm/tools/llvm-objcopy/MachO/MachOReader.cpp @@ -174,6 +174,12 @@ case MachO::LC_FUNCTION_STARTS: O.FunctionStartsCommandIndex = O.LoadCommands.size(); break; + case MachO::LC_DYLD_EXPORTS_TRIE: + O.ExportsTrieCommandIndex = O.LoadCommands.size(); + break; + case MachO::LC_DYLD_CHAINED_FIXUPS: + O.ChainedFixupsCommandIndex = O.LoadCommands.size(); + break; } #define HANDLE_LOAD_COMMAND(LCName, LCValue, LCStruct) \ case MachO::LCName: \ @@ -301,6 +307,14 @@ return readLinkData(O, O.FunctionStartsCommandIndex, O.FunctionStarts); } +void MachOReader::readExportsTrie(Object &O) const { + return readLinkData(O, O.ExportsTrieCommandIndex, O.ExportsTrie); +} + +void MachOReader::readChainedFixups(Object &O) const { + return readLinkData(O, O.ChainedFixupsCommandIndex, O.ChainedFixups); +} + void MachOReader::readIndirectSymbolTable(Object &O) const { MachO::dysymtab_command DySymTab = MachOObj.getDysymtabLoadCommand(); constexpr uint32_t AbsOrLocalMask = @@ -352,6 +366,8 @@ readDataInCodeData(*Obj); readLinkerOptimizationHint(*Obj); readFunctionStartsData(*Obj); + readExportsTrie(*Obj); + readChainedFixups(*Obj); readIndirectSymbolTable(*Obj); readSwiftVersion(*Obj); return std::move(Obj); diff --git a/llvm/tools/llvm-objcopy/MachO/MachOWriter.h b/llvm/tools/llvm-objcopy/MachO/MachOWriter.h --- a/llvm/tools/llvm-objcopy/MachO/MachOWriter.h +++ b/llvm/tools/llvm-objcopy/MachO/MachOWriter.h @@ -50,6 +50,8 @@ void writeDataInCodeData(); void writeLinkerOptimizationHint(); void writeFunctionStartsData(); + void writeChainedFixupsData(); + void writeExportsTrieData(); void writeTail(); public: diff --git a/llvm/tools/llvm-objcopy/MachO/MachOWriter.cpp b/llvm/tools/llvm-objcopy/MachO/MachOWriter.cpp --- a/llvm/tools/llvm-objcopy/MachO/MachOWriter.cpp +++ b/llvm/tools/llvm-objcopy/MachO/MachOWriter.cpp @@ -133,6 +133,26 @@ LinkEditDataCommand.datasize); } + if (O.ChainedFixupsCommandIndex) { + const MachO::linkedit_data_command &LinkEditDataCommand = + O.LoadCommands[*O.ChainedFixupsCommandIndex] + .MachOLoadCommand.linkedit_data_command_data; + + if (LinkEditDataCommand.dataoff) + Ends.push_back(LinkEditDataCommand.dataoff + + LinkEditDataCommand.datasize); + } + + if (O.ExportsTrieCommandIndex) { + const MachO::linkedit_data_command &LinkEditDataCommand = + O.LoadCommands[*O.ExportsTrieCommandIndex] + .MachOLoadCommand.linkedit_data_command_data; + + if (LinkEditDataCommand.dataoff) + Ends.push_back(LinkEditDataCommand.dataoff + + LinkEditDataCommand.datasize); + } + // Otherwise, use the last section / reloction. for (const LoadCommand &LC : O.LoadCommands) for (const std::unique_ptr
&S : LC.Sections) { @@ -585,6 +605,14 @@ return writeLinkData(O.FunctionStartsCommandIndex, O.FunctionStarts); } +void MachOWriter::writeChainedFixupsData() { + return writeLinkData(O.ChainedFixupsCommandIndex, O.ChainedFixups); +} + +void MachOWriter::writeExportsTrieData() { + return writeLinkData(O.ExportsTrieCommandIndex, O.ExportsTrie); +} + void MachOWriter::writeTail() { typedef void (MachOWriter::*WriteHandlerType)(void); typedef std::pair WriteOperation; @@ -670,6 +698,26 @@ &MachOWriter::writeFunctionStartsData); } + if (O.ChainedFixupsCommandIndex) { + const MachO::linkedit_data_command &LinkEditDataCommand = + O.LoadCommands[*O.ChainedFixupsCommandIndex] + .MachOLoadCommand.linkedit_data_command_data; + + if (LinkEditDataCommand.dataoff) + Queue.emplace_back(LinkEditDataCommand.dataoff, + &MachOWriter::writeChainedFixupsData); + } + + if (O.ExportsTrieCommandIndex) { + const MachO::linkedit_data_command &LinkEditDataCommand = + O.LoadCommands[*O.ExportsTrieCommandIndex] + .MachOLoadCommand.linkedit_data_command_data; + + if (LinkEditDataCommand.dataoff) + Queue.emplace_back(LinkEditDataCommand.dataoff, + &MachOWriter::writeExportsTrieData); + } + llvm::sort(Queue, [](const WriteOperation &LHS, const WriteOperation &RHS) { return LHS.first < RHS.first; }); diff --git a/llvm/tools/llvm-objcopy/MachO/Object.h b/llvm/tools/llvm-objcopy/MachO/Object.h --- a/llvm/tools/llvm-objcopy/MachO/Object.h +++ b/llvm/tools/llvm-objcopy/MachO/Object.h @@ -315,6 +315,8 @@ LinkData DataInCode; LinkData LinkerOptimizationHint; LinkData FunctionStarts; + LinkData ExportsTrie; + LinkData ChainedFixups; Optional SwiftVersion; @@ -332,6 +334,10 @@ Optional LinkerOptimizationHintCommandIndex; /// The index LC_FUNCTION_STARTS load comamnd if present. Optional FunctionStartsCommandIndex; + /// The index LC_DYLD_CHAINED_FIXUPS load comamnd if present. + Optional ChainedFixupsCommandIndex; + /// The index LC_DYLD_EXPORTS_TRIE load comamnd if present. + Optional ExportsTrieCommandIndex; /// The index of the LC_SEGMENT or LC_SEGMENT_64 load command /// corresponding to the __TEXT segment. Optional TextSegmentCommandIndex; diff --git a/llvm/tools/llvm-objcopy/MachO/Object.cpp b/llvm/tools/llvm-objcopy/MachO/Object.cpp --- a/llvm/tools/llvm-objcopy/MachO/Object.cpp +++ b/llvm/tools/llvm-objcopy/MachO/Object.cpp @@ -66,6 +66,12 @@ case MachO::LC_FUNCTION_STARTS: FunctionStartsCommandIndex = Index; break; + case MachO::LC_DYLD_CHAINED_FIXUPS: + ChainedFixupsCommandIndex = Index; + break; + case MachO::LC_DYLD_EXPORTS_TRIE: + ExportsTrieCommandIndex = Index; + break; } } }