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);
|
||||
}
|
||||
|
||||
template <class ELFT> struct SectionsSorter {
|
||||
SectionsSorter(SortKind Kind) : Kind(Kind) {}
|
||||
bool operator()(InputSectionBase<ELFT> *A, InputSectionBase<ELFT> *B) {
|
||||
int AlignmentCmp = A->Alignment - B->Alignment;
|
||||
if (Kind == SortKind::Align || (Kind == SortKind::AlignName && AlignmentCmp != 0))
|
||||
return AlignmentCmp > 0;
|
||||
template <class ELFT>
|
||||
static bool compareName(InputSectionBase<ELFT> *A, InputSectionBase<ELFT> *B) {
|
||||
return A->getSectionName() < B->getSectionName();
|
||||
}
|
||||
|
||||
int NameCmp = A->getSectionName().compare(B->getSectionName());
|
||||
if (Kind == SortKind::Name || (Kind == SortKind::NameAlign && NameCmp != 0))
|
||||
return NameCmp < 0;
|
||||
template <class ELFT>
|
||||
static bool compareAlignment(InputSectionBase<ELFT> *A,
|
||||
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)
|
||||
return AlignmentCmp > 0;
|
||||
if (Kind == SortKind::AlignName)
|
||||
return NameCmp < 0;
|
||||
|
||||
llvm_unreachable("unknown section sort kind in predicate");
|
||||
return false;
|
||||
}
|
||||
SortKind Kind;
|
||||
};
|
||||
template <class ELFT>
|
||||
static std::function<bool(InputSectionBase<ELFT> *, InputSectionBase<ELFT> *)>
|
||||
getComparator(SortKind K) {
|
||||
if (K == SortByName)
|
||||
return compareName<ELFT>;
|
||||
return compareAlignment<ELFT>;
|
||||
}
|
||||
|
||||
template <class ELFT>
|
||||
void LinkerScript<ELFT>::createSections(
|
||||
|
@ -173,9 +173,12 @@ void LinkerScript<ELFT>::createSections(
|
|||
continue;
|
||||
}
|
||||
|
||||
if (Cmd->Sort != SortKind::None)
|
||||
if (Cmd->SortInner)
|
||||
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)
|
||||
addSection(Factory, *OutputSections, S, OutputName);
|
||||
|
@ -489,6 +492,7 @@ private:
|
|||
std::vector<StringRef> readInputFilePatterns();
|
||||
InputSectionDescription *readInputSectionRules();
|
||||
unsigned readPhdrType();
|
||||
SortKind readSortKind();
|
||||
SymbolAssignment *readProvide(bool Hidden);
|
||||
Expr readAlign();
|
||||
void readSort();
|
||||
|
@ -731,41 +735,36 @@ std::vector<StringRef> ScriptParser::readInputFilePatterns() {
|
|||
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() {
|
||||
auto *Cmd = new InputSectionDescription;
|
||||
Cmd->FilePattern = next();
|
||||
expect("(");
|
||||
|
||||
// Read EXCLUDE_FILE().
|
||||
if (skip("EXCLUDE_FILE")) {
|
||||
expect("(");
|
||||
while (!Error && !skip(")"))
|
||||
Cmd->ExcludedFiles.push_back(next());
|
||||
}
|
||||
|
||||
if (skip("SORT") || skip("SORT_BY_NAME")) {
|
||||
// Read SORT().
|
||||
if (SortKind K1 = readSortKind()) {
|
||||
Cmd->SortOuter = K1;
|
||||
expect("(");
|
||||
if (skip("SORT_BY_ALIGNMENT")) {
|
||||
Cmd->Sort = SortKind::NameAlign;
|
||||
if (SortKind K2 = readSortKind()) {
|
||||
Cmd->SortInner = K2;
|
||||
expect("(");
|
||||
Cmd->SectionPatterns = readInputFilePatterns();
|
||||
expect(")");
|
||||
} 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();
|
||||
}
|
||||
expect(")");
|
||||
|
|
|
@ -88,13 +88,14 @@ struct OutputSectionCommand : BaseCommand {
|
|||
ConstraintKind Constraint = ConstraintKind::NoConstraint;
|
||||
};
|
||||
|
||||
enum class SortKind { None, Name, Align, NameAlign, AlignName };
|
||||
enum SortKind { SortNone, SortByName, SortByAlignment };
|
||||
|
||||
struct InputSectionDescription : BaseCommand {
|
||||
InputSectionDescription() : BaseCommand(InputSectionKind) {}
|
||||
static bool classof(const BaseCommand *C);
|
||||
StringRef FilePattern;
|
||||
SortKind Sort = SortKind::None;
|
||||
SortKind SortOuter = SortNone;
|
||||
SortKind SortInner = SortNone;
|
||||
std::vector<StringRef> ExcludedFiles;
|
||||
std::vector<StringRef> SectionPatterns;
|
||||
};
|
||||
|
|
Loading…
Reference in New Issue