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