Simplify SORT and --sort-section command line option handling.

Differential Revision: https://reviews.llvm.org/D24685

llvm-svn: 282006
This commit is contained in:
Rui Ueyama 2016-09-20 19:42:41 +00:00
parent db3438abcb
commit ee92470969
2 changed files with 28 additions and 30 deletions

View File

@ -156,6 +156,12 @@ static bool matchConstraints(ArrayRef<InputSectionBase<ELFT> *> Sections,
});
}
static void sortSections(std::vector<InputSectionData *> &Sections,
SortSectionPolicy K) {
if (K != SortSectionPolicy::Default && K != SortSectionPolicy::None)
std::stable_sort(Sections.begin(), Sections.end(), getComparator(K));
}
// Compute and remember which sections the InputSectionDescription matches.
template <class ELFT>
void LinkerScript<ELFT>::computeInputSections(InputSectionDescription *I) {
@ -175,13 +181,24 @@ void LinkerScript<ELFT>::computeInputSections(InputSectionDescription *I) {
}
}
// Sort for SORT() commands.
if (I->SortInner != SortSectionPolicy::Default)
std::stable_sort(I->Sections.begin(), I->Sections.end(),
getComparator(I->SortInner));
if (I->SortOuter != SortSectionPolicy::Default)
std::stable_sort(I->Sections.begin(), I->Sections.end(),
getComparator(I->SortOuter));
// Sort sections as instructed by SORT-family commands and --sort-section
// option. Because SORT-family commands can be nested at most two depth
// (e.g. SORT_BY_NAME(SORT_BY_ALIGNMENT(.text.*))) and because the command
// line option is respected even if a SORT command is given, the exact
// behavior we have here is a bit complicated. Here are the rules.
//
// 1. If two SORT commands are given, --sort-section is ignored.
// 2. If one SORT command is given, and if it is not SORT_NONE,
// --sort-section is handled as an inner SORT command.
// 3. If one SORT command is given, and if it is SORT_NONE, don't sort.
// 4. If no SORT command is given, sort according to --sort-section.
if (I->SortOuter != SortSectionPolicy::None) {
if (I->SortInner == SortSectionPolicy::Default)
sortSections(I->Sections, Config->SortSection);
else
sortSections(I->Sections, I->SortInner);
sortSections(I->Sections, I->SortOuter);
}
// We do not add duplicate input sections, so mark them with a dummy output
// section for now.
@ -1058,27 +1075,6 @@ SortSectionPolicy ScriptParser::readSortKind() {
return SortSectionPolicy::Default;
}
static void selectSortKind(InputSectionDescription *Cmd) {
if (Cmd->SortOuter == SortSectionPolicy::None) {
Cmd->SortOuter = SortSectionPolicy::Default;
return;
}
if (Cmd->SortOuter != SortSectionPolicy::Default) {
// If the section sorting command in linker script is nested, the command
// line option will be ignored.
if (Cmd->SortInner != SortSectionPolicy::Default)
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
// a following form: ((EXCLUDE_FILE(file_pattern+))? section_pattern+)+
// Example: *(.foo.1 EXCLUDE_FILE (*a.o) .foo.2 EXCLUDE_FILE (*b.o) .foo.3)
@ -1133,11 +1129,9 @@ ScriptParser::readInputSectionRules(StringRef FilePattern) {
Cmd->SectionPatterns.push_back({Regex(), readFilePatterns()});
}
expect(")");
selectSortKind(Cmd);
return Cmd;
}
selectSortKind(Cmd);
readSectionExcludes(Cmd);
return Cmd;
}

View File

@ -86,6 +86,10 @@
# 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
## SORT_NONE as a inner sort directive.
# RUN: echo "SECTIONS { .aaa : { *(SORT_BY_NAME(SORT_NONE(.aaa.*))) } }" > %t10.script
# RUN: ld.lld -o %t11 --script %t10.script %t2.o %t1.o
# RUN: llvm-objdump -s %t11 | FileCheck -check-prefix=SORTED_A %s
.global _start
_start: