Bug Summary

File:tools/lld/ELF/ScriptParser.cpp
Warning:line 885, column 3
Undefined or garbage value returned to caller

Annotated Source Code

Press '?' to see keyboard shortcuts

clang -cc1 -triple x86_64-pc-linux-gnu -analyze -disable-free -disable-llvm-verifier -discard-value-names -main-file-name ScriptParser.cpp -analyzer-store=region -analyzer-opt-analyze-nested-blocks -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=cplusplus -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -mrelocation-model pic -pic-level 2 -mthread-model posix -fmath-errno -masm-verbose -mconstructor-aliases -munwind-tables -fuse-init-array -target-cpu x86-64 -dwarf-column-info -debugger-tuning=gdb -momit-leaf-frame-pointer -ffunction-sections -fdata-sections -resource-dir /usr/lib/llvm-8/lib/clang/8.0.0 -D _DEBUG -D _GNU_SOURCE -D __STDC_CONSTANT_MACROS -D __STDC_FORMAT_MACROS -D __STDC_LIMIT_MACROS -I /build/llvm-toolchain-snapshot-8~svn345461/build-llvm/tools/lld/ELF -I /build/llvm-toolchain-snapshot-8~svn345461/tools/lld/ELF -I /build/llvm-toolchain-snapshot-8~svn345461/tools/lld/include -I /build/llvm-toolchain-snapshot-8~svn345461/build-llvm/tools/lld/include -I /build/llvm-toolchain-snapshot-8~svn345461/build-llvm/include -I /build/llvm-toolchain-snapshot-8~svn345461/include -U NDEBUG -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/6.3.0/../../../../include/c++/6.3.0 -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/6.3.0/../../../../include/x86_64-linux-gnu/c++/6.3.0 -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/6.3.0/../../../../include/x86_64-linux-gnu/c++/6.3.0 -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/6.3.0/../../../../include/c++/6.3.0/backward -internal-isystem /usr/include/clang/8.0.0/include/ -internal-isystem /usr/local/include -internal-isystem /usr/lib/llvm-8/lib/clang/8.0.0/include -internal-externc-isystem /usr/include/x86_64-linux-gnu -internal-externc-isystem /include -internal-externc-isystem /usr/include -O2 -Wno-unused-parameter -Wwrite-strings -Wno-missing-field-initializers -Wno-long-long -Wno-maybe-uninitialized -Wno-comment -std=c++11 -fdeprecated-macro -fdebug-compilation-dir /build/llvm-toolchain-snapshot-8~svn345461/build-llvm/tools/lld/ELF -ferror-limit 19 -fmessage-length 0 -fvisibility-inlines-hidden -fobjc-runtime=gcc -fdiagnostics-show-option -vectorize-loops -vectorize-slp -analyzer-output=html -analyzer-config stable-report-filename=true -o /tmp/scan-build-2018-10-27-211344-32123-1 -x c++ /build/llvm-toolchain-snapshot-8~svn345461/tools/lld/ELF/ScriptParser.cpp -faddrsig

/build/llvm-toolchain-snapshot-8~svn345461/tools/lld/ELF/ScriptParser.cpp

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
38using namespace llvm;
39using namespace llvm::ELF;
40using namespace llvm::support::endian;
41using namespace lld;
42using namespace lld::elf;
43
44static bool isUnderSysroot(StringRef Path);
45
46namespace {
47class ScriptParser final : ScriptLexer {
48public:
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
58private:
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
130static StringRef unquote(StringRef S) {
131 if (S.startswith("\""))
132 return S.substr(1, S.size() - 2);
133 return S;
134}
135
136static 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.
147static 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
154static ExprValue add(ExprValue A, ExprValue B) {
155 moveAbsRight(A, B);
156 return {A.Sec, A.ForceAbsolute, A.getSectionOffset() + B.getValue(), A.Loc};
157}
158
159static 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
166static 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
172static 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
178void 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
199void ScriptParser::readVersionScript() {
200 readVersionScriptCommand();
201 if (!atEOF())
202 setError("EOF expected, but got " + next());
203}
204
205void 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
223void ScriptParser::readVersion() {
224 expect("{");
225 readVersionScriptCommand();
226 expect("}");
227}
228
229void 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
273void 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
281void 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
311void 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
320void 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
329void ScriptParser::readExtern() {
330 expect("(");
331 while (!errorCount() && !consume(")"))
332 Config->Undefined.push_back(next());
333}
334
335void 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
344void 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
360void ScriptParser::readInput() {
361 expect("(");
362 while (!errorCount() && !consume(")")) {
363 if (consume("AS_NEEDED"))
364 readAsNeeded();
365 else
366 addFile(unquote(next()));
367 }
368}
369
370void 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
379void ScriptParser::readOutputArch() {
380 // OUTPUT_ARCH is ignored for now.
381 expect("(");
382 while (!errorCount() && !consume(")"))
383 skip();
384}
385
386std::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.
407void 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
425void 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
450void 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
464void 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
476std::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
515void 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
559void 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
576static 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
589StringMatcher ScriptParser::readFilePatterns() {
590 std::vector<StringRef> V;
591 while (!errorCount() && !consume(")"))
592 V.push_back(next());
593 return StringMatcher(V);
594}
595
596SortSectionPolicy 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.
621std::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().
653InputSectionDescription *
654ScriptParser::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
687InputSectionDescription *
688ScriptParser::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
702void ScriptParser::readSort() {
703 expect("(");
704 expect("CONSTRUCTORS");
705 expect(")");
706}
707
708Expr 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
726uint32_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.
736bool 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
764void 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
773static 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
784OutputSection *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
795OutputSection *ScriptParser::readOutputSectionDescription(StringRef OutSec) {
796 OutputSection *Cmd =
797 Script->createOutputSection(OutSec, getCurrentLocation());
798
799 size_t SymbolsReferenced = Script->ReferencedSymbols.size();
800
801 if (peek() != ":")
1
Taking false branch
802 readSectionAddressType(Cmd);
803 expect(":");
804
805 std::string Location = getCurrentLocation();
806 if (consume("AT"))
2
Assuming the condition is false
3
Taking false branch
807 Cmd->LMAExpr = readParenExpr();
808 if (consume("ALIGN"))
4
Assuming the condition is false
5
Taking false branch
809 Cmd->AlignExpr = checkAlignment(readParenExpr(), Location);
810 if (consume("SUBALIGN"))
6
Assuming the condition is false
7
Taking false branch
811 Cmd->SubalignExpr = checkAlignment(readParenExpr(), Location);
812
813 // Parse constraints.
814 if (consume("ONLY_IF_RO"))
8
Assuming the condition is false
9
Taking false branch
815 Cmd->Constraint = ConstraintKind::ReadOnly;
816 if (consume("ONLY_IF_RW"))
10
Assuming the condition is false
11
Taking false branch
817 Cmd->Constraint = ConstraintKind::ReadWrite;
818 expect("{");
819
820 while (!errorCount() && !consume("}")) {
12
Assuming the condition is false
13
Loop condition is false. Execution continues on line 845
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(">"))
14
Assuming the condition is false
15
Taking false branch
846 Cmd->MemoryRegionName = next();
847
848 if (consume("AT")) {
16
Assuming the condition is false
17
Taking false branch
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("="))
18
Assuming the condition is true
19
Taking true branch
859 Cmd->Filler = parseFill(next());
20
Calling 'ScriptParser::parseFill'
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.
878uint32_t ScriptParser::parseFill(StringRef Tok) {
879 uint32_t V = 0;
880 if (!to_integer(Tok, V))
21
Taking false branch
881 setError("invalid filler expression: " + Tok);
882
883 uint32_t Buf;
22
'Buf' declared without an initial value
884 write32be(&Buf, V);
23
Calling 'write32be'
31
Returning from 'write32be'
885 return Buf;
32
Undefined or garbage value returned to caller
886}
887
888SymbolAssignment *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
897SymbolAssignment *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
922SymbolAssignment *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.
935Expr 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
945Expr 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.
999Expr 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
1026Expr 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
1036Expr 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.
1049static 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
1079ByteCommand *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
1097StringRef 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
1107static void checkIfExists(OutputSection *Cmd, StringRef Location) {
1108 if (Cmd->Location.empty() && Script->ErrorOnMissingSection)
1109 error(Location + ": undefined section " + Cmd->Name);
1110}
1111
1112Expr 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
1278Expr ScriptParser::readTernary(Expr Cond) {
1279 Expr L = readExpr();
1280 expect(":");
1281 Expr R = readExpr();
1282 return [=] { return Cond().getValue() ? L() : R(); };
1283}
1284
1285Expr ScriptParser::readParenExpr() {
1286 expect("(");
1287 Expr E = readExpr();
1288 expect(")");
1289 return E;
1290}
1291
1292std::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").
1303unsigned 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.
1333void 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: *; };".
1353void 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
1386static 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: *; };".
1391std::pair<std::vector<SymbolVersion>, std::vector<SymbolVersion>>
1392ScriptParser::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)" };"
1426std::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
1447uint64_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 ... }
1461void 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.
1492std::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
1518void elf::readLinkerScript(MemoryBufferRef MB) {
1519 ScriptParser(MB).readLinkerScript();
1520}
1521
1522void elf::readVersionScript(MemoryBufferRef MB) {
1523 ScriptParser(MB).readVersionScript();
1524}
1525
1526void elf::readDynamicList(MemoryBufferRef MB) {
1527 ScriptParser(MB).readDynamicList();
1528}
1529
1530void elf::readDefsym(StringRef Name, MemoryBufferRef MB) {
1531 ScriptParser(MB).readDefsym(Name);
1532}

/build/llvm-toolchain-snapshot-8~svn345461/include/llvm/Support/Endian.h

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
27namespace llvm {
28namespace support {
29
30enum endianness {big, little, native};
31
32// These are named values for common alignments.
33enum {aligned = 0, unaligned = 1};
34
35namespace detail {
36
37/// ::value is either alignment, or alignof(T) if alignment is 0.
38template<class T, int alignment>
39struct PickAlignment {
40 enum { value = alignment == 0 ? alignof(T) : alignment };
41};
42
43} // end namespace detail
44
45namespace endian {
46
47constexpr endianness system_endianness() {
48 return sys::IsBigEndianHost ? big : little;
49}
50
51template <typename value_type>
52inline 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.
59template<typename value_type, endianness endian>
60inline 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.
65template <typename value_type, std::size_t alignment>
66inline 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
76template<typename value_type,
77 endianness endian,
78 std::size_t alignment>
79inline 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.
85template <typename value_type, std::size_t alignment, typename CharT>
86inline 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
92template<typename value_type, endianness endian, std::size_t alignment,
93 typename CharT>
94inline 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.
99template <typename value_type, std::size_t alignment>
100inline 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
107template<typename value_type,
108 endianness endian,
109 std::size_t alignment>
110inline void write(void *memory, value_type value) {
111 write<value_type, alignment>(memory, value, endian);
112}
113
114template <typename value_type>
115using 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.
119template <typename value_type, endianness endian, std::size_t alignment>
120inline 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.
153template <typename value_type, endianness endian, std::size_t alignment>
154inline 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
205namespace detail {
206
207template<typename value_type,
208 endianness endian,
209 std::size_t alignment>
210struct 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
245private:
246 AlignedCharArray<PickAlignment<value_type, alignment>::value,
247 sizeof(value_type)> Value;
248
249public:
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
268using ulittle16_t =
269 detail::packed_endian_specific_integral<uint16_t, little, unaligned>;
270using ulittle32_t =
271 detail::packed_endian_specific_integral<uint32_t, little, unaligned>;
272using ulittle64_t =
273 detail::packed_endian_specific_integral<uint64_t, little, unaligned>;
274
275using little16_t =
276 detail::packed_endian_specific_integral<int16_t, little, unaligned>;
277using little32_t =
278 detail::packed_endian_specific_integral<int32_t, little, unaligned>;
279using little64_t =
280 detail::packed_endian_specific_integral<int64_t, little, unaligned>;
281
282using aligned_ulittle16_t =
283 detail::packed_endian_specific_integral<uint16_t, little, aligned>;
284using aligned_ulittle32_t =
285 detail::packed_endian_specific_integral<uint32_t, little, aligned>;
286using aligned_ulittle64_t =
287 detail::packed_endian_specific_integral<uint64_t, little, aligned>;
288
289using aligned_little16_t =
290 detail::packed_endian_specific_integral<int16_t, little, aligned>;
291using aligned_little32_t =
292 detail::packed_endian_specific_integral<int32_t, little, aligned>;
293using aligned_little64_t =
294 detail::packed_endian_specific_integral<int64_t, little, aligned>;
295
296using ubig16_t =
297 detail::packed_endian_specific_integral<uint16_t, big, unaligned>;
298using ubig32_t =
299 detail::packed_endian_specific_integral<uint32_t, big, unaligned>;
300using ubig64_t =
301 detail::packed_endian_specific_integral<uint64_t, big, unaligned>;
302
303using big16_t =
304 detail::packed_endian_specific_integral<int16_t, big, unaligned>;
305using big32_t =
306 detail::packed_endian_specific_integral<int32_t, big, unaligned>;
307using big64_t =
308 detail::packed_endian_specific_integral<int64_t, big, unaligned>;
309
310using aligned_ubig16_t =
311 detail::packed_endian_specific_integral<uint16_t, big, aligned>;
312using aligned_ubig32_t =
313 detail::packed_endian_specific_integral<uint32_t, big, aligned>;
314using aligned_ubig64_t =
315 detail::packed_endian_specific_integral<uint64_t, big, aligned>;
316
317using aligned_big16_t =
318 detail::packed_endian_specific_integral<int16_t, big, aligned>;
319using aligned_big32_t =
320 detail::packed_endian_specific_integral<int32_t, big, aligned>;
321using aligned_big64_t =
322 detail::packed_endian_specific_integral<int64_t, big, aligned>;
323
324using unaligned_uint16_t =
325 detail::packed_endian_specific_integral<uint16_t, native, unaligned>;
326using unaligned_uint32_t =
327 detail::packed_endian_specific_integral<uint32_t, native, unaligned>;
328using unaligned_uint64_t =
329 detail::packed_endian_specific_integral<uint64_t, native, unaligned>;
330
331using unaligned_int16_t =
332 detail::packed_endian_specific_integral<int16_t, native, unaligned>;
333using unaligned_int32_t =
334 detail::packed_endian_specific_integral<int32_t, native, unaligned>;
335using unaligned_int64_t =
336 detail::packed_endian_specific_integral<int64_t, native, unaligned>;
337
338namespace endian {
339
340template <typename T> inline T read(const void *P, endianness E) {
341 return read<T, unaligned>(P, E);
342}
343
344template <typename T, endianness E> inline T read(const void *P) {
345 return *(const detail::packed_endian_specific_integral<T, E, unaligned> *)P;
346}
347
348inline uint16_t read16(const void *P, endianness E) {
349 return read<uint16_t>(P, E);
350}
351inline uint32_t read32(const void *P, endianness E) {
352 return read<uint32_t>(P, E);
353}
354inline uint64_t read64(const void *P, endianness E) {
355 return read<uint64_t>(P, E);
356}
357
358template <endianness E> inline uint16_t read16(const void *P) {
359 return read<uint16_t, E>(P);
360}
361template <endianness E> inline uint32_t read32(const void *P) {
362 return read<uint32_t, E>(P);
363}
364template <endianness E> inline uint64_t read64(const void *P) {
365 return read<uint64_t, E>(P);
366}
367
368inline uint16_t read16le(const void *P) { return read16<little>(P); }
369inline uint32_t read32le(const void *P) { return read32<little>(P); }
370inline uint64_t read64le(const void *P) { return read64<little>(P); }
371inline uint16_t read16be(const void *P) { return read16<big>(P); }
372inline uint32_t read32be(const void *P) { return read32<big>(P); }
373inline uint64_t read64be(const void *P) { return read64<big>(P); }
374
375template <typename T> inline void write(void *P, T V, endianness E) {
376 write<T, unaligned>(P, V, E);
377}
378
379template <typename T, endianness E> inline void write(void *P, T V) {
380 *(detail::packed_endian_specific_integral<T, E, unaligned> *)P = V;
381}
26
Returning without writing to '*P'
382
383inline void write16(void *P, uint16_t V, endianness E) {
384 write<uint16_t>(P, V, E);
385}
386inline void write32(void *P, uint32_t V, endianness E) {
387 write<uint32_t>(P, V, E);
388}
389inline void write64(void *P, uint64_t V, endianness E) {
390 write<uint64_t>(P, V, E);
391}
392
393template <endianness E> inline void write16(void *P, uint16_t V) {
394 write<uint16_t, E>(P, V);
395}
396template <endianness E> inline void write32(void *P, uint32_t V) {
397 write<uint32_t, E>(P, V);
25
Calling 'write<unsigned int, llvm::support::big>'
27
Returning from 'write<unsigned int, llvm::support::big>'
398}
28
Returning without writing to '*P'
399template <endianness E> inline void write64(void *P, uint64_t V) {
400 write<uint64_t, E>(P, V);
401}
402
403inline void write16le(void *P, uint16_t V) { write16<little>(P, V); }
404inline void write32le(void *P, uint32_t V) { write32<little>(P, V); }
405inline void write64le(void *P, uint64_t V) { write64<little>(P, V); }
406inline void write16be(void *P, uint16_t V) { write16<big>(P, V); }
407inline void write32be(void *P, uint32_t V) { write32<big>(P, V); }
24
Calling 'write32<llvm::support::big>'
29
Returning from 'write32<llvm::support::big>'
30
Returning without writing to '*P'
408inline 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