Convert an use of OutputSections to OutputSectionCommands.

This allows moving clearOutputSections a bit earlier.

llvm-svn: 304947
This commit is contained in:
Rafael Espindola 2017-06-07 22:23:01 +00:00
parent cd19815bc2
commit 2356c9ffae
3 changed files with 16 additions and 11 deletions

View File

@ -1051,10 +1051,12 @@ std::pair<Thunk *, bool> ThunkCreator::getThunk(SymbolBody &Body,
// Call Fn on every executable InputSection accessed via the linker script
// InputSectionDescription::Sections.
void ThunkCreator::forEachExecInputSection(
ArrayRef<OutputSection *> OutputSections,
std::function<void(OutputSection *, std::vector<InputSection*> *,
InputSection *)> Fn) {
for (OutputSection *OS : OutputSections) {
ArrayRef<OutputSectionCommand *> OutputSections,
std::function<void(OutputSection *, std::vector<InputSection *> *,
InputSection *)>
Fn) {
for (OutputSectionCommand *Cmd : OutputSections) {
OutputSection *OS = Cmd->Sec;
if (!(OS->Flags & SHF_ALLOC) || !(OS->Flags & SHF_EXECINSTR))
continue;
if (OutputSectionCommand *C = Script->getCmd(OS))
@ -1077,7 +1079,8 @@ void ThunkCreator::forEachExecInputSection(
//
// FIXME: All Thunks are assumed to be in range of the relocation. Range
// extension Thunks are not yet supported.
bool ThunkCreator::createThunks(ArrayRef<OutputSection *> OutputSections) {
bool ThunkCreator::createThunks(
ArrayRef<OutputSectionCommand *> OutputSections) {
// Create all the Thunks and insert them into synthetic ThunkSections. The
// ThunkSections are later inserted back into the OutputSection.

View File

@ -21,6 +21,7 @@ class SymbolBody;
class InputSection;
class InputSectionBase;
class OutputSection;
struct OutputSectionCommand;
// List of target-independent relocation types. Relocations read
// from files are converted to these types so that the main code
@ -123,7 +124,7 @@ class Thunk;
class ThunkCreator {
public:
// Return true if Thunks have been added to OutputSections
bool createThunks(ArrayRef<OutputSection *> OutputSections);
bool createThunks(ArrayRef<OutputSectionCommand *> OutputSections);
private:
void mergeThunks();
@ -131,9 +132,10 @@ private:
std::vector<InputSection *> *ISR);
ThunkSection *getISThunkSec(InputSection *IS, OutputSection *OS);
void forEachExecInputSection(
ArrayRef<OutputSection *> OutputSections,
ArrayRef<OutputSectionCommand *> OutputSections,
std::function<void(OutputSection *, std::vector<InputSection *> *,
InputSection *)> Fn);
InputSection *)>
Fn);
std::pair<Thunk *, bool> getThunk(SymbolBody &Body, uint32_t Type);
// Track Symbols that already have a Thunk

View File

@ -1243,6 +1243,8 @@ template <class ELFT> void Writer<ELFT>::finalizeSections() {
In<ELFT>::VerSym, In<ELFT>::VerNeed, InX::Dynamic},
[](SyntheticSection *SS) { SS->finalizeContents(); });
clearOutputSections();
// Some architectures use small displacements for jump instructions.
// It is linker's responsibility to create thunks containing long
// jump instructions if jump targets are too far. Create thunks.
@ -1254,13 +1256,11 @@ template <class ELFT> void Writer<ELFT>::finalizeSections() {
// are out of range. This will need to turn into a loop that converges
// when no more Thunks are added
ThunkCreator TC;
if (TC.createThunks(OutputSections))
if (TC.createThunks(OutputSectionCommands))
applySynthetic({InX::MipsGot},
[](SyntheticSection *SS) { SS->updateAllocSize(); });
}
clearOutputSections();
// Fill other section headers. The dynamic table is finalized
// at the end because some tags like RELSZ depend on result
// of finalizing other sections.