[lld] r307225 - Move fabricateDefaultCommands earlier.
Rafael Espindola via llvm-commits
llvm-commits at lists.llvm.org
Wed Jul 5 16:36:24 PDT 2017
Author: rafael
Date: Wed Jul 5 16:36:24 2017
New Revision: 307225
URL: http://llvm.org/viewvc/llvm-project?rev=307225&view=rev
Log:
Move fabricateDefaultCommands earlier.
It is now just after the OutputSections are created, which is as early
as it can possibly go.
Modified:
lld/trunk/ELF/LinkerScript.cpp
lld/trunk/ELF/LinkerScript.h
lld/trunk/ELF/OutputSections.cpp
lld/trunk/ELF/OutputSections.h
lld/trunk/ELF/Writer.cpp
Modified: lld/trunk/ELF/LinkerScript.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/LinkerScript.cpp?rev=307225&r1=307224&r2=307225&view=diff
==============================================================================
--- lld/trunk/ELF/LinkerScript.cpp (original)
+++ lld/trunk/ELF/LinkerScript.cpp Wed Jul 5 16:36:24 2017
@@ -901,6 +901,92 @@ OutputSectionCommand *LinkerScript::getC
return I->second;
}
+void OutputSectionCommand::sort(std::function<int(InputSectionBase *S)> Order) {
+ typedef std::pair<unsigned, InputSection *> Pair;
+ auto Comp = [](const Pair &A, const Pair &B) { return A.first < B.first; };
+
+ std::vector<Pair> V;
+ assert(Commands.size() == 1);
+ auto *ISD = cast<InputSectionDescription>(Commands[0]);
+ for (InputSection *S : ISD->Sections)
+ V.push_back({Order(S), S});
+ std::stable_sort(V.begin(), V.end(), Comp);
+ ISD->Sections.clear();
+ for (Pair &P : V)
+ ISD->Sections.push_back(P.second);
+}
+
+// Returns true if S matches /Filename.?\.o$/.
+static bool isCrtBeginEnd(StringRef S, StringRef Filename) {
+ if (!S.endswith(".o"))
+ return false;
+ S = S.drop_back(2);
+ if (S.endswith(Filename))
+ return true;
+ return !S.empty() && S.drop_back().endswith(Filename);
+}
+
+static bool isCrtbegin(StringRef S) { return isCrtBeginEnd(S, "crtbegin"); }
+static bool isCrtend(StringRef S) { return isCrtBeginEnd(S, "crtend"); }
+
+// .ctors and .dtors are sorted by this priority from highest to lowest.
+//
+// 1. The section was contained in crtbegin (crtbegin contains
+// some sentinel value in its .ctors and .dtors so that the runtime
+// can find the beginning of the sections.)
+//
+// 2. The section has an optional priority value in the form of ".ctors.N"
+// or ".dtors.N" where N is a number. Unlike .{init,fini}_array,
+// they are compared as string rather than number.
+//
+// 3. The section is just ".ctors" or ".dtors".
+//
+// 4. The section was contained in crtend, which contains an end marker.
+//
+// In an ideal world, we don't need this function because .init_array and
+// .ctors are duplicate features (and .init_array is newer.) However, there
+// are too many real-world use cases of .ctors, so we had no choice to
+// support that with this rather ad-hoc semantics.
+static bool compCtors(const InputSection *A, const InputSection *B) {
+ bool BeginA = isCrtbegin(A->File->getName());
+ bool BeginB = isCrtbegin(B->File->getName());
+ if (BeginA != BeginB)
+ return BeginA;
+ bool EndA = isCrtend(A->File->getName());
+ bool EndB = isCrtend(B->File->getName());
+ if (EndA != EndB)
+ return EndB;
+ StringRef X = A->Name;
+ StringRef Y = B->Name;
+ assert(X.startswith(".ctors") || X.startswith(".dtors"));
+ assert(Y.startswith(".ctors") || Y.startswith(".dtors"));
+ X = X.substr(6);
+ Y = Y.substr(6);
+ if (X.empty() && Y.empty())
+ return false;
+ return X < Y;
+}
+
+// Sorts input sections by the special rules for .ctors and .dtors.
+// Unfortunately, the rules are different from the one for .{init,fini}_array.
+// Read the comment above.
+void OutputSectionCommand::sortCtorsDtors() {
+ assert(Commands.size() == 1);
+ auto *ISD = cast<InputSectionDescription>(Commands[0]);
+ std::stable_sort(ISD->Sections.begin(), ISD->Sections.end(), compCtors);
+}
+
+// Sorts input sections by section name suffixes, so that .foo.N comes
+// before .foo.M if N < M. Used to sort .{init,fini}_array.N sections.
+// We want to keep the original order if the priorities are the same
+// because the compiler keeps the original initialization order in a
+// translation unit and we need to respect that.
+// For more detail, read the section of the GCC's manual about init_priority.
+void OutputSectionCommand::sortInitFini() {
+ // Sort sections by priority.
+ sort([](InputSectionBase *S) { return getPriority(S->Name); });
+}
+
uint32_t OutputSectionCommand::getFiller() {
if (Filler)
return *Filler;
Modified: lld/trunk/ELF/LinkerScript.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/LinkerScript.h?rev=307225&r1=307224&r2=307225&view=diff
==============================================================================
--- lld/trunk/ELF/LinkerScript.h (original)
+++ lld/trunk/ELF/LinkerScript.h Wed Jul 5 16:36:24 2017
@@ -140,6 +140,10 @@ struct OutputSectionCommand : BaseComman
template <class ELFT> void writeTo(uint8_t *Buf);
template <class ELFT> void maybeCompress();
uint32_t getFiller();
+
+ void sort(std::function<int(InputSectionBase *S)> Order);
+ void sortInitFini();
+ void sortCtorsDtors();
};
// This struct represents one section match pattern in SECTIONS() command.
Modified: lld/trunk/ELF/OutputSections.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/OutputSections.cpp?rev=307225&r1=307224&r2=307225&view=diff
==============================================================================
--- lld/trunk/ELF/OutputSections.cpp (original)
+++ lld/trunk/ELF/OutputSections.cpp Wed Jul 5 16:36:24 2017
@@ -101,88 +101,6 @@ void OutputSection::addSection(InputSect
this->Entsize = std::max(this->Entsize, S->Entsize);
}
-void OutputSection::sort(std::function<int(InputSectionBase *S)> Order) {
- typedef std::pair<unsigned, InputSection *> Pair;
- auto Comp = [](const Pair &A, const Pair &B) { return A.first < B.first; };
-
- std::vector<Pair> V;
- for (InputSection *S : Sections)
- V.push_back({Order(S), S});
- std::stable_sort(V.begin(), V.end(), Comp);
- Sections.clear();
- for (Pair &P : V)
- Sections.push_back(P.second);
-}
-
-// Sorts input sections by section name suffixes, so that .foo.N comes
-// before .foo.M if N < M. Used to sort .{init,fini}_array.N sections.
-// We want to keep the original order if the priorities are the same
-// because the compiler keeps the original initialization order in a
-// translation unit and we need to respect that.
-// For more detail, read the section of the GCC's manual about init_priority.
-void OutputSection::sortInitFini() {
- // Sort sections by priority.
- sort([](InputSectionBase *S) { return getPriority(S->Name); });
-}
-
-// Returns true if S matches /Filename.?\.o$/.
-static bool isCrtBeginEnd(StringRef S, StringRef Filename) {
- if (!S.endswith(".o"))
- return false;
- S = S.drop_back(2);
- if (S.endswith(Filename))
- return true;
- return !S.empty() && S.drop_back().endswith(Filename);
-}
-
-static bool isCrtbegin(StringRef S) { return isCrtBeginEnd(S, "crtbegin"); }
-static bool isCrtend(StringRef S) { return isCrtBeginEnd(S, "crtend"); }
-
-// .ctors and .dtors are sorted by this priority from highest to lowest.
-//
-// 1. The section was contained in crtbegin (crtbegin contains
-// some sentinel value in its .ctors and .dtors so that the runtime
-// can find the beginning of the sections.)
-//
-// 2. The section has an optional priority value in the form of ".ctors.N"
-// or ".dtors.N" where N is a number. Unlike .{init,fini}_array,
-// they are compared as string rather than number.
-//
-// 3. The section is just ".ctors" or ".dtors".
-//
-// 4. The section was contained in crtend, which contains an end marker.
-//
-// In an ideal world, we don't need this function because .init_array and
-// .ctors are duplicate features (and .init_array is newer.) However, there
-// are too many real-world use cases of .ctors, so we had no choice to
-// support that with this rather ad-hoc semantics.
-static bool compCtors(const InputSection *A, const InputSection *B) {
- bool BeginA = isCrtbegin(A->File->getName());
- bool BeginB = isCrtbegin(B->File->getName());
- if (BeginA != BeginB)
- return BeginA;
- bool EndA = isCrtend(A->File->getName());
- bool EndB = isCrtend(B->File->getName());
- if (EndA != EndB)
- return EndB;
- StringRef X = A->Name;
- StringRef Y = B->Name;
- assert(X.startswith(".ctors") || X.startswith(".dtors"));
- assert(Y.startswith(".ctors") || Y.startswith(".dtors"));
- X = X.substr(6);
- Y = Y.substr(6);
- if (X.empty() && Y.empty())
- return false;
- return X < Y;
-}
-
-// Sorts input sections by the special rules for .ctors and .dtors.
-// Unfortunately, the rules are different from the one for .{init,fini}_array.
-// Read the comment above.
-void OutputSection::sortCtorsDtors() {
- std::stable_sort(Sections.begin(), Sections.end(), compCtors);
-}
-
static SectionKey createKey(InputSectionBase *C, StringRef OutsecName) {
// The ELF spec just says
// ----------------------------------------------------------------
Modified: lld/trunk/ELF/OutputSections.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/OutputSections.h?rev=307225&r1=307224&r2=307225&view=diff
==============================================================================
--- lld/trunk/ELF/OutputSections.h (original)
+++ lld/trunk/ELF/OutputSections.h Wed Jul 5 16:36:24 2017
@@ -80,9 +80,6 @@ public:
uint32_t ShName = 0;
void addSection(InputSection *S);
- void sort(std::function<int(InputSectionBase *S)> Order);
- void sortInitFini();
- void sortCtorsDtors();
std::vector<InputSection *> Sections;
// Used for implementation of --compress-debug-sections option.
Modified: lld/trunk/ELF/Writer.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/Writer.cpp?rev=307225&r1=307224&r2=307225&view=diff
==============================================================================
--- lld/trunk/ELF/Writer.cpp (original)
+++ lld/trunk/ELF/Writer.cpp Wed Jul 5 16:36:24 2017
@@ -79,7 +79,6 @@ private:
void addStartEndSymbols();
void addStartStopSymbols(OutputSection *Sec);
uint64_t getEntryAddr();
- OutputSection *findSection(StringRef Name);
OutputSection *findSectionInScript(StringRef Name);
OutputSectionCommand *findSectionCommand(StringRef Name);
@@ -186,9 +185,8 @@ template <class ELFT> void Writer<ELFT>:
// output sections by default rules. We still need to give the
// linker script a chance to run, because it might contain
// non-SECTIONS commands such as ASSERT.
- createSections();
Script->processCommands(Factory);
- Script->fabricateDefaultCommands();
+ createSections();
}
clearOutputSections();
@@ -870,20 +868,19 @@ template <class ELFT> void Writer<ELFT>:
// Sort input sections by section name suffixes for
// __attribute__((init_priority(N))).
-static void sortInitFini(OutputSection *S) {
- if (S)
- S->sortInitFini();
+static void sortInitFini(OutputSectionCommand *Cmd) {
+ if (Cmd)
+ Cmd->sortInitFini();
}
// Sort input sections by the special rule for .ctors and .dtors.
-static void sortCtorsDtors(OutputSection *S) {
- if (S)
- S->sortCtorsDtors();
+static void sortCtorsDtors(OutputSectionCommand *Cmd) {
+ if (Cmd)
+ Cmd->sortCtorsDtors();
}
// Sort input sections using the list provided by --symbol-ordering-file.
-template <class ELFT>
-static void sortBySymbolsOrder(ArrayRef<OutputSection *> OutputSections) {
+template <class ELFT> static void sortBySymbolsOrder() {
if (Config->SymbolOrderingFile.empty())
return;
@@ -908,8 +905,9 @@ static void sortBySymbolsOrder(ArrayRef<
}
// Sort sections by priority.
- for (OutputSection *Sec : OutputSections)
- Sec->sort([&](InputSectionBase *S) { return SectionOrder.lookup(S); });
+ for (BaseCommand *Base : Script->Opt.Commands)
+ if (auto *Cmd = dyn_cast<OutputSectionCommand>(Base))
+ Cmd->sort([&](InputSectionBase *S) { return SectionOrder.lookup(S); });
}
template <class ELFT>
@@ -939,11 +937,12 @@ template <class ELFT> void Writer<ELFT>:
if (IS)
Factory.addInputSec(IS, getOutputSectionName(IS->Name));
- sortBySymbolsOrder<ELFT>(OutputSections);
- sortInitFini(findSection(".init_array"));
- sortInitFini(findSection(".fini_array"));
- sortCtorsDtors(findSection(".ctors"));
- sortCtorsDtors(findSection(".dtors"));
+ Script->fabricateDefaultCommands();
+ sortBySymbolsOrder<ELFT>();
+ sortInitFini(findSectionCommand(".init_array"));
+ sortInitFini(findSectionCommand(".fini_array"));
+ sortCtorsDtors(findSectionCommand(".ctors"));
+ sortCtorsDtors(findSectionCommand(".dtors"));
}
// We want to find how similar two ranks are.
@@ -1398,13 +1397,6 @@ template <class ELFT> OutputSection *Wri
return nullptr;
}
-template <class ELFT> OutputSection *Writer<ELFT>::findSection(StringRef Name) {
- for (OutputSection *Sec : OutputSections)
- if (Sec->Name == Name)
- return Sec;
- return nullptr;
-}
-
static bool needsPtLoad(OutputSection *Sec) {
if (!(Sec->Flags & SHF_ALLOC))
return false;
More information about the llvm-commits
mailing list