MachO: Add linker-optimisation hint framework to MC.
Another part of the ARM64 backend (so tests will be following soon).
This is currently used by the linker to relax adrp/ldr pairs into nops
where possible, though could well be more broadly applicable.
llvm-svn: 205084
diff --git a/llvm/lib/MC/MachObjectWriter.cpp b/llvm/lib/MC/MachObjectWriter.cpp
index bbe589f..5fcea5f 100644
--- a/llvm/lib/MC/MachObjectWriter.cpp
+++ b/llvm/lib/MC/MachObjectWriter.cpp
@@ -761,6 +761,14 @@
LoadCommandsSize += sizeof(MachO::linkedit_data_command);
}
+ // Add the loh load command size, if used.
+ uint64_t LOHRawSize = Asm.getLOHContainer().getEmitSize(*this, Layout);
+ uint64_t LOHSize = RoundUpToAlignment(LOHRawSize, is64Bit() ? 8 : 4);
+ if (LOHSize) {
+ ++NumLoadCommands;
+ LoadCommandsSize += sizeof(MachO::linkedit_data_command);
+ }
+
// Add the symbol table load command sizes, if used.
unsigned NumSymbols = LocalSymbolData.size() + ExternalSymbolData.size() +
UndefinedSymbolData.size();
@@ -849,6 +857,12 @@
DataRegionsSize);
}
+ // Write the loh load command, if used.
+ uint64_t LOHTableEnd = DataInCodeTableEnd + LOHSize;
+ if (LOHSize)
+ WriteLinkeditLoadCommand(MachO::LC_LINKER_OPTIMIZATION_HINT,
+ DataInCodeTableEnd, LOHSize);
+
// Write the symbol table load command, if used.
if (NumSymbols) {
unsigned FirstLocalSymbol = 0;
@@ -865,10 +879,10 @@
// If used, the indirect symbols are written after the section data.
if (NumIndirectSymbols)
- IndirectSymbolOffset = DataInCodeTableEnd;
+ IndirectSymbolOffset = LOHTableEnd;
// The symbol table is written after the indirect symbol data.
- uint64_t SymbolTableOffset = DataInCodeTableEnd + IndirectSymbolSize;
+ uint64_t SymbolTableOffset = LOHTableEnd + IndirectSymbolSize;
// The string table is written after symbol table.
uint64_t StringTableOffset =
@@ -935,6 +949,17 @@
Write16(Data->Kind);
}
+ // Write out the loh commands, if there is one.
+ if (LOHSize) {
+#ifndef NDEBUG
+ unsigned Start = OS.tell();
+#endif
+ Asm.getLOHContainer().Emit(*this, Layout);
+ // Pad to a multiple of the pointer size.
+ WriteBytes("", OffsetToAlignment(LOHRawSize, is64Bit() ? 8 : 4));
+ assert(OS.tell() - Start == LOHSize);
+ }
+
// Write the symbol table data, if used.
if (NumSymbols) {
// Write the indirect symbol entries.