diff options
| author | Dimitry Andric <dim@FreeBSD.org> | 2023-07-26 19:03:47 +0000 |
|---|---|---|
| committer | Dimitry Andric <dim@FreeBSD.org> | 2023-07-26 19:04:23 +0000 |
| commit | 7fa27ce4a07f19b07799a767fc29416f3b625afb (patch) | |
| tree | 27825c83636c4de341eb09a74f49f5d38a15d165 /lld/ELF/ScriptParser.cpp | |
| parent | e3b557809604d036af6e00c60f012c2025b59a5e (diff) | |
Diffstat (limited to 'lld/ELF/ScriptParser.cpp')
| -rw-r--r-- | lld/ELF/ScriptParser.cpp | 83 |
1 files changed, 50 insertions, 33 deletions
diff --git a/lld/ELF/ScriptParser.cpp b/lld/ELF/ScriptParser.cpp index bb09bde5d22e..3577e78c0d98 100644 --- a/lld/ELF/ScriptParser.cpp +++ b/lld/ELF/ScriptParser.cpp @@ -145,7 +145,7 @@ private: } // namespace static StringRef unquote(StringRef s) { - if (s.startswith("\"")) + if (s.starts_with("\"")) return s.substr(1, s.size() - 2); return s; } @@ -177,6 +177,12 @@ static ExprValue bitAnd(ExprValue a, ExprValue b) { (a.getValue() & b.getValue()) - a.getSecAddr(), a.loc}; } +static ExprValue bitXor(ExprValue a, ExprValue b) { + moveAbsRight(a, b); + return {a.sec, a.forceAbsolute, + (a.getValue() ^ b.getValue()) - a.getSecAddr(), a.loc}; +} + static ExprValue bitOr(ExprValue a, ExprValue b) { moveAbsRight(a, b); return {a.sec, a.forceAbsolute, @@ -290,7 +296,7 @@ void ScriptParser::readDefsym(StringRef name) { } void ScriptParser::addFile(StringRef s) { - if (isUnderSysroot && s.startswith("/")) { + if (isUnderSysroot && s.starts_with("/")) { SmallString<128> pathData; StringRef path = (config->sysroot + s).toStringRef(pathData); if (sys::fs::exists(path)) @@ -300,17 +306,17 @@ void ScriptParser::addFile(StringRef s) { return; } - if (s.startswith("/")) { + if (s.starts_with("/")) { // Case 1: s is an absolute path. Just open it. ctx.driver.addFile(s, /*withLOption=*/false); - } else if (s.startswith("=")) { + } else if (s.starts_with("=")) { // Case 2: relative to the sysroot. if (config->sysroot.empty()) ctx.driver.addFile(s.substr(1), /*withLOption=*/false); else ctx.driver.addFile(saver().save(config->sysroot + "/" + s.substr(1)), /*withLOption=*/false); - } else if (s.startswith("-l")) { + } else if (s.starts_with("-l")) { // Case 3: search in the list of library paths. ctx.driver.addLibrary(s.substr(2)); } else { @@ -419,6 +425,7 @@ static std::pair<ELFKind, uint16_t> parseBfdName(StringRef s) { .Case("elf32-avr", {ELF32LEKind, EM_AVR}) .Case("elf32-iamcu", {ELF32LEKind, EM_IAMCU}) .Case("elf32-littlearm", {ELF32LEKind, EM_ARM}) + .Case("elf32-bigarm", {ELF32BEKind, EM_ARM}) .Case("elf32-x86-64", {ELF32LEKind, EM_X86_64}) .Case("elf64-aarch64", {ELF64LEKind, EM_AARCH64}) .Case("elf64-littleaarch64", {ELF64LEKind, EM_AARCH64}) @@ -438,6 +445,8 @@ static std::pair<ELFKind, uint16_t> parseBfdName(StringRef s) { .Case("elf64-littleriscv", {ELF64LEKind, EM_RISCV}) .Case("elf64-sparc", {ELF64BEKind, EM_SPARCV9}) .Case("elf32-msp430", {ELF32LEKind, EM_MSP430}) + .Case("elf32-loongarch", {ELF32LEKind, EM_LOONGARCH}) + .Case("elf64-loongarch", {ELF64LEKind, EM_LOONGARCH}) .Default({ELFNoneKind, EM_NONE}); } @@ -627,7 +636,7 @@ void ScriptParser::readTarget() { StringRef tok = unquote(next()); expect(")"); - if (tok.startswith("elf")) + if (tok.starts_with("elf")) config->formatBinary = false; else if (tok == "binary") config->formatBinary = true; @@ -637,12 +646,13 @@ void ScriptParser::readTarget() { static int precedence(StringRef op) { return StringSwitch<int>(op) - .Cases("*", "/", "%", 10) - .Cases("+", "-", 9) - .Cases("<<", ">>", 8) - .Cases("<", "<=", ">", ">=", 7) - .Cases("==", "!=", 6) - .Case("&", 5) + .Cases("*", "/", "%", 11) + .Cases("+", "-", 10) + .Cases("<<", ">>", 9) + .Cases("<", "<=", ">", ">=", 8) + .Cases("==", "!=", 7) + .Case("&", 6) + .Case("^", 5) .Case("|", 4) .Case("&&", 3) .Case("||", 2) @@ -660,6 +670,7 @@ StringMatcher ScriptParser::readFilePatterns() { SortSectionPolicy ScriptParser::peekSortKind() { return StringSwitch<SortSectionPolicy>(peek()) + .Case("REVERSE", SortSectionPolicy::Reverse) .Cases("SORT", "SORT_BY_NAME", SortSectionPolicy::Name) .Case("SORT_BY_ALIGNMENT", SortSectionPolicy::Alignment) .Case("SORT_BY_INIT_PRIORITY", SortSectionPolicy::Priority) @@ -834,7 +845,7 @@ bool ScriptParser::readSectionDirective(OutputSection *cmd, StringRef tok1, Stri // The value is a recognized literal SHT_*. cmd->type = it->second; skip(); - } else if (value.startswith("SHT_")) { + } else if (value.starts_with("SHT_")) { setError("unknown section type " + value); } else { // Otherwise, read an expression. @@ -896,11 +907,13 @@ OutputDesc *ScriptParser::readOverlaySectionDescription() { osd->osec.commands.push_back( readInputSectionRules(next(), withFlags, withoutFlags)); } + osd->osec.phdrs = readOutputSectionPhdrs(); return osd; } OutputDesc *ScriptParser::readOutputSectionDescription(StringRef outSec) { - OutputDesc *cmd = script->createOutputSection(outSec, getCurrentLocation()); + OutputDesc *cmd = + script->createOutputSection(unquote(outSec), getCurrentLocation()); OutputSection *osec = &cmd->osec; // Maybe relro. Will reset to false if DATA_SEGMENT_RELRO_END is absent. osec->relro = seenDataAlign && !seenRelroEnd; @@ -979,7 +992,7 @@ OutputDesc *ScriptParser::readOutputSectionDescription(StringRef outSec) { osec->phdrs = readOutputSectionPhdrs(); - if (peek() == "=" || peek().startswith("=")) { + if (peek() == "=" || peek().starts_with("=")) { inExpr = true; consume("="); osec->filler = readFill(); @@ -1039,11 +1052,11 @@ SymbolAssignment *ScriptParser::readAssignment(StringRef tok) { size_t oldPos = pos; SymbolAssignment *cmd = nullptr; const StringRef op = peek(); - if (op.startswith("=")) { + if (op.starts_with("=")) { // Support = followed by an expression without whitespace. SaveAndRestore saved(inExpr, true); cmd = readSymbolAssignment(tok); - } else if ((op.size() == 2 && op[1] == '=' && strchr("*/+-&|", op[0])) || + } else if ((op.size() == 2 && op[1] == '=' && strchr("*/+-&^|", op[0])) || op == "<<=" || op == ">>=") { cmd = readSymbolAssignment(tok); } else if (tok == "PROVIDE") { @@ -1070,7 +1083,7 @@ SymbolAssignment *ScriptParser::readSymbolAssignment(StringRef name) { name = unquote(name); StringRef op = next(); assert(op == "=" || op == "*=" || op == "/=" || op == "+=" || op == "-=" || - op == "&=" || op == "|=" || op == "<<=" || op == ">>="); + op == "&=" || op == "^=" || op == "|=" || op == "<<=" || op == ">>="); // Note: GNU ld does not support %= or ^=. Expr e = readExpr(); if (op != "=") { @@ -1090,11 +1103,13 @@ SymbolAssignment *ScriptParser::readSymbolAssignment(StringRef name) { case '-': return sub(lhs, e()); case '<': - return lhs.getValue() << e().getValue(); + return lhs.getValue() << e().getValue() % 64; case '>': - return lhs.getValue() >> e().getValue(); + return lhs.getValue() >> e().getValue() % 64; case '&': return lhs.getValue() & e().getValue(); + case '^': + return lhs.getValue() ^ e().getValue(); case '|': return lhs.getValue() | e().getValue(); default: @@ -1143,9 +1158,9 @@ Expr ScriptParser::combine(StringRef op, Expr l, Expr r) { }; } if (op == "<<") - return [=] { return l().getValue() << r().getValue(); }; + return [=] { return l().getValue() << r().getValue() % 64; }; if (op == ">>") - return [=] { return l().getValue() >> r().getValue(); }; + return [=] { return l().getValue() >> r().getValue() % 64; }; if (op == "<") return [=] { return l().getValue() < r().getValue(); }; if (op == ">") @@ -1164,6 +1179,8 @@ Expr ScriptParser::combine(StringRef op, Expr l, Expr r) { return [=] { return l().getValue() && r().getValue(); }; if (op == "&") return [=] { return bitAnd(l(), r()); }; + if (op == "^") + return [=] { return bitXor(l(), r()); }; if (op == "|") return [=] { return bitOr(l(), r()); }; llvm_unreachable("invalid operator"); @@ -1224,24 +1241,24 @@ Expr ScriptParser::readConstant() { static std::optional<uint64_t> parseInt(StringRef tok) { // Hexadecimal uint64_t val; - if (tok.startswith_insensitive("0x")) { + if (tok.starts_with_insensitive("0x")) { if (!to_integer(tok.substr(2), val, 16)) return std::nullopt; return val; } - if (tok.endswith_insensitive("H")) { + if (tok.ends_with_insensitive("H")) { if (!to_integer(tok.drop_back(), val, 16)) return std::nullopt; return val; } // Decimal - if (tok.endswith_insensitive("K")) { + if (tok.ends_with_insensitive("K")) { if (!to_integer(tok.drop_back(), val, 10)) return std::nullopt; return val * 1024; } - if (tok.endswith_insensitive("M")) { + if (tok.ends_with_insensitive("M")) { if (!to_integer(tok.drop_back(), val, 10)) return std::nullopt; return val * 1024 * 1024; @@ -1379,7 +1396,7 @@ Expr ScriptParser::readPrimary() { }; } if (tok == "ADDR") { - StringRef name = readParenLiteral(); + StringRef name = unquote(readParenLiteral()); OutputSection *osec = &script->getOrCreateOutputSection(name)->osec; osec->usedInExpression = true; return [=]() -> ExprValue { @@ -1404,7 +1421,7 @@ Expr ScriptParser::readPrimary() { }; } if (tok == "ALIGNOF") { - StringRef name = readParenLiteral(); + StringRef name = unquote(readParenLiteral()); OutputSection *osec = &script->getOrCreateOutputSection(name)->osec; return [=] { checkIfExists(*osec, location); @@ -1462,7 +1479,7 @@ Expr ScriptParser::readPrimary() { return script->memoryRegions[name]->length; } if (tok == "LOADADDR") { - StringRef name = readParenLiteral(); + StringRef name = unquote(readParenLiteral()); OutputSection *osec = &script->getOrCreateOutputSection(name)->osec; osec->usedInExpression = true; return [=] { @@ -1506,7 +1523,7 @@ Expr ScriptParser::readPrimary() { return [=] { return e(); }; } if (tok == "SIZEOF") { - StringRef name = readParenLiteral(); + StringRef name = unquote(readParenLiteral()); OutputSection *cmd = &script->getOrCreateOutputSection(name)->osec; // Linker script does not create an output section if its content is empty. // We want to allow SIZEOF(.foo) where .foo is a section which happened to @@ -1525,7 +1542,7 @@ Expr ScriptParser::readPrimary() { return [=] { return *val; }; // Tok is a symbol name. - if (tok.startswith("\"")) + if (tok.starts_with("\"")) tok = unquote(tok); else if (!isValidSymbolName(tok)) setError("malformed number: " + tok); @@ -1549,7 +1566,7 @@ Expr ScriptParser::readParenExpr() { SmallVector<StringRef, 0> ScriptParser::readOutputSectionPhdrs() { SmallVector<StringRef, 0> phdrs; - while (!errorCount() && peek().startswith(":")) { + while (!errorCount() && peek().starts_with(":")) { StringRef tok = next(); phdrs.push_back((tok.size() == 1) ? next() : tok.substr(1)); } @@ -1676,7 +1693,7 @@ SmallVector<SymbolVersion, 0> ScriptParser::readVersionExtern() { while (!errorCount() && peek() != "}") { StringRef tok = next(); ret.push_back( - {unquote(tok), isCXX, !tok.startswith("\"") && hasWildcard(tok)}); + {unquote(tok), isCXX, !tok.starts_with("\"") && hasWildcard(tok)}); if (consume("}")) return ret; expect(";"); |
