Create a vector containing all input sections.

Previously, we do this piece of code to iterate over all input sections.

  for (elf::ObjectFile<ELFT> *F : Symtab.getObjectFiles())
    for (InputSectionBase<ELFT> *S : F->getSections())

It turned out that this mechanisms doesn't work well with synthetic
input sections because synthetic input sections don't belong to any
input file.

This patch defines a vector that contains all input sections including
synthetic ones.

llvm-svn: 286051
This commit is contained in:
Rui Ueyama 2016-11-05 22:37:59 +00:00
parent 16480186f8
commit 8c6a5aaf15
10 changed files with 72 additions and 65 deletions

View File

@ -750,6 +750,16 @@ template <class ELFT> void LinkerDriver::link(opt::InputArgList &Args) {
for (auto *Arg : Args.filtered(OPT_wrap))
Symtab.wrap(Arg->getValue());
// Now that we have a complete list of input files.
// Beyond this point, no new files are added.
// Aggregate all input sections into one place.
for (elf::ObjectFile<ELFT> *F : Symtab.getObjectFiles())
for (InputSectionBase<ELFT> *S : F->getSections())
Symtab.Sections.push_back(S);
for (BinaryFile *F : Symtab.getBinaryFiles())
for (InputSectionData *S : F->getSections())
Symtab.Sections.push_back(cast<InputSection<ELFT>>(S));
// Do size optimizations: garbage collection and identical code folding.
if (Config->GcSections)
markLive<ELFT>();
@ -758,15 +768,13 @@ template <class ELFT> void LinkerDriver::link(opt::InputArgList &Args) {
// MergeInputSection::splitIntoPieces needs to be called before
// any call of MergeInputSection::getOffset. Do that.
for (elf::ObjectFile<ELFT> *F : Symtab.getObjectFiles()) {
for (InputSectionBase<ELFT> *S : F->getSections()) {
if (!S || S == &InputSection<ELFT>::Discarded || !S->Live)
continue;
if (S->Compressed)
S->uncompress();
if (auto *MS = dyn_cast<MergeInputSection<ELFT>>(S))
MS->splitIntoPieces();
}
for (InputSectionBase<ELFT> *S : Symtab.Sections) {
if (!S || S == &InputSection<ELFT>::Discarded || !S->Live)
continue;
if (S->Compressed)
S->uncompress();
if (auto *MS = dyn_cast<MergeInputSection<ELFT>>(S))
MS->splitIntoPieces();
}
// Write the result to the file.

View File

@ -147,10 +147,9 @@ template <class ELFT> bool ICF<ELFT>::isEligible(InputSectionBase<ELFT> *Sec) {
template <class ELFT>
std::vector<InputSection<ELFT> *> ICF<ELFT>::getSections() {
std::vector<InputSection<ELFT> *> V;
for (ObjectFile<ELFT> *F : Symtab<ELFT>::X->getObjectFiles())
for (InputSectionBase<ELFT> *S : F->getSections())
if (isEligible(S))
V.push_back(cast<InputSection<ELFT>>(S));
for (InputSectionBase<ELFT> *S : Symtab<ELFT>::X->Sections)
if (isEligible(S))
V.push_back(cast<InputSection<ELFT>>(S));
return V;
}

View File

@ -12,8 +12,8 @@
#include "Error.h"
#include "InputFiles.h"
#include "Symbols.h"
#include "llvm/ADT/SmallString.h"
#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/SmallString.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/ADT/Twine.h"
#include "llvm/CodeGen/CommandFlags.h"

View File

@ -29,8 +29,8 @@
#include "Symbols.h"
#include "Target.h"
#include "Writer.h"
#include "llvm/ADT/SmallString.h"
#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/SmallString.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/ADT/StringSwitch.h"
#include "llvm/Support/Casting.h"
@ -193,14 +193,20 @@ void LinkerScript<ELFT>::computeInputSections(InputSectionDescription *I) {
// and attach them to I.
for (SectionPattern &Pat : I->SectionPatterns) {
size_t SizeBefore = I->Sections.size();
for (ObjectFile<ELFT> *F : Symtab<ELFT>::X->getObjectFiles()) {
StringRef Filename = sys::path::filename(F->getName());
for (InputSectionBase<ELFT> *S : Symtab<ELFT>::X->Sections) {
if (isDiscarded(S) || S->OutSec)
continue;
StringRef Filename;
if (elf::ObjectFile<ELFT> *F = S->getFile())
Filename = sys::path::filename(F->getName());
if (!I->FilePat.match(Filename) || Pat.ExcludedFilePat.match(Filename))
continue;
for (InputSectionBase<ELFT> *S : F->getSections())
if (!isDiscarded(S) && !S->OutSec && Pat.SectionPat.match(S->Name))
I->Sections.push_back(S);
if (Pat.SectionPat.match(S->Name))
I->Sections.push_back(S);
if (Pat.SectionPat.match("COMMON"))
I->Sections.push_back(InputSection<ELFT>::CommonInputSection);
}
@ -363,11 +369,11 @@ void LinkerScript<ELFT>::processCommands(OutputSectionFactory<ELFT> &Factory) {
template <class ELFT>
void LinkerScript<ELFT>::createSections(OutputSectionFactory<ELFT> &Factory) {
processCommands(Factory);
// Add orphan sections.
for (ObjectFile<ELFT> *F : Symtab<ELFT>::X->getObjectFiles())
for (InputSectionBase<ELFT> *S : F->getSections())
if (!isDiscarded(S) && !S->OutSec)
addSection(Factory, S, getOutputSectionName(S->Name));
for (InputSectionBase<ELFT> *S : Symtab<ELFT>::X->Sections)
if (!isDiscarded(S) && !S->OutSec)
addSection(Factory, S, getOutputSectionName(S->Name));
}
// Sets value of a section-defined symbol. Two kinds of

View File

@ -18,9 +18,9 @@
#include "llvm/ADT/DenseSet.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/Support/MemoryBuffer.h"
#include <functional>
#include <cstddef>
#include <cstdint>
#include <functional>
#include <memory>
#include <vector>

View File

@ -238,18 +238,16 @@ template <class ELFT> void elf::markLive() {
// Preserve special sections and those which are specified in linker
// script KEEP command.
for (ObjectFile<ELFT> *F : Symtab<ELFT>::X->getObjectFiles()) {
for (InputSectionBase<ELFT> *Sec : F->getSections()) {
if (!Sec || Sec == &InputSection<ELFT>::Discarded)
continue;
// .eh_frame is always marked as live now, but also it can reference to
// sections that contain personality. We preserve all non-text sections
// referred by .eh_frame here.
if (auto *EH = dyn_cast_or_null<EhInputSection<ELFT>>(Sec))
scanEhFrameSection<ELFT>(*EH, Enqueue);
if (isReserved(Sec) || Script<ELFT>::X->shouldKeep(Sec))
Enqueue({Sec, 0});
}
for (InputSectionBase<ELFT> *Sec : Symtab<ELFT>::X->Sections) {
if (!Sec || Sec == &InputSection<ELFT>::Discarded)
continue;
// .eh_frame is always marked as live now, but also it can reference to
// sections that contain personality. We preserve all non-text sections
// referred by .eh_frame here.
if (auto *EH = dyn_cast_or_null<EhInputSection<ELFT>>(Sec))
scanEhFrameSection<ELFT>(*EH, Enqueue);
if (isReserved(Sec) || Script<ELFT>::X->shouldKeep(Sec))
Enqueue({Sec, 0});
}
// Mark all reachable sections.

View File

@ -91,6 +91,8 @@ public:
void trace(StringRef Name);
void wrap(StringRef Name);
std::vector<InputSectionBase<ELFT> *> Sections;
private:
std::vector<SymbolBody *> findAll(const StringMatcher &M);
std::pair<Symbol *, bool> insert(StringRef &Name);

View File

@ -646,26 +646,24 @@ template <class ELFT>
void Writer<ELFT>::forEachRelSec(
std::function<void(InputSectionBase<ELFT> &, const typename ELFT::Shdr &)>
Fn) {
for (elf::ObjectFile<ELFT> *F : Symtab<ELFT>::X->getObjectFiles()) {
for (InputSectionBase<ELFT> *IS : F->getSections()) {
if (isDiscarded(IS))
continue;
// Scan all relocations. Each relocation goes through a series
// of tests to determine if it needs special treatment, such as
// creating GOT, PLT, copy relocations, etc.
// Note that relocations for non-alloc sections are directly
// processed by InputSection::relocateNonAlloc.
if (!(IS->Flags & SHF_ALLOC))
continue;
if (auto *S = dyn_cast<InputSection<ELFT>>(IS)) {
for (const Elf_Shdr *RelSec : S->RelocSections)
Fn(*S, *RelSec);
continue;
}
if (auto *S = dyn_cast<EhInputSection<ELFT>>(IS))
if (S->RelocSection)
Fn(*S, *S->RelocSection);
for (InputSectionBase<ELFT> *IS : Symtab<ELFT>::X->Sections) {
if (isDiscarded(IS))
continue;
// Scan all relocations. Each relocation goes through a series
// of tests to determine if it needs special treatment, such as
// creating GOT, PLT, copy relocations, etc.
// Note that relocations for non-alloc sections are directly
// processed by InputSection::relocateNonAlloc.
if (!(IS->Flags & SHF_ALLOC))
continue;
if (auto *S = dyn_cast<InputSection<ELFT>>(IS)) {
for (const Elf_Shdr *RelSec : S->RelocSections)
Fn(*S, *RelSec);
continue;
}
if (auto *S = dyn_cast<EhInputSection<ELFT>>(IS))
if (S->RelocSection)
Fn(*S, *S->RelocSection);
}
}
@ -685,13 +683,8 @@ void Writer<ELFT>::addInputSec(InputSectionBase<ELFT> *IS) {
}
template <class ELFT> void Writer<ELFT>::createSections() {
for (elf::ObjectFile<ELFT> *F : Symtab<ELFT>::X->getObjectFiles())
for (InputSectionBase<ELFT> *IS : F->getSections())
addInputSec(IS);
for (BinaryFile *F : Symtab<ELFT>::X->getBinaryFiles())
for (InputSectionData *ID : F->getSections())
addInputSec(cast<InputSection<ELFT>>(ID));
for (InputSectionBase<ELFT> *IS : Symtab<ELFT>::X->Sections)
addInputSec(IS);
sortInitFini(findSection(".init_array"));
sortInitFini(findSection(".fini_array"));

View File

@ -10,6 +10,7 @@
#ifndef LLD_CORE_READER_H
#define LLD_CORE_READER_H
#include "lld/Core/LLVM.h"
#include "lld/Core/Reference.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/Support/ErrorOr.h"

View File

@ -7,15 +7,15 @@
//
//===----------------------------------------------------------------------===//
#include "lld/Core/File.h"
#include "lld/Core/Reader.h"
#include "lld/Core/File.h"
#include "lld/Core/Reference.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/Support/Errc.h"
#include "llvm/Support/FileSystem.h"
#include "llvm/Support/MemoryBuffer.h"
#include <memory>
#include <algorithm>
#include <memory>
namespace lld {