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 StartOfExportTrie2 = StartOfFunctionStarts + O.FunctionStarts.Data.size(); + uint64_t StartOfChainedFixups = + StartOfExportTrie2 + 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 = StartOfExportTrie2; + 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; } } }