From c998a8c04419456149c84ab60c4be30a566c8596 Mon Sep 17 00:00:00 2001 From: Rui Ueyama Date: Fri, 22 Apr 2016 00:03:13 +0000 Subject: [PATCH] ELF: Make the special variable "." as a LinkerScript class member. I will eventually make `evaluate` function a usual parse function rather than a function that works on a separate token list. This is the first step toward that. llvm-svn: 267083 --- lld/ELF/LinkerScript.cpp | 43 ++++++++++++++++++++++--------------------- lld/ELF/LinkerScript.h | 9 ++++++++- 2 files changed, 30 insertions(+), 22 deletions(-) diff --git a/lld/ELF/LinkerScript.cpp b/lld/ELF/LinkerScript.cpp index 6457bc3..43d8022 100644 --- a/lld/ELF/LinkerScript.cpp +++ b/lld/ELF/LinkerScript.cpp @@ -80,17 +80,16 @@ static bool expect(ArrayRef &Tokens, StringRef S) { return true; } -static uint64_t parseExpr(ArrayRef &Tokens, uint64_t Dot); - // This is a part of the operator-precedence parser to evaluate // arithmetic expressions in SECTIONS command. This function evaluates an // integer literal, a parenthesized expression or the special variable ".". -static uint64_t parsePrimary(ArrayRef &Tokens, uint64_t Dot) { +template +uint64_t LinkerScript::parsePrimary(ArrayRef &Tokens) { StringRef Tok = next(Tokens); if (Tok == ".") return Dot; if (Tok == "(") { - uint64_t V = parseExpr(Tokens, Dot); + uint64_t V = parseExpr(Tokens); if (!expect(Tokens, ")")) return 0; return V; @@ -121,15 +120,16 @@ static uint64_t apply(StringRef Op, uint64_t L, uint64_t R) { // This is an operator-precedence parser to evaluate // arithmetic expressions in SECTIONS command. // Tokens should start with an operator. -static uint64_t parseExpr1(uint64_t Lhs, int MinPrec, - ArrayRef &Tokens, uint64_t Dot) { +template +uint64_t LinkerScript::parseExpr1(ArrayRef &Tokens, + uint64_t Lhs, int MinPrec) { while (!Tokens.empty()) { // Read an operator and an expression. StringRef Op1 = Tokens.front(); if (precedence(Op1) < MinPrec) return Lhs; next(Tokens); - uint64_t Rhs = parsePrimary(Tokens, Dot); + uint64_t Rhs = parsePrimary(Tokens); // Evaluate the remaining part of the expression first if the // next operator has greater precedence than the previous one. @@ -139,7 +139,7 @@ static uint64_t parseExpr1(uint64_t Lhs, int MinPrec, StringRef Op2 = Tokens.front(); if (precedence(Op2) <= precedence(Op1)) break; - Rhs = parseExpr1(Rhs, precedence(Op2), Tokens, Dot); + Rhs = parseExpr1(Tokens, Rhs, precedence(Op2)); } Lhs = apply(Op1, Lhs, Rhs); @@ -147,14 +147,16 @@ static uint64_t parseExpr1(uint64_t Lhs, int MinPrec, return Lhs; } -static uint64_t parseExpr(ArrayRef &Tokens, uint64_t Dot) { - uint64_t V = parsePrimary(Tokens, Dot); - return parseExpr1(V, 0, Tokens, Dot); +template +uint64_t LinkerScript::parseExpr(ArrayRef &Tokens) { + uint64_t V = parsePrimary(Tokens); + return parseExpr1(Tokens, V, 0); } // Evaluates the expression given by list of tokens. -static uint64_t evaluate(ArrayRef Tokens, uint64_t Dot) { - uint64_t V = parseExpr(Tokens, Dot); +template +uint64_t LinkerScript::evaluate(ArrayRef Tokens) { + uint64_t V = parseExpr(Tokens); if (!Tokens.empty()) error("stray token: " + Tokens[0]); return V; @@ -207,13 +209,12 @@ void LinkerScript::assignAddresses( } // Assign addresses as instructed by linker script SECTIONS sub-commands. + Dot = Out::ElfHeader->getSize() + Out::ProgramHeaders->getSize(); uintX_t ThreadBssOffset = 0; - uintX_t VA = - Out::ElfHeader->getSize() + Out::ProgramHeaders->getSize(); for (SectionsCommand &Cmd : Opt.Commands) { if (Cmd.Kind == ExprKind) { - VA = evaluate(Cmd.Expr, VA); + Dot = evaluate(Cmd.Expr); continue; } @@ -222,17 +223,17 @@ void LinkerScript::assignAddresses( continue; if ((Sec->getFlags() & SHF_TLS) && Sec->getType() == SHT_NOBITS) { - uintX_t TVA = VA + ThreadBssOffset; + uintX_t TVA = Dot + ThreadBssOffset; TVA = alignTo(TVA, Sec->getAlign()); Sec->setVA(TVA); - ThreadBssOffset = TVA - VA + Sec->getSize(); + ThreadBssOffset = TVA - Dot + Sec->getSize(); continue; } if (Sec->getFlags() & SHF_ALLOC) { - VA = alignTo(VA, Sec->getAlign()); - Sec->setVA(VA); - VA += Sec->getSize(); + Dot = alignTo(Dot, Sec->getAlign()); + Sec->setVA(Dot); + Dot += Sec->getSize(); continue; } } diff --git a/lld/ELF/LinkerScript.h b/lld/ELF/LinkerScript.h index 88bc0ad..5c07e7f 100644 --- a/lld/ELF/LinkerScript.h +++ b/lld/ELF/LinkerScript.h @@ -86,10 +86,17 @@ public: int compareSections(StringRef A, StringRef B); private: + // "ScriptConfig" is a bit too long, so define a short name for it. + ScriptConfiguration &Opt = *ScriptConfig; + int getSectionIndex(StringRef Name); SectionRule *find(InputSectionBase *S); - ScriptConfiguration &Opt = *ScriptConfig; + uint64_t evaluate(ArrayRef Tokens); + uint64_t parseExpr(ArrayRef &Tokens); + uint64_t parsePrimary(ArrayRef &Tokens); + uint64_t parseExpr1(ArrayRef &Tokens, uint64_t Lhs, int MinPrec); + typename ELFT::uint Dot; }; // Variable template is a C++14 feature, so we can't template -- 2.7.4