Factor out code to a new function. NFC.

llvm-svn: 345088
This commit is contained in:
Rui Ueyama 2018-10-23 22:03:33 +00:00
parent e01d516ac7
commit 5a30177ef6
1 changed files with 52 additions and 27 deletions

View File

@ -53,6 +53,7 @@ private:
void forEachRelSec(llvm::function_ref<void(InputSectionBase &)> Fn);
void sortSections();
void resolveShfLinkOrder();
void maybeAddThunks();
void sortInputSections();
void finalizeSections();
void setReservedSymbolSections();
@ -1461,6 +1462,46 @@ template <class ELFT> void Writer<ELFT>::resolveShfLinkOrder() {
}
}
// For most RISC ISAs, we need to generate content that depends on the address
// of InputSections. For example some architectures such as AArch64 use small
// displacements for jump instructions that is the linker's responsibility for
// creating range extension thunks for. As the generation of the content may
// also alter InputSection addresses we must converge to a fixed point.
template <class ELFT> void Writer<ELFT>::maybeAddThunks() {
if (!Target->NeedsThunks && !Config->AndroidPackDynRelocs &&
!Config->RelrPackDynRelocs)
return;
ThunkCreator TC;
AArch64Err843419Patcher A64P;
for (;;) {
bool Changed = false;
Script->assignAddresses();
if (Target->NeedsThunks)
Changed |= TC.createThunks(OutputSections);
if (Config->FixCortexA53Errata843419) {
if (Changed)
Script->assignAddresses();
Changed |= A64P.createFixes();
}
if (In.MipsGot)
In.MipsGot->updateAllocSize();
Changed |= In.RelaDyn->updateAllocSize();
if (In.RelrDyn)
Changed |= In.RelrDyn->updateAllocSize();
if (!Changed)
return;
}
}
static void finalizeSynthetic(SyntheticSection *Sec) {
if (Sec && !Sec->empty() && Sec->getParent())
Sec->finalizeContents();
@ -1693,33 +1734,17 @@ template <class ELFT> void Writer<ELFT>::finalizeSections() {
// needs to be resolved before any other address dependent operation.
resolveShfLinkOrder();
// Some architectures need to generate content that depends on the address
// of InputSections. For example some architectures use small displacements
// for jump instructions that is the linker's responsibility for creating
// range extension thunks for. As the generation of the content may also
// alter InputSection addresses we must converge to a fixed point.
if (Target->NeedsThunks || Config->AndroidPackDynRelocs ||
Config->RelrPackDynRelocs) {
ThunkCreator TC;
AArch64Err843419Patcher A64P;
bool Changed;
do {
Script->assignAddresses();
Changed = false;
if (Target->NeedsThunks)
Changed |= TC.createThunks(OutputSections);
if (Config->FixCortexA53Errata843419) {
if (Changed)
Script->assignAddresses();
Changed |= A64P.createFixes();
}
if (In.MipsGot)
In.MipsGot->updateAllocSize();
Changed |= In.RelaDyn->updateAllocSize();
if (In.RelrDyn)
Changed |= In.RelrDyn->updateAllocSize();
} while (Changed);
}
// Jump instructions in many ISAs have small displacements, and therefore they
// cannot jump to arbitrary addresses in memory. For example, RISC-V JAL
// instruction can target only +-1 MiB from PC. It is a linker's
// responsibility to create and insert small pieces of code between sections
// to extend the ranges if jump targets are out of range. Such code pieces are
// called "thunks".
//
// We add thunks at this stage. We couldn't do this before this point because
// this is the earliest point where we know sizes of sections and their
// layouts (that are needed to determine if jump targets are in range).
maybeAddThunks();
// createThunks may have added local symbols to the static symbol table
finalizeSynthetic(In.SymTab);