blob: 7cec67a6448af95cc8aacdeff11ff8692ae31a35 [file] [log] [blame]
Rui Ueyamaf7c5fbb2015-09-30 17:23:26 +00001//===- LinkerScript.cpp ---------------------------------------------------===//
2//
3// The LLVM Linker
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9//
10// This file contains the parser/evaluator of the linker script.
11// It does not construct an AST but consume linker script directives directly.
Rui Ueyama34f29242015-10-13 19:51:57 +000012// Results are written to Driver or Config object.
Rui Ueyamaf7c5fbb2015-09-30 17:23:26 +000013//
14//===----------------------------------------------------------------------===//
15
Rui Ueyama717677a2016-02-11 21:17:59 +000016#include "LinkerScript.h"
Rui Ueyamaf7c5fbb2015-09-30 17:23:26 +000017#include "Config.h"
18#include "Driver.h"
Rui Ueyama1ebc8ed2016-02-12 21:47:28 +000019#include "InputSection.h"
Rui Ueyamaf7c5fbb2015-09-30 17:23:26 +000020#include "SymbolTable.h"
21#include "llvm/Support/FileSystem.h"
22#include "llvm/Support/MemoryBuffer.h"
Rui Ueyamaf03f3cc2015-10-13 00:09:21 +000023#include "llvm/Support/Path.h"
Rui Ueyamaa47ee682015-10-11 01:53:04 +000024#include "llvm/Support/StringSaver.h"
Rui Ueyamaf7c5fbb2015-09-30 17:23:26 +000025
26using namespace llvm;
Rui Ueyama1ebc8ed2016-02-12 21:47:28 +000027using namespace llvm::object;
Rui Ueyamaf7c5fbb2015-09-30 17:23:26 +000028using namespace lld;
29using namespace lld::elf2;
30
Rui Ueyama717677a2016-02-11 21:17:59 +000031LinkerScript *elf2::Script;
32
Rui Ueyama1ebc8ed2016-02-12 21:47:28 +000033template <class ELFT>
34StringRef LinkerScript::getOutputSection(InputSectionBase<ELFT> *S) {
35 for (SectionRule &R : Sections)
36 if (R.match(S))
37 return R.Dest;
38 return "";
Rui Ueyama717677a2016-02-11 21:17:59 +000039}
40
Rui Ueyama1ebc8ed2016-02-12 21:47:28 +000041template <class ELFT>
42bool LinkerScript::isDiscarded(InputSectionBase<ELFT> *S) {
43 return getOutputSection(S) == "/DISCARD/";
Rui Ueyama717677a2016-02-11 21:17:59 +000044}
45
Rui Ueyamae9c58062016-02-12 20:41:43 +000046// A compartor to sort output sections. Returns -1 or 1 if both
47// A and B are mentioned in linker scripts. Otherwise, returns 0
48// to use the default rule which is implemented in Writer.cpp.
Rui Ueyama717677a2016-02-11 21:17:59 +000049int LinkerScript::compareSections(StringRef A, StringRef B) {
Rui Ueyamae9c58062016-02-12 20:41:43 +000050 auto E = SectionOrder.end();
51 auto I = std::find(SectionOrder.begin(), E, A);
52 auto J = std::find(SectionOrder.begin(), E, B);
53 if (I == E || J == E)
Rui Ueyama717677a2016-02-11 21:17:59 +000054 return 0;
55 return I < J ? -1 : 1;
56}
57
Rui Ueyama1ebc8ed2016-02-12 21:47:28 +000058// Returns true if S matches T. S may contain a meta character '*'
59// which matches zero or more occurrences of any character.
60static bool matchStr(StringRef S, StringRef T) {
61 for (;;) {
62 if (S.empty())
63 return T.empty();
64 if (S[0] == '*') {
65 S = S.substr(1);
66 if (S.empty())
67 // Fast path. If a pattern is '*', it matches anything.
68 return true;
69 for (size_t I = 0, E = T.size(); I < E; ++I)
70 if (matchStr(S, T.substr(I)))
71 return true;
72 return false;
73 }
74 if (T.empty() || S[0] != T[0])
75 return false;
76 S = S.substr(1);
77 T = T.substr(1);
78 }
79}
80
81template <class ELFT> bool SectionRule::match(InputSectionBase<ELFT> *S) {
82 return matchStr(SectionPattern, S->getSectionName());
83}
84
Rui Ueyama717677a2016-02-11 21:17:59 +000085class elf2::ScriptParser {
Rui Ueyamaf7c5fbb2015-09-30 17:23:26 +000086public:
Rui Ueyama717677a2016-02-11 21:17:59 +000087 ScriptParser(BumpPtrAllocator *A, StringRef S, bool B)
George Rimarf23b2322016-02-19 10:45:45 +000088 : Saver(*A), Tokens(tokenize(S)), IsUnderSysroot(B) {
89 Cmd["ENTRY"] = &ScriptParser::readEntry;
90 Cmd["EXTERN"] = &ScriptParser::readExtern;
91 Cmd["GROUP"] = &ScriptParser::readGroup;
92 Cmd["INCLUDE"] = &ScriptParser::readInclude;
93 Cmd["INPUT"] = &ScriptParser::readGroup;
94 Cmd["OUTPUT"] = &ScriptParser::readOutput;
95 Cmd["OUTPUT_ARCH"] = &ScriptParser::readOutputArch;
96 Cmd["OUTPUT_FORMAT"] = &ScriptParser::readOutputFormat;
97 Cmd["SEARCH_DIR"] = &ScriptParser::readSearchDir;
98 Cmd["SECTIONS"] = &ScriptParser::readSections;
99 Cmd[";"] = [](ScriptParser &) {};
100 }
101
Rui Ueyamaf7c5fbb2015-09-30 17:23:26 +0000102 void run();
103
104private:
Rui Ueyama025d59b2016-02-02 20:27:59 +0000105 void setError(const Twine &Msg);
Rui Ueyamaf7c5fbb2015-09-30 17:23:26 +0000106 static std::vector<StringRef> tokenize(StringRef S);
107 static StringRef skipSpace(StringRef S);
Rui Ueyama025d59b2016-02-02 20:27:59 +0000108 bool atEOF();
Rui Ueyamaf7c5fbb2015-09-30 17:23:26 +0000109 StringRef next();
Denis Protivensky8e3b38a2015-11-12 09:52:08 +0000110 bool skip(StringRef Tok);
Rui Ueyamaf7c5fbb2015-09-30 17:23:26 +0000111 void expect(StringRef Expect);
112
Rui Ueyama52a15092015-10-11 03:28:42 +0000113 void addFile(StringRef Path);
114
Rui Ueyamaf7c5fbb2015-09-30 17:23:26 +0000115 void readAsNeeded();
Denis Protivensky90c50992015-10-08 06:48:38 +0000116 void readEntry();
George Rimar83f406c2015-10-19 17:35:12 +0000117 void readExtern();
Rui Ueyamaf7c5fbb2015-09-30 17:23:26 +0000118 void readGroup();
Rui Ueyama31aa1f82015-10-11 01:31:55 +0000119 void readInclude();
Rui Ueyamaee592822015-10-07 00:25:09 +0000120 void readOutput();
Davide Italiano9159ce92015-10-12 21:50:08 +0000121 void readOutputArch();
Rui Ueyamaf7c5fbb2015-09-30 17:23:26 +0000122 void readOutputFormat();
Davide Italiano68a39a62015-10-08 17:51:41 +0000123 void readSearchDir();
Denis Protivensky8e3b38a2015-11-12 09:52:08 +0000124 void readSections();
125
126 void readOutputSectionDescription();
Rui Ueyamaf7c5fbb2015-09-30 17:23:26 +0000127
Rui Ueyamaa47ee682015-10-11 01:53:04 +0000128 StringSaver Saver;
Rui Ueyamaf7c5fbb2015-09-30 17:23:26 +0000129 std::vector<StringRef> Tokens;
George Rimarf23b2322016-02-19 10:45:45 +0000130 llvm::StringMap<std::function<void(ScriptParser &)>> Cmd;
Rui Ueyamaf7c5fbb2015-09-30 17:23:26 +0000131 size_t Pos = 0;
Simon Atanasyan16b0cc92015-11-26 05:53:00 +0000132 bool IsUnderSysroot;
George Rimarf23b2322016-02-19 10:45:45 +0000133 bool Error = false;
Rui Ueyamaf7c5fbb2015-09-30 17:23:26 +0000134};
Rui Ueyamaf7c5fbb2015-09-30 17:23:26 +0000135
Rui Ueyama717677a2016-02-11 21:17:59 +0000136void ScriptParser::run() {
Rui Ueyamaf7c5fbb2015-09-30 17:23:26 +0000137 while (!atEOF()) {
138 StringRef Tok = next();
George Rimarf23b2322016-02-19 10:45:45 +0000139 auto It = Cmd.find(Tok);
140 if (It != Cmd.end()) {
141 std::function<void(ScriptParser &)> &Handler = It->second;
142 Handler(*this);
Rui Ueyamaf7c5fbb2015-09-30 17:23:26 +0000143 } else {
Rui Ueyama025d59b2016-02-02 20:27:59 +0000144 setError("unknown directive: " + Tok);
Rui Ueyamaf7c5fbb2015-09-30 17:23:26 +0000145 }
146 }
147}
148
Rui Ueyama025d59b2016-02-02 20:27:59 +0000149// We don't want to record cascading errors. Keep only the first one.
Rui Ueyama717677a2016-02-11 21:17:59 +0000150void ScriptParser::setError(const Twine &Msg) {
Rui Ueyama025d59b2016-02-02 20:27:59 +0000151 if (Error)
152 return;
153 error(Msg);
154 Error = true;
155}
156
Rui Ueyamaf7c5fbb2015-09-30 17:23:26 +0000157// Split S into linker script tokens.
Rui Ueyama717677a2016-02-11 21:17:59 +0000158std::vector<StringRef> ScriptParser::tokenize(StringRef S) {
Rui Ueyamaf7c5fbb2015-09-30 17:23:26 +0000159 std::vector<StringRef> Ret;
160 for (;;) {
161 S = skipSpace(S);
162 if (S.empty())
163 return Ret;
164
165 // Quoted token
166 if (S.startswith("\"")) {
167 size_t E = S.find("\"", 1);
Rui Ueyama025d59b2016-02-02 20:27:59 +0000168 if (E == StringRef::npos) {
169 error("unclosed quote");
170 return {};
171 }
Pete Cooper60259332016-01-22 23:46:37 +0000172 Ret.push_back(S.substr(1, E - 1));
Rui Ueyamaf7c5fbb2015-09-30 17:23:26 +0000173 S = S.substr(E + 1);
174 continue;
175 }
176
177 // Unquoted token
178 size_t Pos = S.find_first_not_of(
179 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"
180 "0123456789_.$/\\~=+[]*?-:");
181 // A character that cannot start a word (which is usually a
182 // punctuation) forms a single character token.
183 if (Pos == 0)
184 Pos = 1;
185 Ret.push_back(S.substr(0, Pos));
186 S = S.substr(Pos);
187 }
188}
189
190// Skip leading whitespace characters or /**/-style comments.
Rui Ueyama717677a2016-02-11 21:17:59 +0000191StringRef ScriptParser::skipSpace(StringRef S) {
Rui Ueyamaf7c5fbb2015-09-30 17:23:26 +0000192 for (;;) {
193 if (S.startswith("/*")) {
194 size_t E = S.find("*/", 2);
Rui Ueyama025d59b2016-02-02 20:27:59 +0000195 if (E == StringRef::npos) {
196 error("unclosed comment in a linker script");
197 return "";
198 }
Rui Ueyamaf7c5fbb2015-09-30 17:23:26 +0000199 S = S.substr(E + 2);
200 continue;
201 }
202 size_t Size = S.size();
203 S = S.ltrim();
204 if (S.size() == Size)
205 return S;
206 }
207}
208
Rui Ueyama025d59b2016-02-02 20:27:59 +0000209// An errneous token is handled as if it were the last token before EOF.
Rui Ueyama717677a2016-02-11 21:17:59 +0000210bool ScriptParser::atEOF() { return Error || Tokens.size() == Pos; }
Rui Ueyama025d59b2016-02-02 20:27:59 +0000211
Rui Ueyama717677a2016-02-11 21:17:59 +0000212StringRef ScriptParser::next() {
Rui Ueyama025d59b2016-02-02 20:27:59 +0000213 if (Error)
214 return "";
215 if (atEOF()) {
216 setError("unexpected EOF");
217 return "";
218 }
Rui Ueyamaf7c5fbb2015-09-30 17:23:26 +0000219 return Tokens[Pos++];
220}
221
Rui Ueyama717677a2016-02-11 21:17:59 +0000222bool ScriptParser::skip(StringRef Tok) {
Rui Ueyama025d59b2016-02-02 20:27:59 +0000223 if (Error)
224 return false;
225 if (atEOF()) {
226 setError("unexpected EOF");
227 return false;
228 }
Denis Protivensky8e3b38a2015-11-12 09:52:08 +0000229 if (Tok != Tokens[Pos])
230 return false;
231 ++Pos;
232 return true;
233}
234
Rui Ueyama717677a2016-02-11 21:17:59 +0000235void ScriptParser::expect(StringRef Expect) {
Rui Ueyama025d59b2016-02-02 20:27:59 +0000236 if (Error)
237 return;
Rui Ueyamaf7c5fbb2015-09-30 17:23:26 +0000238 StringRef Tok = next();
239 if (Tok != Expect)
Rui Ueyama025d59b2016-02-02 20:27:59 +0000240 setError(Expect + " expected, but got " + Tok);
Rui Ueyamaf7c5fbb2015-09-30 17:23:26 +0000241}
242
Rui Ueyama717677a2016-02-11 21:17:59 +0000243void ScriptParser::addFile(StringRef S) {
Simon Atanasyan16b0cc92015-11-26 05:53:00 +0000244 if (IsUnderSysroot && S.startswith("/")) {
245 SmallString<128> Path;
246 (Config->Sysroot + S).toStringRef(Path);
247 if (sys::fs::exists(Path)) {
248 Driver->addFile(Saver.save(Path.str()));
249 return;
250 }
251 }
252
Rui Ueyamaf03f3cc2015-10-13 00:09:21 +0000253 if (sys::path::is_absolute(S)) {
Rui Ueyama52a15092015-10-11 03:28:42 +0000254 Driver->addFile(S);
255 } else if (S.startswith("=")) {
256 if (Config->Sysroot.empty())
257 Driver->addFile(S.substr(1));
258 else
259 Driver->addFile(Saver.save(Config->Sysroot + "/" + S.substr(1)));
260 } else if (S.startswith("-l")) {
Rui Ueyama21eecb42016-02-02 21:13:09 +0000261 Driver->addLibrary(S.substr(2));
Simon Atanasyana1b8fc32015-11-26 20:23:46 +0000262 } else if (sys::fs::exists(S)) {
263 Driver->addFile(S);
Rui Ueyama52a15092015-10-11 03:28:42 +0000264 } else {
265 std::string Path = findFromSearchPaths(S);
266 if (Path.empty())
Rui Ueyama025d59b2016-02-02 20:27:59 +0000267 setError("Unable to find " + S);
268 else
269 Driver->addFile(Saver.save(Path));
Rui Ueyama52a15092015-10-11 03:28:42 +0000270 }
271}
272
Rui Ueyama717677a2016-02-11 21:17:59 +0000273void ScriptParser::readAsNeeded() {
Rui Ueyamaf7c5fbb2015-09-30 17:23:26 +0000274 expect("(");
Rui Ueyama35da9b62015-10-11 20:59:12 +0000275 bool Orig = Config->AsNeeded;
276 Config->AsNeeded = true;
Rui Ueyama025d59b2016-02-02 20:27:59 +0000277 while (!Error) {
Rui Ueyamaf7c5fbb2015-09-30 17:23:26 +0000278 StringRef Tok = next();
279 if (Tok == ")")
Rui Ueyama35da9b62015-10-11 20:59:12 +0000280 break;
Rui Ueyama52a15092015-10-11 03:28:42 +0000281 addFile(Tok);
Rui Ueyamaf7c5fbb2015-09-30 17:23:26 +0000282 }
Rui Ueyama35da9b62015-10-11 20:59:12 +0000283 Config->AsNeeded = Orig;
Rui Ueyamaf7c5fbb2015-09-30 17:23:26 +0000284}
285
Rui Ueyama717677a2016-02-11 21:17:59 +0000286void ScriptParser::readEntry() {
Denis Protivensky90c50992015-10-08 06:48:38 +0000287 // -e <symbol> takes predecence over ENTRY(<symbol>).
288 expect("(");
289 StringRef Tok = next();
290 if (Config->Entry.empty())
291 Config->Entry = Tok;
292 expect(")");
293}
294
Rui Ueyama717677a2016-02-11 21:17:59 +0000295void ScriptParser::readExtern() {
George Rimar83f406c2015-10-19 17:35:12 +0000296 expect("(");
Rui Ueyama025d59b2016-02-02 20:27:59 +0000297 while (!Error) {
George Rimar83f406c2015-10-19 17:35:12 +0000298 StringRef Tok = next();
299 if (Tok == ")")
300 return;
301 Config->Undefined.push_back(Tok);
302 }
303}
304
Rui Ueyama717677a2016-02-11 21:17:59 +0000305void ScriptParser::readGroup() {
Rui Ueyamaf7c5fbb2015-09-30 17:23:26 +0000306 expect("(");
Rui Ueyama025d59b2016-02-02 20:27:59 +0000307 while (!Error) {
Rui Ueyamaf7c5fbb2015-09-30 17:23:26 +0000308 StringRef Tok = next();
309 if (Tok == ")")
310 return;
311 if (Tok == "AS_NEEDED") {
312 readAsNeeded();
313 continue;
314 }
Rui Ueyama52a15092015-10-11 03:28:42 +0000315 addFile(Tok);
Rui Ueyamaf7c5fbb2015-09-30 17:23:26 +0000316 }
317}
318
Rui Ueyama717677a2016-02-11 21:17:59 +0000319void ScriptParser::readInclude() {
Rui Ueyama31aa1f82015-10-11 01:31:55 +0000320 StringRef Tok = next();
321 auto MBOrErr = MemoryBuffer::getFile(Tok);
Rui Ueyama025d59b2016-02-02 20:27:59 +0000322 if (!MBOrErr) {
323 setError("cannot open " + Tok);
324 return;
325 }
Rui Ueyama31aa1f82015-10-11 01:31:55 +0000326 std::unique_ptr<MemoryBuffer> &MB = *MBOrErr;
Rui Ueyamaa47ee682015-10-11 01:53:04 +0000327 StringRef S = Saver.save(MB->getMemBufferRef().getBuffer());
328 std::vector<StringRef> V = tokenize(S);
Rui Ueyama31aa1f82015-10-11 01:31:55 +0000329 Tokens.insert(Tokens.begin() + Pos, V.begin(), V.end());
Rui Ueyama31aa1f82015-10-11 01:31:55 +0000330}
331
Rui Ueyama717677a2016-02-11 21:17:59 +0000332void ScriptParser::readOutput() {
Rui Ueyamaee592822015-10-07 00:25:09 +0000333 // -o <file> takes predecence over OUTPUT(<file>).
334 expect("(");
335 StringRef Tok = next();
336 if (Config->OutputFile.empty())
337 Config->OutputFile = Tok;
338 expect(")");
339}
340
Rui Ueyama717677a2016-02-11 21:17:59 +0000341void ScriptParser::readOutputArch() {
Davide Italiano9159ce92015-10-12 21:50:08 +0000342 // Error checking only for now.
343 expect("(");
344 next();
345 expect(")");
346}
347
Rui Ueyama717677a2016-02-11 21:17:59 +0000348void ScriptParser::readOutputFormat() {
Rui Ueyamaf7c5fbb2015-09-30 17:23:26 +0000349 // Error checking only for now.
350 expect("(");
351 next();
Davide Italiano6836c612015-10-12 21:08:41 +0000352 StringRef Tok = next();
353 if (Tok == ")")
354 return;
Rui Ueyama025d59b2016-02-02 20:27:59 +0000355 if (Tok != ",") {
356 setError("unexpected token: " + Tok);
357 return;
358 }
Davide Italiano6836c612015-10-12 21:08:41 +0000359 next();
360 expect(",");
361 next();
Rui Ueyamaf7c5fbb2015-09-30 17:23:26 +0000362 expect(")");
363}
364
Rui Ueyama717677a2016-02-11 21:17:59 +0000365void ScriptParser::readSearchDir() {
Davide Italiano68a39a62015-10-08 17:51:41 +0000366 expect("(");
Rui Ueyama52a15092015-10-11 03:28:42 +0000367 Config->SearchPaths.push_back(next());
Davide Italiano68a39a62015-10-08 17:51:41 +0000368 expect(")");
369}
370
Rui Ueyama717677a2016-02-11 21:17:59 +0000371void ScriptParser::readSections() {
Denis Protivensky8e3b38a2015-11-12 09:52:08 +0000372 expect("{");
Rui Ueyama025d59b2016-02-02 20:27:59 +0000373 while (!Error && !skip("}"))
Denis Protivensky8e3b38a2015-11-12 09:52:08 +0000374 readOutputSectionDescription();
375}
376
Rui Ueyama717677a2016-02-11 21:17:59 +0000377void ScriptParser::readOutputSectionDescription() {
Rui Ueyamae9c58062016-02-12 20:41:43 +0000378 StringRef OutSec = next();
379 Script->SectionOrder.push_back(OutSec);
Denis Protivensky8e3b38a2015-11-12 09:52:08 +0000380 expect(":");
381 expect("{");
Rui Ueyama025d59b2016-02-02 20:27:59 +0000382 while (!Error && !skip("}")) {
Denis Protivensky8e3b38a2015-11-12 09:52:08 +0000383 next(); // Skip input file name.
384 expect("(");
Rui Ueyama025d59b2016-02-02 20:27:59 +0000385 while (!Error && !skip(")"))
Rui Ueyama1ebc8ed2016-02-12 21:47:28 +0000386 Script->Sections.push_back({OutSec, next()});
Denis Protivensky8e3b38a2015-11-12 09:52:08 +0000387 }
388}
389
Simon Atanasyan16b0cc92015-11-26 05:53:00 +0000390static bool isUnderSysroot(StringRef Path) {
391 if (Config->Sysroot == "")
392 return false;
393 for (; !Path.empty(); Path = sys::path::parent_path(Path))
394 if (sys::fs::equivalent(Config->Sysroot, Path))
395 return true;
396 return false;
397}
398
Rui Ueyamaf7c5fbb2015-09-30 17:23:26 +0000399// Entry point. The other functions or classes are private to this file.
Rui Ueyamaf9de0d62016-02-11 21:38:55 +0000400void LinkerScript::read(MemoryBufferRef MB) {
Simon Atanasyan16b0cc92015-11-26 05:53:00 +0000401 StringRef Path = MB.getBufferIdentifier();
Rui Ueyamaf9de0d62016-02-11 21:38:55 +0000402 ScriptParser(&Alloc, MB.getBuffer(), isUnderSysroot(Path)).run();
Rui Ueyamaf7c5fbb2015-09-30 17:23:26 +0000403}
Rui Ueyama1ebc8ed2016-02-12 21:47:28 +0000404
405template StringRef LinkerScript::getOutputSection(InputSectionBase<ELF32LE> *);
406template StringRef LinkerScript::getOutputSection(InputSectionBase<ELF32BE> *);
407template StringRef LinkerScript::getOutputSection(InputSectionBase<ELF64LE> *);
408template StringRef LinkerScript::getOutputSection(InputSectionBase<ELF64BE> *);
409
410template bool LinkerScript::isDiscarded(InputSectionBase<ELF32LE> *);
411template bool LinkerScript::isDiscarded(InputSectionBase<ELF32BE> *);
412template bool LinkerScript::isDiscarded(InputSectionBase<ELF64LE> *);
413template bool LinkerScript::isDiscarded(InputSectionBase<ELF64BE> *);
414
415template bool SectionRule::match(InputSectionBase<ELF32LE> *);
416template bool SectionRule::match(InputSectionBase<ELF32BE> *);
417template bool SectionRule::match(InputSectionBase<ELF64LE> *);
418template bool SectionRule::match(InputSectionBase<ELF64BE> *);