diff options
Diffstat (limited to 'lld/ELF/ScriptParser.cpp')
| -rw-r--r-- | lld/ELF/ScriptParser.cpp | 57 |
1 files changed, 52 insertions, 5 deletions
diff --git a/lld/ELF/ScriptParser.cpp b/lld/ELF/ScriptParser.cpp index 107b4c6e7af0..bdbce396cba1 100644 --- a/lld/ELF/ScriptParser.cpp +++ b/lld/ELF/ScriptParser.cpp @@ -87,6 +87,8 @@ private: OutputDesc *readOverlaySectionDescription(); OutputDesc *readOutputSectionDescription(StringRef outSec); SmallVector<SectionCommand *, 0> readOverlay(); + SectionClassDesc *readSectionClassDescription(); + StringRef readSectionClassName(); SmallVector<StringRef, 0> readOutputSectionPhdrs(); std::pair<uint64_t, uint64_t> readInputSectionFlags(); InputSectionDescription *readInputSectionDescription(StringRef tok); @@ -605,6 +607,33 @@ SmallVector<SectionCommand *, 0> ScriptParser::readOverlay() { return v; } +SectionClassDesc *ScriptParser::readSectionClassDescription() { + StringRef name = readSectionClassName(); + SectionClassDesc *desc = make<SectionClassDesc>(name); + if (!script->sectionClasses.insert({CachedHashStringRef(name), desc}).second) + setError("section class '" + name + "' already defined"); + expect("{"); + while (auto tok = till("}")) { + if (tok == "(" || tok == ")") { + setError("expected filename pattern"); + } else if (peek() == "(") { + InputSectionDescription *isd = readInputSectionDescription(tok); + if (!isd->classRef.empty()) + setError("section class '" + name + "' references class '" + + isd->classRef + "'"); + desc->sc.commands.push_back(isd); + } + } + return desc; +} + +StringRef ScriptParser::readSectionClassName() { + expect("("); + StringRef name = unquote(next()); + expect(")"); + return name; +} + void ScriptParser::readOverwriteSections() { expect("{"); while (auto tok = till("}")) @@ -619,7 +648,12 @@ void ScriptParser::readSections() { for (SectionCommand *cmd : readOverlay()) v.push_back(cmd); continue; - } else if (tok == "INCLUDE") { + } + if (tok == "CLASS") { + v.push_back(readSectionClassDescription()); + continue; + } + if (tok == "INCLUDE") { readInclude(); continue; } @@ -822,8 +856,14 @@ ScriptParser::readInputSectionDescription(StringRef tok) { expect("("); if (consume("INPUT_SECTION_FLAGS")) std::tie(withFlags, withoutFlags) = readInputSectionFlags(); - InputSectionDescription *cmd = - readInputSectionRules(next(), withFlags, withoutFlags); + + tok = next(); + InputSectionDescription *cmd; + if (tok == "CLASS") + cmd = make<InputSectionDescription>(StringRef{}, withFlags, withoutFlags, + readSectionClassName()); + else + cmd = readInputSectionRules(tok, withFlags, withoutFlags); expect(")"); script->keptSections.push_back(cmd); return cmd; @@ -832,6 +872,9 @@ ScriptParser::readInputSectionDescription(StringRef tok) { std::tie(withFlags, withoutFlags) = readInputSectionFlags(); tok = next(); } + if (tok == "CLASS") + return make<InputSectionDescription>(StringRef{}, withFlags, withoutFlags, + readSectionClassName()); return readInputSectionRules(tok, withFlags, withoutFlags); } @@ -951,8 +994,12 @@ OutputDesc *ScriptParser::readOverlaySectionDescription() { std::tie(withFlags, withoutFlags) = readInputSectionFlags(); tok = till(""); } - osd->osec.commands.push_back( - readInputSectionRules(tok, withFlags, withoutFlags)); + if (tok == "CLASS") + osd->osec.commands.push_back(make<InputSectionDescription>( + StringRef{}, withFlags, withoutFlags, readSectionClassName())); + else + osd->osec.commands.push_back( + readInputSectionRules(tok, withFlags, withoutFlags)); } osd->osec.phdrs = readOutputSectionPhdrs(); return osd; |
