ELF: Remove OutSection class and use a map instead.

It is easier to handle section filler data separately rather than
merging with section names.

llvm-svn: 262175
This commit is contained in:
Rui Ueyama 2016-02-28 05:09:11 +00:00
parent 7a6c9aed7a
commit 3e80897627
2 changed files with 19 additions and 24 deletions

View File

@ -55,21 +55,20 @@ template <class ELFT> bool LinkerScript::shouldKeep(InputSectionBase<ELFT> *S) {
} }
ArrayRef<uint8_t> LinkerScript::getFiller(StringRef Name) { ArrayRef<uint8_t> LinkerScript::getFiller(StringRef Name) {
for (OutSection &C : OutSections) auto I = Filler.find(Name);
if (C.Name == Name) if (I == Filler.end())
return C.Filler;
return {}; return {};
return I->second;
} }
// A compartor to sort output sections. Returns -1 or 1 if both // A compartor to sort output sections. Returns -1 or 1 if both
// A and B are mentioned in linker scripts. Otherwise, returns 0 // A and B are mentioned in linker scripts. Otherwise, returns 0
// to use the default rule which is implemented in Writer.cpp. // to use the default rule which is implemented in Writer.cpp.
int LinkerScript::compareSections(StringRef A, StringRef B) { int LinkerScript::compareSections(StringRef A, StringRef B) {
auto Begin = OutSections.begin(); auto E = SectionOrder.end();
auto End = OutSections.end(); auto I = std::find(SectionOrder.begin(), E, A);
auto I = std::find_if(Begin, End, [&](OutSection &C) { return C.Name == A; }); auto J = std::find(SectionOrder.begin(), E, B);
auto J = std::find_if(Begin, End, [&](OutSection &C) { return C.Name == B; }); if (I == E || J == E)
if (I == End || J == End)
return 0; return 0;
return I < J ? -1 : 1; return I < J ? -1 : 1;
} }
@ -429,18 +428,18 @@ std::vector<uint8_t> ScriptParser::parseHex(StringRef S) {
} }
void ScriptParser::readOutputSectionDescription() { void ScriptParser::readOutputSectionDescription() {
OutSection OutSec; StringRef OutSec = next();
OutSec.Name = next(); Script->SectionOrder.push_back(OutSec);
expect(":"); expect(":");
expect("{"); expect("{");
while (!Error && !skip("}")) { while (!Error && !skip("}")) {
StringRef Tok = next(); StringRef Tok = next();
if (Tok == "*") { if (Tok == "*") {
readSectionPatterns(OutSec.Name, false); readSectionPatterns(OutSec, false);
} else if (Tok == "KEEP") { } else if (Tok == "KEEP") {
expect("("); expect("(");
next(); // Skip * next(); // Skip *
readSectionPatterns(OutSec.Name, true); readSectionPatterns(OutSec, true);
expect(")"); expect(")");
} else { } else {
setError("Unknown command " + Tok); setError("Unknown command " + Tok);
@ -452,11 +451,10 @@ void ScriptParser::readOutputSectionDescription() {
setError("Filler should be a HEX value"); setError("Filler should be a HEX value");
return; return;
} }
Tok = Tok.substr(3); // Skip '=0x' Tok = Tok.substr(3);
OutSec.Filler = parseHex(Tok); Script->Filler[OutSec] = parseHex(Tok);
next(); next();
} }
Script->OutSections.push_back(OutSec);
} }
static bool isUnderSysroot(StringRef Path) { static bool isUnderSysroot(StringRef Path) {

View File

@ -40,11 +40,6 @@ private:
StringRef SectionPattern; StringRef SectionPattern;
}; };
struct OutSection {
StringRef Name;
std::vector<uint8_t> Filler;
};
// This is a runner of the linker script. // This is a runner of the linker script.
class LinkerScript { class LinkerScript {
friend class ScriptParser; friend class ScriptParser;
@ -66,9 +61,11 @@ private:
// SECTIONS commands. // SECTIONS commands.
std::vector<SectionRule> Sections; std::vector<SectionRule> Sections;
// Output sections information. // Output sections are sorted by this order.
// They are sorted by the order of the container. std::vector<StringRef> SectionOrder;
std::vector<OutSection> OutSections;
// Section fill attribute for each section.
llvm::StringMap<std::vector<uint8_t>> Filler;
llvm::BumpPtrAllocator Alloc; llvm::BumpPtrAllocator Alloc;
}; };