[lld] r281771 - [ELF] - Implemented --sort-section cmd line option and SORT_NONE script command.
George Rimar via llvm-commits
llvm-commits at lists.llvm.org
Fri Sep 16 13:21:56 PDT 2016
Author: grimar
Date: Fri Sep 16 15:21:55 2016
New Revision: 281771
URL: http://llvm.org/viewvc/llvm-project?rev=281771&view=rev
Log:
[ELF] - Implemented --sort-section cmd line option and SORT_NONE script command.
This fixes Bug 30385 - SORT_NONE not implemented,
`SORT_NONE' disables section sorting by ignoring the command line
section sorting option.
That is why this patch also implements --sort-section option.
Description of sorting rules
available at https://sourceware.org/binutils/docs/ld/Input-Section-Wildcards.html
Differential revision: https://reviews.llvm.org/D24604
Modified:
lld/trunk/ELF/Config.h
lld/trunk/ELF/Driver.cpp
lld/trunk/ELF/LinkerScript.cpp
lld/trunk/ELF/LinkerScript.h
lld/trunk/ELF/Options.td
lld/trunk/test/ELF/linkerscript/sort-nested.s
lld/trunk/test/ELF/linkerscript/sort.s
Modified: lld/trunk/ELF/Config.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/Config.h?rev=281771&r1=281770&r2=281771&view=diff
==============================================================================
--- lld/trunk/ELF/Config.h (original)
+++ lld/trunk/ELF/Config.h Fri Sep 16 15:21:55 2016
@@ -42,6 +42,9 @@ enum class StripPolicy { None, All, Debu
// For --unresolved-symbols.
enum class UnresolvedPolicy { NoUndef, ReportError, Warn, Ignore };
+// For --sort-section and linkerscript sorting rules.
+enum class SortSectionPolicy { None, IgnoreConfig, Alignment, Name, Priority };
+
struct SymbolVersion {
llvm::StringRef Name;
bool IsExternCpp;
@@ -124,6 +127,7 @@ struct Configuration {
bool ZOrigin;
bool ZRelro;
DiscardPolicy Discard;
+ SortSectionPolicy SortSection;
StripPolicy Strip = StripPolicy::None;
UnresolvedPolicy UnresolvedSymbols;
BuildIdKind BuildId = BuildIdKind::None;
Modified: lld/trunk/ELF/Driver.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/Driver.cpp?rev=281771&r1=281770&r2=281771&view=diff
==============================================================================
--- lld/trunk/ELF/Driver.cpp (original)
+++ lld/trunk/ELF/Driver.cpp Fri Sep 16 15:21:55 2016
@@ -407,6 +407,17 @@ static StringMap<uint64_t> getSectionSta
return Ret;
}
+static SortSectionPolicy getSortKind(opt::InputArgList &Args) {
+ StringRef S = getString(Args, OPT_sort_section);
+ if (S == "alignment")
+ return SortSectionPolicy::Alignment;
+ if (S == "name")
+ return SortSectionPolicy::Name;
+ if (!S.empty())
+ error("unknown --sort-section rule: " + S);
+ return SortSectionPolicy::None;
+}
+
// Initializes Config members by the command line options.
void LinkerDriver::readConfigs(opt::InputArgList &Args) {
for (auto *Arg : Args.filtered(OPT_L))
@@ -530,6 +541,8 @@ void LinkerDriver::readConfigs(opt::Inpu
for (auto *Arg : Args.filtered(OPT_undefined))
Config->Undefined.push_back(Arg->getValue());
+ Config->SortSection = getSortKind(Args);
+
Config->UnresolvedSymbols = getUnresolvedSymbolOption(Args);
if (auto *Arg = Args.getLastArg(OPT_dynamic_list))
Modified: lld/trunk/ELF/LinkerScript.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/LinkerScript.cpp?rev=281771&r1=281770&r2=281771&view=diff
==============================================================================
--- lld/trunk/ELF/LinkerScript.cpp (original)
+++ lld/trunk/ELF/LinkerScript.cpp Fri Sep 16 15:21:55 2016
@@ -131,12 +131,17 @@ static bool compareAlignment(InputSectio
}
static std::function<bool(InputSectionData *, InputSectionData *)>
-getComparator(SortKind K) {
- if (K == SortByPriority)
- return comparePriority;
- if (K == SortByName)
+getComparator(SortSectionPolicy K) {
+ switch (K) {
+ case SortSectionPolicy::Alignment:
+ return compareAlignment;
+ case SortSectionPolicy::Name:
return compareName;
- return compareAlignment;
+ case SortSectionPolicy::Priority:
+ return comparePriority;
+ default:
+ llvm_unreachable("unknown sort policy");
+ }
}
static bool checkConstraint(uint64_t Flags, ConstraintKind Kind) {
@@ -180,10 +185,10 @@ void LinkerScript<ELFT>::computeInputSec
return;
}
- if (I->SortInner)
+ if (I->SortInner != SortSectionPolicy::None)
std::stable_sort(I->Sections.begin(), I->Sections.end(),
getComparator(I->SortInner));
- if (I->SortOuter)
+ if (I->SortOuter != SortSectionPolicy::None)
std::stable_sort(I->Sections.begin(), I->Sections.end(),
getComparator(I->SortOuter));
@@ -704,7 +709,7 @@ private:
void readSectionExcludes(InputSectionDescription *Cmd);
InputSectionDescription *readInputSectionRules(StringRef FilePattern);
unsigned readPhdrType();
- SortKind readSortKind();
+ SortSectionPolicy readSortKind();
SymbolAssignment *readProvideHidden(bool Provide, bool Hidden);
SymbolAssignment *readProvideOrAssignment(StringRef Tok, bool MakeAbsolute);
void readSort();
@@ -985,14 +990,39 @@ Regex ScriptParser::readFilePatterns() {
return compileGlobPatterns(V);
}
-SortKind ScriptParser::readSortKind() {
+SortSectionPolicy ScriptParser::readSortKind() {
if (skip("SORT") || skip("SORT_BY_NAME"))
- return SortByName;
+ return SortSectionPolicy::Name;
if (skip("SORT_BY_ALIGNMENT"))
- return SortByAlignment;
+ return SortSectionPolicy::Alignment;
if (skip("SORT_BY_INIT_PRIORITY"))
- return SortByPriority;
- return SortNone;
+ return SortSectionPolicy::Priority;
+ // `SORT_NONE' disables section sorting by ignoring the command line
+ // section sorting option.
+ if (skip("SORT_NONE"))
+ return SortSectionPolicy::IgnoreConfig;
+ return SortSectionPolicy::None;
+}
+
+static void selectSortKind(InputSectionDescription *Cmd) {
+ if (Cmd->SortOuter == SortSectionPolicy::IgnoreConfig) {
+ Cmd->SortOuter = SortSectionPolicy::None;
+ return;
+ }
+
+ if (Cmd->SortOuter != SortSectionPolicy::None) {
+ // If the section sorting command in linker script is nested, the command
+ // line option will be ignored.
+ if (Cmd->SortInner != SortSectionPolicy::None)
+ return;
+ // If the section sorting command in linker script isn't nested, the
+ // command line option will make the section sorting command to be treated
+ // as nested sorting command.
+ Cmd->SortInner = Config->SortSection;
+ return;
+ }
+ // If sorting rule not specified, use command line option.
+ Cmd->SortOuter = Config->SortSection;
}
// Method reads a list of sequence of excluded files and section globs given in
@@ -1031,10 +1061,12 @@ ScriptParser::readInputSectionRules(Stri
expect("(");
// Read SORT().
- if (SortKind K1 = readSortKind()) {
+ SortSectionPolicy K1 = readSortKind();
+ if (K1 != SortSectionPolicy::None) {
Cmd->SortOuter = K1;
expect("(");
- if (SortKind K2 = readSortKind()) {
+ SortSectionPolicy K2 = readSortKind();
+ if (K2 != SortSectionPolicy::None) {
Cmd->SortInner = K2;
expect("(");
Cmd->SectionsVec.push_back({llvm::Regex(), readFilePatterns()});
@@ -1043,9 +1075,11 @@ ScriptParser::readInputSectionRules(Stri
Cmd->SectionsVec.push_back({llvm::Regex(), readFilePatterns()});
}
expect(")");
+ selectSortKind(Cmd);
return Cmd;
}
+ selectSortKind(Cmd);
readSectionExcludes(Cmd);
return Cmd;
}
Modified: lld/trunk/ELF/LinkerScript.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/LinkerScript.h?rev=281771&r1=281770&r2=281771&view=diff
==============================================================================
--- lld/trunk/ELF/LinkerScript.h (original)
+++ lld/trunk/ELF/LinkerScript.h Fri Sep 16 15:21:55 2016
@@ -10,6 +10,7 @@
#ifndef LLD_ELF_LINKER_SCRIPT_H
#define LLD_ELF_LINKER_SCRIPT_H
+#include "Config.h"
#include "Strings.h"
#include "Writer.h"
#include "lld/Core/LLVM.h"
@@ -97,16 +98,14 @@ struct OutputSectionCommand : BaseComman
ConstraintKind Constraint = ConstraintKind::NoConstraint;
};
-enum SortKind { SortNone, SortByPriority, SortByName, SortByAlignment };
-
struct InputSectionDescription : BaseCommand {
InputSectionDescription(StringRef FilePattern)
: BaseCommand(InputSectionKind),
FileRe(compileGlobPatterns({FilePattern})) {}
static bool classof(const BaseCommand *C);
llvm::Regex FileRe;
- SortKind SortOuter = SortNone;
- SortKind SortInner = SortNone;
+ SortSectionPolicy SortOuter = SortSectionPolicy::None;
+ SortSectionPolicy SortInner = SortSectionPolicy::None;
// Pairs of section regex and files excluded.
std::list<std::pair<llvm::Regex, llvm::Regex>> SectionsVec;
std::vector<InputSectionData *> Sections;
Modified: lld/trunk/ELF/Options.td
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/Options.td?rev=281771&r1=281770&r2=281771&view=diff
==============================================================================
--- lld/trunk/ELF/Options.td (original)
+++ lld/trunk/ELF/Options.td Fri Sep 16 15:21:55 2016
@@ -160,6 +160,8 @@ def shared: F<"shared">, HelpText<"Build
def soname: J<"soname=">, HelpText<"Set DT_SONAME">;
+def sort_section: S<"sort-section">, HelpText<"Specifies sections sorting rule when linkerscript is used">;
+
def start_lib: F<"start-lib">,
HelpText<"Start a grouping of objects that should be treated as if they were together in an archive">;
Modified: lld/trunk/test/ELF/linkerscript/sort-nested.s
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/ELF/linkerscript/sort-nested.s?rev=281771&r1=281770&r2=281771&view=diff
==============================================================================
--- lld/trunk/test/ELF/linkerscript/sort-nested.s (original)
+++ lld/trunk/test/ELF/linkerscript/sort-nested.s Fri Sep 16 15:21:55 2016
@@ -23,6 +23,16 @@
# SORTED_NA: 02000000 00000000 00000000 00000000
# SORTED_NA: 55000000 00000000
+## If the section sorting command in linker script isn't nested, the
+## command line option will make the section sorting command to be treated
+## as nested sorting command.
+# RUN: echo "SECTIONS { .aaa : { *(SORT_BY_ALIGNMENT(.aaa.*)) } }" > %t3.script
+# RUN: ld.lld --sort-section name -o %t3 --script %t3.script %t1.o %t2.o
+# RUN: llvm-objdump -s %t3 | FileCheck -check-prefix=SORTED_AN %s
+# RUN: echo "SECTIONS { .aaa : { *(SORT_BY_NAME(.aaa.*)) } }" > %t4.script
+# RUN: ld.lld --sort-section alignment -o %t4 --script %t4.script %t1.o %t2.o
+# RUN: llvm-objdump -s %t4 | FileCheck -check-prefix=SORTED_NA %s
+
.global _start
_start:
nop
Modified: lld/trunk/test/ELF/linkerscript/sort.s
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/ELF/linkerscript/sort.s?rev=281771&r1=281770&r2=281771&view=diff
==============================================================================
--- lld/trunk/test/ELF/linkerscript/sort.s (original)
+++ lld/trunk/test/ELF/linkerscript/sort.s Fri Sep 16 15:21:55 2016
@@ -66,6 +66,27 @@
# SORTED_ALIGNMENT-NEXT: 0180 44000000 00000000 01000000 00000000
# SORTED_ALIGNMENT-NEXT: 0190 55000000 00000000
+## SORT_NONE itself does not sort anything.
+# RUN: echo "SECTIONS { .aaa : { *(SORT_NONE(.aaa.*)) } }" > %t6.script
+# RUN: ld.lld -o %t7 --script %t6.script %t2.o %t1.o
+# RUN: llvm-objdump -s %t7 | FileCheck -check-prefix=UNSORTED %s
+
+## Check --sort-section alignment option.
+# RUN: echo "SECTIONS { .aaa : { *(.aaa.*) } }" > %t7.script
+# RUN: ld.lld --sort-section alignment -o %t8 --script %t7.script %t1.o %t2.o
+# RUN: llvm-objdump -s %t8 | FileCheck -check-prefix=SORTED_ALIGNMENT %s
+
+## Check --sort-section name option.
+# RUN: echo "SECTIONS { .aaa : { *(.aaa.*) } }" > %t8.script
+# RUN: ld.lld --sort-section name -o %t9 --script %t8.script %t1.o %t2.o
+# RUN: llvm-objdump -s %t9 | FileCheck -check-prefix=SORTED_B %s
+
+## SORT_NONE disables the --sort-section.
+# RUN: echo "SECTIONS { .aaa : { *(SORT_NONE(.aaa.*)) } }" > %t9.script
+# RUN: ld.lld --sort-section name -o %t10 --script %t9.script %t2.o %t1.o
+# RUN: llvm-objdump -s %t10 | FileCheck -check-prefix=UNSORTED %s
+
+
.global _start
_start:
nop
More information about the llvm-commits
mailing list