--- /dev/null
+# REQUIRES: aarch64-registered-target
+## Test that we can copy LC_LINKER_OPTIMIZATION_HINT.
+
+# RUN: llvm-mc -filetype=obj -triple=arm64-apple-darwin %s -o %t.o
+# RUN: llvm-objdump --macho --link-opt-hints - < %t.o > %tloh.txt
+# RUN: FileCheck --input-file=%tloh.txt %s
+
+# CHECK: Linker optimiztion hints (8 total bytes)
+# CHECK-NEXT: identifier 7 AdrpAdd
+
+# RUN: llvm-objcopy %t.o %t.copy.o
+# RUN: llvm-objdump --macho --link-opt-hints - < %t.copy.o | diff %tloh.txt -
+
+.text
+.align 2
+_test:
+L1:
+ adrp x0, _foo@PAGE
+L2:
+ add x0, x0, _foo@PAGEOFF
+.loh AdrpAdd L1, L2
+
+.data
+_foo:
+ .long 0
uint64_t StartOfFunctionStarts = StartOfExportTrie + O.Exports.Trie.size();
uint64_t StartOfDataInCode =
StartOfFunctionStarts + O.FunctionStarts.Data.size();
- uint64_t StartOfSymbols = StartOfDataInCode + O.DataInCode.Data.size();
+ uint64_t StartOfLinkerOptimizationHint =
+ StartOfDataInCode + O.DataInCode.Data.size();
+ uint64_t StartOfSymbols =
+ StartOfLinkerOptimizationHint + O.LinkerOptimizationHint.Data.size();
uint64_t StartOfIndirectSymbols =
StartOfSymbols + NListSize * O.SymTable.Symbols.size();
uint64_t StartOfSymbolStrings =
MLC.linkedit_data_command_data.dataoff = StartOfDataInCode;
MLC.linkedit_data_command_data.datasize = O.DataInCode.Data.size();
break;
+ case MachO::LC_LINKER_OPTIMIZATION_HINT:
+ MLC.linkedit_data_command_data.dataoff = StartOfLinkerOptimizationHint;
+ MLC.linkedit_data_command_data.datasize =
+ O.LinkerOptimizationHint.Data.size();
+ break;
case MachO::LC_FUNCTION_STARTS:
MLC.linkedit_data_command_data.dataoff = StartOfFunctionStarts;
MLC.linkedit_data_command_data.datasize = O.FunctionStarts.Data.size();
// LC_ENCRYPT_INFO/LC_ENCRYPTION_INFO_64 need to be adjusted.
case MachO::LC_ENCRYPTION_INFO:
case MachO::LC_ENCRYPTION_INFO_64:
- case MachO::LC_LINKER_OPTIMIZATION_HINT:
case MachO::LC_LOAD_DYLINKER:
case MachO::LC_MAIN:
case MachO::LC_RPATH:
case MachO::LC_DATA_IN_CODE:
O.DataInCodeCommandIndex = O.LoadCommands.size();
break;
+ case MachO::LC_LINKER_OPTIMIZATION_HINT:
+ O.LinkerOptimizationHintCommandIndex = O.LoadCommands.size();
+ break;
case MachO::LC_FUNCTION_STARTS:
O.FunctionStartsCommandIndex = O.LoadCommands.size();
break;
return readLinkData(O, O.DataInCodeCommandIndex, O.DataInCode);
}
+void MachOReader::readLinkerOptimizationHint(Object &O) const {
+ return readLinkData(O, O.LinkerOptimizationHintCommandIndex,
+ O.LinkerOptimizationHint);
+}
+
void MachOReader::readFunctionStartsData(Object &O) const {
return readLinkData(O, O.FunctionStartsCommandIndex, O.FunctionStarts);
}
readExportInfo(*Obj);
readCodeSignature(*Obj);
readDataInCodeData(*Obj);
+ readLinkerOptimizationHint(*Obj);
readFunctionStartsData(*Obj);
readIndirectSymbolTable(*Obj);
readSwiftVersion(*Obj);
void readLinkData(Object &O, Optional<size_t> LCIndex, LinkData &LD) const;
void readCodeSignature(Object &O) const;
void readDataInCodeData(Object &O) const;
+ void readLinkerOptimizationHint(Object &O) const;
void readFunctionStartsData(Object &O) const;
void readIndirectSymbolTable(Object &O) const;
void readSwiftVersion(Object &O) const;
LinkEditDataCommand.datasize);
}
+ if (O.LinkerOptimizationHintCommandIndex) {
+ const MachO::linkedit_data_command &LinkEditDataCommand =
+ O.LoadCommands[*O.LinkerOptimizationHintCommandIndex]
+ .MachOLoadCommand.linkedit_data_command_data;
+
+ if (LinkEditDataCommand.dataoff)
+ Ends.push_back(LinkEditDataCommand.dataoff +
+ LinkEditDataCommand.datasize);
+ }
+
if (O.FunctionStartsCommandIndex) {
const MachO::linkedit_data_command &LinkEditDataCommand =
O.LoadCommands[*O.FunctionStartsCommandIndex]
return writeLinkData(O.DataInCodeCommandIndex, O.DataInCode);
}
+void MachOWriter::writeLinkerOptimizationHint() {
+ return writeLinkData(O.LinkerOptimizationHintCommandIndex,
+ O.LinkerOptimizationHint);
+}
+
void MachOWriter::writeFunctionStartsData() {
return writeLinkData(O.FunctionStartsCommandIndex, O.FunctionStarts);
}
&MachOWriter::writeDataInCodeData);
}
+ if (O.LinkerOptimizationHintCommandIndex) {
+ const MachO::linkedit_data_command &LinkEditDataCommand =
+ O.LoadCommands[*O.LinkerOptimizationHintCommandIndex]
+ .MachOLoadCommand.linkedit_data_command_data;
+
+ if (LinkEditDataCommand.dataoff)
+ Queue.emplace_back(LinkEditDataCommand.dataoff,
+ &MachOWriter::writeLinkerOptimizationHint);
+ }
+
if (O.FunctionStartsCommandIndex) {
const MachO::linkedit_data_command &LinkEditDataCommand =
O.LoadCommands[*O.FunctionStartsCommandIndex]
void writeLinkData(Optional<size_t> LCIndex, const LinkData &LD);
void writeCodeSignatureData();
void writeDataInCodeData();
+ void writeLinkerOptimizationHint();
void writeFunctionStartsData();
void writeTail();
case MachO::LC_DATA_IN_CODE:
DataInCodeCommandIndex = Index;
break;
+ case MachO::LC_LINKER_OPTIMIZATION_HINT:
+ LinkerOptimizationHintCommandIndex = Index;
+ break;
case MachO::LC_FUNCTION_STARTS:
FunctionStartsCommandIndex = Index;
break;
ExportInfo Exports;
IndirectSymbolTable IndirectSymTable;
LinkData DataInCode;
+ LinkData LinkerOptimizationHint;
LinkData FunctionStarts;
LinkData CodeSignature;
Optional<size_t> DySymTabCommandIndex;
/// The index LC_DATA_IN_CODE load comamnd if present.
Optional<size_t> DataInCodeCommandIndex;
+ /// The index of LC_LINKER_OPTIMIZATIN_HINT load comamnd if present.
+ Optional<size_t> LinkerOptimizationHintCommandIndex;
/// The index LC_FUNCTION_STARTS load comamnd if present.
Optional<size_t> FunctionStartsCommandIndex;