Skip to content

Commit 814dffa

Browse files
committed
[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
1 parent 43f6dad commit 814dffa

File tree

8 files changed

+76
-2
lines changed

8 files changed

+76
-2
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
# REQUIRES: aarch64-registered-target
2+
## Test that we can copy LC_LINKER_OPTIMIZATION_HINT.
3+
4+
# RUN: llvm-mc -filetype=obj -triple=arm64-apple-darwin %s -o %t.o
5+
# RUN: llvm-objdump --macho --link-opt-hints - < %t.o > %tloh.txt
6+
# RUN: FileCheck --input-file=%tloh.txt %s
7+
8+
# CHECK: Linker optimiztion hints (8 total bytes)
9+
# CHECK-NEXT: identifier 7 AdrpAdd
10+
11+
# RUN: llvm-objcopy %t.o %t.copy.o
12+
# RUN: llvm-objdump --macho --link-opt-hints - < %t.copy.o | diff %tloh.txt -
13+
14+
.text
15+
.align 2
16+
_test:
17+
L1:
18+
adrp x0, _foo@PAGE
19+
L2:
20+
add x0, x0, _foo@PAGEOFF
21+
.loh AdrpAdd L1, L2
22+
23+
.data
24+
_foo:
25+
.long 0

llvm/tools/llvm-objcopy/MachO/MachOLayoutBuilder.cpp

+9-2
Original file line numberDiff line numberDiff line change
@@ -251,7 +251,10 @@ Error MachOLayoutBuilder::layoutTail(uint64_t Offset) {
251251
uint64_t StartOfFunctionStarts = StartOfExportTrie + O.Exports.Trie.size();
252252
uint64_t StartOfDataInCode =
253253
StartOfFunctionStarts + O.FunctionStarts.Data.size();
254-
uint64_t StartOfSymbols = StartOfDataInCode + O.DataInCode.Data.size();
254+
uint64_t StartOfLinkerOptimizationHint =
255+
StartOfDataInCode + O.DataInCode.Data.size();
256+
uint64_t StartOfSymbols =
257+
StartOfLinkerOptimizationHint + O.LinkerOptimizationHint.Data.size();
255258
uint64_t StartOfIndirectSymbols =
256259
StartOfSymbols + NListSize * O.SymTable.Symbols.size();
257260
uint64_t StartOfSymbolStrings =
@@ -320,6 +323,11 @@ Error MachOLayoutBuilder::layoutTail(uint64_t Offset) {
320323
MLC.linkedit_data_command_data.dataoff = StartOfDataInCode;
321324
MLC.linkedit_data_command_data.datasize = O.DataInCode.Data.size();
322325
break;
326+
case MachO::LC_LINKER_OPTIMIZATION_HINT:
327+
MLC.linkedit_data_command_data.dataoff = StartOfLinkerOptimizationHint;
328+
MLC.linkedit_data_command_data.datasize =
329+
O.LinkerOptimizationHint.Data.size();
330+
break;
323331
case MachO::LC_FUNCTION_STARTS:
324332
MLC.linkedit_data_command_data.dataoff = StartOfFunctionStarts;
325333
MLC.linkedit_data_command_data.datasize = O.FunctionStarts.Data.size();
@@ -355,7 +363,6 @@ Error MachOLayoutBuilder::layoutTail(uint64_t Offset) {
355363
// LC_ENCRYPT_INFO/LC_ENCRYPTION_INFO_64 need to be adjusted.
356364
case MachO::LC_ENCRYPTION_INFO:
357365
case MachO::LC_ENCRYPTION_INFO_64:
358-
case MachO::LC_LINKER_OPTIMIZATION_HINT:
359366
case MachO::LC_LOAD_DYLINKER:
360367
case MachO::LC_MAIN:
361368
case MachO::LC_RPATH:

llvm/tools/llvm-objcopy/MachO/MachOReader.cpp

+9
Original file line numberDiff line numberDiff line change
@@ -151,6 +151,9 @@ Error MachOReader::readLoadCommands(Object &O) const {
151151
case MachO::LC_DATA_IN_CODE:
152152
O.DataInCodeCommandIndex = O.LoadCommands.size();
153153
break;
154+
case MachO::LC_LINKER_OPTIMIZATION_HINT:
155+
O.LinkerOptimizationHintCommandIndex = O.LoadCommands.size();
156+
break;
154157
case MachO::LC_FUNCTION_STARTS:
155158
O.FunctionStartsCommandIndex = O.LoadCommands.size();
156159
break;
@@ -276,6 +279,11 @@ void MachOReader::readDataInCodeData(Object &O) const {
276279
return readLinkData(O, O.DataInCodeCommandIndex, O.DataInCode);
277280
}
278281

282+
void MachOReader::readLinkerOptimizationHint(Object &O) const {
283+
return readLinkData(O, O.LinkerOptimizationHintCommandIndex,
284+
O.LinkerOptimizationHint);
285+
}
286+
279287
void MachOReader::readFunctionStartsData(Object &O) const {
280288
return readLinkData(O, O.FunctionStartsCommandIndex, O.FunctionStarts);
281289
}
@@ -330,6 +338,7 @@ Expected<std::unique_ptr<Object>> MachOReader::create() const {
330338
readExportInfo(*Obj);
331339
readCodeSignature(*Obj);
332340
readDataInCodeData(*Obj);
341+
readLinkerOptimizationHint(*Obj);
333342
readFunctionStartsData(*Obj);
334343
readIndirectSymbolTable(*Obj);
335344
readSwiftVersion(*Obj);

llvm/tools/llvm-objcopy/MachO/MachOReader.h

+1
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@ class MachOReader : public Reader {
3939
void readLinkData(Object &O, Optional<size_t> LCIndex, LinkData &LD) const;
4040
void readCodeSignature(Object &O) const;
4141
void readDataInCodeData(Object &O) const;
42+
void readLinkerOptimizationHint(Object &O) const;
4243
void readFunctionStartsData(Object &O) const;
4344
void readIndirectSymbolTable(Object &O) const;
4445
void readSwiftVersion(Object &O) const;

llvm/tools/llvm-objcopy/MachO/MachOWriter.cpp

+25
Original file line numberDiff line numberDiff line change
@@ -107,6 +107,16 @@ size_t MachOWriter::totalSize() const {
107107
LinkEditDataCommand.datasize);
108108
}
109109

110+
if (O.LinkerOptimizationHintCommandIndex) {
111+
const MachO::linkedit_data_command &LinkEditDataCommand =
112+
O.LoadCommands[*O.LinkerOptimizationHintCommandIndex]
113+
.MachOLoadCommand.linkedit_data_command_data;
114+
115+
if (LinkEditDataCommand.dataoff)
116+
Ends.push_back(LinkEditDataCommand.dataoff +
117+
LinkEditDataCommand.datasize);
118+
}
119+
110120
if (O.FunctionStartsCommandIndex) {
111121
const MachO::linkedit_data_command &LinkEditDataCommand =
112122
O.LoadCommands[*O.FunctionStartsCommandIndex]
@@ -421,6 +431,11 @@ void MachOWriter::writeDataInCodeData() {
421431
return writeLinkData(O.DataInCodeCommandIndex, O.DataInCode);
422432
}
423433

434+
void MachOWriter::writeLinkerOptimizationHint() {
435+
return writeLinkData(O.LinkerOptimizationHintCommandIndex,
436+
O.LinkerOptimizationHint);
437+
}
438+
424439
void MachOWriter::writeFunctionStartsData() {
425440
return writeLinkData(O.FunctionStartsCommandIndex, O.FunctionStarts);
426441
}
@@ -490,6 +505,16 @@ void MachOWriter::writeTail() {
490505
&MachOWriter::writeDataInCodeData);
491506
}
492507

508+
if (O.LinkerOptimizationHintCommandIndex) {
509+
const MachO::linkedit_data_command &LinkEditDataCommand =
510+
O.LoadCommands[*O.LinkerOptimizationHintCommandIndex]
511+
.MachOLoadCommand.linkedit_data_command_data;
512+
513+
if (LinkEditDataCommand.dataoff)
514+
Queue.emplace_back(LinkEditDataCommand.dataoff,
515+
&MachOWriter::writeLinkerOptimizationHint);
516+
}
517+
493518
if (O.FunctionStartsCommandIndex) {
494519
const MachO::linkedit_data_command &LinkEditDataCommand =
495520
O.LoadCommands[*O.FunctionStartsCommandIndex]

llvm/tools/llvm-objcopy/MachO/MachOWriter.h

+1
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,7 @@ class MachOWriter {
4848
void writeLinkData(Optional<size_t> LCIndex, const LinkData &LD);
4949
void writeCodeSignatureData();
5050
void writeDataInCodeData();
51+
void writeLinkerOptimizationHint();
5152
void writeFunctionStartsData();
5253
void writeTail();
5354

llvm/tools/llvm-objcopy/MachO/Object.cpp

+3
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,9 @@ void Object::updateLoadCommandIndexes() {
4646
case MachO::LC_DATA_IN_CODE:
4747
DataInCodeCommandIndex = Index;
4848
break;
49+
case MachO::LC_LINKER_OPTIMIZATION_HINT:
50+
LinkerOptimizationHintCommandIndex = Index;
51+
break;
4952
case MachO::LC_FUNCTION_STARTS:
5053
FunctionStartsCommandIndex = Index;
5154
break;

llvm/tools/llvm-objcopy/MachO/Object.h

+3
Original file line numberDiff line numberDiff line change
@@ -313,6 +313,7 @@ struct Object {
313313
ExportInfo Exports;
314314
IndirectSymbolTable IndirectSymTable;
315315
LinkData DataInCode;
316+
LinkData LinkerOptimizationHint;
316317
LinkData FunctionStarts;
317318
LinkData CodeSignature;
318319

@@ -328,6 +329,8 @@ struct Object {
328329
Optional<size_t> DySymTabCommandIndex;
329330
/// The index LC_DATA_IN_CODE load comamnd if present.
330331
Optional<size_t> DataInCodeCommandIndex;
332+
/// The index of LC_LINKER_OPTIMIZATIN_HINT load comamnd if present.
333+
Optional<size_t> LinkerOptimizationHintCommandIndex;
331334
/// The index LC_FUNCTION_STARTS load comamnd if present.
332335
Optional<size_t> FunctionStartsCommandIndex;
333336

0 commit comments

Comments
 (0)