forked from OSchip/llvm-project
Split InputSectionDescription::Sort into SortInner and SortOuter.
Summary: The comparator function to compare input sections as instructed by SORT command was a bit too complicated because it needed to handle four different cases. This patch split it into two function calls. This patch also simplifies the parser. Reviewers: grimar Subscribers: llvm-commits Differential Revision: https://reviews.llvm.org/D23140 llvm-svn: 277780
This commit is contained in:
parent
3bade138b5
commit
742c38361b
|
@ -135,27 +135,27 @@ static void addSection(OutputSectionFactory<ELFT> &Factory,
|
||||||
Sec->addSection(C);
|
Sec->addSection(C);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class ELFT> struct SectionsSorter {
|
template <class ELFT>
|
||||||
SectionsSorter(SortKind Kind) : Kind(Kind) {}
|
static bool compareName(InputSectionBase<ELFT> *A, InputSectionBase<ELFT> *B) {
|
||||||
bool operator()(InputSectionBase<ELFT> *A, InputSectionBase<ELFT> *B) {
|
return A->getSectionName() < B->getSectionName();
|
||||||
int AlignmentCmp = A->Alignment - B->Alignment;
|
}
|
||||||
if (Kind == SortKind::Align || (Kind == SortKind::AlignName && AlignmentCmp != 0))
|
|
||||||
return AlignmentCmp > 0;
|
|
||||||
|
|
||||||
int NameCmp = A->getSectionName().compare(B->getSectionName());
|
template <class ELFT>
|
||||||
if (Kind == SortKind::Name || (Kind == SortKind::NameAlign && NameCmp != 0))
|
static bool compareAlignment(InputSectionBase<ELFT> *A,
|
||||||
return NameCmp < 0;
|
InputSectionBase<ELFT> *B) {
|
||||||
|
// ">" is not a mistake. Larger alignments are placed before smaller
|
||||||
|
// alignments in order to reduce the amount of padding necessary.
|
||||||
|
// This is compatible with GNU.
|
||||||
|
return A->Alignment > B->Alignment;
|
||||||
|
}
|
||||||
|
|
||||||
if (Kind == SortKind::NameAlign)
|
template <class ELFT>
|
||||||
return AlignmentCmp > 0;
|
static std::function<bool(InputSectionBase<ELFT> *, InputSectionBase<ELFT> *)>
|
||||||
if (Kind == SortKind::AlignName)
|
getComparator(SortKind K) {
|
||||||
return NameCmp < 0;
|
if (K == SortByName)
|
||||||
|
return compareName<ELFT>;
|
||||||
llvm_unreachable("unknown section sort kind in predicate");
|
return compareAlignment<ELFT>;
|
||||||
return false;
|
}
|
||||||
}
|
|
||||||
SortKind Kind;
|
|
||||||
};
|
|
||||||
|
|
||||||
template <class ELFT>
|
template <class ELFT>
|
||||||
void LinkerScript<ELFT>::createSections(
|
void LinkerScript<ELFT>::createSections(
|
||||||
|
@ -173,9 +173,12 @@ void LinkerScript<ELFT>::createSections(
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Cmd->Sort != SortKind::None)
|
if (Cmd->SortInner)
|
||||||
std::stable_sort(Sections.begin(), Sections.end(),
|
std::stable_sort(Sections.begin(), Sections.end(),
|
||||||
SectionsSorter<ELFT>(Cmd->Sort));
|
getComparator<ELFT>(Cmd->SortInner));
|
||||||
|
if (Cmd->SortOuter)
|
||||||
|
std::stable_sort(Sections.begin(), Sections.end(),
|
||||||
|
getComparator<ELFT>(Cmd->SortOuter));
|
||||||
|
|
||||||
for (InputSectionBase<ELFT> *S : Sections)
|
for (InputSectionBase<ELFT> *S : Sections)
|
||||||
addSection(Factory, *OutputSections, S, OutputName);
|
addSection(Factory, *OutputSections, S, OutputName);
|
||||||
|
@ -489,6 +492,7 @@ private:
|
||||||
std::vector<StringRef> readInputFilePatterns();
|
std::vector<StringRef> readInputFilePatterns();
|
||||||
InputSectionDescription *readInputSectionRules();
|
InputSectionDescription *readInputSectionRules();
|
||||||
unsigned readPhdrType();
|
unsigned readPhdrType();
|
||||||
|
SortKind readSortKind();
|
||||||
SymbolAssignment *readProvide(bool Hidden);
|
SymbolAssignment *readProvide(bool Hidden);
|
||||||
Expr readAlign();
|
Expr readAlign();
|
||||||
void readSort();
|
void readSort();
|
||||||
|
@ -731,41 +735,36 @@ std::vector<StringRef> ScriptParser::readInputFilePatterns() {
|
||||||
return V;
|
return V;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
SortKind ScriptParser::readSortKind() {
|
||||||
|
if (skip("SORT") || skip("SORT_BY_NAME"))
|
||||||
|
return SortByName;
|
||||||
|
if (skip("SORT_BY_ALIGNMENT"))
|
||||||
|
return SortByAlignment;
|
||||||
|
return SortNone;
|
||||||
|
}
|
||||||
|
|
||||||
InputSectionDescription *ScriptParser::readInputSectionRules() {
|
InputSectionDescription *ScriptParser::readInputSectionRules() {
|
||||||
auto *Cmd = new InputSectionDescription;
|
auto *Cmd = new InputSectionDescription;
|
||||||
Cmd->FilePattern = next();
|
Cmd->FilePattern = next();
|
||||||
expect("(");
|
expect("(");
|
||||||
|
|
||||||
|
// Read EXCLUDE_FILE().
|
||||||
if (skip("EXCLUDE_FILE")) {
|
if (skip("EXCLUDE_FILE")) {
|
||||||
expect("(");
|
expect("(");
|
||||||
while (!Error && !skip(")"))
|
while (!Error && !skip(")"))
|
||||||
Cmd->ExcludedFiles.push_back(next());
|
Cmd->ExcludedFiles.push_back(next());
|
||||||
}
|
}
|
||||||
|
|
||||||
if (skip("SORT") || skip("SORT_BY_NAME")) {
|
// Read SORT().
|
||||||
|
if (SortKind K1 = readSortKind()) {
|
||||||
|
Cmd->SortOuter = K1;
|
||||||
expect("(");
|
expect("(");
|
||||||
if (skip("SORT_BY_ALIGNMENT")) {
|
if (SortKind K2 = readSortKind()) {
|
||||||
Cmd->Sort = SortKind::NameAlign;
|
Cmd->SortInner = K2;
|
||||||
expect("(");
|
expect("(");
|
||||||
Cmd->SectionPatterns = readInputFilePatterns();
|
Cmd->SectionPatterns = readInputFilePatterns();
|
||||||
expect(")");
|
expect(")");
|
||||||
} else {
|
} else {
|
||||||
Cmd->Sort = SortKind::Name;
|
|
||||||
Cmd->SectionPatterns = readInputFilePatterns();
|
|
||||||
}
|
|
||||||
expect(")");
|
|
||||||
return Cmd;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (skip("SORT_BY_ALIGNMENT")) {
|
|
||||||
expect("(");
|
|
||||||
if (skip("SORT") || skip("SORT_BY_NAME")) {
|
|
||||||
Cmd->Sort = SortKind::AlignName;
|
|
||||||
expect("(");
|
|
||||||
Cmd->SectionPatterns = readInputFilePatterns();
|
|
||||||
expect(")");
|
|
||||||
} else {
|
|
||||||
Cmd->Sort = SortKind::Align;
|
|
||||||
Cmd->SectionPatterns = readInputFilePatterns();
|
Cmd->SectionPatterns = readInputFilePatterns();
|
||||||
}
|
}
|
||||||
expect(")");
|
expect(")");
|
||||||
|
|
|
@ -88,13 +88,14 @@ struct OutputSectionCommand : BaseCommand {
|
||||||
ConstraintKind Constraint = ConstraintKind::NoConstraint;
|
ConstraintKind Constraint = ConstraintKind::NoConstraint;
|
||||||
};
|
};
|
||||||
|
|
||||||
enum class SortKind { None, Name, Align, NameAlign, AlignName };
|
enum SortKind { SortNone, SortByName, SortByAlignment };
|
||||||
|
|
||||||
struct InputSectionDescription : BaseCommand {
|
struct InputSectionDescription : BaseCommand {
|
||||||
InputSectionDescription() : BaseCommand(InputSectionKind) {}
|
InputSectionDescription() : BaseCommand(InputSectionKind) {}
|
||||||
static bool classof(const BaseCommand *C);
|
static bool classof(const BaseCommand *C);
|
||||||
StringRef FilePattern;
|
StringRef FilePattern;
|
||||||
SortKind Sort = SortKind::None;
|
SortKind SortOuter = SortNone;
|
||||||
|
SortKind SortInner = SortNone;
|
||||||
std::vector<StringRef> ExcludedFiles;
|
std::vector<StringRef> ExcludedFiles;
|
||||||
std::vector<StringRef> SectionPatterns;
|
std::vector<StringRef> SectionPatterns;
|
||||||
};
|
};
|
||||||
|
|
Loading…
Reference in New Issue