[lld] r276121 - [ELF] Create output sections in LinkerScript class
Eugene Leviant via llvm-commits
llvm-commits at lists.llvm.org
Wed Jul 20 07:43:20 PDT 2016
Author: evgeny777
Date: Wed Jul 20 09:43:20 2016
New Revision: 276121
URL: http://llvm.org/viewvc/llvm-project?rev=276121&view=rev
Log:
[ELF] Create output sections in LinkerScript class
Modified:
lld/trunk/ELF/InputSection.cpp
lld/trunk/ELF/InputSection.h
lld/trunk/ELF/LinkerScript.cpp
lld/trunk/ELF/LinkerScript.h
lld/trunk/ELF/Writer.cpp
Modified: lld/trunk/ELF/InputSection.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/InputSection.cpp?rev=276121&r1=276120&r2=276121&view=diff
==============================================================================
--- lld/trunk/ELF/InputSection.cpp (original)
+++ lld/trunk/ELF/InputSection.cpp Wed Jul 20 09:43:20 2016
@@ -28,11 +28,6 @@ using namespace llvm::support::endian;
using namespace lld;
using namespace lld::elf;
-template <class ELFT> bool elf::isDiscarded(InputSectionBase<ELFT> *S) {
- return !S || S == &InputSection<ELFT>::Discarded || !S->Live ||
- Script<ELFT>::X->isDiscarded(S);
-}
-
template <class ELFT>
InputSectionBase<ELFT>::InputSectionBase(elf::ObjectFile<ELFT> *File,
const Elf_Shdr *Header,
@@ -650,11 +645,6 @@ bool MipsOptionsInputSection<ELFT>::clas
return S->SectionKind == InputSectionBase<ELFT>::MipsOptions;
}
-template bool elf::isDiscarded<ELF32LE>(InputSectionBase<ELF32LE> *);
-template bool elf::isDiscarded<ELF32BE>(InputSectionBase<ELF32BE> *);
-template bool elf::isDiscarded<ELF64LE>(InputSectionBase<ELF64LE> *);
-template bool elf::isDiscarded<ELF64BE>(InputSectionBase<ELF64BE> *);
-
template class elf::InputSectionBase<ELF32LE>;
template class elf::InputSectionBase<ELF32BE>;
template class elf::InputSectionBase<ELF64LE>;
Modified: lld/trunk/ELF/InputSection.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/InputSection.h?rev=276121&r1=276120&r2=276121&view=diff
==============================================================================
--- lld/trunk/ELF/InputSection.h (original)
+++ lld/trunk/ELF/InputSection.h Wed Jul 20 09:43:20 2016
@@ -21,8 +21,6 @@
namespace lld {
namespace elf {
-template <class ELFT> bool isDiscarded(InputSectionBase<ELFT> *S);
-
class SymbolBody;
template <class ELFT> class ICF;
Modified: lld/trunk/ELF/LinkerScript.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/LinkerScript.cpp?rev=276121&r1=276120&r2=276121&view=diff
==============================================================================
--- lld/trunk/ELF/LinkerScript.cpp (original)
+++ lld/trunk/ELF/LinkerScript.cpp Wed Jul 20 09:43:20 2016
@@ -196,7 +196,7 @@ StringRef LinkerScript<ELFT>::getOutputS
template <class ELFT>
bool LinkerScript<ELFT>::isDiscarded(InputSectionBase<ELFT> *S) {
- return getOutputSection(S) == "/DISCARD/";
+ return !S || !S->Live || getOutputSection(S) == "/DISCARD/";
}
template <class ELFT>
@@ -208,6 +208,46 @@ bool LinkerScript<ELFT>::shouldKeep(Inpu
}
template <class ELFT>
+std::vector<std::unique_ptr<OutputSectionBase<ELFT>>>
+LinkerScript<ELFT>::createSections(OutputSectionFactory<ELFT> &Factory) {
+ std::vector<std::unique_ptr<OutputSectionBase<ELFT>>> Result;
+ // Add input section to output section. If there is no output section yet,
+ // then create it and add to output section list.
+ auto AddInputSec = [&](InputSectionBase<ELFT> *C, StringRef Name) {
+ OutputSectionBase<ELFT> *Sec;
+ bool IsNew;
+ std::tie(Sec, IsNew) = Factory.create(C, Name);
+ if (IsNew)
+ Result.emplace_back(Sec);
+ Sec->addSection(C);
+ };
+
+ // Select input sections matching rule and add them to corresponding
+ // output section. Section rules are processed in order they're listed
+ // in script, so correct input section order is maintained by design.
+ for (SectionRule &R : Opt.Sections)
+ for (const std::unique_ptr<ObjectFile<ELFT>> &F :
+ Symtab<ELFT>::X->getObjectFiles())
+ for (InputSectionBase<ELFT> *S : F->getSections())
+ if (!isDiscarded(S) && !S->OutSec &&
+ globMatch(R.SectionPattern, S->getSectionName()))
+ // Add single input section to output section.
+ AddInputSec(S, R.Dest);
+
+ // Add all other input sections, which are not listed in script.
+ for (const std::unique_ptr<ObjectFile<ELFT>> &F :
+ Symtab<ELFT>::X->getObjectFiles())
+ for (InputSectionBase<ELFT> *S : F->getSections())
+ if (!isDiscarded(S)) {
+ if (!S->OutSec)
+ AddInputSec(S, getOutputSectionName(S));
+ } else
+ reportDiscarded(S, F);
+
+ return Result;
+}
+
+template <class ELFT>
void LinkerScript<ELFT>::assignAddresses(
ArrayRef<OutputSectionBase<ELFT> *> Sections) {
// Orphan sections are sections present in the input files which
Modified: lld/trunk/ELF/LinkerScript.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/LinkerScript.h?rev=276121&r1=276120&r2=276121&view=diff
==============================================================================
--- lld/trunk/ELF/LinkerScript.h (original)
+++ lld/trunk/ELF/LinkerScript.h Wed Jul 20 09:43:20 2016
@@ -19,6 +19,9 @@
namespace lld {
namespace elf {
+template <class ELFT> class InputSectionBase;
+template <class ELFT> class OutputSectionBase;
+template <class ELFT> class OutputSectionFactory;
// Parses a linker script. Calling this function updates
// Config and ScriptConfig.
@@ -93,6 +96,8 @@ public:
ArrayRef<uint8_t> getFiller(StringRef Name);
bool isDiscarded(InputSectionBase<ELFT> *S);
bool shouldKeep(InputSectionBase<ELFT> *S);
+ std::vector<std::unique_ptr<OutputSectionBase<ELFT>>>
+ createSections(OutputSectionFactory<ELFT> &Factory);
void assignAddresses(ArrayRef<OutputSectionBase<ELFT> *> S);
int compareSections(StringRef A, StringRef B);
void addScriptedSymbols();
Modified: lld/trunk/ELF/Writer.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/Writer.cpp?rev=276121&r1=276120&r2=276121&view=diff
==============================================================================
--- lld/trunk/ELF/Writer.cpp (original)
+++ lld/trunk/ELF/Writer.cpp Wed Jul 20 09:43:20 2016
@@ -48,7 +48,8 @@ private:
void copyLocalSymbols();
void addReservedSymbols();
- void createSections();
+ std::vector<std::unique_ptr<OutputSectionBase<ELFT>>> createSections();
+ void finalizeSections();
void addPredefinedSections();
bool needsGot();
@@ -70,7 +71,7 @@ private:
BumpPtrAllocator Alloc;
std::vector<OutputSectionBase<ELFT> *> OutputSections;
- std::vector<std::unique_ptr<OutputSectionBase<ELFT>>> OwningSections;
+ OutputSectionFactory<ELFT> Factory;
void addRelIpltSymbols();
void addStartEndSymbols();
@@ -216,7 +217,15 @@ template <class ELFT> void Writer<ELFT>:
if (!Config->DiscardAll)
copyLocalSymbols();
addReservedSymbols();
- createSections();
+
+ std::vector<std::unique_ptr<OutputSectionBase<ELFT>>> Sections =
+ ScriptConfig->DoLayout ? Script<ELFT>::X->createSections(Factory)
+ : createSections();
+
+ for (std::unique_ptr<OutputSectionBase<ELFT>> &S : Sections)
+ OutputSections.push_back(S.get());
+
+ finalizeSections();
if (HasError)
return;
@@ -477,6 +486,10 @@ template <class ELFT> bool elf::isOutput
return !Symtab<ELFT>::X->getSharedFiles().empty() || Config->Pic;
}
+template <class ELFT> static bool isDiscarded(InputSectionBase<ELFT> *S) {
+ return !S || S == &InputSection<ELFT>::Discarded || !S->Live;
+}
+
// Program header entry
template<class ELFT>
PhdrEntry<ELFT>::PhdrEntry(unsigned Type, unsigned Flags) {
@@ -623,11 +636,11 @@ template <class ELFT> static void sortCt
reinterpret_cast<OutputSection<ELFT> *>(S)->sortCtorsDtors();
}
-// Create output section objects and add them to OutputSections.
-template <class ELFT> void Writer<ELFT>::createSections() {
- // Create output sections for input object file sections.
- std::vector<OutputSectionBase<ELFT> *> RegularSections;
- OutputSectionFactory<ELFT> Factory;
+template <class ELFT>
+std::vector<std::unique_ptr<OutputSectionBase<ELFT>>>
+Writer<ELFT>::createSections() {
+ std::vector<std::unique_ptr<OutputSectionBase<ELFT>>> Result;
+
for (const std::unique_ptr<elf::ObjectFile<ELFT>> &F :
Symtab.getObjectFiles()) {
for (InputSectionBase<ELFT> *C : F->getSections()) {
@@ -638,14 +651,19 @@ template <class ELFT> void Writer<ELFT>:
OutputSectionBase<ELFT> *Sec;
bool IsNew;
std::tie(Sec, IsNew) = Factory.create(C, getOutputSectionName(C));
- if (IsNew) {
- OwningSections.emplace_back(Sec);
- OutputSections.push_back(Sec);
- RegularSections.push_back(Sec);
- }
+ if (IsNew)
+ Result.emplace_back(Sec);
+
Sec->addSection(C);
}
}
+ return Result;
+}
+
+// Create output section objects and add them to OutputSections.
+template <class ELFT> void Writer<ELFT>::finalizeSections() {
+ // Create output sections for input object file sections.
+ std::vector<OutputSectionBase<ELFT> *> RegularSections = OutputSections;
// If we have a .opd section (used under PPC64 for function descriptors),
// store a pointer to it here so that we can use it later when processing
More information about the llvm-commits
mailing list