xref: /openbsd-src/gnu/llvm/lld/ELF/ScriptParser.cpp (revision 42a61acefa8b3288ff2163fb55e934a3fee39974)
1ece8a530Spatrick //===- ScriptParser.cpp ---------------------------------------------------===//
2ece8a530Spatrick //
3ece8a530Spatrick // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4ece8a530Spatrick // See https://llvm.org/LICENSE.txt for license information.
5ece8a530Spatrick // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6ece8a530Spatrick //
7ece8a530Spatrick //===----------------------------------------------------------------------===//
8ece8a530Spatrick //
9ece8a530Spatrick // This file contains a recursive-descendent parser for linker scripts.
10ece8a530Spatrick // Parsed results are stored to Config and Script global objects.
11ece8a530Spatrick //
12ece8a530Spatrick //===----------------------------------------------------------------------===//
13ece8a530Spatrick 
14ece8a530Spatrick #include "ScriptParser.h"
15ece8a530Spatrick #include "Config.h"
16ece8a530Spatrick #include "Driver.h"
1705edf1c1Srobert #include "InputFiles.h"
18ece8a530Spatrick #include "LinkerScript.h"
19ece8a530Spatrick #include "OutputSections.h"
20ece8a530Spatrick #include "ScriptLexer.h"
2105edf1c1Srobert #include "SymbolTable.h"
22ece8a530Spatrick #include "Symbols.h"
23ece8a530Spatrick #include "Target.h"
2405edf1c1Srobert #include "lld/Common/CommonLinkerContext.h"
25ece8a530Spatrick #include "llvm/ADT/SmallString.h"
26ece8a530Spatrick #include "llvm/ADT/StringRef.h"
27ece8a530Spatrick #include "llvm/ADT/StringSet.h"
28ece8a530Spatrick #include "llvm/ADT/StringSwitch.h"
29ece8a530Spatrick #include "llvm/BinaryFormat/ELF.h"
30ece8a530Spatrick #include "llvm/Support/Casting.h"
31ece8a530Spatrick #include "llvm/Support/ErrorHandling.h"
32ece8a530Spatrick #include "llvm/Support/FileSystem.h"
331cf9926bSpatrick #include "llvm/Support/MathExtras.h"
34ece8a530Spatrick #include "llvm/Support/Path.h"
3505edf1c1Srobert #include "llvm/Support/SaveAndRestore.h"
361cf9926bSpatrick #include "llvm/Support/TimeProfiler.h"
37ece8a530Spatrick #include <cassert>
38ece8a530Spatrick #include <limits>
39ece8a530Spatrick #include <vector>
40ece8a530Spatrick 
41ece8a530Spatrick using namespace llvm;
42ece8a530Spatrick using namespace llvm::ELF;
43ece8a530Spatrick using namespace llvm::support::endian;
44bb684c34Spatrick using namespace lld;
45bb684c34Spatrick using namespace lld::elf;
46ece8a530Spatrick 
47ece8a530Spatrick namespace {
48ece8a530Spatrick class ScriptParser final : ScriptLexer {
49ece8a530Spatrick public:
ScriptParser(MemoryBufferRef mb)50ece8a530Spatrick   ScriptParser(MemoryBufferRef mb) : ScriptLexer(mb) {
51ece8a530Spatrick     // Initialize IsUnderSysroot
52ece8a530Spatrick     if (config->sysroot == "")
53ece8a530Spatrick       return;
54ece8a530Spatrick     StringRef path = mb.getBufferIdentifier();
55ece8a530Spatrick     for (; !path.empty(); path = sys::path::parent_path(path)) {
56ece8a530Spatrick       if (!sys::fs::equivalent(config->sysroot, path))
57ece8a530Spatrick         continue;
58ece8a530Spatrick       isUnderSysroot = true;
59ece8a530Spatrick       return;
60ece8a530Spatrick     }
61ece8a530Spatrick   }
62ece8a530Spatrick 
63ece8a530Spatrick   void readLinkerScript();
64ece8a530Spatrick   void readVersionScript();
65ece8a530Spatrick   void readDynamicList();
66ece8a530Spatrick   void readDefsym(StringRef name);
67ece8a530Spatrick 
68ece8a530Spatrick private:
69ece8a530Spatrick   void addFile(StringRef path);
70ece8a530Spatrick 
71ece8a530Spatrick   void readAsNeeded();
72ece8a530Spatrick   void readEntry();
73ece8a530Spatrick   void readExtern();
74ece8a530Spatrick   void readGroup();
75ece8a530Spatrick   void readInclude();
76ece8a530Spatrick   void readInput();
77ece8a530Spatrick   void readMemory();
78ece8a530Spatrick   void readOutput();
79ece8a530Spatrick   void readOutputArch();
80ece8a530Spatrick   void readOutputFormat();
811cf9926bSpatrick   void readOverwriteSections();
82ece8a530Spatrick   void readPhdrs();
83ece8a530Spatrick   void readRegionAlias();
84ece8a530Spatrick   void readSearchDir();
85ece8a530Spatrick   void readSections();
86ece8a530Spatrick   void readTarget();
87ece8a530Spatrick   void readVersion();
88ece8a530Spatrick   void readVersionScriptCommand();
89ece8a530Spatrick 
90ece8a530Spatrick   SymbolAssignment *readSymbolAssignment(StringRef name);
91ece8a530Spatrick   ByteCommand *readByteCommand(StringRef tok);
92ece8a530Spatrick   std::array<uint8_t, 4> readFill();
93ece8a530Spatrick   bool readSectionDirective(OutputSection *cmd, StringRef tok1, StringRef tok2);
94ece8a530Spatrick   void readSectionAddressType(OutputSection *cmd);
9505edf1c1Srobert   OutputDesc *readOverlaySectionDescription();
9605edf1c1Srobert   OutputDesc *readOutputSectionDescription(StringRef outSec);
9705edf1c1Srobert   SmallVector<SectionCommand *, 0> readOverlay();
9805edf1c1Srobert   SmallVector<StringRef, 0> readOutputSectionPhdrs();
99bb684c34Spatrick   std::pair<uint64_t, uint64_t> readInputSectionFlags();
100ece8a530Spatrick   InputSectionDescription *readInputSectionDescription(StringRef tok);
101ece8a530Spatrick   StringMatcher readFilePatterns();
10205edf1c1Srobert   SmallVector<SectionPattern, 0> readInputSectionsList();
103bb684c34Spatrick   InputSectionDescription *readInputSectionRules(StringRef filePattern,
104bb684c34Spatrick                                                  uint64_t withFlags,
105bb684c34Spatrick                                                  uint64_t withoutFlags);
106ece8a530Spatrick   unsigned readPhdrType();
1071cf9926bSpatrick   SortSectionPolicy peekSortKind();
108ece8a530Spatrick   SortSectionPolicy readSortKind();
109ece8a530Spatrick   SymbolAssignment *readProvideHidden(bool provide, bool hidden);
110ece8a530Spatrick   SymbolAssignment *readAssignment(StringRef tok);
111ece8a530Spatrick   void readSort();
112ece8a530Spatrick   Expr readAssert();
113ece8a530Spatrick   Expr readConstant();
114ece8a530Spatrick   Expr getPageSize();
115ece8a530Spatrick 
116bb684c34Spatrick   Expr readMemoryAssignment(StringRef, StringRef, StringRef);
11705edf1c1Srobert   void readMemoryAttributes(uint32_t &flags, uint32_t &invFlags,
11805edf1c1Srobert                             uint32_t &negFlags, uint32_t &negInvFlags);
119ece8a530Spatrick 
120ece8a530Spatrick   Expr combine(StringRef op, Expr l, Expr r);
121ece8a530Spatrick   Expr readExpr();
122ece8a530Spatrick   Expr readExpr1(Expr lhs, int minPrec);
123ece8a530Spatrick   StringRef readParenLiteral();
124ece8a530Spatrick   Expr readPrimary();
125ece8a530Spatrick   Expr readTernary(Expr cond);
126ece8a530Spatrick   Expr readParenExpr();
127ece8a530Spatrick 
128ece8a530Spatrick   // For parsing version script.
12905edf1c1Srobert   SmallVector<SymbolVersion, 0> readVersionExtern();
130ece8a530Spatrick   void readAnonymousDeclaration();
131ece8a530Spatrick   void readVersionDeclaration(StringRef verStr);
132ece8a530Spatrick 
13305edf1c1Srobert   std::pair<SmallVector<SymbolVersion, 0>, SmallVector<SymbolVersion, 0>>
134ece8a530Spatrick   readSymbols();
135ece8a530Spatrick 
13605edf1c1Srobert   // True if a script being read is in the --sysroot directory.
137ece8a530Spatrick   bool isUnderSysroot = false;
138ece8a530Spatrick 
13905edf1c1Srobert   bool seenDataAlign = false;
14005edf1c1Srobert   bool seenRelroEnd = false;
14105edf1c1Srobert 
142ece8a530Spatrick   // A set to detect an INCLUDE() cycle.
143ece8a530Spatrick   StringSet<> seen;
144ece8a530Spatrick };
145ece8a530Spatrick } // namespace
146ece8a530Spatrick 
unquote(StringRef s)147ece8a530Spatrick static StringRef unquote(StringRef s) {
148ece8a530Spatrick   if (s.startswith("\""))
149ece8a530Spatrick     return s.substr(1, s.size() - 2);
150ece8a530Spatrick   return s;
151ece8a530Spatrick }
152ece8a530Spatrick 
153ece8a530Spatrick // Some operations only support one non absolute value. Move the
154ece8a530Spatrick // absolute one to the right hand side for convenience.
moveAbsRight(ExprValue & a,ExprValue & b)155ece8a530Spatrick static void moveAbsRight(ExprValue &a, ExprValue &b) {
156ece8a530Spatrick   if (a.sec == nullptr || (a.forceAbsolute && !b.isAbsolute()))
157ece8a530Spatrick     std::swap(a, b);
158ece8a530Spatrick   if (!b.isAbsolute())
159ece8a530Spatrick     error(a.loc + ": at least one side of the expression must be absolute");
160ece8a530Spatrick }
161ece8a530Spatrick 
add(ExprValue a,ExprValue b)162ece8a530Spatrick static ExprValue add(ExprValue a, ExprValue b) {
163ece8a530Spatrick   moveAbsRight(a, b);
164ece8a530Spatrick   return {a.sec, a.forceAbsolute, a.getSectionOffset() + b.getValue(), a.loc};
165ece8a530Spatrick }
166ece8a530Spatrick 
sub(ExprValue a,ExprValue b)167ece8a530Spatrick static ExprValue sub(ExprValue a, ExprValue b) {
168ece8a530Spatrick   // The distance between two symbols in sections is absolute.
169ece8a530Spatrick   if (!a.isAbsolute() && !b.isAbsolute())
170ece8a530Spatrick     return a.getValue() - b.getValue();
171ece8a530Spatrick   return {a.sec, false, a.getSectionOffset() - b.getValue(), a.loc};
172ece8a530Spatrick }
173ece8a530Spatrick 
bitAnd(ExprValue a,ExprValue b)174ece8a530Spatrick static ExprValue bitAnd(ExprValue a, ExprValue b) {
175ece8a530Spatrick   moveAbsRight(a, b);
176ece8a530Spatrick   return {a.sec, a.forceAbsolute,
177ece8a530Spatrick           (a.getValue() & b.getValue()) - a.getSecAddr(), a.loc};
178ece8a530Spatrick }
179ece8a530Spatrick 
bitOr(ExprValue a,ExprValue b)180ece8a530Spatrick static ExprValue bitOr(ExprValue a, ExprValue b) {
181ece8a530Spatrick   moveAbsRight(a, b);
182ece8a530Spatrick   return {a.sec, a.forceAbsolute,
183ece8a530Spatrick           (a.getValue() | b.getValue()) - a.getSecAddr(), a.loc};
184ece8a530Spatrick }
185ece8a530Spatrick 
readDynamicList()186ece8a530Spatrick void ScriptParser::readDynamicList() {
187ece8a530Spatrick   expect("{");
18805edf1c1Srobert   SmallVector<SymbolVersion, 0> locals;
18905edf1c1Srobert   SmallVector<SymbolVersion, 0> globals;
190ece8a530Spatrick   std::tie(locals, globals) = readSymbols();
191ece8a530Spatrick   expect(";");
192ece8a530Spatrick 
193ece8a530Spatrick   if (!atEOF()) {
194ece8a530Spatrick     setError("EOF expected, but got " + next());
195ece8a530Spatrick     return;
196ece8a530Spatrick   }
197ece8a530Spatrick   if (!locals.empty()) {
198ece8a530Spatrick     setError("\"local:\" scope not supported in --dynamic-list");
199ece8a530Spatrick     return;
200ece8a530Spatrick   }
201ece8a530Spatrick 
202ece8a530Spatrick   for (SymbolVersion v : globals)
203ece8a530Spatrick     config->dynamicList.push_back(v);
204ece8a530Spatrick }
205ece8a530Spatrick 
readVersionScript()206ece8a530Spatrick void ScriptParser::readVersionScript() {
207ece8a530Spatrick   readVersionScriptCommand();
208ece8a530Spatrick   if (!atEOF())
209ece8a530Spatrick     setError("EOF expected, but got " + next());
210ece8a530Spatrick }
211ece8a530Spatrick 
readVersionScriptCommand()212ece8a530Spatrick void ScriptParser::readVersionScriptCommand() {
213ece8a530Spatrick   if (consume("{")) {
214ece8a530Spatrick     readAnonymousDeclaration();
215ece8a530Spatrick     return;
216ece8a530Spatrick   }
217ece8a530Spatrick 
218ece8a530Spatrick   while (!atEOF() && !errorCount() && peek() != "}") {
219ece8a530Spatrick     StringRef verStr = next();
220ece8a530Spatrick     if (verStr == "{") {
221ece8a530Spatrick       setError("anonymous version definition is used in "
222ece8a530Spatrick                "combination with other version definitions");
223ece8a530Spatrick       return;
224ece8a530Spatrick     }
225ece8a530Spatrick     expect("{");
226ece8a530Spatrick     readVersionDeclaration(verStr);
227ece8a530Spatrick   }
228ece8a530Spatrick }
229ece8a530Spatrick 
readVersion()230ece8a530Spatrick void ScriptParser::readVersion() {
231ece8a530Spatrick   expect("{");
232ece8a530Spatrick   readVersionScriptCommand();
233ece8a530Spatrick   expect("}");
234ece8a530Spatrick }
235ece8a530Spatrick 
readLinkerScript()236ece8a530Spatrick void ScriptParser::readLinkerScript() {
237ece8a530Spatrick   while (!atEOF()) {
238ece8a530Spatrick     StringRef tok = next();
239ece8a530Spatrick     if (tok == ";")
240ece8a530Spatrick       continue;
241ece8a530Spatrick 
242ece8a530Spatrick     if (tok == "ENTRY") {
243ece8a530Spatrick       readEntry();
244ece8a530Spatrick     } else if (tok == "EXTERN") {
245ece8a530Spatrick       readExtern();
246ece8a530Spatrick     } else if (tok == "GROUP") {
247ece8a530Spatrick       readGroup();
248ece8a530Spatrick     } else if (tok == "INCLUDE") {
249ece8a530Spatrick       readInclude();
250ece8a530Spatrick     } else if (tok == "INPUT") {
251ece8a530Spatrick       readInput();
252ece8a530Spatrick     } else if (tok == "MEMORY") {
253ece8a530Spatrick       readMemory();
254ece8a530Spatrick     } else if (tok == "OUTPUT") {
255ece8a530Spatrick       readOutput();
256ece8a530Spatrick     } else if (tok == "OUTPUT_ARCH") {
257ece8a530Spatrick       readOutputArch();
258ece8a530Spatrick     } else if (tok == "OUTPUT_FORMAT") {
259ece8a530Spatrick       readOutputFormat();
2601cf9926bSpatrick     } else if (tok == "OVERWRITE_SECTIONS") {
2611cf9926bSpatrick       readOverwriteSections();
262ece8a530Spatrick     } else if (tok == "PHDRS") {
263ece8a530Spatrick       readPhdrs();
264ece8a530Spatrick     } else if (tok == "REGION_ALIAS") {
265ece8a530Spatrick       readRegionAlias();
266ece8a530Spatrick     } else if (tok == "SEARCH_DIR") {
267ece8a530Spatrick       readSearchDir();
268ece8a530Spatrick     } else if (tok == "SECTIONS") {
269ece8a530Spatrick       readSections();
270ece8a530Spatrick     } else if (tok == "TARGET") {
271ece8a530Spatrick       readTarget();
272ece8a530Spatrick     } else if (tok == "VERSION") {
273ece8a530Spatrick       readVersion();
274ece8a530Spatrick     } else if (SymbolAssignment *cmd = readAssignment(tok)) {
275ece8a530Spatrick       script->sectionCommands.push_back(cmd);
276ece8a530Spatrick     } else {
277ece8a530Spatrick       setError("unknown directive: " + tok);
278ece8a530Spatrick     }
279ece8a530Spatrick   }
280ece8a530Spatrick }
281ece8a530Spatrick 
readDefsym(StringRef name)282ece8a530Spatrick void ScriptParser::readDefsym(StringRef name) {
283ece8a530Spatrick   if (errorCount())
284ece8a530Spatrick     return;
285ece8a530Spatrick   Expr e = readExpr();
286ece8a530Spatrick   if (!atEOF())
287ece8a530Spatrick     setError("EOF expected, but got " + next());
288ece8a530Spatrick   SymbolAssignment *cmd = make<SymbolAssignment>(name, e, getCurrentLocation());
289ece8a530Spatrick   script->sectionCommands.push_back(cmd);
290ece8a530Spatrick }
291ece8a530Spatrick 
addFile(StringRef s)292ece8a530Spatrick void ScriptParser::addFile(StringRef s) {
293ece8a530Spatrick   if (isUnderSysroot && s.startswith("/")) {
294ece8a530Spatrick     SmallString<128> pathData;
295ece8a530Spatrick     StringRef path = (config->sysroot + s).toStringRef(pathData);
2961cf9926bSpatrick     if (sys::fs::exists(path))
29705edf1c1Srobert       ctx.driver.addFile(saver().save(path), /*withLOption=*/false);
2981cf9926bSpatrick     else
2991cf9926bSpatrick       setError("cannot find " + s + " inside " + config->sysroot);
300ece8a530Spatrick     return;
301ece8a530Spatrick   }
302ece8a530Spatrick 
303ece8a530Spatrick   if (s.startswith("/")) {
304bb684c34Spatrick     // Case 1: s is an absolute path. Just open it.
30505edf1c1Srobert     ctx.driver.addFile(s, /*withLOption=*/false);
306ece8a530Spatrick   } else if (s.startswith("=")) {
307bb684c34Spatrick     // Case 2: relative to the sysroot.
308ece8a530Spatrick     if (config->sysroot.empty())
30905edf1c1Srobert       ctx.driver.addFile(s.substr(1), /*withLOption=*/false);
310ece8a530Spatrick     else
31105edf1c1Srobert       ctx.driver.addFile(saver().save(config->sysroot + "/" + s.substr(1)),
312ece8a530Spatrick                          /*withLOption=*/false);
313ece8a530Spatrick   } else if (s.startswith("-l")) {
314bb684c34Spatrick     // Case 3: search in the list of library paths.
31505edf1c1Srobert     ctx.driver.addLibrary(s.substr(2));
316bb684c34Spatrick   } else {
317bb684c34Spatrick     // Case 4: s is a relative path. Search in the directory of the script file.
318bb684c34Spatrick     std::string filename = std::string(getCurrentMB().getBufferIdentifier());
319bb684c34Spatrick     StringRef directory = sys::path::parent_path(filename);
320bb684c34Spatrick     if (!directory.empty()) {
321bb684c34Spatrick       SmallString<0> path(directory);
322bb684c34Spatrick       sys::path::append(path, s);
323bb684c34Spatrick       if (sys::fs::exists(path)) {
32405edf1c1Srobert         ctx.driver.addFile(path, /*withLOption=*/false);
325bb684c34Spatrick         return;
326bb684c34Spatrick       }
327bb684c34Spatrick     }
328bb684c34Spatrick     // Then search in the current working directory.
329bb684c34Spatrick     if (sys::fs::exists(s)) {
33005edf1c1Srobert       ctx.driver.addFile(s, /*withLOption=*/false);
331ece8a530Spatrick     } else {
332bb684c34Spatrick       // Finally, search in the list of library paths.
33305edf1c1Srobert       if (std::optional<std::string> path = findFromSearchPaths(s))
33405edf1c1Srobert         ctx.driver.addFile(saver().save(*path), /*withLOption=*/true);
335ece8a530Spatrick       else
336ece8a530Spatrick         setError("unable to find " + s);
337ece8a530Spatrick     }
338ece8a530Spatrick   }
339bb684c34Spatrick }
340ece8a530Spatrick 
readAsNeeded()341ece8a530Spatrick void ScriptParser::readAsNeeded() {
342ece8a530Spatrick   expect("(");
343ece8a530Spatrick   bool orig = config->asNeeded;
344ece8a530Spatrick   config->asNeeded = true;
345ece8a530Spatrick   while (!errorCount() && !consume(")"))
346ece8a530Spatrick     addFile(unquote(next()));
347ece8a530Spatrick   config->asNeeded = orig;
348ece8a530Spatrick }
349ece8a530Spatrick 
readEntry()350ece8a530Spatrick void ScriptParser::readEntry() {
351ece8a530Spatrick   // -e <symbol> takes predecence over ENTRY(<symbol>).
352ece8a530Spatrick   expect("(");
353ece8a530Spatrick   StringRef tok = next();
354ece8a530Spatrick   if (config->entry.empty())
35505edf1c1Srobert     config->entry = unquote(tok);
356ece8a530Spatrick   expect(")");
357ece8a530Spatrick }
358ece8a530Spatrick 
readExtern()359ece8a530Spatrick void ScriptParser::readExtern() {
360ece8a530Spatrick   expect("(");
361ece8a530Spatrick   while (!errorCount() && !consume(")"))
362ece8a530Spatrick     config->undefined.push_back(unquote(next()));
363ece8a530Spatrick }
364ece8a530Spatrick 
readGroup()365ece8a530Spatrick void ScriptParser::readGroup() {
366ece8a530Spatrick   bool orig = InputFile::isInGroup;
367ece8a530Spatrick   InputFile::isInGroup = true;
368ece8a530Spatrick   readInput();
369ece8a530Spatrick   InputFile::isInGroup = orig;
370ece8a530Spatrick   if (!orig)
371ece8a530Spatrick     ++InputFile::nextGroupId;
372ece8a530Spatrick }
373ece8a530Spatrick 
readInclude()374ece8a530Spatrick void ScriptParser::readInclude() {
375ece8a530Spatrick   StringRef tok = unquote(next());
376ece8a530Spatrick 
377ece8a530Spatrick   if (!seen.insert(tok).second) {
378ece8a530Spatrick     setError("there is a cycle in linker script INCLUDEs");
379ece8a530Spatrick     return;
380ece8a530Spatrick   }
381ece8a530Spatrick 
38205edf1c1Srobert   if (std::optional<std::string> path = searchScript(tok)) {
38305edf1c1Srobert     if (std::optional<MemoryBufferRef> mb = readFile(*path))
384ece8a530Spatrick       tokenize(*mb);
385ece8a530Spatrick     return;
386ece8a530Spatrick   }
387ece8a530Spatrick   setError("cannot find linker script " + tok);
388ece8a530Spatrick }
389ece8a530Spatrick 
readInput()390ece8a530Spatrick void ScriptParser::readInput() {
391ece8a530Spatrick   expect("(");
392ece8a530Spatrick   while (!errorCount() && !consume(")")) {
393ece8a530Spatrick     if (consume("AS_NEEDED"))
394ece8a530Spatrick       readAsNeeded();
395ece8a530Spatrick     else
396ece8a530Spatrick       addFile(unquote(next()));
397ece8a530Spatrick   }
398ece8a530Spatrick }
399ece8a530Spatrick 
readOutput()400ece8a530Spatrick void ScriptParser::readOutput() {
401ece8a530Spatrick   // -o <file> takes predecence over OUTPUT(<file>).
402ece8a530Spatrick   expect("(");
403ece8a530Spatrick   StringRef tok = next();
404ece8a530Spatrick   if (config->outputFile.empty())
405ece8a530Spatrick     config->outputFile = unquote(tok);
406ece8a530Spatrick   expect(")");
407ece8a530Spatrick }
408ece8a530Spatrick 
readOutputArch()409ece8a530Spatrick void ScriptParser::readOutputArch() {
410ece8a530Spatrick   // OUTPUT_ARCH is ignored for now.
411ece8a530Spatrick   expect("(");
412ece8a530Spatrick   while (!errorCount() && !consume(")"))
413ece8a530Spatrick     skip();
414ece8a530Spatrick }
415ece8a530Spatrick 
parseBfdName(StringRef s)416ece8a530Spatrick static std::pair<ELFKind, uint16_t> parseBfdName(StringRef s) {
417ece8a530Spatrick   return StringSwitch<std::pair<ELFKind, uint16_t>>(s)
418ece8a530Spatrick       .Case("elf32-i386", {ELF32LEKind, EM_386})
41905edf1c1Srobert       .Case("elf32-avr", {ELF32LEKind, EM_AVR})
420ece8a530Spatrick       .Case("elf32-iamcu", {ELF32LEKind, EM_IAMCU})
421ece8a530Spatrick       .Case("elf32-littlearm", {ELF32LEKind, EM_ARM})
422ece8a530Spatrick       .Case("elf32-x86-64", {ELF32LEKind, EM_X86_64})
423ece8a530Spatrick       .Case("elf64-aarch64", {ELF64LEKind, EM_AARCH64})
424ece8a530Spatrick       .Case("elf64-littleaarch64", {ELF64LEKind, EM_AARCH64})
4251cf9926bSpatrick       .Case("elf64-bigaarch64", {ELF64BEKind, EM_AARCH64})
426ece8a530Spatrick       .Case("elf32-powerpc", {ELF32BEKind, EM_PPC})
4271cf9926bSpatrick       .Case("elf32-powerpcle", {ELF32LEKind, EM_PPC})
428ece8a530Spatrick       .Case("elf64-powerpc", {ELF64BEKind, EM_PPC64})
429ece8a530Spatrick       .Case("elf64-powerpcle", {ELF64LEKind, EM_PPC64})
430ece8a530Spatrick       .Case("elf64-x86-64", {ELF64LEKind, EM_X86_64})
431ece8a530Spatrick       .Cases("elf32-tradbigmips", "elf32-bigmips", {ELF32BEKind, EM_MIPS})
432ece8a530Spatrick       .Case("elf32-ntradbigmips", {ELF32BEKind, EM_MIPS})
433ece8a530Spatrick       .Case("elf32-tradlittlemips", {ELF32LEKind, EM_MIPS})
434ece8a530Spatrick       .Case("elf32-ntradlittlemips", {ELF32LEKind, EM_MIPS})
435ece8a530Spatrick       .Case("elf64-tradbigmips", {ELF64BEKind, EM_MIPS})
436ece8a530Spatrick       .Case("elf64-tradlittlemips", {ELF64LEKind, EM_MIPS})
437ece8a530Spatrick       .Case("elf32-littleriscv", {ELF32LEKind, EM_RISCV})
438ece8a530Spatrick       .Case("elf64-littleriscv", {ELF64LEKind, EM_RISCV})
439bb684c34Spatrick       .Case("elf64-sparc", {ELF64BEKind, EM_SPARCV9})
4401cf9926bSpatrick       .Case("elf32-msp430", {ELF32LEKind, EM_MSP430})
441ece8a530Spatrick       .Default({ELFNoneKind, EM_NONE});
442ece8a530Spatrick }
443ece8a530Spatrick 
4441cf9926bSpatrick // Parse OUTPUT_FORMAT(bfdname) or OUTPUT_FORMAT(default, big, little). Choose
4451cf9926bSpatrick // big if -EB is specified, little if -EL is specified, or default if neither is
4461cf9926bSpatrick // specified.
readOutputFormat()447ece8a530Spatrick void ScriptParser::readOutputFormat() {
448ece8a530Spatrick   expect("(");
449ece8a530Spatrick 
4501cf9926bSpatrick   StringRef s;
451bb684c34Spatrick   config->bfdname = unquote(next());
4521cf9926bSpatrick   if (!consume(")")) {
4531cf9926bSpatrick     expect(",");
4541cf9926bSpatrick     s = unquote(next());
4551cf9926bSpatrick     if (config->optEB)
4561cf9926bSpatrick       config->bfdname = s;
4571cf9926bSpatrick     expect(",");
4581cf9926bSpatrick     s = unquote(next());
4591cf9926bSpatrick     if (config->optEL)
4601cf9926bSpatrick       config->bfdname = s;
4611cf9926bSpatrick     consume(")");
4621cf9926bSpatrick   }
4631cf9926bSpatrick   s = config->bfdname;
464ece8a530Spatrick   if (s.consume_back("-freebsd"))
465ece8a530Spatrick     config->osabi = ELFOSABI_FREEBSD;
466ece8a530Spatrick 
467ece8a530Spatrick   std::tie(config->ekind, config->emachine) = parseBfdName(s);
468ece8a530Spatrick   if (config->emachine == EM_NONE)
469bb684c34Spatrick     setError("unknown output format name: " + config->bfdname);
470ece8a530Spatrick   if (s == "elf32-ntradlittlemips" || s == "elf32-ntradbigmips")
471ece8a530Spatrick     config->mipsN32Abi = true;
4721cf9926bSpatrick   if (config->emachine == EM_MSP430)
4731cf9926bSpatrick     config->osabi = ELFOSABI_STANDALONE;
474ece8a530Spatrick }
475ece8a530Spatrick 
readPhdrs()476ece8a530Spatrick void ScriptParser::readPhdrs() {
477ece8a530Spatrick   expect("{");
478ece8a530Spatrick 
479ece8a530Spatrick   while (!errorCount() && !consume("}")) {
480ece8a530Spatrick     PhdrsCommand cmd;
481ece8a530Spatrick     cmd.name = next();
482ece8a530Spatrick     cmd.type = readPhdrType();
483ece8a530Spatrick 
484ece8a530Spatrick     while (!errorCount() && !consume(";")) {
485ece8a530Spatrick       if (consume("FILEHDR"))
486ece8a530Spatrick         cmd.hasFilehdr = true;
487ece8a530Spatrick       else if (consume("PHDRS"))
488ece8a530Spatrick         cmd.hasPhdrs = true;
489ece8a530Spatrick       else if (consume("AT"))
490ece8a530Spatrick         cmd.lmaExpr = readParenExpr();
491ece8a530Spatrick       else if (consume("FLAGS"))
492ece8a530Spatrick         cmd.flags = readParenExpr()().getValue();
493ece8a530Spatrick       else
494ece8a530Spatrick         setError("unexpected header attribute: " + next());
495ece8a530Spatrick     }
496ece8a530Spatrick 
497ece8a530Spatrick     script->phdrsCommands.push_back(cmd);
498ece8a530Spatrick   }
499ece8a530Spatrick }
500ece8a530Spatrick 
readRegionAlias()501ece8a530Spatrick void ScriptParser::readRegionAlias() {
502ece8a530Spatrick   expect("(");
503ece8a530Spatrick   StringRef alias = unquote(next());
504ece8a530Spatrick   expect(",");
505ece8a530Spatrick   StringRef name = next();
506ece8a530Spatrick   expect(")");
507ece8a530Spatrick 
508ece8a530Spatrick   if (script->memoryRegions.count(alias))
509ece8a530Spatrick     setError("redefinition of memory region '" + alias + "'");
510ece8a530Spatrick   if (!script->memoryRegions.count(name))
511ece8a530Spatrick     setError("memory region '" + name + "' is not defined");
512ece8a530Spatrick   script->memoryRegions.insert({alias, script->memoryRegions[name]});
513ece8a530Spatrick }
514ece8a530Spatrick 
readSearchDir()515ece8a530Spatrick void ScriptParser::readSearchDir() {
516ece8a530Spatrick   expect("(");
517ece8a530Spatrick   StringRef tok = next();
518ece8a530Spatrick   if (!config->nostdlib)
519ece8a530Spatrick     config->searchPaths.push_back(unquote(tok));
520ece8a530Spatrick   expect(")");
521ece8a530Spatrick }
522ece8a530Spatrick 
523ece8a530Spatrick // This reads an overlay description. Overlays are used to describe output
524ece8a530Spatrick // sections that use the same virtual memory range and normally would trigger
525ece8a530Spatrick // linker's sections sanity check failures.
526ece8a530Spatrick // https://sourceware.org/binutils/docs/ld/Overlay-Description.html#Overlay-Description
readOverlay()52705edf1c1Srobert SmallVector<SectionCommand *, 0> ScriptParser::readOverlay() {
528ece8a530Spatrick   // VA and LMA expressions are optional, though for simplicity of
529ece8a530Spatrick   // implementation we assume they are not. That is what OVERLAY was designed
530ece8a530Spatrick   // for first of all: to allow sections with overlapping VAs at different LMAs.
531ece8a530Spatrick   Expr addrExpr = readExpr();
532ece8a530Spatrick   expect(":");
533ece8a530Spatrick   expect("AT");
534ece8a530Spatrick   Expr lmaExpr = readParenExpr();
535ece8a530Spatrick   expect("{");
536ece8a530Spatrick 
53705edf1c1Srobert   SmallVector<SectionCommand *, 0> v;
538ece8a530Spatrick   OutputSection *prev = nullptr;
539ece8a530Spatrick   while (!errorCount() && !consume("}")) {
540ece8a530Spatrick     // VA is the same for all sections. The LMAs are consecutive in memory
541ece8a530Spatrick     // starting from the base load address specified.
54205edf1c1Srobert     OutputDesc *osd = readOverlaySectionDescription();
54305edf1c1Srobert     osd->osec.addrExpr = addrExpr;
544ece8a530Spatrick     if (prev)
54505edf1c1Srobert       osd->osec.lmaExpr = [=] { return prev->getLMA() + prev->size; };
546ece8a530Spatrick     else
54705edf1c1Srobert       osd->osec.lmaExpr = lmaExpr;
54805edf1c1Srobert     v.push_back(osd);
54905edf1c1Srobert     prev = &osd->osec;
550ece8a530Spatrick   }
551ece8a530Spatrick 
552ece8a530Spatrick   // According to the specification, at the end of the overlay, the location
553ece8a530Spatrick   // counter should be equal to the overlay base address plus size of the
554ece8a530Spatrick   // largest section seen in the overlay.
555ece8a530Spatrick   // Here we want to create the Dot assignment command to achieve that.
556ece8a530Spatrick   Expr moveDot = [=] {
557ece8a530Spatrick     uint64_t max = 0;
55805edf1c1Srobert     for (SectionCommand *cmd : v)
55905edf1c1Srobert       max = std::max(max, cast<OutputDesc>(cmd)->osec.size);
560ece8a530Spatrick     return addrExpr().getValue() + max;
561ece8a530Spatrick   };
562ece8a530Spatrick   v.push_back(make<SymbolAssignment>(".", moveDot, getCurrentLocation()));
563ece8a530Spatrick   return v;
564ece8a530Spatrick }
565ece8a530Spatrick 
readOverwriteSections()5661cf9926bSpatrick void ScriptParser::readOverwriteSections() {
5671cf9926bSpatrick   expect("{");
5681cf9926bSpatrick   while (!errorCount() && !consume("}"))
5691cf9926bSpatrick     script->overwriteSections.push_back(readOutputSectionDescription(next()));
5701cf9926bSpatrick }
5711cf9926bSpatrick 
readSections()572ece8a530Spatrick void ScriptParser::readSections() {
573ece8a530Spatrick   expect("{");
57405edf1c1Srobert   SmallVector<SectionCommand *, 0> v;
575ece8a530Spatrick   while (!errorCount() && !consume("}")) {
576ece8a530Spatrick     StringRef tok = next();
577ece8a530Spatrick     if (tok == "OVERLAY") {
57805edf1c1Srobert       for (SectionCommand *cmd : readOverlay())
579ece8a530Spatrick         v.push_back(cmd);
580ece8a530Spatrick       continue;
581ece8a530Spatrick     } else if (tok == "INCLUDE") {
582ece8a530Spatrick       readInclude();
583ece8a530Spatrick       continue;
584ece8a530Spatrick     }
585ece8a530Spatrick 
58605edf1c1Srobert     if (SectionCommand *cmd = readAssignment(tok))
587ece8a530Spatrick       v.push_back(cmd);
588ece8a530Spatrick     else
589ece8a530Spatrick       v.push_back(readOutputSectionDescription(tok));
590ece8a530Spatrick   }
59105edf1c1Srobert 
59205edf1c1Srobert   // If DATA_SEGMENT_RELRO_END is absent, for sections after DATA_SEGMENT_ALIGN,
59305edf1c1Srobert   // the relro fields should be cleared.
59405edf1c1Srobert   if (!seenRelroEnd)
59505edf1c1Srobert     for (SectionCommand *cmd : v)
59605edf1c1Srobert       if (auto *osd = dyn_cast<OutputDesc>(cmd))
59705edf1c1Srobert         osd->osec.relro = false;
59805edf1c1Srobert 
599bb684c34Spatrick   script->sectionCommands.insert(script->sectionCommands.end(), v.begin(),
600bb684c34Spatrick                                  v.end());
601ece8a530Spatrick 
602bb684c34Spatrick   if (atEOF() || !consume("INSERT")) {
603bb684c34Spatrick     script->hasSectionsCommand = true;
604ece8a530Spatrick     return;
605ece8a530Spatrick   }
606ece8a530Spatrick 
607bb684c34Spatrick   bool isAfter = false;
608bb684c34Spatrick   if (consume("AFTER"))
609bb684c34Spatrick     isAfter = true;
610bb684c34Spatrick   else if (!consume("BEFORE"))
611bb684c34Spatrick     setError("expected AFTER/BEFORE, but got '" + next() + "'");
612bb684c34Spatrick   StringRef where = next();
61305edf1c1Srobert   SmallVector<StringRef, 0> names;
61405edf1c1Srobert   for (SectionCommand *cmd : v)
61505edf1c1Srobert     if (auto *os = dyn_cast<OutputDesc>(cmd))
61605edf1c1Srobert       names.push_back(os->osec.name);
6171cf9926bSpatrick   if (!names.empty())
6181cf9926bSpatrick     script->insertCommands.push_back({std::move(names), isAfter, where});
619ece8a530Spatrick }
620ece8a530Spatrick 
readTarget()621ece8a530Spatrick void ScriptParser::readTarget() {
622ece8a530Spatrick   // TARGET(foo) is an alias for "--format foo". Unlike GNU linkers,
623ece8a530Spatrick   // we accept only a limited set of BFD names (i.e. "elf" or "binary")
624ece8a530Spatrick   // for --format. We recognize only /^elf/ and "binary" in the linker
625ece8a530Spatrick   // script as well.
626ece8a530Spatrick   expect("(");
62705edf1c1Srobert   StringRef tok = unquote(next());
628ece8a530Spatrick   expect(")");
629ece8a530Spatrick 
630ece8a530Spatrick   if (tok.startswith("elf"))
631ece8a530Spatrick     config->formatBinary = false;
632ece8a530Spatrick   else if (tok == "binary")
633ece8a530Spatrick     config->formatBinary = true;
634ece8a530Spatrick   else
635ece8a530Spatrick     setError("unknown target: " + tok);
636ece8a530Spatrick }
637ece8a530Spatrick 
precedence(StringRef op)638ece8a530Spatrick static int precedence(StringRef op) {
639ece8a530Spatrick   return StringSwitch<int>(op)
64005edf1c1Srobert       .Cases("*", "/", "%", 10)
64105edf1c1Srobert       .Cases("+", "-", 9)
64205edf1c1Srobert       .Cases("<<", ">>", 8)
64305edf1c1Srobert       .Cases("<", "<=", ">", ">=", 7)
64405edf1c1Srobert       .Cases("==", "!=", 6)
64505edf1c1Srobert       .Case("&", 5)
64605edf1c1Srobert       .Case("|", 4)
64705edf1c1Srobert       .Case("&&", 3)
64805edf1c1Srobert       .Case("||", 2)
64905edf1c1Srobert       .Case("?", 1)
650ece8a530Spatrick       .Default(-1);
651ece8a530Spatrick }
652ece8a530Spatrick 
readFilePatterns()653ece8a530Spatrick StringMatcher ScriptParser::readFilePatterns() {
654bb684c34Spatrick   StringMatcher Matcher;
655bb684c34Spatrick 
656ece8a530Spatrick   while (!errorCount() && !consume(")"))
657bb684c34Spatrick     Matcher.addPattern(SingleStringMatcher(next()));
658bb684c34Spatrick   return Matcher;
659ece8a530Spatrick }
660ece8a530Spatrick 
peekSortKind()6611cf9926bSpatrick SortSectionPolicy ScriptParser::peekSortKind() {
6621cf9926bSpatrick   return StringSwitch<SortSectionPolicy>(peek())
6631cf9926bSpatrick       .Cases("SORT", "SORT_BY_NAME", SortSectionPolicy::Name)
6641cf9926bSpatrick       .Case("SORT_BY_ALIGNMENT", SortSectionPolicy::Alignment)
6651cf9926bSpatrick       .Case("SORT_BY_INIT_PRIORITY", SortSectionPolicy::Priority)
6661cf9926bSpatrick       .Case("SORT_NONE", SortSectionPolicy::None)
6671cf9926bSpatrick       .Default(SortSectionPolicy::Default);
6681cf9926bSpatrick }
6691cf9926bSpatrick 
readSortKind()670ece8a530Spatrick SortSectionPolicy ScriptParser::readSortKind() {
6711cf9926bSpatrick   SortSectionPolicy ret = peekSortKind();
6721cf9926bSpatrick   if (ret != SortSectionPolicy::Default)
6731cf9926bSpatrick     skip();
6741cf9926bSpatrick   return ret;
675ece8a530Spatrick }
676ece8a530Spatrick 
677ece8a530Spatrick // Reads SECTIONS command contents in the following form:
678ece8a530Spatrick //
679ece8a530Spatrick // <contents> ::= <elem>*
680ece8a530Spatrick // <elem>     ::= <exclude>? <glob-pattern>
681ece8a530Spatrick // <exclude>  ::= "EXCLUDE_FILE" "(" <glob-pattern>+ ")"
682ece8a530Spatrick //
683ece8a530Spatrick // For example,
684ece8a530Spatrick //
685ece8a530Spatrick // *(.foo EXCLUDE_FILE (a.o) .bar EXCLUDE_FILE (b.o) .baz)
686ece8a530Spatrick //
687ece8a530Spatrick // is parsed as ".foo", ".bar" with "a.o", and ".baz" with "b.o".
688ece8a530Spatrick // The semantics of that is section .foo in any file, section .bar in
689ece8a530Spatrick // any file but a.o, and section .baz in any file but b.o.
readInputSectionsList()69005edf1c1Srobert SmallVector<SectionPattern, 0> ScriptParser::readInputSectionsList() {
69105edf1c1Srobert   SmallVector<SectionPattern, 0> ret;
692ece8a530Spatrick   while (!errorCount() && peek() != ")") {
693ece8a530Spatrick     StringMatcher excludeFilePat;
694ece8a530Spatrick     if (consume("EXCLUDE_FILE")) {
695ece8a530Spatrick       expect("(");
696ece8a530Spatrick       excludeFilePat = readFilePatterns();
697ece8a530Spatrick     }
698ece8a530Spatrick 
699bb684c34Spatrick     StringMatcher SectionMatcher;
7001cf9926bSpatrick     // Break if the next token is ), EXCLUDE_FILE, or SORT*.
7011cf9926bSpatrick     while (!errorCount() && peek() != ")" && peek() != "EXCLUDE_FILE" &&
7021cf9926bSpatrick            peekSortKind() == SortSectionPolicy::Default)
703bb684c34Spatrick       SectionMatcher.addPattern(unquote(next()));
704ece8a530Spatrick 
705bb684c34Spatrick     if (!SectionMatcher.empty())
706bb684c34Spatrick       ret.push_back({std::move(excludeFilePat), std::move(SectionMatcher)});
7071cf9926bSpatrick     else if (excludeFilePat.empty())
7081cf9926bSpatrick       break;
709ece8a530Spatrick     else
710ece8a530Spatrick       setError("section pattern is expected");
711ece8a530Spatrick   }
712ece8a530Spatrick   return ret;
713ece8a530Spatrick }
714ece8a530Spatrick 
715ece8a530Spatrick // Reads contents of "SECTIONS" directive. That directive contains a
716ece8a530Spatrick // list of glob patterns for input sections. The grammar is as follows.
717ece8a530Spatrick //
718ece8a530Spatrick // <patterns> ::= <section-list>
719ece8a530Spatrick //              | <sort> "(" <section-list> ")"
720ece8a530Spatrick //              | <sort> "(" <sort> "(" <section-list> ")" ")"
721ece8a530Spatrick //
722ece8a530Spatrick // <sort>     ::= "SORT" | "SORT_BY_NAME" | "SORT_BY_ALIGNMENT"
723ece8a530Spatrick //              | "SORT_BY_INIT_PRIORITY" | "SORT_NONE"
724ece8a530Spatrick //
725ece8a530Spatrick // <section-list> is parsed by readInputSectionsList().
726ece8a530Spatrick InputSectionDescription *
readInputSectionRules(StringRef filePattern,uint64_t withFlags,uint64_t withoutFlags)727bb684c34Spatrick ScriptParser::readInputSectionRules(StringRef filePattern, uint64_t withFlags,
728bb684c34Spatrick                                     uint64_t withoutFlags) {
729bb684c34Spatrick   auto *cmd =
730bb684c34Spatrick       make<InputSectionDescription>(filePattern, withFlags, withoutFlags);
731ece8a530Spatrick   expect("(");
732ece8a530Spatrick 
733ece8a530Spatrick   while (!errorCount() && !consume(")")) {
734ece8a530Spatrick     SortSectionPolicy outer = readSortKind();
735ece8a530Spatrick     SortSectionPolicy inner = SortSectionPolicy::Default;
73605edf1c1Srobert     SmallVector<SectionPattern, 0> v;
737ece8a530Spatrick     if (outer != SortSectionPolicy::Default) {
738ece8a530Spatrick       expect("(");
739ece8a530Spatrick       inner = readSortKind();
740ece8a530Spatrick       if (inner != SortSectionPolicy::Default) {
741ece8a530Spatrick         expect("(");
742ece8a530Spatrick         v = readInputSectionsList();
743ece8a530Spatrick         expect(")");
744ece8a530Spatrick       } else {
745ece8a530Spatrick         v = readInputSectionsList();
746ece8a530Spatrick       }
747ece8a530Spatrick       expect(")");
748ece8a530Spatrick     } else {
749ece8a530Spatrick       v = readInputSectionsList();
750ece8a530Spatrick     }
751ece8a530Spatrick 
752ece8a530Spatrick     for (SectionPattern &pat : v) {
753ece8a530Spatrick       pat.sortInner = inner;
754ece8a530Spatrick       pat.sortOuter = outer;
755ece8a530Spatrick     }
756ece8a530Spatrick 
757ece8a530Spatrick     std::move(v.begin(), v.end(), std::back_inserter(cmd->sectionPatterns));
758ece8a530Spatrick   }
759ece8a530Spatrick   return cmd;
760ece8a530Spatrick }
761ece8a530Spatrick 
762ece8a530Spatrick InputSectionDescription *
readInputSectionDescription(StringRef tok)763ece8a530Spatrick ScriptParser::readInputSectionDescription(StringRef tok) {
764ece8a530Spatrick   // Input section wildcard can be surrounded by KEEP.
765ece8a530Spatrick   // https://sourceware.org/binutils/docs/ld/Input-Section-Keep.html#Input-Section-Keep
766bb684c34Spatrick   uint64_t withFlags = 0;
767bb684c34Spatrick   uint64_t withoutFlags = 0;
768ece8a530Spatrick   if (tok == "KEEP") {
769ece8a530Spatrick     expect("(");
770bb684c34Spatrick     if (consume("INPUT_SECTION_FLAGS"))
771bb684c34Spatrick       std::tie(withFlags, withoutFlags) = readInputSectionFlags();
772bb684c34Spatrick     InputSectionDescription *cmd =
773bb684c34Spatrick         readInputSectionRules(next(), withFlags, withoutFlags);
774ece8a530Spatrick     expect(")");
775ece8a530Spatrick     script->keptSections.push_back(cmd);
776ece8a530Spatrick     return cmd;
777ece8a530Spatrick   }
778bb684c34Spatrick   if (tok == "INPUT_SECTION_FLAGS") {
779bb684c34Spatrick     std::tie(withFlags, withoutFlags) = readInputSectionFlags();
780bb684c34Spatrick     tok = next();
781bb684c34Spatrick   }
782bb684c34Spatrick   return readInputSectionRules(tok, withFlags, withoutFlags);
783ece8a530Spatrick }
784ece8a530Spatrick 
readSort()785ece8a530Spatrick void ScriptParser::readSort() {
786ece8a530Spatrick   expect("(");
787ece8a530Spatrick   expect("CONSTRUCTORS");
788ece8a530Spatrick   expect(")");
789ece8a530Spatrick }
790ece8a530Spatrick 
readAssert()791ece8a530Spatrick Expr ScriptParser::readAssert() {
792ece8a530Spatrick   expect("(");
793ece8a530Spatrick   Expr e = readExpr();
794ece8a530Spatrick   expect(",");
795ece8a530Spatrick   StringRef msg = unquote(next());
796ece8a530Spatrick   expect(")");
797ece8a530Spatrick 
798ece8a530Spatrick   return [=] {
799ece8a530Spatrick     if (!e().getValue())
800ece8a530Spatrick       errorOrWarn(msg);
801ece8a530Spatrick     return script->getDot();
802ece8a530Spatrick   };
803ece8a530Spatrick }
804ece8a530Spatrick 
80505edf1c1Srobert #define ECase(X)                                                               \
80605edf1c1Srobert   { #X, X }
80705edf1c1Srobert constexpr std::pair<const char *, unsigned> typeMap[] = {
80805edf1c1Srobert     ECase(SHT_PROGBITS),   ECase(SHT_NOTE),       ECase(SHT_NOBITS),
80905edf1c1Srobert     ECase(SHT_INIT_ARRAY), ECase(SHT_FINI_ARRAY), ECase(SHT_PREINIT_ARRAY),
81005edf1c1Srobert };
81105edf1c1Srobert #undef ECase
81205edf1c1Srobert 
813ece8a530Spatrick // Tries to read the special directive for an output section definition which
81405edf1c1Srobert // can be one of following: "(NOLOAD)", "(COPY)", "(INFO)", "(OVERLAY)", and
81505edf1c1Srobert // "(TYPE=<value>)".
81605edf1c1Srobert // Tok1 and Tok2 are next 2 tokens peeked. See comment for
81705edf1c1Srobert // readSectionAddressType below.
readSectionDirective(OutputSection * cmd,StringRef tok1,StringRef tok2)818ece8a530Spatrick bool ScriptParser::readSectionDirective(OutputSection *cmd, StringRef tok1, StringRef tok2) {
819ece8a530Spatrick   if (tok1 != "(")
820ece8a530Spatrick     return false;
82105edf1c1Srobert   if (tok2 != "NOLOAD" && tok2 != "COPY" && tok2 != "INFO" &&
82205edf1c1Srobert       tok2 != "OVERLAY" && tok2 != "TYPE")
823ece8a530Spatrick     return false;
824ece8a530Spatrick 
825ece8a530Spatrick   expect("(");
826ece8a530Spatrick   if (consume("NOLOAD")) {
827667950d7Spatrick     cmd->type = SHT_NOBITS;
82805edf1c1Srobert     cmd->typeIsSet = true;
82905edf1c1Srobert   } else if (consume("TYPE")) {
83005edf1c1Srobert     expect("=");
83105edf1c1Srobert     StringRef value = peek();
83205edf1c1Srobert     auto it = llvm::find_if(typeMap, [=](auto e) { return e.first == value; });
83305edf1c1Srobert     if (it != std::end(typeMap)) {
83405edf1c1Srobert       // The value is a recognized literal SHT_*.
83505edf1c1Srobert       cmd->type = it->second;
83605edf1c1Srobert       skip();
83705edf1c1Srobert     } else if (value.startswith("SHT_")) {
83805edf1c1Srobert       setError("unknown section type " + value);
83905edf1c1Srobert     } else {
84005edf1c1Srobert       // Otherwise, read an expression.
84105edf1c1Srobert       cmd->type = readExpr()().getValue();
84205edf1c1Srobert     }
84305edf1c1Srobert     cmd->typeIsSet = true;
844ece8a530Spatrick   } else {
845ece8a530Spatrick     skip(); // This is "COPY", "INFO" or "OVERLAY".
846ece8a530Spatrick     cmd->nonAlloc = true;
847ece8a530Spatrick   }
848ece8a530Spatrick   expect(")");
849ece8a530Spatrick   return true;
850ece8a530Spatrick }
851ece8a530Spatrick 
852ece8a530Spatrick // Reads an expression and/or the special directive for an output
853ece8a530Spatrick // section definition. Directive is one of following: "(NOLOAD)",
854ece8a530Spatrick // "(COPY)", "(INFO)" or "(OVERLAY)".
855ece8a530Spatrick //
856ece8a530Spatrick // An output section name can be followed by an address expression
857ece8a530Spatrick // and/or directive. This grammar is not LL(1) because "(" can be
858ece8a530Spatrick // interpreted as either the beginning of some expression or beginning
859ece8a530Spatrick // of directive.
860ece8a530Spatrick //
861ece8a530Spatrick // https://sourceware.org/binutils/docs/ld/Output-Section-Address.html
862ece8a530Spatrick // https://sourceware.org/binutils/docs/ld/Output-Section-Type.html
readSectionAddressType(OutputSection * cmd)863ece8a530Spatrick void ScriptParser::readSectionAddressType(OutputSection *cmd) {
86405edf1c1Srobert   // Temporarily set inExpr to support TYPE=<value> without spaces.
86505edf1c1Srobert   bool saved = std::exchange(inExpr, true);
86605edf1c1Srobert   bool isDirective = readSectionDirective(cmd, peek(), peek2());
86705edf1c1Srobert   inExpr = saved;
86805edf1c1Srobert   if (isDirective)
869ece8a530Spatrick     return;
870ece8a530Spatrick 
871ece8a530Spatrick   cmd->addrExpr = readExpr();
872ece8a530Spatrick   if (peek() == "(" && !readSectionDirective(cmd, "(", peek2()))
873ece8a530Spatrick     setError("unknown section directive: " + peek2());
874ece8a530Spatrick }
875ece8a530Spatrick 
checkAlignment(Expr e,std::string & loc)876ece8a530Spatrick static Expr checkAlignment(Expr e, std::string &loc) {
877ece8a530Spatrick   return [=] {
878ece8a530Spatrick     uint64_t alignment = std::max((uint64_t)1, e().getValue());
879ece8a530Spatrick     if (!isPowerOf2_64(alignment)) {
880ece8a530Spatrick       error(loc + ": alignment must be power of 2");
881ece8a530Spatrick       return (uint64_t)1; // Return a dummy value.
882ece8a530Spatrick     }
883ece8a530Spatrick     return alignment;
884ece8a530Spatrick   };
885ece8a530Spatrick }
886ece8a530Spatrick 
readOverlaySectionDescription()88705edf1c1Srobert OutputDesc *ScriptParser::readOverlaySectionDescription() {
88805edf1c1Srobert   OutputDesc *osd = script->createOutputSection(next(), getCurrentLocation());
88905edf1c1Srobert   osd->osec.inOverlay = true;
890ece8a530Spatrick   expect("{");
891bb684c34Spatrick   while (!errorCount() && !consume("}")) {
892bb684c34Spatrick     uint64_t withFlags = 0;
893bb684c34Spatrick     uint64_t withoutFlags = 0;
894bb684c34Spatrick     if (consume("INPUT_SECTION_FLAGS"))
895bb684c34Spatrick       std::tie(withFlags, withoutFlags) = readInputSectionFlags();
89605edf1c1Srobert     osd->osec.commands.push_back(
897bb684c34Spatrick         readInputSectionRules(next(), withFlags, withoutFlags));
898bb684c34Spatrick   }
89905edf1c1Srobert   return osd;
900ece8a530Spatrick }
901ece8a530Spatrick 
readOutputSectionDescription(StringRef outSec)90205edf1c1Srobert OutputDesc *ScriptParser::readOutputSectionDescription(StringRef outSec) {
90305edf1c1Srobert   OutputDesc *cmd = script->createOutputSection(outSec, getCurrentLocation());
90405edf1c1Srobert   OutputSection *osec = &cmd->osec;
90505edf1c1Srobert   // Maybe relro. Will reset to false if DATA_SEGMENT_RELRO_END is absent.
90605edf1c1Srobert   osec->relro = seenDataAlign && !seenRelroEnd;
907ece8a530Spatrick 
908ece8a530Spatrick   size_t symbolsReferenced = script->referencedSymbols.size();
909ece8a530Spatrick 
910ece8a530Spatrick   if (peek() != ":")
91105edf1c1Srobert     readSectionAddressType(osec);
912ece8a530Spatrick   expect(":");
913ece8a530Spatrick 
914ece8a530Spatrick   std::string location = getCurrentLocation();
915ece8a530Spatrick   if (consume("AT"))
91605edf1c1Srobert     osec->lmaExpr = readParenExpr();
917ece8a530Spatrick   if (consume("ALIGN"))
91805edf1c1Srobert     osec->alignExpr = checkAlignment(readParenExpr(), location);
919ece8a530Spatrick   if (consume("SUBALIGN"))
92005edf1c1Srobert     osec->subalignExpr = checkAlignment(readParenExpr(), location);
921ece8a530Spatrick 
922ece8a530Spatrick   // Parse constraints.
923ece8a530Spatrick   if (consume("ONLY_IF_RO"))
92405edf1c1Srobert     osec->constraint = ConstraintKind::ReadOnly;
925ece8a530Spatrick   if (consume("ONLY_IF_RW"))
92605edf1c1Srobert     osec->constraint = ConstraintKind::ReadWrite;
927ece8a530Spatrick   expect("{");
928ece8a530Spatrick 
929ece8a530Spatrick   while (!errorCount() && !consume("}")) {
930ece8a530Spatrick     StringRef tok = next();
931ece8a530Spatrick     if (tok == ";") {
932ece8a530Spatrick       // Empty commands are allowed. Do nothing here.
933ece8a530Spatrick     } else if (SymbolAssignment *assign = readAssignment(tok)) {
93405edf1c1Srobert       osec->commands.push_back(assign);
935ece8a530Spatrick     } else if (ByteCommand *data = readByteCommand(tok)) {
93605edf1c1Srobert       osec->commands.push_back(data);
937ece8a530Spatrick     } else if (tok == "CONSTRUCTORS") {
938ece8a530Spatrick       // CONSTRUCTORS is a keyword to make the linker recognize C++ ctors/dtors
939ece8a530Spatrick       // by name. This is for very old file formats such as ECOFF/XCOFF.
940ece8a530Spatrick       // For ELF, we should ignore.
941ece8a530Spatrick     } else if (tok == "FILL") {
942ece8a530Spatrick       // We handle the FILL command as an alias for =fillexp section attribute,
943ece8a530Spatrick       // which is different from what GNU linkers do.
944ece8a530Spatrick       // https://sourceware.org/binutils/docs/ld/Output-Section-Data.html
945bb684c34Spatrick       if (peek() != "(")
946bb684c34Spatrick         setError("( expected, but got " + peek());
94705edf1c1Srobert       osec->filler = readFill();
948ece8a530Spatrick     } else if (tok == "SORT") {
949ece8a530Spatrick       readSort();
950ece8a530Spatrick     } else if (tok == "INCLUDE") {
951ece8a530Spatrick       readInclude();
95205edf1c1Srobert     } else if (tok == "(" || tok == ")") {
95305edf1c1Srobert       setError("expected filename pattern");
954ece8a530Spatrick     } else if (peek() == "(") {
95505edf1c1Srobert       osec->commands.push_back(readInputSectionDescription(tok));
956ece8a530Spatrick     } else {
957ece8a530Spatrick       // We have a file name and no input sections description. It is not a
958ece8a530Spatrick       // commonly used syntax, but still acceptable. In that case, all sections
959ece8a530Spatrick       // from the file will be included.
960bb684c34Spatrick       // FIXME: GNU ld permits INPUT_SECTION_FLAGS to be used here. We do not
961bb684c34Spatrick       // handle this case here as it will already have been matched by the
962bb684c34Spatrick       // case above.
963ece8a530Spatrick       auto *isd = make<InputSectionDescription>(tok);
964bb684c34Spatrick       isd->sectionPatterns.push_back({{}, StringMatcher("*")});
96505edf1c1Srobert       osec->commands.push_back(isd);
966ece8a530Spatrick     }
967ece8a530Spatrick   }
968ece8a530Spatrick 
969ece8a530Spatrick   if (consume(">"))
97005edf1c1Srobert     osec->memoryRegionName = std::string(next());
971ece8a530Spatrick 
972ece8a530Spatrick   if (consume("AT")) {
973ece8a530Spatrick     expect(">");
97405edf1c1Srobert     osec->lmaRegionName = std::string(next());
975ece8a530Spatrick   }
976ece8a530Spatrick 
97705edf1c1Srobert   if (osec->lmaExpr && !osec->lmaRegionName.empty())
978ece8a530Spatrick     error("section can't have both LMA and a load region");
979ece8a530Spatrick 
98005edf1c1Srobert   osec->phdrs = readOutputSectionPhdrs();
981ece8a530Spatrick 
982ece8a530Spatrick   if (peek() == "=" || peek().startswith("=")) {
983ece8a530Spatrick     inExpr = true;
984ece8a530Spatrick     consume("=");
98505edf1c1Srobert     osec->filler = readFill();
986ece8a530Spatrick     inExpr = false;
987ece8a530Spatrick   }
988ece8a530Spatrick 
989ece8a530Spatrick   // Consume optional comma following output section command.
990ece8a530Spatrick   consume(",");
991ece8a530Spatrick 
992ece8a530Spatrick   if (script->referencedSymbols.size() > symbolsReferenced)
99305edf1c1Srobert     osec->expressionsUseSymbols = true;
994ece8a530Spatrick   return cmd;
995ece8a530Spatrick }
996ece8a530Spatrick 
997ece8a530Spatrick // Reads a `=<fillexp>` expression and returns its value as a big-endian number.
998ece8a530Spatrick // https://sourceware.org/binutils/docs/ld/Output-Section-Fill.html
999ece8a530Spatrick // We do not support using symbols in such expressions.
1000ece8a530Spatrick //
1001ece8a530Spatrick // When reading a hexstring, ld.bfd handles it as a blob of arbitrary
1002ece8a530Spatrick // size, while ld.gold always handles it as a 32-bit big-endian number.
1003ece8a530Spatrick // We are compatible with ld.gold because it's easier to implement.
1004bb684c34Spatrick // Also, we require that expressions with operators must be wrapped into
1005bb684c34Spatrick // round brackets. We did it to resolve the ambiguity when parsing scripts like:
1006bb684c34Spatrick // SECTIONS { .foo : { ... } =120+3 /DISCARD/ : { ... } }
readFill()1007ece8a530Spatrick std::array<uint8_t, 4> ScriptParser::readFill() {
1008bb684c34Spatrick   uint64_t value = readPrimary()().val;
1009ece8a530Spatrick   if (value > UINT32_MAX)
1010ece8a530Spatrick     setError("filler expression result does not fit 32-bit: 0x" +
1011ece8a530Spatrick              Twine::utohexstr(value));
1012ece8a530Spatrick 
1013ece8a530Spatrick   std::array<uint8_t, 4> buf;
1014ece8a530Spatrick   write32be(buf.data(), (uint32_t)value);
1015ece8a530Spatrick   return buf;
1016ece8a530Spatrick }
1017ece8a530Spatrick 
readProvideHidden(bool provide,bool hidden)1018ece8a530Spatrick SymbolAssignment *ScriptParser::readProvideHidden(bool provide, bool hidden) {
1019ece8a530Spatrick   expect("(");
102005edf1c1Srobert   StringRef name = next(), eq = peek();
102105edf1c1Srobert   if (eq != "=") {
102205edf1c1Srobert     setError("= expected, but got " + next());
102305edf1c1Srobert     while (!atEOF() && next() != ")")
102405edf1c1Srobert       ;
102505edf1c1Srobert     return nullptr;
102605edf1c1Srobert   }
102705edf1c1Srobert   SymbolAssignment *cmd = readSymbolAssignment(name);
1028ece8a530Spatrick   cmd->provide = provide;
1029ece8a530Spatrick   cmd->hidden = hidden;
1030ece8a530Spatrick   expect(")");
1031ece8a530Spatrick   return cmd;
1032ece8a530Spatrick }
1033ece8a530Spatrick 
readAssignment(StringRef tok)1034ece8a530Spatrick SymbolAssignment *ScriptParser::readAssignment(StringRef tok) {
1035ece8a530Spatrick   // Assert expression returns Dot, so this is equal to ".=."
1036ece8a530Spatrick   if (tok == "ASSERT")
1037ece8a530Spatrick     return make<SymbolAssignment>(".", readAssert(), getCurrentLocation());
1038ece8a530Spatrick 
1039ece8a530Spatrick   size_t oldPos = pos;
1040ece8a530Spatrick   SymbolAssignment *cmd = nullptr;
104105edf1c1Srobert   const StringRef op = peek();
104205edf1c1Srobert   if (op.startswith("=")) {
104305edf1c1Srobert     // Support = followed by an expression without whitespace.
104405edf1c1Srobert     SaveAndRestore saved(inExpr, true);
1045ece8a530Spatrick     cmd = readSymbolAssignment(tok);
104605edf1c1Srobert   } else if ((op.size() == 2 && op[1] == '=' && strchr("*/+-&|", op[0])) ||
104705edf1c1Srobert              op == "<<=" || op == ">>=") {
104805edf1c1Srobert     cmd = readSymbolAssignment(tok);
104905edf1c1Srobert   } else if (tok == "PROVIDE") {
105005edf1c1Srobert     SaveAndRestore saved(inExpr, true);
1051ece8a530Spatrick     cmd = readProvideHidden(true, false);
105205edf1c1Srobert   } else if (tok == "HIDDEN") {
105305edf1c1Srobert     SaveAndRestore saved(inExpr, true);
1054ece8a530Spatrick     cmd = readProvideHidden(false, true);
105505edf1c1Srobert   } else if (tok == "PROVIDE_HIDDEN") {
105605edf1c1Srobert     SaveAndRestore saved(inExpr, true);
1057ece8a530Spatrick     cmd = readProvideHidden(true, true);
105805edf1c1Srobert   }
1059ece8a530Spatrick 
1060ece8a530Spatrick   if (cmd) {
1061ece8a530Spatrick     cmd->commandString =
1062ece8a530Spatrick         tok.str() + " " +
1063ece8a530Spatrick         llvm::join(tokens.begin() + oldPos, tokens.begin() + pos, " ");
1064ece8a530Spatrick     expect(";");
1065ece8a530Spatrick   }
1066ece8a530Spatrick   return cmd;
1067ece8a530Spatrick }
1068ece8a530Spatrick 
readSymbolAssignment(StringRef name)1069ece8a530Spatrick SymbolAssignment *ScriptParser::readSymbolAssignment(StringRef name) {
10701cf9926bSpatrick   name = unquote(name);
1071ece8a530Spatrick   StringRef op = next();
107205edf1c1Srobert   assert(op == "=" || op == "*=" || op == "/=" || op == "+=" || op == "-=" ||
107305edf1c1Srobert          op == "&=" || op == "|=" || op == "<<=" || op == ">>=");
107405edf1c1Srobert   // Note: GNU ld does not support %= or ^=.
1075ece8a530Spatrick   Expr e = readExpr();
107605edf1c1Srobert   if (op != "=") {
1077ece8a530Spatrick     std::string loc = getCurrentLocation();
107805edf1c1Srobert     e = [=, c = op[0]]() -> ExprValue {
107905edf1c1Srobert       ExprValue lhs = script->getSymbolValue(name, loc);
108005edf1c1Srobert       switch (c) {
108105edf1c1Srobert       case '*':
108205edf1c1Srobert         return lhs.getValue() * e().getValue();
108305edf1c1Srobert       case '/':
108405edf1c1Srobert         if (uint64_t rv = e().getValue())
108505edf1c1Srobert           return lhs.getValue() / rv;
108605edf1c1Srobert         error(loc + ": division by zero");
108705edf1c1Srobert         return 0;
108805edf1c1Srobert       case '+':
108905edf1c1Srobert         return add(lhs, e());
109005edf1c1Srobert       case '-':
109105edf1c1Srobert         return sub(lhs, e());
109205edf1c1Srobert       case '<':
109305edf1c1Srobert         return lhs.getValue() << e().getValue();
109405edf1c1Srobert       case '>':
109505edf1c1Srobert         return lhs.getValue() >> e().getValue();
109605edf1c1Srobert       case '&':
109705edf1c1Srobert         return lhs.getValue() & e().getValue();
109805edf1c1Srobert       case '|':
109905edf1c1Srobert         return lhs.getValue() | e().getValue();
110005edf1c1Srobert       default:
110105edf1c1Srobert         llvm_unreachable("");
110205edf1c1Srobert       }
110305edf1c1Srobert     };
1104ece8a530Spatrick   }
1105ece8a530Spatrick   return make<SymbolAssignment>(name, e, getCurrentLocation());
1106ece8a530Spatrick }
1107ece8a530Spatrick 
1108ece8a530Spatrick // This is an operator-precedence parser to parse a linker
1109ece8a530Spatrick // script expression.
readExpr()1110ece8a530Spatrick Expr ScriptParser::readExpr() {
1111ece8a530Spatrick   // Our lexer is context-aware. Set the in-expression bit so that
1112ece8a530Spatrick   // they apply different tokenization rules.
1113ece8a530Spatrick   bool orig = inExpr;
1114ece8a530Spatrick   inExpr = true;
1115ece8a530Spatrick   Expr e = readExpr1(readPrimary(), 0);
1116ece8a530Spatrick   inExpr = orig;
1117ece8a530Spatrick   return e;
1118ece8a530Spatrick }
1119ece8a530Spatrick 
combine(StringRef op,Expr l,Expr r)1120ece8a530Spatrick Expr ScriptParser::combine(StringRef op, Expr l, Expr r) {
1121ece8a530Spatrick   if (op == "+")
1122ece8a530Spatrick     return [=] { return add(l(), r()); };
1123ece8a530Spatrick   if (op == "-")
1124ece8a530Spatrick     return [=] { return sub(l(), r()); };
1125ece8a530Spatrick   if (op == "*")
1126ece8a530Spatrick     return [=] { return l().getValue() * r().getValue(); };
1127ece8a530Spatrick   if (op == "/") {
1128ece8a530Spatrick     std::string loc = getCurrentLocation();
1129ece8a530Spatrick     return [=]() -> uint64_t {
1130ece8a530Spatrick       if (uint64_t rv = r().getValue())
1131ece8a530Spatrick         return l().getValue() / rv;
1132ece8a530Spatrick       error(loc + ": division by zero");
1133ece8a530Spatrick       return 0;
1134ece8a530Spatrick     };
1135ece8a530Spatrick   }
1136ece8a530Spatrick   if (op == "%") {
1137ece8a530Spatrick     std::string loc = getCurrentLocation();
1138ece8a530Spatrick     return [=]() -> uint64_t {
1139ece8a530Spatrick       if (uint64_t rv = r().getValue())
1140ece8a530Spatrick         return l().getValue() % rv;
1141ece8a530Spatrick       error(loc + ": modulo by zero");
1142ece8a530Spatrick       return 0;
1143ece8a530Spatrick     };
1144ece8a530Spatrick   }
1145ece8a530Spatrick   if (op == "<<")
1146ece8a530Spatrick     return [=] { return l().getValue() << r().getValue(); };
1147ece8a530Spatrick   if (op == ">>")
1148ece8a530Spatrick     return [=] { return l().getValue() >> r().getValue(); };
1149ece8a530Spatrick   if (op == "<")
1150ece8a530Spatrick     return [=] { return l().getValue() < r().getValue(); };
1151ece8a530Spatrick   if (op == ">")
1152ece8a530Spatrick     return [=] { return l().getValue() > r().getValue(); };
1153ece8a530Spatrick   if (op == ">=")
1154ece8a530Spatrick     return [=] { return l().getValue() >= r().getValue(); };
1155ece8a530Spatrick   if (op == "<=")
1156ece8a530Spatrick     return [=] { return l().getValue() <= r().getValue(); };
1157ece8a530Spatrick   if (op == "==")
1158ece8a530Spatrick     return [=] { return l().getValue() == r().getValue(); };
1159ece8a530Spatrick   if (op == "!=")
1160ece8a530Spatrick     return [=] { return l().getValue() != r().getValue(); };
1161ece8a530Spatrick   if (op == "||")
1162ece8a530Spatrick     return [=] { return l().getValue() || r().getValue(); };
1163ece8a530Spatrick   if (op == "&&")
1164ece8a530Spatrick     return [=] { return l().getValue() && r().getValue(); };
1165ece8a530Spatrick   if (op == "&")
1166ece8a530Spatrick     return [=] { return bitAnd(l(), r()); };
1167ece8a530Spatrick   if (op == "|")
1168ece8a530Spatrick     return [=] { return bitOr(l(), r()); };
1169ece8a530Spatrick   llvm_unreachable("invalid operator");
1170ece8a530Spatrick }
1171ece8a530Spatrick 
1172ece8a530Spatrick // This is a part of the operator-precedence parser. This function
1173ece8a530Spatrick // assumes that the remaining token stream starts with an operator.
readExpr1(Expr lhs,int minPrec)1174ece8a530Spatrick Expr ScriptParser::readExpr1(Expr lhs, int minPrec) {
1175ece8a530Spatrick   while (!atEOF() && !errorCount()) {
1176ece8a530Spatrick     // Read an operator and an expression.
1177ece8a530Spatrick     StringRef op1 = peek();
1178ece8a530Spatrick     if (precedence(op1) < minPrec)
1179ece8a530Spatrick       break;
118005edf1c1Srobert     if (consume("?"))
118105edf1c1Srobert       return readTernary(lhs);
1182ece8a530Spatrick     skip();
1183ece8a530Spatrick     Expr rhs = readPrimary();
1184ece8a530Spatrick 
1185ece8a530Spatrick     // Evaluate the remaining part of the expression first if the
1186ece8a530Spatrick     // next operator has greater precedence than the previous one.
1187ece8a530Spatrick     // For example, if we have read "+" and "3", and if the next
1188ece8a530Spatrick     // operator is "*", then we'll evaluate 3 * ... part first.
1189ece8a530Spatrick     while (!atEOF()) {
1190ece8a530Spatrick       StringRef op2 = peek();
1191ece8a530Spatrick       if (precedence(op2) <= precedence(op1))
1192ece8a530Spatrick         break;
1193ece8a530Spatrick       rhs = readExpr1(rhs, precedence(op2));
1194ece8a530Spatrick     }
1195ece8a530Spatrick 
1196ece8a530Spatrick     lhs = combine(op1, lhs, rhs);
1197ece8a530Spatrick   }
1198ece8a530Spatrick   return lhs;
1199ece8a530Spatrick }
1200ece8a530Spatrick 
getPageSize()1201ece8a530Spatrick Expr ScriptParser::getPageSize() {
1202ece8a530Spatrick   std::string location = getCurrentLocation();
1203ece8a530Spatrick   return [=]() -> uint64_t {
1204ece8a530Spatrick     if (target)
1205ece8a530Spatrick       return config->commonPageSize;
1206ece8a530Spatrick     error(location + ": unable to calculate page size");
1207ece8a530Spatrick     return 4096; // Return a dummy value.
1208ece8a530Spatrick   };
1209ece8a530Spatrick }
1210ece8a530Spatrick 
readConstant()1211ece8a530Spatrick Expr ScriptParser::readConstant() {
1212ece8a530Spatrick   StringRef s = readParenLiteral();
1213ece8a530Spatrick   if (s == "COMMONPAGESIZE")
1214ece8a530Spatrick     return getPageSize();
1215ece8a530Spatrick   if (s == "MAXPAGESIZE")
1216ece8a530Spatrick     return [] { return config->maxPageSize; };
1217ece8a530Spatrick   setError("unknown constant: " + s);
1218ece8a530Spatrick   return [] { return 0; };
1219ece8a530Spatrick }
1220ece8a530Spatrick 
1221ece8a530Spatrick // Parses Tok as an integer. It recognizes hexadecimal (prefixed with
1222ece8a530Spatrick // "0x" or suffixed with "H") and decimal numbers. Decimal numbers may
1223ece8a530Spatrick // have "K" (Ki) or "M" (Mi) suffixes.
parseInt(StringRef tok)122405edf1c1Srobert static std::optional<uint64_t> parseInt(StringRef tok) {
1225ece8a530Spatrick   // Hexadecimal
1226ece8a530Spatrick   uint64_t val;
12271cf9926bSpatrick   if (tok.startswith_insensitive("0x")) {
1228ece8a530Spatrick     if (!to_integer(tok.substr(2), val, 16))
122905edf1c1Srobert       return std::nullopt;
1230ece8a530Spatrick     return val;
1231ece8a530Spatrick   }
12321cf9926bSpatrick   if (tok.endswith_insensitive("H")) {
1233ece8a530Spatrick     if (!to_integer(tok.drop_back(), val, 16))
123405edf1c1Srobert       return std::nullopt;
1235ece8a530Spatrick     return val;
1236ece8a530Spatrick   }
1237ece8a530Spatrick 
1238ece8a530Spatrick   // Decimal
12391cf9926bSpatrick   if (tok.endswith_insensitive("K")) {
1240ece8a530Spatrick     if (!to_integer(tok.drop_back(), val, 10))
124105edf1c1Srobert       return std::nullopt;
1242ece8a530Spatrick     return val * 1024;
1243ece8a530Spatrick   }
12441cf9926bSpatrick   if (tok.endswith_insensitive("M")) {
1245ece8a530Spatrick     if (!to_integer(tok.drop_back(), val, 10))
124605edf1c1Srobert       return std::nullopt;
1247ece8a530Spatrick     return val * 1024 * 1024;
1248ece8a530Spatrick   }
1249ece8a530Spatrick   if (!to_integer(tok, val, 10))
125005edf1c1Srobert     return std::nullopt;
1251ece8a530Spatrick   return val;
1252ece8a530Spatrick }
1253ece8a530Spatrick 
readByteCommand(StringRef tok)1254ece8a530Spatrick ByteCommand *ScriptParser::readByteCommand(StringRef tok) {
1255ece8a530Spatrick   int size = StringSwitch<int>(tok)
1256ece8a530Spatrick                  .Case("BYTE", 1)
1257ece8a530Spatrick                  .Case("SHORT", 2)
1258ece8a530Spatrick                  .Case("LONG", 4)
1259ece8a530Spatrick                  .Case("QUAD", 8)
1260ece8a530Spatrick                  .Default(-1);
1261ece8a530Spatrick   if (size == -1)
1262ece8a530Spatrick     return nullptr;
1263ece8a530Spatrick 
1264ece8a530Spatrick   size_t oldPos = pos;
1265ece8a530Spatrick   Expr e = readParenExpr();
1266ece8a530Spatrick   std::string commandString =
1267ece8a530Spatrick       tok.str() + " " +
1268ece8a530Spatrick       llvm::join(tokens.begin() + oldPos, tokens.begin() + pos, " ");
1269ece8a530Spatrick   return make<ByteCommand>(e, size, commandString);
1270ece8a530Spatrick }
1271ece8a530Spatrick 
parseFlag(StringRef tok)127205edf1c1Srobert static std::optional<uint64_t> parseFlag(StringRef tok) {
127305edf1c1Srobert   if (std::optional<uint64_t> asInt = parseInt(tok))
1274bb684c34Spatrick     return asInt;
1275bb684c34Spatrick #define CASE_ENT(enum) #enum, ELF::enum
127605edf1c1Srobert   return StringSwitch<std::optional<uint64_t>>(tok)
1277bb684c34Spatrick       .Case(CASE_ENT(SHF_WRITE))
1278bb684c34Spatrick       .Case(CASE_ENT(SHF_ALLOC))
1279bb684c34Spatrick       .Case(CASE_ENT(SHF_EXECINSTR))
1280bb684c34Spatrick       .Case(CASE_ENT(SHF_MERGE))
1281bb684c34Spatrick       .Case(CASE_ENT(SHF_STRINGS))
1282bb684c34Spatrick       .Case(CASE_ENT(SHF_INFO_LINK))
1283bb684c34Spatrick       .Case(CASE_ENT(SHF_LINK_ORDER))
1284bb684c34Spatrick       .Case(CASE_ENT(SHF_OS_NONCONFORMING))
1285bb684c34Spatrick       .Case(CASE_ENT(SHF_GROUP))
1286bb684c34Spatrick       .Case(CASE_ENT(SHF_TLS))
1287bb684c34Spatrick       .Case(CASE_ENT(SHF_COMPRESSED))
1288bb684c34Spatrick       .Case(CASE_ENT(SHF_EXCLUDE))
1289bb684c34Spatrick       .Case(CASE_ENT(SHF_ARM_PURECODE))
129005edf1c1Srobert       .Default(std::nullopt);
1291bb684c34Spatrick #undef CASE_ENT
1292bb684c34Spatrick }
1293bb684c34Spatrick 
1294bb684c34Spatrick // Reads the '(' <flags> ')' list of section flags in
1295bb684c34Spatrick // INPUT_SECTION_FLAGS '(' <flags> ')' in the
1296bb684c34Spatrick // following form:
1297bb684c34Spatrick // <flags> ::= <flag>
1298bb684c34Spatrick //           | <flags> & flag
1299bb684c34Spatrick // <flag>  ::= Recognized Flag Name, or Integer value of flag.
1300bb684c34Spatrick // If the first character of <flag> is a ! then this means without flag,
1301bb684c34Spatrick // otherwise with flag.
1302bb684c34Spatrick // Example: SHF_EXECINSTR & !SHF_WRITE means with flag SHF_EXECINSTR and
1303bb684c34Spatrick // without flag SHF_WRITE.
readInputSectionFlags()1304bb684c34Spatrick std::pair<uint64_t, uint64_t> ScriptParser::readInputSectionFlags() {
1305bb684c34Spatrick    uint64_t withFlags = 0;
1306bb684c34Spatrick    uint64_t withoutFlags = 0;
1307bb684c34Spatrick    expect("(");
1308bb684c34Spatrick    while (!errorCount()) {
1309bb684c34Spatrick     StringRef tok = unquote(next());
1310bb684c34Spatrick     bool without = tok.consume_front("!");
131105edf1c1Srobert     if (std::optional<uint64_t> flag = parseFlag(tok)) {
1312bb684c34Spatrick       if (without)
1313bb684c34Spatrick         withoutFlags |= *flag;
1314bb684c34Spatrick       else
1315bb684c34Spatrick         withFlags |= *flag;
1316bb684c34Spatrick     } else {
1317bb684c34Spatrick       setError("unrecognised flag: " + tok);
1318bb684c34Spatrick     }
1319bb684c34Spatrick     if (consume(")"))
1320bb684c34Spatrick       break;
1321bb684c34Spatrick     if (!consume("&")) {
1322bb684c34Spatrick       next();
1323bb684c34Spatrick       setError("expected & or )");
1324bb684c34Spatrick     }
1325bb684c34Spatrick   }
1326bb684c34Spatrick   return std::make_pair(withFlags, withoutFlags);
1327bb684c34Spatrick }
1328bb684c34Spatrick 
readParenLiteral()1329ece8a530Spatrick StringRef ScriptParser::readParenLiteral() {
1330ece8a530Spatrick   expect("(");
1331ece8a530Spatrick   bool orig = inExpr;
1332ece8a530Spatrick   inExpr = false;
1333ece8a530Spatrick   StringRef tok = next();
1334ece8a530Spatrick   inExpr = orig;
1335ece8a530Spatrick   expect(")");
1336ece8a530Spatrick   return tok;
1337ece8a530Spatrick }
1338ece8a530Spatrick 
checkIfExists(const OutputSection & osec,StringRef location)133905edf1c1Srobert static void checkIfExists(const OutputSection &osec, StringRef location) {
134005edf1c1Srobert   if (osec.location.empty() && script->errorOnMissingSection)
134105edf1c1Srobert     error(location + ": undefined section " + osec.name);
1342ece8a530Spatrick }
1343ece8a530Spatrick 
isValidSymbolName(StringRef s)13441cf9926bSpatrick static bool isValidSymbolName(StringRef s) {
13451cf9926bSpatrick   auto valid = [](char c) {
13461cf9926bSpatrick     return isAlnum(c) || c == '$' || c == '.' || c == '_';
13471cf9926bSpatrick   };
13481cf9926bSpatrick   return !s.empty() && !isDigit(s[0]) && llvm::all_of(s, valid);
13491cf9926bSpatrick }
13501cf9926bSpatrick 
readPrimary()1351ece8a530Spatrick Expr ScriptParser::readPrimary() {
1352ece8a530Spatrick   if (peek() == "(")
1353ece8a530Spatrick     return readParenExpr();
1354ece8a530Spatrick 
1355ece8a530Spatrick   if (consume("~")) {
1356ece8a530Spatrick     Expr e = readPrimary();
1357ece8a530Spatrick     return [=] { return ~e().getValue(); };
1358ece8a530Spatrick   }
1359ece8a530Spatrick   if (consume("!")) {
1360ece8a530Spatrick     Expr e = readPrimary();
1361ece8a530Spatrick     return [=] { return !e().getValue(); };
1362ece8a530Spatrick   }
1363ece8a530Spatrick   if (consume("-")) {
1364ece8a530Spatrick     Expr e = readPrimary();
1365ece8a530Spatrick     return [=] { return -e().getValue(); };
1366ece8a530Spatrick   }
1367ece8a530Spatrick 
1368ece8a530Spatrick   StringRef tok = next();
1369ece8a530Spatrick   std::string location = getCurrentLocation();
1370ece8a530Spatrick 
1371ece8a530Spatrick   // Built-in functions are parsed here.
1372ece8a530Spatrick   // https://sourceware.org/binutils/docs/ld/Builtin-Functions.html.
1373ece8a530Spatrick   if (tok == "ABSOLUTE") {
1374ece8a530Spatrick     Expr inner = readParenExpr();
1375ece8a530Spatrick     return [=] {
1376ece8a530Spatrick       ExprValue i = inner();
1377ece8a530Spatrick       i.forceAbsolute = true;
1378ece8a530Spatrick       return i;
1379ece8a530Spatrick     };
1380ece8a530Spatrick   }
1381ece8a530Spatrick   if (tok == "ADDR") {
1382ece8a530Spatrick     StringRef name = readParenLiteral();
138305edf1c1Srobert     OutputSection *osec = &script->getOrCreateOutputSection(name)->osec;
138405edf1c1Srobert     osec->usedInExpression = true;
1385ece8a530Spatrick     return [=]() -> ExprValue {
138605edf1c1Srobert       checkIfExists(*osec, location);
138705edf1c1Srobert       return {osec, false, 0, location};
1388ece8a530Spatrick     };
1389ece8a530Spatrick   }
1390ece8a530Spatrick   if (tok == "ALIGN") {
1391ece8a530Spatrick     expect("(");
1392ece8a530Spatrick     Expr e = readExpr();
1393ece8a530Spatrick     if (consume(")")) {
1394ece8a530Spatrick       e = checkAlignment(e, location);
139505edf1c1Srobert       return [=] { return alignToPowerOf2(script->getDot(), e().getValue()); };
1396ece8a530Spatrick     }
1397ece8a530Spatrick     expect(",");
1398ece8a530Spatrick     Expr e2 = checkAlignment(readExpr(), location);
1399ece8a530Spatrick     expect(")");
1400ece8a530Spatrick     return [=] {
1401ece8a530Spatrick       ExprValue v = e();
1402ece8a530Spatrick       v.alignment = e2().getValue();
1403ece8a530Spatrick       return v;
1404ece8a530Spatrick     };
1405ece8a530Spatrick   }
1406ece8a530Spatrick   if (tok == "ALIGNOF") {
1407ece8a530Spatrick     StringRef name = readParenLiteral();
140805edf1c1Srobert     OutputSection *osec = &script->getOrCreateOutputSection(name)->osec;
1409ece8a530Spatrick     return [=] {
141005edf1c1Srobert       checkIfExists(*osec, location);
141105edf1c1Srobert       return osec->addralign;
1412ece8a530Spatrick     };
1413ece8a530Spatrick   }
1414ece8a530Spatrick   if (tok == "ASSERT")
1415ece8a530Spatrick     return readAssert();
1416ece8a530Spatrick   if (tok == "CONSTANT")
1417ece8a530Spatrick     return readConstant();
1418ece8a530Spatrick   if (tok == "DATA_SEGMENT_ALIGN") {
1419ece8a530Spatrick     expect("(");
1420ece8a530Spatrick     Expr e = readExpr();
1421ece8a530Spatrick     expect(",");
1422ece8a530Spatrick     readExpr();
1423ece8a530Spatrick     expect(")");
142405edf1c1Srobert     seenDataAlign = true;
1425ece8a530Spatrick     return [=] {
142605edf1c1Srobert       uint64_t align = std::max(uint64_t(1), e().getValue());
142705edf1c1Srobert       return (script->getDot() + align - 1) & -align;
1428ece8a530Spatrick     };
1429ece8a530Spatrick   }
1430ece8a530Spatrick   if (tok == "DATA_SEGMENT_END") {
1431ece8a530Spatrick     expect("(");
1432ece8a530Spatrick     expect(".");
1433ece8a530Spatrick     expect(")");
1434ece8a530Spatrick     return [] { return script->getDot(); };
1435ece8a530Spatrick   }
1436ece8a530Spatrick   if (tok == "DATA_SEGMENT_RELRO_END") {
1437ece8a530Spatrick     // GNU linkers implements more complicated logic to handle
1438ece8a530Spatrick     // DATA_SEGMENT_RELRO_END. We instead ignore the arguments and
1439ece8a530Spatrick     // just align to the next page boundary for simplicity.
1440ece8a530Spatrick     expect("(");
1441ece8a530Spatrick     readExpr();
1442ece8a530Spatrick     expect(",");
1443ece8a530Spatrick     readExpr();
1444ece8a530Spatrick     expect(")");
144505edf1c1Srobert     seenRelroEnd = true;
1446ece8a530Spatrick     Expr e = getPageSize();
144705edf1c1Srobert     return [=] { return alignToPowerOf2(script->getDot(), e().getValue()); };
1448ece8a530Spatrick   }
1449ece8a530Spatrick   if (tok == "DEFINED") {
14501cf9926bSpatrick     StringRef name = unquote(readParenLiteral());
14511cf9926bSpatrick     return [=] {
145205edf1c1Srobert       Symbol *b = symtab.find(name);
14531cf9926bSpatrick       return (b && b->isDefined()) ? 1 : 0;
14541cf9926bSpatrick     };
1455ece8a530Spatrick   }
1456ece8a530Spatrick   if (tok == "LENGTH") {
1457ece8a530Spatrick     StringRef name = readParenLiteral();
1458ece8a530Spatrick     if (script->memoryRegions.count(name) == 0) {
1459ece8a530Spatrick       setError("memory region not defined: " + name);
1460ece8a530Spatrick       return [] { return 0; };
1461ece8a530Spatrick     }
1462bb684c34Spatrick     return script->memoryRegions[name]->length;
1463ece8a530Spatrick   }
1464ece8a530Spatrick   if (tok == "LOADADDR") {
1465ece8a530Spatrick     StringRef name = readParenLiteral();
146605edf1c1Srobert     OutputSection *osec = &script->getOrCreateOutputSection(name)->osec;
146705edf1c1Srobert     osec->usedInExpression = true;
1468ece8a530Spatrick     return [=] {
146905edf1c1Srobert       checkIfExists(*osec, location);
147005edf1c1Srobert       return osec->getLMA();
1471ece8a530Spatrick     };
1472ece8a530Spatrick   }
14731cf9926bSpatrick   if (tok == "LOG2CEIL") {
14741cf9926bSpatrick     expect("(");
14751cf9926bSpatrick     Expr a = readExpr();
14761cf9926bSpatrick     expect(")");
14771cf9926bSpatrick     return [=] {
14781cf9926bSpatrick       // LOG2CEIL(0) is defined to be 0.
14791cf9926bSpatrick       return llvm::Log2_64_Ceil(std::max(a().getValue(), UINT64_C(1)));
14801cf9926bSpatrick     };
14811cf9926bSpatrick   }
1482ece8a530Spatrick   if (tok == "MAX" || tok == "MIN") {
1483ece8a530Spatrick     expect("(");
1484ece8a530Spatrick     Expr a = readExpr();
1485ece8a530Spatrick     expect(",");
1486ece8a530Spatrick     Expr b = readExpr();
1487ece8a530Spatrick     expect(")");
1488ece8a530Spatrick     if (tok == "MIN")
1489ece8a530Spatrick       return [=] { return std::min(a().getValue(), b().getValue()); };
1490ece8a530Spatrick     return [=] { return std::max(a().getValue(), b().getValue()); };
1491ece8a530Spatrick   }
1492ece8a530Spatrick   if (tok == "ORIGIN") {
1493ece8a530Spatrick     StringRef name = readParenLiteral();
1494ece8a530Spatrick     if (script->memoryRegions.count(name) == 0) {
1495ece8a530Spatrick       setError("memory region not defined: " + name);
1496ece8a530Spatrick       return [] { return 0; };
1497ece8a530Spatrick     }
1498bb684c34Spatrick     return script->memoryRegions[name]->origin;
1499ece8a530Spatrick   }
1500ece8a530Spatrick   if (tok == "SEGMENT_START") {
1501ece8a530Spatrick     expect("(");
1502ece8a530Spatrick     skip();
1503ece8a530Spatrick     expect(",");
1504ece8a530Spatrick     Expr e = readExpr();
1505ece8a530Spatrick     expect(")");
1506ece8a530Spatrick     return [=] { return e(); };
1507ece8a530Spatrick   }
1508ece8a530Spatrick   if (tok == "SIZEOF") {
1509ece8a530Spatrick     StringRef name = readParenLiteral();
151005edf1c1Srobert     OutputSection *cmd = &script->getOrCreateOutputSection(name)->osec;
1511ece8a530Spatrick     // Linker script does not create an output section if its content is empty.
1512ece8a530Spatrick     // We want to allow SIZEOF(.foo) where .foo is a section which happened to
1513ece8a530Spatrick     // be empty.
1514ece8a530Spatrick     return [=] { return cmd->size; };
1515ece8a530Spatrick   }
1516ece8a530Spatrick   if (tok == "SIZEOF_HEADERS")
1517bb684c34Spatrick     return [=] { return elf::getHeaderSize(); };
1518ece8a530Spatrick 
1519ece8a530Spatrick   // Tok is the dot.
1520ece8a530Spatrick   if (tok == ".")
1521ece8a530Spatrick     return [=] { return script->getSymbolValue(tok, location); };
1522ece8a530Spatrick 
1523ece8a530Spatrick   // Tok is a literal number.
152405edf1c1Srobert   if (std::optional<uint64_t> val = parseInt(tok))
1525ece8a530Spatrick     return [=] { return *val; };
1526ece8a530Spatrick 
1527ece8a530Spatrick   // Tok is a symbol name.
152805edf1c1Srobert   if (tok.startswith("\""))
15291cf9926bSpatrick     tok = unquote(tok);
153005edf1c1Srobert   else if (!isValidSymbolName(tok))
1531ece8a530Spatrick     setError("malformed number: " + tok);
1532ece8a530Spatrick   script->referencedSymbols.push_back(tok);
1533ece8a530Spatrick   return [=] { return script->getSymbolValue(tok, location); };
1534ece8a530Spatrick }
1535ece8a530Spatrick 
readTernary(Expr cond)1536ece8a530Spatrick Expr ScriptParser::readTernary(Expr cond) {
1537ece8a530Spatrick   Expr l = readExpr();
1538ece8a530Spatrick   expect(":");
1539ece8a530Spatrick   Expr r = readExpr();
1540ece8a530Spatrick   return [=] { return cond().getValue() ? l() : r(); };
1541ece8a530Spatrick }
1542ece8a530Spatrick 
readParenExpr()1543ece8a530Spatrick Expr ScriptParser::readParenExpr() {
1544ece8a530Spatrick   expect("(");
1545ece8a530Spatrick   Expr e = readExpr();
1546ece8a530Spatrick   expect(")");
1547ece8a530Spatrick   return e;
1548ece8a530Spatrick }
1549ece8a530Spatrick 
readOutputSectionPhdrs()155005edf1c1Srobert SmallVector<StringRef, 0> ScriptParser::readOutputSectionPhdrs() {
155105edf1c1Srobert   SmallVector<StringRef, 0> phdrs;
1552ece8a530Spatrick   while (!errorCount() && peek().startswith(":")) {
1553ece8a530Spatrick     StringRef tok = next();
1554ece8a530Spatrick     phdrs.push_back((tok.size() == 1) ? next() : tok.substr(1));
1555ece8a530Spatrick   }
1556ece8a530Spatrick   return phdrs;
1557ece8a530Spatrick }
1558ece8a530Spatrick 
1559ece8a530Spatrick // Read a program header type name. The next token must be a
1560ece8a530Spatrick // name of a program header type or a constant (e.g. "0x3").
readPhdrType()1561ece8a530Spatrick unsigned ScriptParser::readPhdrType() {
1562ece8a530Spatrick   StringRef tok = next();
156305edf1c1Srobert   if (std::optional<uint64_t> val = parseInt(tok))
1564ece8a530Spatrick     return *val;
1565ece8a530Spatrick 
1566ece8a530Spatrick   unsigned ret = StringSwitch<unsigned>(tok)
1567ece8a530Spatrick                      .Case("PT_NULL", PT_NULL)
1568ece8a530Spatrick                      .Case("PT_LOAD", PT_LOAD)
1569ece8a530Spatrick                      .Case("PT_DYNAMIC", PT_DYNAMIC)
1570ece8a530Spatrick                      .Case("PT_INTERP", PT_INTERP)
1571ece8a530Spatrick                      .Case("PT_NOTE", PT_NOTE)
1572ece8a530Spatrick                      .Case("PT_SHLIB", PT_SHLIB)
1573ece8a530Spatrick                      .Case("PT_PHDR", PT_PHDR)
1574ece8a530Spatrick                      .Case("PT_TLS", PT_TLS)
1575ece8a530Spatrick                      .Case("PT_GNU_EH_FRAME", PT_GNU_EH_FRAME)
1576ece8a530Spatrick                      .Case("PT_GNU_STACK", PT_GNU_STACK)
1577ece8a530Spatrick                      .Case("PT_GNU_RELRO", PT_GNU_RELRO)
1578bd249b56Sderaadt                      .Case("PT_OPENBSD_MUTABLE", PT_OPENBSD_MUTABLE)
1579ece8a530Spatrick                      .Case("PT_OPENBSD_RANDOMIZE", PT_OPENBSD_RANDOMIZE)
1580*42a61aceSkettenis                      .Case("PT_OPENBSD_SYSCALLS", PT_OPENBSD_SYSCALLS)
1581ece8a530Spatrick                      .Case("PT_OPENBSD_WXNEEDED", PT_OPENBSD_WXNEEDED)
1582ece8a530Spatrick                      .Case("PT_OPENBSD_BOOTDATA", PT_OPENBSD_BOOTDATA)
1583ece8a530Spatrick                      .Default(-1);
1584ece8a530Spatrick 
1585ece8a530Spatrick   if (ret == (unsigned)-1) {
1586ece8a530Spatrick     setError("invalid program header type: " + tok);
1587ece8a530Spatrick     return PT_NULL;
1588ece8a530Spatrick   }
1589ece8a530Spatrick   return ret;
1590ece8a530Spatrick }
1591ece8a530Spatrick 
1592ece8a530Spatrick // Reads an anonymous version declaration.
readAnonymousDeclaration()1593ece8a530Spatrick void ScriptParser::readAnonymousDeclaration() {
159405edf1c1Srobert   SmallVector<SymbolVersion, 0> locals;
159505edf1c1Srobert   SmallVector<SymbolVersion, 0> globals;
1596ece8a530Spatrick   std::tie(locals, globals) = readSymbols();
1597ece8a530Spatrick   for (const SymbolVersion &pat : locals)
15981cf9926bSpatrick     config->versionDefinitions[VER_NDX_LOCAL].localPatterns.push_back(pat);
1599ece8a530Spatrick   for (const SymbolVersion &pat : globals)
16001cf9926bSpatrick     config->versionDefinitions[VER_NDX_GLOBAL].nonLocalPatterns.push_back(pat);
1601ece8a530Spatrick 
1602ece8a530Spatrick   expect(";");
1603ece8a530Spatrick }
1604ece8a530Spatrick 
1605ece8a530Spatrick // Reads a non-anonymous version definition,
1606ece8a530Spatrick // e.g. "VerStr { global: foo; bar; local: *; };".
readVersionDeclaration(StringRef verStr)1607ece8a530Spatrick void ScriptParser::readVersionDeclaration(StringRef verStr) {
1608ece8a530Spatrick   // Read a symbol list.
160905edf1c1Srobert   SmallVector<SymbolVersion, 0> locals;
161005edf1c1Srobert   SmallVector<SymbolVersion, 0> globals;
1611ece8a530Spatrick   std::tie(locals, globals) = readSymbols();
1612ece8a530Spatrick 
1613ece8a530Spatrick   // Create a new version definition and add that to the global symbols.
1614ece8a530Spatrick   VersionDefinition ver;
1615ece8a530Spatrick   ver.name = verStr;
16161cf9926bSpatrick   ver.nonLocalPatterns = std::move(globals);
16171cf9926bSpatrick   ver.localPatterns = std::move(locals);
1618ece8a530Spatrick   ver.id = config->versionDefinitions.size();
1619ece8a530Spatrick   config->versionDefinitions.push_back(ver);
1620ece8a530Spatrick 
1621ece8a530Spatrick   // Each version may have a parent version. For example, "Ver2"
1622ece8a530Spatrick   // defined as "Ver2 { global: foo; local: *; } Ver1;" has "Ver1"
1623ece8a530Spatrick   // as a parent. This version hierarchy is, probably against your
1624ece8a530Spatrick   // instinct, purely for hint; the runtime doesn't care about it
1625ece8a530Spatrick   // at all. In LLD, we simply ignore it.
1626bb684c34Spatrick   if (next() != ";")
1627ece8a530Spatrick     expect(";");
1628ece8a530Spatrick }
1629ece8a530Spatrick 
hasWildcard(StringRef s)1630bb684c34Spatrick bool elf::hasWildcard(StringRef s) {
1631ece8a530Spatrick   return s.find_first_of("?*[") != StringRef::npos;
1632ece8a530Spatrick }
1633ece8a530Spatrick 
1634ece8a530Spatrick // Reads a list of symbols, e.g. "{ global: foo; bar; local: *; };".
163505edf1c1Srobert std::pair<SmallVector<SymbolVersion, 0>, SmallVector<SymbolVersion, 0>>
readSymbols()1636ece8a530Spatrick ScriptParser::readSymbols() {
163705edf1c1Srobert   SmallVector<SymbolVersion, 0> locals;
163805edf1c1Srobert   SmallVector<SymbolVersion, 0> globals;
163905edf1c1Srobert   SmallVector<SymbolVersion, 0> *v = &globals;
1640ece8a530Spatrick 
1641ece8a530Spatrick   while (!errorCount()) {
1642ece8a530Spatrick     if (consume("}"))
1643ece8a530Spatrick       break;
1644ece8a530Spatrick     if (consumeLabel("local")) {
1645ece8a530Spatrick       v = &locals;
1646ece8a530Spatrick       continue;
1647ece8a530Spatrick     }
1648ece8a530Spatrick     if (consumeLabel("global")) {
1649ece8a530Spatrick       v = &globals;
1650ece8a530Spatrick       continue;
1651ece8a530Spatrick     }
1652ece8a530Spatrick 
1653ece8a530Spatrick     if (consume("extern")) {
165405edf1c1Srobert       SmallVector<SymbolVersion, 0> ext = readVersionExtern();
1655ece8a530Spatrick       v->insert(v->end(), ext.begin(), ext.end());
1656ece8a530Spatrick     } else {
1657ece8a530Spatrick       StringRef tok = next();
1658ece8a530Spatrick       v->push_back({unquote(tok), false, hasWildcard(tok)});
1659ece8a530Spatrick     }
1660ece8a530Spatrick     expect(";");
1661ece8a530Spatrick   }
1662ece8a530Spatrick   return {locals, globals};
1663ece8a530Spatrick }
1664ece8a530Spatrick 
1665ece8a530Spatrick // Reads an "extern C++" directive, e.g.,
1666ece8a530Spatrick // "extern "C++" { ns::*; "f(int, double)"; };"
1667ece8a530Spatrick //
1668ece8a530Spatrick // The last semicolon is optional. E.g. this is OK:
1669ece8a530Spatrick // "extern "C++" { ns::*; "f(int, double)" };"
readVersionExtern()167005edf1c1Srobert SmallVector<SymbolVersion, 0> ScriptParser::readVersionExtern() {
1671ece8a530Spatrick   StringRef tok = next();
1672ece8a530Spatrick   bool isCXX = tok == "\"C++\"";
1673ece8a530Spatrick   if (!isCXX && tok != "\"C\"")
1674ece8a530Spatrick     setError("Unknown language");
1675ece8a530Spatrick   expect("{");
1676ece8a530Spatrick 
167705edf1c1Srobert   SmallVector<SymbolVersion, 0> ret;
1678ece8a530Spatrick   while (!errorCount() && peek() != "}") {
1679ece8a530Spatrick     StringRef tok = next();
1680ece8a530Spatrick     ret.push_back(
1681ece8a530Spatrick         {unquote(tok), isCXX, !tok.startswith("\"") && hasWildcard(tok)});
1682ece8a530Spatrick     if (consume("}"))
1683ece8a530Spatrick       return ret;
1684ece8a530Spatrick     expect(";");
1685ece8a530Spatrick   }
1686ece8a530Spatrick 
1687ece8a530Spatrick   expect("}");
1688ece8a530Spatrick   return ret;
1689ece8a530Spatrick }
1690ece8a530Spatrick 
readMemoryAssignment(StringRef s1,StringRef s2,StringRef s3)1691bb684c34Spatrick Expr ScriptParser::readMemoryAssignment(StringRef s1, StringRef s2,
1692ece8a530Spatrick                                         StringRef s3) {
1693ece8a530Spatrick   if (!consume(s1) && !consume(s2) && !consume(s3)) {
1694ece8a530Spatrick     setError("expected one of: " + s1 + ", " + s2 + ", or " + s3);
1695bb684c34Spatrick     return [] { return 0; };
1696ece8a530Spatrick   }
1697ece8a530Spatrick   expect("=");
1698bb684c34Spatrick   return readExpr();
1699ece8a530Spatrick }
1700ece8a530Spatrick 
1701ece8a530Spatrick // Parse the MEMORY command as specified in:
1702ece8a530Spatrick // https://sourceware.org/binutils/docs/ld/MEMORY.html
1703ece8a530Spatrick //
1704ece8a530Spatrick // MEMORY { name [(attr)] : ORIGIN = origin, LENGTH = len ... }
readMemory()1705ece8a530Spatrick void ScriptParser::readMemory() {
1706ece8a530Spatrick   expect("{");
1707ece8a530Spatrick   while (!errorCount() && !consume("}")) {
1708ece8a530Spatrick     StringRef tok = next();
1709ece8a530Spatrick     if (tok == "INCLUDE") {
1710ece8a530Spatrick       readInclude();
1711ece8a530Spatrick       continue;
1712ece8a530Spatrick     }
1713ece8a530Spatrick 
1714ece8a530Spatrick     uint32_t flags = 0;
171505edf1c1Srobert     uint32_t invFlags = 0;
1716ece8a530Spatrick     uint32_t negFlags = 0;
171705edf1c1Srobert     uint32_t negInvFlags = 0;
1718ece8a530Spatrick     if (consume("(")) {
171905edf1c1Srobert       readMemoryAttributes(flags, invFlags, negFlags, negInvFlags);
1720ece8a530Spatrick       expect(")");
1721ece8a530Spatrick     }
1722ece8a530Spatrick     expect(":");
1723ece8a530Spatrick 
1724bb684c34Spatrick     Expr origin = readMemoryAssignment("ORIGIN", "org", "o");
1725ece8a530Spatrick     expect(",");
1726bb684c34Spatrick     Expr length = readMemoryAssignment("LENGTH", "len", "l");
1727ece8a530Spatrick 
1728ece8a530Spatrick     // Add the memory region to the region map.
172905edf1c1Srobert     MemoryRegion *mr = make<MemoryRegion>(tok, origin, length, flags, invFlags,
173005edf1c1Srobert                                           negFlags, negInvFlags);
1731ece8a530Spatrick     if (!script->memoryRegions.insert({tok, mr}).second)
1732ece8a530Spatrick       setError("region '" + tok + "' already defined");
1733ece8a530Spatrick   }
1734ece8a530Spatrick }
1735ece8a530Spatrick 
1736ece8a530Spatrick // This function parses the attributes used to match against section
1737ece8a530Spatrick // flags when placing output sections in a memory region. These flags
1738ece8a530Spatrick // are only used when an explicit memory region name is not used.
readMemoryAttributes(uint32_t & flags,uint32_t & invFlags,uint32_t & negFlags,uint32_t & negInvFlags)173905edf1c1Srobert void ScriptParser::readMemoryAttributes(uint32_t &flags, uint32_t &invFlags,
174005edf1c1Srobert                                         uint32_t &negFlags,
174105edf1c1Srobert                                         uint32_t &negInvFlags) {
1742ece8a530Spatrick   bool invert = false;
1743ece8a530Spatrick 
1744ece8a530Spatrick   for (char c : next().lower()) {
174505edf1c1Srobert     if (c == '!') {
1746ece8a530Spatrick       invert = !invert;
174705edf1c1Srobert       std::swap(flags, negFlags);
174805edf1c1Srobert       std::swap(invFlags, negInvFlags);
174905edf1c1Srobert       continue;
1750ece8a530Spatrick     }
175105edf1c1Srobert     if (c == 'w')
175205edf1c1Srobert       flags |= SHF_WRITE;
175305edf1c1Srobert     else if (c == 'x')
175405edf1c1Srobert       flags |= SHF_EXECINSTR;
175505edf1c1Srobert     else if (c == 'a')
175605edf1c1Srobert       flags |= SHF_ALLOC;
175705edf1c1Srobert     else if (c == 'r')
175805edf1c1Srobert       invFlags |= SHF_WRITE;
175905edf1c1Srobert     else
176005edf1c1Srobert       setError("invalid memory region attribute");
176105edf1c1Srobert   }
176205edf1c1Srobert 
176305edf1c1Srobert   if (invert) {
176405edf1c1Srobert     std::swap(flags, negFlags);
176505edf1c1Srobert     std::swap(invFlags, negInvFlags);
176605edf1c1Srobert   }
1767ece8a530Spatrick }
1768ece8a530Spatrick 
readLinkerScript(MemoryBufferRef mb)1769bb684c34Spatrick void elf::readLinkerScript(MemoryBufferRef mb) {
17701cf9926bSpatrick   llvm::TimeTraceScope timeScope("Read linker script",
17711cf9926bSpatrick                                  mb.getBufferIdentifier());
1772ece8a530Spatrick   ScriptParser(mb).readLinkerScript();
1773ece8a530Spatrick }
1774ece8a530Spatrick 
readVersionScript(MemoryBufferRef mb)1775bb684c34Spatrick void elf::readVersionScript(MemoryBufferRef mb) {
17761cf9926bSpatrick   llvm::TimeTraceScope timeScope("Read version script",
17771cf9926bSpatrick                                  mb.getBufferIdentifier());
1778ece8a530Spatrick   ScriptParser(mb).readVersionScript();
1779ece8a530Spatrick }
1780ece8a530Spatrick 
readDynamicList(MemoryBufferRef mb)1781bb684c34Spatrick void elf::readDynamicList(MemoryBufferRef mb) {
17821cf9926bSpatrick   llvm::TimeTraceScope timeScope("Read dynamic list", mb.getBufferIdentifier());
1783bb684c34Spatrick   ScriptParser(mb).readDynamicList();
1784ece8a530Spatrick }
1785ece8a530Spatrick 
readDefsym(StringRef name,MemoryBufferRef mb)1786bb684c34Spatrick void elf::readDefsym(StringRef name, MemoryBufferRef mb) {
17871cf9926bSpatrick   llvm::TimeTraceScope timeScope("Read defsym input", name);
1788bb684c34Spatrick   ScriptParser(mb).readDefsym(name);
1789bb684c34Spatrick }
1790