File: | tools/lld/ELF/ScriptParser.cpp |
Warning: | line 885, column 3 Undefined or garbage value returned to caller |
Press '?' to see keyboard shortcuts
Keyboard shortcuts:
1 | //===- ScriptParser.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 a recursive-descendent parser for linker scripts. | |||
11 | // Parsed results are stored to Config and Script global objects. | |||
12 | // | |||
13 | //===----------------------------------------------------------------------===// | |||
14 | ||||
15 | #include "ScriptParser.h" | |||
16 | #include "Config.h" | |||
17 | #include "Driver.h" | |||
18 | #include "InputSection.h" | |||
19 | #include "LinkerScript.h" | |||
20 | #include "OutputSections.h" | |||
21 | #include "ScriptLexer.h" | |||
22 | #include "Symbols.h" | |||
23 | #include "Target.h" | |||
24 | #include "lld/Common/Memory.h" | |||
25 | #include "llvm/ADT/SmallString.h" | |||
26 | #include "llvm/ADT/StringRef.h" | |||
27 | #include "llvm/ADT/StringSet.h" | |||
28 | #include "llvm/ADT/StringSwitch.h" | |||
29 | #include "llvm/BinaryFormat/ELF.h" | |||
30 | #include "llvm/Support/Casting.h" | |||
31 | #include "llvm/Support/ErrorHandling.h" | |||
32 | #include "llvm/Support/FileSystem.h" | |||
33 | #include "llvm/Support/Path.h" | |||
34 | #include <cassert> | |||
35 | #include <limits> | |||
36 | #include <vector> | |||
37 | ||||
38 | using namespace llvm; | |||
39 | using namespace llvm::ELF; | |||
40 | using namespace llvm::support::endian; | |||
41 | using namespace lld; | |||
42 | using namespace lld::elf; | |||
43 | ||||
44 | static bool isUnderSysroot(StringRef Path); | |||
45 | ||||
46 | namespace { | |||
47 | class ScriptParser final : ScriptLexer { | |||
48 | public: | |||
49 | ScriptParser(MemoryBufferRef MB) | |||
50 | : ScriptLexer(MB), | |||
51 | IsUnderSysroot(isUnderSysroot(MB.getBufferIdentifier())) {} | |||
52 | ||||
53 | void readLinkerScript(); | |||
54 | void readVersionScript(); | |||
55 | void readDynamicList(); | |||
56 | void readDefsym(StringRef Name); | |||
57 | ||||
58 | private: | |||
59 | void addFile(StringRef Path); | |||
60 | ||||
61 | void readAsNeeded(); | |||
62 | void readEntry(); | |||
63 | void readExtern(); | |||
64 | void readGroup(); | |||
65 | void readInclude(); | |||
66 | void readInput(); | |||
67 | void readMemory(); | |||
68 | void readOutput(); | |||
69 | void readOutputArch(); | |||
70 | void readOutputFormat(); | |||
71 | void readPhdrs(); | |||
72 | void readRegionAlias(); | |||
73 | void readSearchDir(); | |||
74 | void readSections(); | |||
75 | void readTarget(); | |||
76 | void readVersion(); | |||
77 | void readVersionScriptCommand(); | |||
78 | ||||
79 | SymbolAssignment *readSymbolAssignment(StringRef Name); | |||
80 | ByteCommand *readByteCommand(StringRef Tok); | |||
81 | uint32_t readFill(); | |||
82 | uint32_t parseFill(StringRef Tok); | |||
83 | bool readSectionDirective(OutputSection *Cmd, StringRef Tok1, StringRef Tok2); | |||
84 | void readSectionAddressType(OutputSection *Cmd); | |||
85 | OutputSection *readOverlaySectionDescription(); | |||
86 | OutputSection *readOutputSectionDescription(StringRef OutSec); | |||
87 | std::vector<BaseCommand *> readOverlay(); | |||
88 | std::vector<StringRef> readOutputSectionPhdrs(); | |||
89 | InputSectionDescription *readInputSectionDescription(StringRef Tok); | |||
90 | StringMatcher readFilePatterns(); | |||
91 | std::vector<SectionPattern> readInputSectionsList(); | |||
92 | InputSectionDescription *readInputSectionRules(StringRef FilePattern); | |||
93 | unsigned readPhdrType(); | |||
94 | SortSectionPolicy readSortKind(); | |||
95 | SymbolAssignment *readProvideHidden(bool Provide, bool Hidden); | |||
96 | SymbolAssignment *readAssignment(StringRef Tok); | |||
97 | std::pair<ELFKind, uint16_t> readBfdName(); | |||
98 | void readSort(); | |||
99 | Expr readAssert(); | |||
100 | Expr readConstant(); | |||
101 | Expr getPageSize(); | |||
102 | ||||
103 | uint64_t readMemoryAssignment(StringRef, StringRef, StringRef); | |||
104 | std::pair<uint32_t, uint32_t> readMemoryAttributes(); | |||
105 | ||||
106 | Expr combine(StringRef Op, Expr L, Expr R); | |||
107 | Expr readExpr(); | |||
108 | Expr readExpr1(Expr Lhs, int MinPrec); | |||
109 | StringRef readParenLiteral(); | |||
110 | Expr readPrimary(); | |||
111 | Expr readTernary(Expr Cond); | |||
112 | Expr readParenExpr(); | |||
113 | ||||
114 | // For parsing version script. | |||
115 | std::vector<SymbolVersion> readVersionExtern(); | |||
116 | void readAnonymousDeclaration(); | |||
117 | void readVersionDeclaration(StringRef VerStr); | |||
118 | ||||
119 | std::pair<std::vector<SymbolVersion>, std::vector<SymbolVersion>> | |||
120 | readSymbols(); | |||
121 | ||||
122 | // True if a script being read is in a subdirectory specified by -sysroot. | |||
123 | bool IsUnderSysroot; | |||
124 | ||||
125 | // A set to detect an INCLUDE() cycle. | |||
126 | StringSet<> Seen; | |||
127 | }; | |||
128 | } // namespace | |||
129 | ||||
130 | static StringRef unquote(StringRef S) { | |||
131 | if (S.startswith("\"")) | |||
132 | return S.substr(1, S.size() - 2); | |||
133 | return S; | |||
134 | } | |||
135 | ||||
136 | static bool isUnderSysroot(StringRef Path) { | |||
137 | if (Config->Sysroot == "") | |||
138 | return false; | |||
139 | for (; !Path.empty(); Path = sys::path::parent_path(Path)) | |||
140 | if (sys::fs::equivalent(Config->Sysroot, Path)) | |||
141 | return true; | |||
142 | return false; | |||
143 | } | |||
144 | ||||
145 | // Some operations only support one non absolute value. Move the | |||
146 | // absolute one to the right hand side for convenience. | |||
147 | static void moveAbsRight(ExprValue &A, ExprValue &B) { | |||
148 | if (A.Sec == nullptr || (A.ForceAbsolute && !B.isAbsolute())) | |||
149 | std::swap(A, B); | |||
150 | if (!B.isAbsolute()) | |||
151 | error(A.Loc + ": at least one side of the expression must be absolute"); | |||
152 | } | |||
153 | ||||
154 | static ExprValue add(ExprValue A, ExprValue B) { | |||
155 | moveAbsRight(A, B); | |||
156 | return {A.Sec, A.ForceAbsolute, A.getSectionOffset() + B.getValue(), A.Loc}; | |||
157 | } | |||
158 | ||||
159 | static ExprValue sub(ExprValue A, ExprValue B) { | |||
160 | // The distance between two symbols in sections is absolute. | |||
161 | if (!A.isAbsolute() && !B.isAbsolute()) | |||
162 | return A.getValue() - B.getValue(); | |||
163 | return {A.Sec, false, A.getSectionOffset() - B.getValue(), A.Loc}; | |||
164 | } | |||
165 | ||||
166 | static ExprValue bitAnd(ExprValue A, ExprValue B) { | |||
167 | moveAbsRight(A, B); | |||
168 | return {A.Sec, A.ForceAbsolute, | |||
169 | (A.getValue() & B.getValue()) - A.getSecAddr(), A.Loc}; | |||
170 | } | |||
171 | ||||
172 | static ExprValue bitOr(ExprValue A, ExprValue B) { | |||
173 | moveAbsRight(A, B); | |||
174 | return {A.Sec, A.ForceAbsolute, | |||
175 | (A.getValue() | B.getValue()) - A.getSecAddr(), A.Loc}; | |||
176 | } | |||
177 | ||||
178 | void ScriptParser::readDynamicList() { | |||
179 | Config->HasDynamicList = true; | |||
180 | expect("{"); | |||
181 | std::vector<SymbolVersion> Locals; | |||
182 | std::vector<SymbolVersion> Globals; | |||
183 | std::tie(Locals, Globals) = readSymbols(); | |||
184 | expect(";"); | |||
185 | ||||
186 | if (!atEOF()) { | |||
187 | setError("EOF expected, but got " + next()); | |||
188 | return; | |||
189 | } | |||
190 | if (!Locals.empty()) { | |||
191 | setError("\"local:\" scope not supported in --dynamic-list"); | |||
192 | return; | |||
193 | } | |||
194 | ||||
195 | for (SymbolVersion V : Globals) | |||
196 | Config->DynamicList.push_back(V); | |||
197 | } | |||
198 | ||||
199 | void ScriptParser::readVersionScript() { | |||
200 | readVersionScriptCommand(); | |||
201 | if (!atEOF()) | |||
202 | setError("EOF expected, but got " + next()); | |||
203 | } | |||
204 | ||||
205 | void ScriptParser::readVersionScriptCommand() { | |||
206 | if (consume("{")) { | |||
207 | readAnonymousDeclaration(); | |||
208 | return; | |||
209 | } | |||
210 | ||||
211 | while (!atEOF() && !errorCount() && peek() != "}") { | |||
212 | StringRef VerStr = next(); | |||
213 | if (VerStr == "{") { | |||
214 | setError("anonymous version definition is used in " | |||
215 | "combination with other version definitions"); | |||
216 | return; | |||
217 | } | |||
218 | expect("{"); | |||
219 | readVersionDeclaration(VerStr); | |||
220 | } | |||
221 | } | |||
222 | ||||
223 | void ScriptParser::readVersion() { | |||
224 | expect("{"); | |||
225 | readVersionScriptCommand(); | |||
226 | expect("}"); | |||
227 | } | |||
228 | ||||
229 | void ScriptParser::readLinkerScript() { | |||
230 | while (!atEOF()) { | |||
231 | StringRef Tok = next(); | |||
232 | if (Tok == ";") | |||
233 | continue; | |||
234 | ||||
235 | if (Tok == "ENTRY") { | |||
236 | readEntry(); | |||
237 | } else if (Tok == "EXTERN") { | |||
238 | readExtern(); | |||
239 | } else if (Tok == "GROUP") { | |||
240 | readGroup(); | |||
241 | } else if (Tok == "INCLUDE") { | |||
242 | readInclude(); | |||
243 | } else if (Tok == "INPUT") { | |||
244 | readInput(); | |||
245 | } else if (Tok == "MEMORY") { | |||
246 | readMemory(); | |||
247 | } else if (Tok == "OUTPUT") { | |||
248 | readOutput(); | |||
249 | } else if (Tok == "OUTPUT_ARCH") { | |||
250 | readOutputArch(); | |||
251 | } else if (Tok == "OUTPUT_FORMAT") { | |||
252 | readOutputFormat(); | |||
253 | } else if (Tok == "PHDRS") { | |||
254 | readPhdrs(); | |||
255 | } else if (Tok == "REGION_ALIAS") { | |||
256 | readRegionAlias(); | |||
257 | } else if (Tok == "SEARCH_DIR") { | |||
258 | readSearchDir(); | |||
259 | } else if (Tok == "SECTIONS") { | |||
260 | readSections(); | |||
261 | } else if (Tok == "TARGET") { | |||
262 | readTarget(); | |||
263 | } else if (Tok == "VERSION") { | |||
264 | readVersion(); | |||
265 | } else if (SymbolAssignment *Cmd = readAssignment(Tok)) { | |||
266 | Script->SectionCommands.push_back(Cmd); | |||
267 | } else { | |||
268 | setError("unknown directive: " + Tok); | |||
269 | } | |||
270 | } | |||
271 | } | |||
272 | ||||
273 | void ScriptParser::readDefsym(StringRef Name) { | |||
274 | Expr E = readExpr(); | |||
275 | if (!atEOF()) | |||
276 | setError("EOF expected, but got " + next()); | |||
277 | SymbolAssignment *Cmd = make<SymbolAssignment>(Name, E, getCurrentLocation()); | |||
278 | Script->SectionCommands.push_back(Cmd); | |||
279 | } | |||
280 | ||||
281 | void ScriptParser::addFile(StringRef S) { | |||
282 | if (IsUnderSysroot && S.startswith("/")) { | |||
283 | SmallString<128> PathData; | |||
284 | StringRef Path = (Config->Sysroot + S).toStringRef(PathData); | |||
285 | if (sys::fs::exists(Path)) { | |||
286 | Driver->addFile(Saver.save(Path), /*WithLOption=*/false); | |||
287 | return; | |||
288 | } | |||
289 | } | |||
290 | ||||
291 | if (S.startswith("/")) { | |||
292 | Driver->addFile(S, /*WithLOption=*/false); | |||
293 | } else if (S.startswith("=")) { | |||
294 | if (Config->Sysroot.empty()) | |||
295 | Driver->addFile(S.substr(1), /*WithLOption=*/false); | |||
296 | else | |||
297 | Driver->addFile(Saver.save(Config->Sysroot + "/" + S.substr(1)), | |||
298 | /*WithLOption=*/false); | |||
299 | } else if (S.startswith("-l")) { | |||
300 | Driver->addLibrary(S.substr(2)); | |||
301 | } else if (sys::fs::exists(S)) { | |||
302 | Driver->addFile(S, /*WithLOption=*/false); | |||
303 | } else { | |||
304 | if (Optional<std::string> Path = findFromSearchPaths(S)) | |||
305 | Driver->addFile(Saver.save(*Path), /*WithLOption=*/true); | |||
306 | else | |||
307 | setError("unable to find " + S); | |||
308 | } | |||
309 | } | |||
310 | ||||
311 | void ScriptParser::readAsNeeded() { | |||
312 | expect("("); | |||
313 | bool Orig = Config->AsNeeded; | |||
314 | Config->AsNeeded = true; | |||
315 | while (!errorCount() && !consume(")")) | |||
316 | addFile(unquote(next())); | |||
317 | Config->AsNeeded = Orig; | |||
318 | } | |||
319 | ||||
320 | void ScriptParser::readEntry() { | |||
321 | // -e <symbol> takes predecence over ENTRY(<symbol>). | |||
322 | expect("("); | |||
323 | StringRef Tok = next(); | |||
324 | if (Config->Entry.empty()) | |||
325 | Config->Entry = Tok; | |||
326 | expect(")"); | |||
327 | } | |||
328 | ||||
329 | void ScriptParser::readExtern() { | |||
330 | expect("("); | |||
331 | while (!errorCount() && !consume(")")) | |||
332 | Config->Undefined.push_back(next()); | |||
333 | } | |||
334 | ||||
335 | void ScriptParser::readGroup() { | |||
336 | bool Orig = InputFile::IsInGroup; | |||
337 | InputFile::IsInGroup = true; | |||
338 | readInput(); | |||
339 | InputFile::IsInGroup = Orig; | |||
340 | if (!Orig) | |||
341 | ++InputFile::NextGroupId; | |||
342 | } | |||
343 | ||||
344 | void ScriptParser::readInclude() { | |||
345 | StringRef Tok = unquote(next()); | |||
346 | ||||
347 | if (!Seen.insert(Tok).second) { | |||
348 | setError("there is a cycle in linker script INCLUDEs"); | |||
349 | return; | |||
350 | } | |||
351 | ||||
352 | if (Optional<std::string> Path = searchScript(Tok)) { | |||
353 | if (Optional<MemoryBufferRef> MB = readFile(*Path)) | |||
354 | tokenize(*MB); | |||
355 | return; | |||
356 | } | |||
357 | setError("cannot find linker script " + Tok); | |||
358 | } | |||
359 | ||||
360 | void ScriptParser::readInput() { | |||
361 | expect("("); | |||
362 | while (!errorCount() && !consume(")")) { | |||
363 | if (consume("AS_NEEDED")) | |||
364 | readAsNeeded(); | |||
365 | else | |||
366 | addFile(unquote(next())); | |||
367 | } | |||
368 | } | |||
369 | ||||
370 | void ScriptParser::readOutput() { | |||
371 | // -o <file> takes predecence over OUTPUT(<file>). | |||
372 | expect("("); | |||
373 | StringRef Tok = next(); | |||
374 | if (Config->OutputFile.empty()) | |||
375 | Config->OutputFile = unquote(Tok); | |||
376 | expect(")"); | |||
377 | } | |||
378 | ||||
379 | void ScriptParser::readOutputArch() { | |||
380 | // OUTPUT_ARCH is ignored for now. | |||
381 | expect("("); | |||
382 | while (!errorCount() && !consume(")")) | |||
383 | skip(); | |||
384 | } | |||
385 | ||||
386 | std::pair<ELFKind, uint16_t> ScriptParser::readBfdName() { | |||
387 | StringRef S = next(); | |||
388 | if (S == "elf32-i386") | |||
389 | return {ELF32LEKind, EM_386}; | |||
390 | if (S == "elf32-iamcu") | |||
391 | return {ELF32LEKind, EM_IAMCU}; | |||
392 | if (S == "elf32-littlearm") | |||
393 | return {ELF32LEKind, EM_ARM}; | |||
394 | if (S == "elf32-x86-64") | |||
395 | return {ELF32LEKind, EM_X86_64}; | |||
396 | if (S == "elf64-littleaarch64") | |||
397 | return {ELF64LEKind, EM_AARCH64}; | |||
398 | if (S == "elf64-x86-64") | |||
399 | return {ELF64LEKind, EM_X86_64}; | |||
400 | ||||
401 | setError("unknown output format name: " + S); | |||
402 | return {ELFNoneKind, EM_NONE}; | |||
403 | } | |||
404 | ||||
405 | // Parse OUTPUT_FORMAT(bfdname) or OUTPUT_FORMAT(bfdname, big, little). | |||
406 | // Currently we ignore big and little parameters. | |||
407 | void ScriptParser::readOutputFormat() { | |||
408 | expect("("); | |||
409 | ||||
410 | std::pair<ELFKind, uint16_t> P = readBfdName(); | |||
411 | if (Config->EKind == ELFNoneKind) { | |||
412 | Config->EKind = P.first; | |||
413 | Config->EMachine = P.second; | |||
414 | } | |||
415 | ||||
416 | if (consume(")")) | |||
417 | return; | |||
418 | expect(","); | |||
419 | skip(); | |||
420 | expect(","); | |||
421 | skip(); | |||
422 | expect(")"); | |||
423 | } | |||
424 | ||||
425 | void ScriptParser::readPhdrs() { | |||
426 | expect("{"); | |||
427 | ||||
428 | while (!errorCount() && !consume("}")) { | |||
429 | PhdrsCommand Cmd; | |||
430 | Cmd.Name = next(); | |||
431 | Cmd.Type = readPhdrType(); | |||
432 | ||||
433 | while (!errorCount() && !consume(";")) { | |||
434 | if (consume("FILEHDR")) | |||
435 | Cmd.HasFilehdr = true; | |||
436 | else if (consume("PHDRS")) | |||
437 | Cmd.HasPhdrs = true; | |||
438 | else if (consume("AT")) | |||
439 | Cmd.LMAExpr = readParenExpr(); | |||
440 | else if (consume("FLAGS")) | |||
441 | Cmd.Flags = readParenExpr()().getValue(); | |||
442 | else | |||
443 | setError("unexpected header attribute: " + next()); | |||
444 | } | |||
445 | ||||
446 | Script->PhdrsCommands.push_back(Cmd); | |||
447 | } | |||
448 | } | |||
449 | ||||
450 | void ScriptParser::readRegionAlias() { | |||
451 | expect("("); | |||
452 | StringRef Alias = unquote(next()); | |||
453 | expect(","); | |||
454 | StringRef Name = next(); | |||
455 | expect(")"); | |||
456 | ||||
457 | if (Script->MemoryRegions.count(Alias)) | |||
458 | setError("redefinition of memory region '" + Alias + "'"); | |||
459 | if (!Script->MemoryRegions.count(Name)) | |||
460 | setError("memory region '" + Name + "' is not defined"); | |||
461 | Script->MemoryRegions.insert({Alias, Script->MemoryRegions[Name]}); | |||
462 | } | |||
463 | ||||
464 | void ScriptParser::readSearchDir() { | |||
465 | expect("("); | |||
466 | StringRef Tok = next(); | |||
467 | if (!Config->Nostdlib) | |||
468 | Config->SearchPaths.push_back(unquote(Tok)); | |||
469 | expect(")"); | |||
470 | } | |||
471 | ||||
472 | // This reads an overlay description. Overlays are used to describe output | |||
473 | // sections that use the same virtual memory range and normally would trigger | |||
474 | // linker's sections sanity check failures. | |||
475 | // https://sourceware.org/binutils/docs/ld/Overlay-Description.html#Overlay-Description | |||
476 | std::vector<BaseCommand *> ScriptParser::readOverlay() { | |||
477 | // VA and LMA expressions are optional, though for simplicity of | |||
478 | // implementation we assume they are not. That is what OVERLAY was designed | |||
479 | // for first of all: to allow sections with overlapping VAs at different LMAs. | |||
480 | Expr AddrExpr = readExpr(); | |||
481 | expect(":"); | |||
482 | expect("AT"); | |||
483 | Expr LMAExpr = readParenExpr(); | |||
484 | expect("{"); | |||
485 | ||||
486 | std::vector<BaseCommand *> V; | |||
487 | OutputSection *Prev = nullptr; | |||
488 | while (!errorCount() && !consume("}")) { | |||
489 | // VA is the same for all sections. The LMAs are consecutive in memory | |||
490 | // starting from the base load address specified. | |||
491 | OutputSection *OS = readOverlaySectionDescription(); | |||
492 | OS->AddrExpr = AddrExpr; | |||
493 | if (Prev) | |||
494 | OS->LMAExpr = [=] { return Prev->getLMA() + Prev->Size; }; | |||
495 | else | |||
496 | OS->LMAExpr = LMAExpr; | |||
497 | V.push_back(OS); | |||
498 | Prev = OS; | |||
499 | } | |||
500 | ||||
501 | // According to the specification, at the end of the overlay, the location | |||
502 | // counter should be equal to the overlay base address plus size of the | |||
503 | // largest section seen in the overlay. | |||
504 | // Here we want to create the Dot assignment command to achieve that. | |||
505 | Expr MoveDot = [=] { | |||
506 | uint64_t Max = 0; | |||
507 | for (BaseCommand *Cmd : V) | |||
508 | Max = std::max(Max, cast<OutputSection>(Cmd)->Size); | |||
509 | return AddrExpr().getValue() + Max; | |||
510 | }; | |||
511 | V.push_back(make<SymbolAssignment>(".", MoveDot, getCurrentLocation())); | |||
512 | return V; | |||
513 | } | |||
514 | ||||
515 | void ScriptParser::readSections() { | |||
516 | Script->HasSectionsCommand = true; | |||
517 | ||||
518 | // -no-rosegment is used to avoid placing read only non-executable sections in | |||
519 | // their own segment. We do the same if SECTIONS command is present in linker | |||
520 | // script. See comment for computeFlags(). | |||
521 | Config->SingleRoRx = true; | |||
522 | ||||
523 | expect("{"); | |||
524 | std::vector<BaseCommand *> V; | |||
525 | while (!errorCount() && !consume("}")) { | |||
526 | StringRef Tok = next(); | |||
527 | if (Tok == "OVERLAY") { | |||
528 | for (BaseCommand *Cmd : readOverlay()) | |||
529 | V.push_back(Cmd); | |||
530 | continue; | |||
531 | } else if (Tok == "INCLUDE") { | |||
532 | readInclude(); | |||
533 | continue; | |||
534 | } | |||
535 | ||||
536 | if (BaseCommand *Cmd = readAssignment(Tok)) | |||
537 | V.push_back(Cmd); | |||
538 | else | |||
539 | V.push_back(readOutputSectionDescription(Tok)); | |||
540 | } | |||
541 | ||||
542 | if (!atEOF() && consume("INSERT")) { | |||
543 | std::vector<BaseCommand *> *Dest = nullptr; | |||
544 | if (consume("AFTER")) | |||
545 | Dest = &Script->InsertAfterCommands[next()]; | |||
546 | else if (consume("BEFORE")) | |||
547 | Dest = &Script->InsertBeforeCommands[next()]; | |||
548 | else | |||
549 | setError("expected AFTER/BEFORE, but got '" + next() + "'"); | |||
550 | if (Dest) | |||
551 | Dest->insert(Dest->end(), V.begin(), V.end()); | |||
552 | return; | |||
553 | } | |||
554 | ||||
555 | Script->SectionCommands.insert(Script->SectionCommands.end(), V.begin(), | |||
556 | V.end()); | |||
557 | } | |||
558 | ||||
559 | void ScriptParser::readTarget() { | |||
560 | // TARGET(foo) is an alias for "--format foo". Unlike GNU linkers, | |||
561 | // we accept only a limited set of BFD names (i.e. "elf" or "binary") | |||
562 | // for --format. We recognize only /^elf/ and "binary" in the linker | |||
563 | // script as well. | |||
564 | expect("("); | |||
565 | StringRef Tok = next(); | |||
566 | expect(")"); | |||
567 | ||||
568 | if (Tok.startswith("elf")) | |||
569 | Config->FormatBinary = false; | |||
570 | else if (Tok == "binary") | |||
571 | Config->FormatBinary = true; | |||
572 | else | |||
573 | setError("unknown target: " + Tok); | |||
574 | } | |||
575 | ||||
576 | static int precedence(StringRef Op) { | |||
577 | return StringSwitch<int>(Op) | |||
578 | .Cases("*", "/", "%", 8) | |||
579 | .Cases("+", "-", 7) | |||
580 | .Cases("<<", ">>", 6) | |||
581 | .Cases("<", "<=", ">", ">=", "==", "!=", 5) | |||
582 | .Case("&", 4) | |||
583 | .Case("|", 3) | |||
584 | .Case("&&", 2) | |||
585 | .Case("||", 1) | |||
586 | .Default(-1); | |||
587 | } | |||
588 | ||||
589 | StringMatcher ScriptParser::readFilePatterns() { | |||
590 | std::vector<StringRef> V; | |||
591 | while (!errorCount() && !consume(")")) | |||
592 | V.push_back(next()); | |||
593 | return StringMatcher(V); | |||
594 | } | |||
595 | ||||
596 | SortSectionPolicy ScriptParser::readSortKind() { | |||
597 | if (consume("SORT") || consume("SORT_BY_NAME")) | |||
598 | return SortSectionPolicy::Name; | |||
599 | if (consume("SORT_BY_ALIGNMENT")) | |||
600 | return SortSectionPolicy::Alignment; | |||
601 | if (consume("SORT_BY_INIT_PRIORITY")) | |||
602 | return SortSectionPolicy::Priority; | |||
603 | if (consume("SORT_NONE")) | |||
604 | return SortSectionPolicy::None; | |||
605 | return SortSectionPolicy::Default; | |||
606 | } | |||
607 | ||||
608 | // Reads SECTIONS command contents in the following form: | |||
609 | // | |||
610 | // <contents> ::= <elem>* | |||
611 | // <elem> ::= <exclude>? <glob-pattern> | |||
612 | // <exclude> ::= "EXCLUDE_FILE" "(" <glob-pattern>+ ")" | |||
613 | // | |||
614 | // For example, | |||
615 | // | |||
616 | // *(.foo EXCLUDE_FILE (a.o) .bar EXCLUDE_FILE (b.o) .baz) | |||
617 | // | |||
618 | // is parsed as ".foo", ".bar" with "a.o", and ".baz" with "b.o". | |||
619 | // The semantics of that is section .foo in any file, section .bar in | |||
620 | // any file but a.o, and section .baz in any file but b.o. | |||
621 | std::vector<SectionPattern> ScriptParser::readInputSectionsList() { | |||
622 | std::vector<SectionPattern> Ret; | |||
623 | while (!errorCount() && peek() != ")") { | |||
624 | StringMatcher ExcludeFilePat; | |||
625 | if (consume("EXCLUDE_FILE")) { | |||
626 | expect("("); | |||
627 | ExcludeFilePat = readFilePatterns(); | |||
628 | } | |||
629 | ||||
630 | std::vector<StringRef> V; | |||
631 | while (!errorCount() && peek() != ")" && peek() != "EXCLUDE_FILE") | |||
632 | V.push_back(next()); | |||
633 | ||||
634 | if (!V.empty()) | |||
635 | Ret.push_back({std::move(ExcludeFilePat), StringMatcher(V)}); | |||
636 | else | |||
637 | setError("section pattern is expected"); | |||
638 | } | |||
639 | return Ret; | |||
640 | } | |||
641 | ||||
642 | // Reads contents of "SECTIONS" directive. That directive contains a | |||
643 | // list of glob patterns for input sections. The grammar is as follows. | |||
644 | // | |||
645 | // <patterns> ::= <section-list> | |||
646 | // | <sort> "(" <section-list> ")" | |||
647 | // | <sort> "(" <sort> "(" <section-list> ")" ")" | |||
648 | // | |||
649 | // <sort> ::= "SORT" | "SORT_BY_NAME" | "SORT_BY_ALIGNMENT" | |||
650 | // | "SORT_BY_INIT_PRIORITY" | "SORT_NONE" | |||
651 | // | |||
652 | // <section-list> is parsed by readInputSectionsList(). | |||
653 | InputSectionDescription * | |||
654 | ScriptParser::readInputSectionRules(StringRef FilePattern) { | |||
655 | auto *Cmd = make<InputSectionDescription>(FilePattern); | |||
656 | expect("("); | |||
657 | ||||
658 | while (!errorCount() && !consume(")")) { | |||
659 | SortSectionPolicy Outer = readSortKind(); | |||
660 | SortSectionPolicy Inner = SortSectionPolicy::Default; | |||
661 | std::vector<SectionPattern> V; | |||
662 | if (Outer != SortSectionPolicy::Default) { | |||
663 | expect("("); | |||
664 | Inner = readSortKind(); | |||
665 | if (Inner != SortSectionPolicy::Default) { | |||
666 | expect("("); | |||
667 | V = readInputSectionsList(); | |||
668 | expect(")"); | |||
669 | } else { | |||
670 | V = readInputSectionsList(); | |||
671 | } | |||
672 | expect(")"); | |||
673 | } else { | |||
674 | V = readInputSectionsList(); | |||
675 | } | |||
676 | ||||
677 | for (SectionPattern &Pat : V) { | |||
678 | Pat.SortInner = Inner; | |||
679 | Pat.SortOuter = Outer; | |||
680 | } | |||
681 | ||||
682 | std::move(V.begin(), V.end(), std::back_inserter(Cmd->SectionPatterns)); | |||
683 | } | |||
684 | return Cmd; | |||
685 | } | |||
686 | ||||
687 | InputSectionDescription * | |||
688 | ScriptParser::readInputSectionDescription(StringRef Tok) { | |||
689 | // Input section wildcard can be surrounded by KEEP. | |||
690 | // https://sourceware.org/binutils/docs/ld/Input-Section-Keep.html#Input-Section-Keep | |||
691 | if (Tok == "KEEP") { | |||
692 | expect("("); | |||
693 | StringRef FilePattern = next(); | |||
694 | InputSectionDescription *Cmd = readInputSectionRules(FilePattern); | |||
695 | expect(")"); | |||
696 | Script->KeptSections.push_back(Cmd); | |||
697 | return Cmd; | |||
698 | } | |||
699 | return readInputSectionRules(Tok); | |||
700 | } | |||
701 | ||||
702 | void ScriptParser::readSort() { | |||
703 | expect("("); | |||
704 | expect("CONSTRUCTORS"); | |||
705 | expect(")"); | |||
706 | } | |||
707 | ||||
708 | Expr ScriptParser::readAssert() { | |||
709 | expect("("); | |||
710 | Expr E = readExpr(); | |||
711 | expect(","); | |||
712 | StringRef Msg = unquote(next()); | |||
713 | expect(")"); | |||
714 | ||||
715 | return [=] { | |||
716 | if (!E().getValue()) | |||
717 | error(Msg); | |||
718 | return Script->getDot(); | |||
719 | }; | |||
720 | } | |||
721 | ||||
722 | // Reads a FILL(expr) command. We handle the FILL command as an | |||
723 | // alias for =fillexp section attribute, which is different from | |||
724 | // what GNU linkers do. | |||
725 | // https://sourceware.org/binutils/docs/ld/Output-Section-Data.html | |||
726 | uint32_t ScriptParser::readFill() { | |||
727 | expect("("); | |||
728 | uint32_t V = parseFill(next()); | |||
729 | expect(")"); | |||
730 | return V; | |||
731 | } | |||
732 | ||||
733 | // Tries to read the special directive for an output section definition which | |||
734 | // can be one of following: "(NOLOAD)", "(COPY)", "(INFO)" or "(OVERLAY)". | |||
735 | // Tok1 and Tok2 are next 2 tokens peeked. See comment for readSectionAddressType below. | |||
736 | bool ScriptParser::readSectionDirective(OutputSection *Cmd, StringRef Tok1, StringRef Tok2) { | |||
737 | if (Tok1 != "(") | |||
738 | return false; | |||
739 | if (Tok2 != "NOLOAD" && Tok2 != "COPY" && Tok2 != "INFO" && Tok2 != "OVERLAY") | |||
740 | return false; | |||
741 | ||||
742 | expect("("); | |||
743 | if (consume("NOLOAD")) { | |||
744 | Cmd->Noload = true; | |||
745 | } else { | |||
746 | skip(); // This is "COPY", "INFO" or "OVERLAY". | |||
747 | Cmd->NonAlloc = true; | |||
748 | } | |||
749 | expect(")"); | |||
750 | return true; | |||
751 | } | |||
752 | ||||
753 | // Reads an expression and/or the special directive for an output | |||
754 | // section definition. Directive is one of following: "(NOLOAD)", | |||
755 | // "(COPY)", "(INFO)" or "(OVERLAY)". | |||
756 | // | |||
757 | // An output section name can be followed by an address expression | |||
758 | // and/or directive. This grammar is not LL(1) because "(" can be | |||
759 | // interpreted as either the beginning of some expression or beginning | |||
760 | // of directive. | |||
761 | // | |||
762 | // https://sourceware.org/binutils/docs/ld/Output-Section-Address.html | |||
763 | // https://sourceware.org/binutils/docs/ld/Output-Section-Type.html | |||
764 | void ScriptParser::readSectionAddressType(OutputSection *Cmd) { | |||
765 | if (readSectionDirective(Cmd, peek(), peek2())) | |||
766 | return; | |||
767 | ||||
768 | Cmd->AddrExpr = readExpr(); | |||
769 | if (peek() == "(" && !readSectionDirective(Cmd, "(", peek2())) | |||
770 | setError("unknown section directive: " + peek2()); | |||
771 | } | |||
772 | ||||
773 | static Expr checkAlignment(Expr E, std::string &Loc) { | |||
774 | return [=] { | |||
775 | uint64_t Alignment = std::max((uint64_t)1, E().getValue()); | |||
776 | if (!isPowerOf2_64(Alignment)) { | |||
777 | error(Loc + ": alignment must be power of 2"); | |||
778 | return (uint64_t)1; // Return a dummy value. | |||
779 | } | |||
780 | return Alignment; | |||
781 | }; | |||
782 | } | |||
783 | ||||
784 | OutputSection *ScriptParser::readOverlaySectionDescription() { | |||
785 | OutputSection *Cmd = | |||
786 | Script->createOutputSection(next(), getCurrentLocation()); | |||
787 | Cmd->InOverlay = true; | |||
788 | expect("{"); | |||
789 | while (!errorCount() && !consume("}")) | |||
790 | Cmd->SectionCommands.push_back(readInputSectionRules(next())); | |||
791 | Cmd->Phdrs = readOutputSectionPhdrs(); | |||
792 | return Cmd; | |||
793 | } | |||
794 | ||||
795 | OutputSection *ScriptParser::readOutputSectionDescription(StringRef OutSec) { | |||
796 | OutputSection *Cmd = | |||
797 | Script->createOutputSection(OutSec, getCurrentLocation()); | |||
798 | ||||
799 | size_t SymbolsReferenced = Script->ReferencedSymbols.size(); | |||
800 | ||||
801 | if (peek() != ":") | |||
| ||||
802 | readSectionAddressType(Cmd); | |||
803 | expect(":"); | |||
804 | ||||
805 | std::string Location = getCurrentLocation(); | |||
806 | if (consume("AT")) | |||
807 | Cmd->LMAExpr = readParenExpr(); | |||
808 | if (consume("ALIGN")) | |||
809 | Cmd->AlignExpr = checkAlignment(readParenExpr(), Location); | |||
810 | if (consume("SUBALIGN")) | |||
811 | Cmd->SubalignExpr = checkAlignment(readParenExpr(), Location); | |||
812 | ||||
813 | // Parse constraints. | |||
814 | if (consume("ONLY_IF_RO")) | |||
815 | Cmd->Constraint = ConstraintKind::ReadOnly; | |||
816 | if (consume("ONLY_IF_RW")) | |||
817 | Cmd->Constraint = ConstraintKind::ReadWrite; | |||
818 | expect("{"); | |||
819 | ||||
820 | while (!errorCount() && !consume("}")) { | |||
821 | StringRef Tok = next(); | |||
822 | if (Tok == ";") { | |||
823 | // Empty commands are allowed. Do nothing here. | |||
824 | } else if (SymbolAssignment *Assign = readAssignment(Tok)) { | |||
825 | Cmd->SectionCommands.push_back(Assign); | |||
826 | } else if (ByteCommand *Data = readByteCommand(Tok)) { | |||
827 | Cmd->SectionCommands.push_back(Data); | |||
828 | } else if (Tok == "CONSTRUCTORS") { | |||
829 | // CONSTRUCTORS is a keyword to make the linker recognize C++ ctors/dtors | |||
830 | // by name. This is for very old file formats such as ECOFF/XCOFF. | |||
831 | // For ELF, we should ignore. | |||
832 | } else if (Tok == "FILL") { | |||
833 | Cmd->Filler = readFill(); | |||
834 | } else if (Tok == "SORT") { | |||
835 | readSort(); | |||
836 | } else if (Tok == "INCLUDE") { | |||
837 | readInclude(); | |||
838 | } else if (peek() == "(") { | |||
839 | Cmd->SectionCommands.push_back(readInputSectionDescription(Tok)); | |||
840 | } else { | |||
841 | setError("unknown command " + Tok); | |||
842 | } | |||
843 | } | |||
844 | ||||
845 | if (consume(">")) | |||
846 | Cmd->MemoryRegionName = next(); | |||
847 | ||||
848 | if (consume("AT")) { | |||
849 | expect(">"); | |||
850 | Cmd->LMARegionName = next(); | |||
851 | } | |||
852 | ||||
853 | if (Cmd->LMAExpr && !Cmd->LMARegionName.empty()) | |||
854 | error("section can't have both LMA and a load region"); | |||
855 | ||||
856 | Cmd->Phdrs = readOutputSectionPhdrs(); | |||
857 | ||||
858 | if (consume("=")) | |||
859 | Cmd->Filler = parseFill(next()); | |||
860 | else if (peek().startswith("=")) | |||
861 | Cmd->Filler = parseFill(next().drop_front()); | |||
862 | ||||
863 | // Consume optional comma following output section command. | |||
864 | consume(","); | |||
865 | ||||
866 | if (Script->ReferencedSymbols.size() > SymbolsReferenced) | |||
867 | Cmd->ExpressionsUseSymbols = true; | |||
868 | return Cmd; | |||
869 | } | |||
870 | ||||
871 | // Parses a given string as a octal/decimal/hexadecimal number and | |||
872 | // returns it as a big-endian number. Used for `=<fillexp>`. | |||
873 | // https://sourceware.org/binutils/docs/ld/Output-Section-Fill.html | |||
874 | // | |||
875 | // When reading a hexstring, ld.bfd handles it as a blob of arbitrary | |||
876 | // size, while ld.gold always handles it as a 32-bit big-endian number. | |||
877 | // We are compatible with ld.gold because it's easier to implement. | |||
878 | uint32_t ScriptParser::parseFill(StringRef Tok) { | |||
879 | uint32_t V = 0; | |||
880 | if (!to_integer(Tok, V)) | |||
881 | setError("invalid filler expression: " + Tok); | |||
882 | ||||
883 | uint32_t Buf; | |||
884 | write32be(&Buf, V); | |||
885 | return Buf; | |||
| ||||
886 | } | |||
887 | ||||
888 | SymbolAssignment *ScriptParser::readProvideHidden(bool Provide, bool Hidden) { | |||
889 | expect("("); | |||
890 | SymbolAssignment *Cmd = readSymbolAssignment(next()); | |||
891 | Cmd->Provide = Provide; | |||
892 | Cmd->Hidden = Hidden; | |||
893 | expect(")"); | |||
894 | return Cmd; | |||
895 | } | |||
896 | ||||
897 | SymbolAssignment *ScriptParser::readAssignment(StringRef Tok) { | |||
898 | // Assert expression returns Dot, so this is equal to ".=." | |||
899 | if (Tok == "ASSERT") | |||
900 | return make<SymbolAssignment>(".", readAssert(), getCurrentLocation()); | |||
901 | ||||
902 | size_t OldPos = Pos; | |||
903 | SymbolAssignment *Cmd = nullptr; | |||
904 | if (peek() == "=" || peek() == "+=") | |||
905 | Cmd = readSymbolAssignment(Tok); | |||
906 | else if (Tok == "PROVIDE") | |||
907 | Cmd = readProvideHidden(true, false); | |||
908 | else if (Tok == "HIDDEN") | |||
909 | Cmd = readProvideHidden(false, true); | |||
910 | else if (Tok == "PROVIDE_HIDDEN") | |||
911 | Cmd = readProvideHidden(true, true); | |||
912 | ||||
913 | if (Cmd) { | |||
914 | Cmd->CommandString = | |||
915 | Tok.str() + " " + | |||
916 | llvm::join(Tokens.begin() + OldPos, Tokens.begin() + Pos, " "); | |||
917 | expect(";"); | |||
918 | } | |||
919 | return Cmd; | |||
920 | } | |||
921 | ||||
922 | SymbolAssignment *ScriptParser::readSymbolAssignment(StringRef Name) { | |||
923 | StringRef Op = next(); | |||
924 | assert(Op == "=" || Op == "+=")((Op == "=" || Op == "+=") ? static_cast<void> (0) : __assert_fail ("Op == \"=\" || Op == \"+=\"", "/build/llvm-toolchain-snapshot-8~svn345461/tools/lld/ELF/ScriptParser.cpp" , 924, __PRETTY_FUNCTION__)); | |||
925 | Expr E = readExpr(); | |||
926 | if (Op == "+=") { | |||
927 | std::string Loc = getCurrentLocation(); | |||
928 | E = [=] { return add(Script->getSymbolValue(Name, Loc), E()); }; | |||
929 | } | |||
930 | return make<SymbolAssignment>(Name, E, getCurrentLocation()); | |||
931 | } | |||
932 | ||||
933 | // This is an operator-precedence parser to parse a linker | |||
934 | // script expression. | |||
935 | Expr ScriptParser::readExpr() { | |||
936 | // Our lexer is context-aware. Set the in-expression bit so that | |||
937 | // they apply different tokenization rules. | |||
938 | bool Orig = InExpr; | |||
939 | InExpr = true; | |||
940 | Expr E = readExpr1(readPrimary(), 0); | |||
941 | InExpr = Orig; | |||
942 | return E; | |||
943 | } | |||
944 | ||||
945 | Expr ScriptParser::combine(StringRef Op, Expr L, Expr R) { | |||
946 | if (Op == "+") | |||
947 | return [=] { return add(L(), R()); }; | |||
948 | if (Op == "-") | |||
949 | return [=] { return sub(L(), R()); }; | |||
950 | if (Op == "*") | |||
951 | return [=] { return L().getValue() * R().getValue(); }; | |||
952 | if (Op == "/") { | |||
953 | std::string Loc = getCurrentLocation(); | |||
954 | return [=]() -> uint64_t { | |||
955 | if (uint64_t RV = R().getValue()) | |||
956 | return L().getValue() / RV; | |||
957 | error(Loc + ": division by zero"); | |||
958 | return 0; | |||
959 | }; | |||
960 | } | |||
961 | if (Op == "%") { | |||
962 | std::string Loc = getCurrentLocation(); | |||
963 | return [=]() -> uint64_t { | |||
964 | if (uint64_t RV = R().getValue()) | |||
965 | return L().getValue() % RV; | |||
966 | error(Loc + ": modulo by zero"); | |||
967 | return 0; | |||
968 | }; | |||
969 | } | |||
970 | if (Op == "<<") | |||
971 | return [=] { return L().getValue() << R().getValue(); }; | |||
972 | if (Op == ">>") | |||
973 | return [=] { return L().getValue() >> R().getValue(); }; | |||
974 | if (Op == "<") | |||
975 | return [=] { return L().getValue() < R().getValue(); }; | |||
976 | if (Op == ">") | |||
977 | return [=] { return L().getValue() > R().getValue(); }; | |||
978 | if (Op == ">=") | |||
979 | return [=] { return L().getValue() >= R().getValue(); }; | |||
980 | if (Op == "<=") | |||
981 | return [=] { return L().getValue() <= R().getValue(); }; | |||
982 | if (Op == "==") | |||
983 | return [=] { return L().getValue() == R().getValue(); }; | |||
984 | if (Op == "!=") | |||
985 | return [=] { return L().getValue() != R().getValue(); }; | |||
986 | if (Op == "||") | |||
987 | return [=] { return L().getValue() || R().getValue(); }; | |||
988 | if (Op == "&&") | |||
989 | return [=] { return L().getValue() && R().getValue(); }; | |||
990 | if (Op == "&") | |||
991 | return [=] { return bitAnd(L(), R()); }; | |||
992 | if (Op == "|") | |||
993 | return [=] { return bitOr(L(), R()); }; | |||
994 | llvm_unreachable("invalid operator")::llvm::llvm_unreachable_internal("invalid operator", "/build/llvm-toolchain-snapshot-8~svn345461/tools/lld/ELF/ScriptParser.cpp" , 994); | |||
995 | } | |||
996 | ||||
997 | // This is a part of the operator-precedence parser. This function | |||
998 | // assumes that the remaining token stream starts with an operator. | |||
999 | Expr ScriptParser::readExpr1(Expr Lhs, int MinPrec) { | |||
1000 | while (!atEOF() && !errorCount()) { | |||
1001 | // Read an operator and an expression. | |||
1002 | if (consume("?")) | |||
1003 | return readTernary(Lhs); | |||
1004 | StringRef Op1 = peek(); | |||
1005 | if (precedence(Op1) < MinPrec) | |||
1006 | break; | |||
1007 | skip(); | |||
1008 | Expr Rhs = readPrimary(); | |||
1009 | ||||
1010 | // Evaluate the remaining part of the expression first if the | |||
1011 | // next operator has greater precedence than the previous one. | |||
1012 | // For example, if we have read "+" and "3", and if the next | |||
1013 | // operator is "*", then we'll evaluate 3 * ... part first. | |||
1014 | while (!atEOF()) { | |||
1015 | StringRef Op2 = peek(); | |||
1016 | if (precedence(Op2) <= precedence(Op1)) | |||
1017 | break; | |||
1018 | Rhs = readExpr1(Rhs, precedence(Op2)); | |||
1019 | } | |||
1020 | ||||
1021 | Lhs = combine(Op1, Lhs, Rhs); | |||
1022 | } | |||
1023 | return Lhs; | |||
1024 | } | |||
1025 | ||||
1026 | Expr ScriptParser::getPageSize() { | |||
1027 | std::string Location = getCurrentLocation(); | |||
1028 | return [=]() -> uint64_t { | |||
1029 | if (Target) | |||
1030 | return Target->PageSize; | |||
1031 | error(Location + ": unable to calculate page size"); | |||
1032 | return 4096; // Return a dummy value. | |||
1033 | }; | |||
1034 | } | |||
1035 | ||||
1036 | Expr ScriptParser::readConstant() { | |||
1037 | StringRef S = readParenLiteral(); | |||
1038 | if (S == "COMMONPAGESIZE") | |||
1039 | return getPageSize(); | |||
1040 | if (S == "MAXPAGESIZE") | |||
1041 | return [] { return Config->MaxPageSize; }; | |||
1042 | setError("unknown constant: " + S); | |||
1043 | return [] { return 0; }; | |||
1044 | } | |||
1045 | ||||
1046 | // Parses Tok as an integer. It recognizes hexadecimal (prefixed with | |||
1047 | // "0x" or suffixed with "H") and decimal numbers. Decimal numbers may | |||
1048 | // have "K" (Ki) or "M" (Mi) suffixes. | |||
1049 | static Optional<uint64_t> parseInt(StringRef Tok) { | |||
1050 | // Hexadecimal | |||
1051 | uint64_t Val; | |||
1052 | if (Tok.startswith_lower("0x")) { | |||
1053 | if (!to_integer(Tok.substr(2), Val, 16)) | |||
1054 | return None; | |||
1055 | return Val; | |||
1056 | } | |||
1057 | if (Tok.endswith_lower("H")) { | |||
1058 | if (!to_integer(Tok.drop_back(), Val, 16)) | |||
1059 | return None; | |||
1060 | return Val; | |||
1061 | } | |||
1062 | ||||
1063 | // Decimal | |||
1064 | if (Tok.endswith_lower("K")) { | |||
1065 | if (!to_integer(Tok.drop_back(), Val, 10)) | |||
1066 | return None; | |||
1067 | return Val * 1024; | |||
1068 | } | |||
1069 | if (Tok.endswith_lower("M")) { | |||
1070 | if (!to_integer(Tok.drop_back(), Val, 10)) | |||
1071 | return None; | |||
1072 | return Val * 1024 * 1024; | |||
1073 | } | |||
1074 | if (!to_integer(Tok, Val, 10)) | |||
1075 | return None; | |||
1076 | return Val; | |||
1077 | } | |||
1078 | ||||
1079 | ByteCommand *ScriptParser::readByteCommand(StringRef Tok) { | |||
1080 | int Size = StringSwitch<int>(Tok) | |||
1081 | .Case("BYTE", 1) | |||
1082 | .Case("SHORT", 2) | |||
1083 | .Case("LONG", 4) | |||
1084 | .Case("QUAD", 8) | |||
1085 | .Default(-1); | |||
1086 | if (Size == -1) | |||
1087 | return nullptr; | |||
1088 | ||||
1089 | size_t OldPos = Pos; | |||
1090 | Expr E = readParenExpr(); | |||
1091 | std::string CommandString = | |||
1092 | Tok.str() + " " + | |||
1093 | llvm::join(Tokens.begin() + OldPos, Tokens.begin() + Pos, " "); | |||
1094 | return make<ByteCommand>(E, Size, CommandString); | |||
1095 | } | |||
1096 | ||||
1097 | StringRef ScriptParser::readParenLiteral() { | |||
1098 | expect("("); | |||
1099 | bool Orig = InExpr; | |||
1100 | InExpr = false; | |||
1101 | StringRef Tok = next(); | |||
1102 | InExpr = Orig; | |||
1103 | expect(")"); | |||
1104 | return Tok; | |||
1105 | } | |||
1106 | ||||
1107 | static void checkIfExists(OutputSection *Cmd, StringRef Location) { | |||
1108 | if (Cmd->Location.empty() && Script->ErrorOnMissingSection) | |||
1109 | error(Location + ": undefined section " + Cmd->Name); | |||
1110 | } | |||
1111 | ||||
1112 | Expr ScriptParser::readPrimary() { | |||
1113 | if (peek() == "(") | |||
1114 | return readParenExpr(); | |||
1115 | ||||
1116 | if (consume("~")) { | |||
1117 | Expr E = readPrimary(); | |||
1118 | return [=] { return ~E().getValue(); }; | |||
1119 | } | |||
1120 | if (consume("!")) { | |||
1121 | Expr E = readPrimary(); | |||
1122 | return [=] { return !E().getValue(); }; | |||
1123 | } | |||
1124 | if (consume("-")) { | |||
1125 | Expr E = readPrimary(); | |||
1126 | return [=] { return -E().getValue(); }; | |||
1127 | } | |||
1128 | ||||
1129 | StringRef Tok = next(); | |||
1130 | std::string Location = getCurrentLocation(); | |||
1131 | ||||
1132 | // Built-in functions are parsed here. | |||
1133 | // https://sourceware.org/binutils/docs/ld/Builtin-Functions.html. | |||
1134 | if (Tok == "ABSOLUTE") { | |||
1135 | Expr Inner = readParenExpr(); | |||
1136 | return [=] { | |||
1137 | ExprValue I = Inner(); | |||
1138 | I.ForceAbsolute = true; | |||
1139 | return I; | |||
1140 | }; | |||
1141 | } | |||
1142 | if (Tok == "ADDR") { | |||
1143 | StringRef Name = readParenLiteral(); | |||
1144 | OutputSection *Sec = Script->getOrCreateOutputSection(Name); | |||
1145 | return [=]() -> ExprValue { | |||
1146 | checkIfExists(Sec, Location); | |||
1147 | return {Sec, false, 0, Location}; | |||
1148 | }; | |||
1149 | } | |||
1150 | if (Tok == "ALIGN") { | |||
1151 | expect("("); | |||
1152 | Expr E = readExpr(); | |||
1153 | if (consume(")")) { | |||
1154 | E = checkAlignment(E, Location); | |||
1155 | return [=] { return alignTo(Script->getDot(), E().getValue()); }; | |||
1156 | } | |||
1157 | expect(","); | |||
1158 | Expr E2 = checkAlignment(readExpr(), Location); | |||
1159 | expect(")"); | |||
1160 | return [=] { | |||
1161 | ExprValue V = E(); | |||
1162 | V.Alignment = E2().getValue(); | |||
1163 | return V; | |||
1164 | }; | |||
1165 | } | |||
1166 | if (Tok == "ALIGNOF") { | |||
1167 | StringRef Name = readParenLiteral(); | |||
1168 | OutputSection *Cmd = Script->getOrCreateOutputSection(Name); | |||
1169 | return [=] { | |||
1170 | checkIfExists(Cmd, Location); | |||
1171 | return Cmd->Alignment; | |||
1172 | }; | |||
1173 | } | |||
1174 | if (Tok == "ASSERT") | |||
1175 | return readAssert(); | |||
1176 | if (Tok == "CONSTANT") | |||
1177 | return readConstant(); | |||
1178 | if (Tok == "DATA_SEGMENT_ALIGN") { | |||
1179 | expect("("); | |||
1180 | Expr E = readExpr(); | |||
1181 | expect(","); | |||
1182 | readExpr(); | |||
1183 | expect(")"); | |||
1184 | return [=] { | |||
1185 | return alignTo(Script->getDot(), std::max((uint64_t)1, E().getValue())); | |||
1186 | }; | |||
1187 | } | |||
1188 | if (Tok == "DATA_SEGMENT_END") { | |||
1189 | expect("("); | |||
1190 | expect("."); | |||
1191 | expect(")"); | |||
1192 | return [] { return Script->getDot(); }; | |||
1193 | } | |||
1194 | if (Tok == "DATA_SEGMENT_RELRO_END") { | |||
1195 | // GNU linkers implements more complicated logic to handle | |||
1196 | // DATA_SEGMENT_RELRO_END. We instead ignore the arguments and | |||
1197 | // just align to the next page boundary for simplicity. | |||
1198 | expect("("); | |||
1199 | readExpr(); | |||
1200 | expect(","); | |||
1201 | readExpr(); | |||
1202 | expect(")"); | |||
1203 | Expr E = getPageSize(); | |||
1204 | return [=] { return alignTo(Script->getDot(), E().getValue()); }; | |||
1205 | } | |||
1206 | if (Tok == "DEFINED") { | |||
1207 | StringRef Name = readParenLiteral(); | |||
1208 | return [=] { return Symtab->find(Name) ? 1 : 0; }; | |||
1209 | } | |||
1210 | if (Tok == "LENGTH") { | |||
1211 | StringRef Name = readParenLiteral(); | |||
1212 | if (Script->MemoryRegions.count(Name) == 0) { | |||
1213 | setError("memory region not defined: " + Name); | |||
1214 | return [] { return 0; }; | |||
1215 | } | |||
1216 | return [=] { return Script->MemoryRegions[Name]->Length; }; | |||
1217 | } | |||
1218 | if (Tok == "LOADADDR") { | |||
1219 | StringRef Name = readParenLiteral(); | |||
1220 | OutputSection *Cmd = Script->getOrCreateOutputSection(Name); | |||
1221 | return [=] { | |||
1222 | checkIfExists(Cmd, Location); | |||
1223 | return Cmd->getLMA(); | |||
1224 | }; | |||
1225 | } | |||
1226 | if (Tok == "MAX" || Tok == "MIN") { | |||
1227 | expect("("); | |||
1228 | Expr A = readExpr(); | |||
1229 | expect(","); | |||
1230 | Expr B = readExpr(); | |||
1231 | expect(")"); | |||
1232 | if (Tok == "MIN") | |||
1233 | return [=] { return std::min(A().getValue(), B().getValue()); }; | |||
1234 | return [=] { return std::max(A().getValue(), B().getValue()); }; | |||
1235 | } | |||
1236 | if (Tok == "ORIGIN") { | |||
1237 | StringRef Name = readParenLiteral(); | |||
1238 | if (Script->MemoryRegions.count(Name) == 0) { | |||
1239 | setError("memory region not defined: " + Name); | |||
1240 | return [] { return 0; }; | |||
1241 | } | |||
1242 | return [=] { return Script->MemoryRegions[Name]->Origin; }; | |||
1243 | } | |||
1244 | if (Tok == "SEGMENT_START") { | |||
1245 | expect("("); | |||
1246 | skip(); | |||
1247 | expect(","); | |||
1248 | Expr E = readExpr(); | |||
1249 | expect(")"); | |||
1250 | return [=] { return E(); }; | |||
1251 | } | |||
1252 | if (Tok == "SIZEOF") { | |||
1253 | StringRef Name = readParenLiteral(); | |||
1254 | OutputSection *Cmd = Script->getOrCreateOutputSection(Name); | |||
1255 | // Linker script does not create an output section if its content is empty. | |||
1256 | // We want to allow SIZEOF(.foo) where .foo is a section which happened to | |||
1257 | // be empty. | |||
1258 | return [=] { return Cmd->Size; }; | |||
1259 | } | |||
1260 | if (Tok == "SIZEOF_HEADERS") | |||
1261 | return [=] { return elf::getHeaderSize(); }; | |||
1262 | ||||
1263 | // Tok is the dot. | |||
1264 | if (Tok == ".") | |||
1265 | return [=] { return Script->getSymbolValue(Tok, Location); }; | |||
1266 | ||||
1267 | // Tok is a literal number. | |||
1268 | if (Optional<uint64_t> Val = parseInt(Tok)) | |||
1269 | return [=] { return *Val; }; | |||
1270 | ||||
1271 | // Tok is a symbol name. | |||
1272 | if (!isValidCIdentifier(Tok)) | |||
1273 | setError("malformed number: " + Tok); | |||
1274 | Script->ReferencedSymbols.push_back(Tok); | |||
1275 | return [=] { return Script->getSymbolValue(Tok, Location); }; | |||
1276 | } | |||
1277 | ||||
1278 | Expr ScriptParser::readTernary(Expr Cond) { | |||
1279 | Expr L = readExpr(); | |||
1280 | expect(":"); | |||
1281 | Expr R = readExpr(); | |||
1282 | return [=] { return Cond().getValue() ? L() : R(); }; | |||
1283 | } | |||
1284 | ||||
1285 | Expr ScriptParser::readParenExpr() { | |||
1286 | expect("("); | |||
1287 | Expr E = readExpr(); | |||
1288 | expect(")"); | |||
1289 | return E; | |||
1290 | } | |||
1291 | ||||
1292 | std::vector<StringRef> ScriptParser::readOutputSectionPhdrs() { | |||
1293 | std::vector<StringRef> Phdrs; | |||
1294 | while (!errorCount() && peek().startswith(":")) { | |||
1295 | StringRef Tok = next(); | |||
1296 | Phdrs.push_back((Tok.size() == 1) ? next() : Tok.substr(1)); | |||
1297 | } | |||
1298 | return Phdrs; | |||
1299 | } | |||
1300 | ||||
1301 | // Read a program header type name. The next token must be a | |||
1302 | // name of a program header type or a constant (e.g. "0x3"). | |||
1303 | unsigned ScriptParser::readPhdrType() { | |||
1304 | StringRef Tok = next(); | |||
1305 | if (Optional<uint64_t> Val = parseInt(Tok)) | |||
1306 | return *Val; | |||
1307 | ||||
1308 | unsigned Ret = StringSwitch<unsigned>(Tok) | |||
1309 | .Case("PT_NULL", PT_NULL) | |||
1310 | .Case("PT_LOAD", PT_LOAD) | |||
1311 | .Case("PT_DYNAMIC", PT_DYNAMIC) | |||
1312 | .Case("PT_INTERP", PT_INTERP) | |||
1313 | .Case("PT_NOTE", PT_NOTE) | |||
1314 | .Case("PT_SHLIB", PT_SHLIB) | |||
1315 | .Case("PT_PHDR", PT_PHDR) | |||
1316 | .Case("PT_TLS", PT_TLS) | |||
1317 | .Case("PT_GNU_EH_FRAME", PT_GNU_EH_FRAME) | |||
1318 | .Case("PT_GNU_STACK", PT_GNU_STACK) | |||
1319 | .Case("PT_GNU_RELRO", PT_GNU_RELRO) | |||
1320 | .Case("PT_OPENBSD_RANDOMIZE", PT_OPENBSD_RANDOMIZE) | |||
1321 | .Case("PT_OPENBSD_WXNEEDED", PT_OPENBSD_WXNEEDED) | |||
1322 | .Case("PT_OPENBSD_BOOTDATA", PT_OPENBSD_BOOTDATA) | |||
1323 | .Default(-1); | |||
1324 | ||||
1325 | if (Ret == (unsigned)-1) { | |||
1326 | setError("invalid program header type: " + Tok); | |||
1327 | return PT_NULL; | |||
1328 | } | |||
1329 | return Ret; | |||
1330 | } | |||
1331 | ||||
1332 | // Reads an anonymous version declaration. | |||
1333 | void ScriptParser::readAnonymousDeclaration() { | |||
1334 | std::vector<SymbolVersion> Locals; | |||
1335 | std::vector<SymbolVersion> Globals; | |||
1336 | std::tie(Locals, Globals) = readSymbols(); | |||
1337 | ||||
1338 | for (SymbolVersion V : Locals) { | |||
1339 | if (V.Name == "*") | |||
1340 | Config->DefaultSymbolVersion = VER_NDX_LOCAL; | |||
1341 | else | |||
1342 | Config->VersionScriptLocals.push_back(V); | |||
1343 | } | |||
1344 | ||||
1345 | for (SymbolVersion V : Globals) | |||
1346 | Config->VersionScriptGlobals.push_back(V); | |||
1347 | ||||
1348 | expect(";"); | |||
1349 | } | |||
1350 | ||||
1351 | // Reads a non-anonymous version definition, | |||
1352 | // e.g. "VerStr { global: foo; bar; local: *; };". | |||
1353 | void ScriptParser::readVersionDeclaration(StringRef VerStr) { | |||
1354 | // Read a symbol list. | |||
1355 | std::vector<SymbolVersion> Locals; | |||
1356 | std::vector<SymbolVersion> Globals; | |||
1357 | std::tie(Locals, Globals) = readSymbols(); | |||
1358 | ||||
1359 | for (SymbolVersion V : Locals) { | |||
1360 | if (V.Name == "*") | |||
1361 | Config->DefaultSymbolVersion = VER_NDX_LOCAL; | |||
1362 | else | |||
1363 | Config->VersionScriptLocals.push_back(V); | |||
1364 | } | |||
1365 | ||||
1366 | // Create a new version definition and add that to the global symbols. | |||
1367 | VersionDefinition Ver; | |||
1368 | Ver.Name = VerStr; | |||
1369 | Ver.Globals = Globals; | |||
1370 | ||||
1371 | // User-defined version number starts from 2 because 0 and 1 are | |||
1372 | // reserved for VER_NDX_LOCAL and VER_NDX_GLOBAL, respectively. | |||
1373 | Ver.Id = Config->VersionDefinitions.size() + 2; | |||
1374 | Config->VersionDefinitions.push_back(Ver); | |||
1375 | ||||
1376 | // Each version may have a parent version. For example, "Ver2" | |||
1377 | // defined as "Ver2 { global: foo; local: *; } Ver1;" has "Ver1" | |||
1378 | // as a parent. This version hierarchy is, probably against your | |||
1379 | // instinct, purely for hint; the runtime doesn't care about it | |||
1380 | // at all. In LLD, we simply ignore it. | |||
1381 | if (peek() != ";") | |||
1382 | skip(); | |||
1383 | expect(";"); | |||
1384 | } | |||
1385 | ||||
1386 | static bool hasWildcard(StringRef S) { | |||
1387 | return S.find_first_of("?*[") != StringRef::npos; | |||
1388 | } | |||
1389 | ||||
1390 | // Reads a list of symbols, e.g. "{ global: foo; bar; local: *; };". | |||
1391 | std::pair<std::vector<SymbolVersion>, std::vector<SymbolVersion>> | |||
1392 | ScriptParser::readSymbols() { | |||
1393 | std::vector<SymbolVersion> Locals; | |||
1394 | std::vector<SymbolVersion> Globals; | |||
1395 | std::vector<SymbolVersion> *V = &Globals; | |||
1396 | ||||
1397 | while (!errorCount()) { | |||
1398 | if (consume("}")) | |||
1399 | break; | |||
1400 | if (consumeLabel("local")) { | |||
1401 | V = &Locals; | |||
1402 | continue; | |||
1403 | } | |||
1404 | if (consumeLabel("global")) { | |||
1405 | V = &Globals; | |||
1406 | continue; | |||
1407 | } | |||
1408 | ||||
1409 | if (consume("extern")) { | |||
1410 | std::vector<SymbolVersion> Ext = readVersionExtern(); | |||
1411 | V->insert(V->end(), Ext.begin(), Ext.end()); | |||
1412 | } else { | |||
1413 | StringRef Tok = next(); | |||
1414 | V->push_back({unquote(Tok), false, hasWildcard(Tok)}); | |||
1415 | } | |||
1416 | expect(";"); | |||
1417 | } | |||
1418 | return {Locals, Globals}; | |||
1419 | } | |||
1420 | ||||
1421 | // Reads an "extern C++" directive, e.g., | |||
1422 | // "extern "C++" { ns::*; "f(int, double)"; };" | |||
1423 | // | |||
1424 | // The last semicolon is optional. E.g. this is OK: | |||
1425 | // "extern "C++" { ns::*; "f(int, double)" };" | |||
1426 | std::vector<SymbolVersion> ScriptParser::readVersionExtern() { | |||
1427 | StringRef Tok = next(); | |||
1428 | bool IsCXX = Tok == "\"C++\""; | |||
1429 | if (!IsCXX && Tok != "\"C\"") | |||
1430 | setError("Unknown language"); | |||
1431 | expect("{"); | |||
1432 | ||||
1433 | std::vector<SymbolVersion> Ret; | |||
1434 | while (!errorCount() && peek() != "}") { | |||
1435 | StringRef Tok = next(); | |||
1436 | bool HasWildcard = !Tok.startswith("\"") && hasWildcard(Tok); | |||
1437 | Ret.push_back({unquote(Tok), IsCXX, HasWildcard}); | |||
1438 | if (consume("}")) | |||
1439 | return Ret; | |||
1440 | expect(";"); | |||
1441 | } | |||
1442 | ||||
1443 | expect("}"); | |||
1444 | return Ret; | |||
1445 | } | |||
1446 | ||||
1447 | uint64_t ScriptParser::readMemoryAssignment(StringRef S1, StringRef S2, | |||
1448 | StringRef S3) { | |||
1449 | if (!consume(S1) && !consume(S2) && !consume(S3)) { | |||
1450 | setError("expected one of: " + S1 + ", " + S2 + ", or " + S3); | |||
1451 | return 0; | |||
1452 | } | |||
1453 | expect("="); | |||
1454 | return readExpr()().getValue(); | |||
1455 | } | |||
1456 | ||||
1457 | // Parse the MEMORY command as specified in: | |||
1458 | // https://sourceware.org/binutils/docs/ld/MEMORY.html | |||
1459 | // | |||
1460 | // MEMORY { name [(attr)] : ORIGIN = origin, LENGTH = len ... } | |||
1461 | void ScriptParser::readMemory() { | |||
1462 | expect("{"); | |||
1463 | while (!errorCount() && !consume("}")) { | |||
1464 | StringRef Tok = next(); | |||
1465 | if (Tok == "INCLUDE") { | |||
1466 | readInclude(); | |||
1467 | continue; | |||
1468 | } | |||
1469 | ||||
1470 | uint32_t Flags = 0; | |||
1471 | uint32_t NegFlags = 0; | |||
1472 | if (consume("(")) { | |||
1473 | std::tie(Flags, NegFlags) = readMemoryAttributes(); | |||
1474 | expect(")"); | |||
1475 | } | |||
1476 | expect(":"); | |||
1477 | ||||
1478 | uint64_t Origin = readMemoryAssignment("ORIGIN", "org", "o"); | |||
1479 | expect(","); | |||
1480 | uint64_t Length = readMemoryAssignment("LENGTH", "len", "l"); | |||
1481 | ||||
1482 | // Add the memory region to the region map. | |||
1483 | MemoryRegion *MR = make<MemoryRegion>(Tok, Origin, Length, Flags, NegFlags); | |||
1484 | if (!Script->MemoryRegions.insert({Tok, MR}).second) | |||
1485 | setError("region '" + Tok + "' already defined"); | |||
1486 | } | |||
1487 | } | |||
1488 | ||||
1489 | // This function parses the attributes used to match against section | |||
1490 | // flags when placing output sections in a memory region. These flags | |||
1491 | // are only used when an explicit memory region name is not used. | |||
1492 | std::pair<uint32_t, uint32_t> ScriptParser::readMemoryAttributes() { | |||
1493 | uint32_t Flags = 0; | |||
1494 | uint32_t NegFlags = 0; | |||
1495 | bool Invert = false; | |||
1496 | ||||
1497 | for (char C : next().lower()) { | |||
1498 | uint32_t Flag = 0; | |||
1499 | if (C == '!') | |||
1500 | Invert = !Invert; | |||
1501 | else if (C == 'w') | |||
1502 | Flag = SHF_WRITE; | |||
1503 | else if (C == 'x') | |||
1504 | Flag = SHF_EXECINSTR; | |||
1505 | else if (C == 'a') | |||
1506 | Flag = SHF_ALLOC; | |||
1507 | else if (C != 'r') | |||
1508 | setError("invalid memory region attribute"); | |||
1509 | ||||
1510 | if (Invert) | |||
1511 | NegFlags |= Flag; | |||
1512 | else | |||
1513 | Flags |= Flag; | |||
1514 | } | |||
1515 | return {Flags, NegFlags}; | |||
1516 | } | |||
1517 | ||||
1518 | void elf::readLinkerScript(MemoryBufferRef MB) { | |||
1519 | ScriptParser(MB).readLinkerScript(); | |||
1520 | } | |||
1521 | ||||
1522 | void elf::readVersionScript(MemoryBufferRef MB) { | |||
1523 | ScriptParser(MB).readVersionScript(); | |||
1524 | } | |||
1525 | ||||
1526 | void elf::readDynamicList(MemoryBufferRef MB) { | |||
1527 | ScriptParser(MB).readDynamicList(); | |||
1528 | } | |||
1529 | ||||
1530 | void elf::readDefsym(StringRef Name, MemoryBufferRef MB) { | |||
1531 | ScriptParser(MB).readDefsym(Name); | |||
1532 | } |
1 | //===- Endian.h - Utilities for IO with endian specific data ----*- C++ -*-===// |
2 | // |
3 | // The LLVM Compiler Infrastructure |
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 declares generic functions to read and write endian specific data. |
11 | // |
12 | //===----------------------------------------------------------------------===// |
13 | |
14 | #ifndef LLVM_SUPPORT_ENDIAN_H |
15 | #define LLVM_SUPPORT_ENDIAN_H |
16 | |
17 | #include "llvm/Support/AlignOf.h" |
18 | #include "llvm/Support/Compiler.h" |
19 | #include "llvm/Support/Host.h" |
20 | #include "llvm/Support/SwapByteOrder.h" |
21 | #include <cassert> |
22 | #include <cstddef> |
23 | #include <cstdint> |
24 | #include <cstring> |
25 | #include <type_traits> |
26 | |
27 | namespace llvm { |
28 | namespace support { |
29 | |
30 | enum endianness {big, little, native}; |
31 | |
32 | // These are named values for common alignments. |
33 | enum {aligned = 0, unaligned = 1}; |
34 | |
35 | namespace detail { |
36 | |
37 | /// ::value is either alignment, or alignof(T) if alignment is 0. |
38 | template<class T, int alignment> |
39 | struct PickAlignment { |
40 | enum { value = alignment == 0 ? alignof(T) : alignment }; |
41 | }; |
42 | |
43 | } // end namespace detail |
44 | |
45 | namespace endian { |
46 | |
47 | constexpr endianness system_endianness() { |
48 | return sys::IsBigEndianHost ? big : little; |
49 | } |
50 | |
51 | template <typename value_type> |
52 | inline value_type byte_swap(value_type value, endianness endian) { |
53 | if ((endian != native) && (endian != system_endianness())) |
54 | sys::swapByteOrder(value); |
55 | return value; |
56 | } |
57 | |
58 | /// Swap the bytes of value to match the given endianness. |
59 | template<typename value_type, endianness endian> |
60 | inline value_type byte_swap(value_type value) { |
61 | return byte_swap(value, endian); |
62 | } |
63 | |
64 | /// Read a value of a particular endianness from memory. |
65 | template <typename value_type, std::size_t alignment> |
66 | inline value_type read(const void *memory, endianness endian) { |
67 | value_type ret; |
68 | |
69 | memcpy(&ret, |
70 | LLVM_ASSUME_ALIGNED(__builtin_assume_aligned(memory, (detail::PickAlignment<value_type , alignment>::value)) |
71 | memory, (detail::PickAlignment<value_type, alignment>::value))__builtin_assume_aligned(memory, (detail::PickAlignment<value_type , alignment>::value)), |
72 | sizeof(value_type)); |
73 | return byte_swap<value_type>(ret, endian); |
74 | } |
75 | |
76 | template<typename value_type, |
77 | endianness endian, |
78 | std::size_t alignment> |
79 | inline value_type read(const void *memory) { |
80 | return read<value_type, alignment>(memory, endian); |
81 | } |
82 | |
83 | /// Read a value of a particular endianness from a buffer, and increment the |
84 | /// buffer past that value. |
85 | template <typename value_type, std::size_t alignment, typename CharT> |
86 | inline value_type readNext(const CharT *&memory, endianness endian) { |
87 | value_type ret = read<value_type, alignment>(memory, endian); |
88 | memory += sizeof(value_type); |
89 | return ret; |
90 | } |
91 | |
92 | template<typename value_type, endianness endian, std::size_t alignment, |
93 | typename CharT> |
94 | inline value_type readNext(const CharT *&memory) { |
95 | return readNext<value_type, alignment, CharT>(memory, endian); |
96 | } |
97 | |
98 | /// Write a value to memory with a particular endianness. |
99 | template <typename value_type, std::size_t alignment> |
100 | inline void write(void *memory, value_type value, endianness endian) { |
101 | value = byte_swap<value_type>(value, endian); |
102 | memcpy(LLVM_ASSUME_ALIGNED(__builtin_assume_aligned(memory, (detail::PickAlignment<value_type , alignment>::value)) |
103 | memory, (detail::PickAlignment<value_type, alignment>::value))__builtin_assume_aligned(memory, (detail::PickAlignment<value_type , alignment>::value)), |
104 | &value, sizeof(value_type)); |
105 | } |
106 | |
107 | template<typename value_type, |
108 | endianness endian, |
109 | std::size_t alignment> |
110 | inline void write(void *memory, value_type value) { |
111 | write<value_type, alignment>(memory, value, endian); |
112 | } |
113 | |
114 | template <typename value_type> |
115 | using make_unsigned_t = typename std::make_unsigned<value_type>::type; |
116 | |
117 | /// Read a value of a particular endianness from memory, for a location |
118 | /// that starts at the given bit offset within the first byte. |
119 | template <typename value_type, endianness endian, std::size_t alignment> |
120 | inline value_type readAtBitAlignment(const void *memory, uint64_t startBit) { |
121 | assert(startBit < 8)((startBit < 8) ? static_cast<void> (0) : __assert_fail ("startBit < 8", "/build/llvm-toolchain-snapshot-8~svn345461/include/llvm/Support/Endian.h" , 121, __PRETTY_FUNCTION__)); |
122 | if (startBit == 0) |
123 | return read<value_type, endian, alignment>(memory); |
124 | else { |
125 | // Read two values and compose the result from them. |
126 | value_type val[2]; |
127 | memcpy(&val[0], |
128 | LLVM_ASSUME_ALIGNED(__builtin_assume_aligned(memory, (detail::PickAlignment<value_type , alignment>::value)) |
129 | memory, (detail::PickAlignment<value_type, alignment>::value))__builtin_assume_aligned(memory, (detail::PickAlignment<value_type , alignment>::value)), |
130 | sizeof(value_type) * 2); |
131 | val[0] = byte_swap<value_type, endian>(val[0]); |
132 | val[1] = byte_swap<value_type, endian>(val[1]); |
133 | |
134 | // Shift bits from the lower value into place. |
135 | make_unsigned_t<value_type> lowerVal = val[0] >> startBit; |
136 | // Mask off upper bits after right shift in case of signed type. |
137 | make_unsigned_t<value_type> numBitsFirstVal = |
138 | (sizeof(value_type) * 8) - startBit; |
139 | lowerVal &= ((make_unsigned_t<value_type>)1 << numBitsFirstVal) - 1; |
140 | |
141 | // Get the bits from the upper value. |
142 | make_unsigned_t<value_type> upperVal = |
143 | val[1] & (((make_unsigned_t<value_type>)1 << startBit) - 1); |
144 | // Shift them in to place. |
145 | upperVal <<= numBitsFirstVal; |
146 | |
147 | return lowerVal | upperVal; |
148 | } |
149 | } |
150 | |
151 | /// Write a value to memory with a particular endianness, for a location |
152 | /// that starts at the given bit offset within the first byte. |
153 | template <typename value_type, endianness endian, std::size_t alignment> |
154 | inline void writeAtBitAlignment(void *memory, value_type value, |
155 | uint64_t startBit) { |
156 | assert(startBit < 8)((startBit < 8) ? static_cast<void> (0) : __assert_fail ("startBit < 8", "/build/llvm-toolchain-snapshot-8~svn345461/include/llvm/Support/Endian.h" , 156, __PRETTY_FUNCTION__)); |
157 | if (startBit == 0) |
158 | write<value_type, endian, alignment>(memory, value); |
159 | else { |
160 | // Read two values and shift the result into them. |
161 | value_type val[2]; |
162 | memcpy(&val[0], |
163 | LLVM_ASSUME_ALIGNED(__builtin_assume_aligned(memory, (detail::PickAlignment<value_type , alignment>::value)) |
164 | memory, (detail::PickAlignment<value_type, alignment>::value))__builtin_assume_aligned(memory, (detail::PickAlignment<value_type , alignment>::value)), |
165 | sizeof(value_type) * 2); |
166 | val[0] = byte_swap<value_type, endian>(val[0]); |
167 | val[1] = byte_swap<value_type, endian>(val[1]); |
168 | |
169 | // Mask off any existing bits in the upper part of the lower value that |
170 | // we want to replace. |
171 | val[0] &= ((make_unsigned_t<value_type>)1 << startBit) - 1; |
172 | make_unsigned_t<value_type> numBitsFirstVal = |
173 | (sizeof(value_type) * 8) - startBit; |
174 | make_unsigned_t<value_type> lowerVal = value; |
175 | if (startBit > 0) { |
176 | // Mask off the upper bits in the new value that are not going to go into |
177 | // the lower value. This avoids a left shift of a negative value, which |
178 | // is undefined behavior. |
179 | lowerVal &= (((make_unsigned_t<value_type>)1 << numBitsFirstVal) - 1); |
180 | // Now shift the new bits into place |
181 | lowerVal <<= startBit; |
182 | } |
183 | val[0] |= lowerVal; |
184 | |
185 | // Mask off any existing bits in the lower part of the upper value that |
186 | // we want to replace. |
187 | val[1] &= ~(((make_unsigned_t<value_type>)1 << startBit) - 1); |
188 | // Next shift the bits that go into the upper value into position. |
189 | make_unsigned_t<value_type> upperVal = value >> numBitsFirstVal; |
190 | // Mask off upper bits after right shift in case of signed type. |
191 | upperVal &= ((make_unsigned_t<value_type>)1 << startBit) - 1; |
192 | val[1] |= upperVal; |
193 | |
194 | // Finally, rewrite values. |
195 | val[0] = byte_swap<value_type, endian>(val[0]); |
196 | val[1] = byte_swap<value_type, endian>(val[1]); |
197 | memcpy(LLVM_ASSUME_ALIGNED(__builtin_assume_aligned(memory, (detail::PickAlignment<value_type , alignment>::value)) |
198 | memory, (detail::PickAlignment<value_type, alignment>::value))__builtin_assume_aligned(memory, (detail::PickAlignment<value_type , alignment>::value)), |
199 | &val[0], sizeof(value_type) * 2); |
200 | } |
201 | } |
202 | |
203 | } // end namespace endian |
204 | |
205 | namespace detail { |
206 | |
207 | template<typename value_type, |
208 | endianness endian, |
209 | std::size_t alignment> |
210 | struct packed_endian_specific_integral { |
211 | packed_endian_specific_integral() = default; |
212 | |
213 | explicit packed_endian_specific_integral(value_type val) { *this = val; } |
214 | |
215 | operator value_type() const { |
216 | return endian::read<value_type, endian, alignment>( |
217 | (const void*)Value.buffer); |
218 | } |
219 | |
220 | void operator=(value_type newValue) { |
221 | endian::write<value_type, endian, alignment>( |
222 | (void*)Value.buffer, newValue); |
223 | } |
224 | |
225 | packed_endian_specific_integral &operator+=(value_type newValue) { |
226 | *this = *this + newValue; |
227 | return *this; |
228 | } |
229 | |
230 | packed_endian_specific_integral &operator-=(value_type newValue) { |
231 | *this = *this - newValue; |
232 | return *this; |
233 | } |
234 | |
235 | packed_endian_specific_integral &operator|=(value_type newValue) { |
236 | *this = *this | newValue; |
237 | return *this; |
238 | } |
239 | |
240 | packed_endian_specific_integral &operator&=(value_type newValue) { |
241 | *this = *this & newValue; |
242 | return *this; |
243 | } |
244 | |
245 | private: |
246 | AlignedCharArray<PickAlignment<value_type, alignment>::value, |
247 | sizeof(value_type)> Value; |
248 | |
249 | public: |
250 | struct ref { |
251 | explicit ref(void *Ptr) : Ptr(Ptr) {} |
252 | |
253 | operator value_type() const { |
254 | return endian::read<value_type, endian, alignment>(Ptr); |
255 | } |
256 | |
257 | void operator=(value_type NewValue) { |
258 | endian::write<value_type, endian, alignment>(Ptr, NewValue); |
259 | } |
260 | |
261 | private: |
262 | void *Ptr; |
263 | }; |
264 | }; |
265 | |
266 | } // end namespace detail |
267 | |
268 | using ulittle16_t = |
269 | detail::packed_endian_specific_integral<uint16_t, little, unaligned>; |
270 | using ulittle32_t = |
271 | detail::packed_endian_specific_integral<uint32_t, little, unaligned>; |
272 | using ulittle64_t = |
273 | detail::packed_endian_specific_integral<uint64_t, little, unaligned>; |
274 | |
275 | using little16_t = |
276 | detail::packed_endian_specific_integral<int16_t, little, unaligned>; |
277 | using little32_t = |
278 | detail::packed_endian_specific_integral<int32_t, little, unaligned>; |
279 | using little64_t = |
280 | detail::packed_endian_specific_integral<int64_t, little, unaligned>; |
281 | |
282 | using aligned_ulittle16_t = |
283 | detail::packed_endian_specific_integral<uint16_t, little, aligned>; |
284 | using aligned_ulittle32_t = |
285 | detail::packed_endian_specific_integral<uint32_t, little, aligned>; |
286 | using aligned_ulittle64_t = |
287 | detail::packed_endian_specific_integral<uint64_t, little, aligned>; |
288 | |
289 | using aligned_little16_t = |
290 | detail::packed_endian_specific_integral<int16_t, little, aligned>; |
291 | using aligned_little32_t = |
292 | detail::packed_endian_specific_integral<int32_t, little, aligned>; |
293 | using aligned_little64_t = |
294 | detail::packed_endian_specific_integral<int64_t, little, aligned>; |
295 | |
296 | using ubig16_t = |
297 | detail::packed_endian_specific_integral<uint16_t, big, unaligned>; |
298 | using ubig32_t = |
299 | detail::packed_endian_specific_integral<uint32_t, big, unaligned>; |
300 | using ubig64_t = |
301 | detail::packed_endian_specific_integral<uint64_t, big, unaligned>; |
302 | |
303 | using big16_t = |
304 | detail::packed_endian_specific_integral<int16_t, big, unaligned>; |
305 | using big32_t = |
306 | detail::packed_endian_specific_integral<int32_t, big, unaligned>; |
307 | using big64_t = |
308 | detail::packed_endian_specific_integral<int64_t, big, unaligned>; |
309 | |
310 | using aligned_ubig16_t = |
311 | detail::packed_endian_specific_integral<uint16_t, big, aligned>; |
312 | using aligned_ubig32_t = |
313 | detail::packed_endian_specific_integral<uint32_t, big, aligned>; |
314 | using aligned_ubig64_t = |
315 | detail::packed_endian_specific_integral<uint64_t, big, aligned>; |
316 | |
317 | using aligned_big16_t = |
318 | detail::packed_endian_specific_integral<int16_t, big, aligned>; |
319 | using aligned_big32_t = |
320 | detail::packed_endian_specific_integral<int32_t, big, aligned>; |
321 | using aligned_big64_t = |
322 | detail::packed_endian_specific_integral<int64_t, big, aligned>; |
323 | |
324 | using unaligned_uint16_t = |
325 | detail::packed_endian_specific_integral<uint16_t, native, unaligned>; |
326 | using unaligned_uint32_t = |
327 | detail::packed_endian_specific_integral<uint32_t, native, unaligned>; |
328 | using unaligned_uint64_t = |
329 | detail::packed_endian_specific_integral<uint64_t, native, unaligned>; |
330 | |
331 | using unaligned_int16_t = |
332 | detail::packed_endian_specific_integral<int16_t, native, unaligned>; |
333 | using unaligned_int32_t = |
334 | detail::packed_endian_specific_integral<int32_t, native, unaligned>; |
335 | using unaligned_int64_t = |
336 | detail::packed_endian_specific_integral<int64_t, native, unaligned>; |
337 | |
338 | namespace endian { |
339 | |
340 | template <typename T> inline T read(const void *P, endianness E) { |
341 | return read<T, unaligned>(P, E); |
342 | } |
343 | |
344 | template <typename T, endianness E> inline T read(const void *P) { |
345 | return *(const detail::packed_endian_specific_integral<T, E, unaligned> *)P; |
346 | } |
347 | |
348 | inline uint16_t read16(const void *P, endianness E) { |
349 | return read<uint16_t>(P, E); |
350 | } |
351 | inline uint32_t read32(const void *P, endianness E) { |
352 | return read<uint32_t>(P, E); |
353 | } |
354 | inline uint64_t read64(const void *P, endianness E) { |
355 | return read<uint64_t>(P, E); |
356 | } |
357 | |
358 | template <endianness E> inline uint16_t read16(const void *P) { |
359 | return read<uint16_t, E>(P); |
360 | } |
361 | template <endianness E> inline uint32_t read32(const void *P) { |
362 | return read<uint32_t, E>(P); |
363 | } |
364 | template <endianness E> inline uint64_t read64(const void *P) { |
365 | return read<uint64_t, E>(P); |
366 | } |
367 | |
368 | inline uint16_t read16le(const void *P) { return read16<little>(P); } |
369 | inline uint32_t read32le(const void *P) { return read32<little>(P); } |
370 | inline uint64_t read64le(const void *P) { return read64<little>(P); } |
371 | inline uint16_t read16be(const void *P) { return read16<big>(P); } |
372 | inline uint32_t read32be(const void *P) { return read32<big>(P); } |
373 | inline uint64_t read64be(const void *P) { return read64<big>(P); } |
374 | |
375 | template <typename T> inline void write(void *P, T V, endianness E) { |
376 | write<T, unaligned>(P, V, E); |
377 | } |
378 | |
379 | template <typename T, endianness E> inline void write(void *P, T V) { |
380 | *(detail::packed_endian_specific_integral<T, E, unaligned> *)P = V; |
381 | } |
382 | |
383 | inline void write16(void *P, uint16_t V, endianness E) { |
384 | write<uint16_t>(P, V, E); |
385 | } |
386 | inline void write32(void *P, uint32_t V, endianness E) { |
387 | write<uint32_t>(P, V, E); |
388 | } |
389 | inline void write64(void *P, uint64_t V, endianness E) { |
390 | write<uint64_t>(P, V, E); |
391 | } |
392 | |
393 | template <endianness E> inline void write16(void *P, uint16_t V) { |
394 | write<uint16_t, E>(P, V); |
395 | } |
396 | template <endianness E> inline void write32(void *P, uint32_t V) { |
397 | write<uint32_t, E>(P, V); |
398 | } |
399 | template <endianness E> inline void write64(void *P, uint64_t V) { |
400 | write<uint64_t, E>(P, V); |
401 | } |
402 | |
403 | inline void write16le(void *P, uint16_t V) { write16<little>(P, V); } |
404 | inline void write32le(void *P, uint32_t V) { write32<little>(P, V); } |
405 | inline void write64le(void *P, uint64_t V) { write64<little>(P, V); } |
406 | inline void write16be(void *P, uint16_t V) { write16<big>(P, V); } |
407 | inline void write32be(void *P, uint32_t V) { write32<big>(P, V); } |
408 | inline void write64be(void *P, uint64_t V) { write64<big>(P, V); } |
409 | |
410 | } // end namespace endian |
411 | |
412 | } // end namespace support |
413 | } // end namespace llvm |
414 | |
415 | #endif // LLVM_SUPPORT_ENDIAN_H |