mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2024-10-18 10:32:48 +02:00
[llvm-objcopy][MachO] Support LC_LINKER_OPTIMIZATION_HINT load command
The load command is currently specific to arm64 and holds information for instruction rewriting, e.g. converting a GOT load to an ADR to compute a local address. (On ELF the information is usually conveyed by relocations, e.g. R_X86_64_REX_GOTPCRELX, R_PPC64_TOC16_HA) Reviewed By: alexander-shaposhnikov Differential Revision: https://reviews.llvm.org/D104968
This commit is contained in:
parent
6a9d0ef2f8
commit
37f389b2f8
25
test/tools/llvm-objcopy/MachO/lc-linker-optimization-hint.s
Normal file
25
test/tools/llvm-objcopy/MachO/lc-linker-optimization-hint.s
Normal file
@ -0,0 +1,25 @@
|
||||
# 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
|
@ -251,7 +251,10 @@ Error MachOLayoutBuilder::layoutTail(uint64_t Offset) {
|
||||
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 =
|
||||
@ -320,6 +323,11 @@ Error MachOLayoutBuilder::layoutTail(uint64_t Offset) {
|
||||
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();
|
||||
@ -355,7 +363,6 @@ Error MachOLayoutBuilder::layoutTail(uint64_t Offset) {
|
||||
// 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:
|
||||
|
@ -151,6 +151,9 @@ Error MachOReader::readLoadCommands(Object &O) const {
|
||||
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;
|
||||
@ -276,6 +279,11 @@ void MachOReader::readDataInCodeData(Object &O) const {
|
||||
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);
|
||||
}
|
||||
@ -330,6 +338,7 @@ Expected<std::unique_ptr<Object>> MachOReader::create() const {
|
||||
readExportInfo(*Obj);
|
||||
readCodeSignature(*Obj);
|
||||
readDataInCodeData(*Obj);
|
||||
readLinkerOptimizationHint(*Obj);
|
||||
readFunctionStartsData(*Obj);
|
||||
readIndirectSymbolTable(*Obj);
|
||||
readSwiftVersion(*Obj);
|
||||
|
@ -39,6 +39,7 @@ class MachOReader : public Reader {
|
||||
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;
|
||||
|
@ -107,6 +107,16 @@ size_t MachOWriter::totalSize() 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]
|
||||
@ -421,6 +431,11 @@ void MachOWriter::writeDataInCodeData() {
|
||||
return writeLinkData(O.DataInCodeCommandIndex, O.DataInCode);
|
||||
}
|
||||
|
||||
void MachOWriter::writeLinkerOptimizationHint() {
|
||||
return writeLinkData(O.LinkerOptimizationHintCommandIndex,
|
||||
O.LinkerOptimizationHint);
|
||||
}
|
||||
|
||||
void MachOWriter::writeFunctionStartsData() {
|
||||
return writeLinkData(O.FunctionStartsCommandIndex, O.FunctionStarts);
|
||||
}
|
||||
@ -490,6 +505,16 @@ void MachOWriter::writeTail() {
|
||||
&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]
|
||||
|
@ -48,6 +48,7 @@ class MachOWriter {
|
||||
void writeLinkData(Optional<size_t> LCIndex, const LinkData &LD);
|
||||
void writeCodeSignatureData();
|
||||
void writeDataInCodeData();
|
||||
void writeLinkerOptimizationHint();
|
||||
void writeFunctionStartsData();
|
||||
void writeTail();
|
||||
|
||||
|
@ -46,6 +46,9 @@ void Object::updateLoadCommandIndexes() {
|
||||
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;
|
||||
|
@ -313,6 +313,7 @@ struct Object {
|
||||
ExportInfo Exports;
|
||||
IndirectSymbolTable IndirectSymTable;
|
||||
LinkData DataInCode;
|
||||
LinkData LinkerOptimizationHint;
|
||||
LinkData FunctionStarts;
|
||||
LinkData CodeSignature;
|
||||
|
||||
@ -328,6 +329,8 @@ struct Object {
|
||||
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;
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user