Bug Summary

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

Annotated Source Code

/build/llvm-toolchain-snapshot-6.0~svn318882/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 "Memory.h"
21#include "OutputSections.h"
22#include "ScriptLexer.h"
23#include "Symbols.h"
24#include "Target.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 readMemory();
67 void readOutput();
68 void readOutputArch();
69 void readOutputFormat();
70 void readPhdrs();
71 void readRegionAlias();
72 void readSearchDir();
73 void readSections();
74 void readVersion();
75 void readVersionScriptCommand();
76
77 SymbolAssignment *readAssignment(StringRef Name);
78 ByteCommand *readByteCommand(StringRef Tok);
79 uint32_t readFill();
80 uint32_t parseFill(StringRef Tok);
81 void readSectionAddressType(OutputSection *Cmd);
82 OutputSection *readOutputSectionDescription(StringRef OutSec);
83 std::vector<StringRef> readOutputSectionPhdrs();
84 InputSectionDescription *readInputSectionDescription(StringRef Tok);
85 StringMatcher readFilePatterns();
86 std::vector<SectionPattern> readInputSectionsList();
87 InputSectionDescription *readInputSectionRules(StringRef FilePattern);
88 unsigned readPhdrType();
89 SortSectionPolicy readSortKind();
90 SymbolAssignment *readProvideHidden(bool Provide, bool Hidden);
91 SymbolAssignment *readProvideOrAssignment(StringRef Tok);
92 void readSort();
93 AssertCommand *readAssert();
94 Expr readAssertExpr();
95 Expr readConstant();
96 Expr getPageSize();
97
98 uint64_t readMemoryAssignment(StringRef, StringRef, StringRef);
99 std::pair<uint32_t, uint32_t> readMemoryAttributes();
100
101 Expr readExpr();
102 Expr readExpr1(Expr Lhs, int MinPrec);
103 StringRef readParenLiteral();
104 Expr readPrimary();
105 Expr readTernary(Expr Cond);
106 Expr readParenExpr();
107
108 // For parsing version script.
109 std::vector<SymbolVersion> readVersionExtern();
110 void readAnonymousDeclaration();
111 void readVersionDeclaration(StringRef VerStr);
112
113 std::pair<std::vector<SymbolVersion>, std::vector<SymbolVersion>>
114 readSymbols();
115
116 // True if a script being read is in a subdirectory specified by -sysroot.
117 bool IsUnderSysroot;
118
119 // A set to detect an INCLUDE() cycle.
120 StringSet<> Seen;
121};
122} // namespace
123
124static StringRef unquote(StringRef S) {
125 if (S.startswith("\""))
126 return S.substr(1, S.size() - 2);
127 return S;
128}
129
130static bool isUnderSysroot(StringRef Path) {
131 if (Config->Sysroot == "")
132 return false;
133 for (; !Path.empty(); Path = sys::path::parent_path(Path))
134 if (sys::fs::equivalent(Config->Sysroot, Path))
135 return true;
136 return false;
137}
138
139// Some operations only support one non absolute value. Move the
140// absolute one to the right hand side for convenience.
141static void moveAbsRight(ExprValue &A, ExprValue &B) {
142 if (A.Sec == nullptr || (A.ForceAbsolute && !B.isAbsolute()))
143 std::swap(A, B);
144 if (!B.isAbsolute())
145 error(A.Loc + ": at least one side of the expression must be absolute");
146}
147
148static ExprValue add(ExprValue A, ExprValue B) {
149 moveAbsRight(A, B);
150 return {A.Sec, A.ForceAbsolute, A.getSectionOffset() + B.getValue(), A.Loc};
151}
152
153static ExprValue sub(ExprValue A, ExprValue B) {
154 return {A.Sec, false, A.getSectionOffset() - B.getValue(), A.Loc};
155}
156
157static ExprValue mul(ExprValue A, ExprValue B) {
158 return A.getValue() * B.getValue();
159}
160
161static ExprValue div(ExprValue A, ExprValue B) {
162 if (uint64_t BV = B.getValue())
163 return A.getValue() / BV;
164 error("division by zero");
165 return 0;
166}
167
168static ExprValue bitAnd(ExprValue A, ExprValue B) {
169 moveAbsRight(A, B);
170 return {A.Sec, A.ForceAbsolute,
171 (A.getValue() & B.getValue()) - A.getSecAddr(), A.Loc};
172}
173
174static ExprValue bitOr(ExprValue A, ExprValue B) {
175 moveAbsRight(A, B);
176 return {A.Sec, A.ForceAbsolute,
177 (A.getValue() | B.getValue()) - A.getSecAddr(), A.Loc};
178}
179
180void ScriptParser::readDynamicList() {
181 Config->HasDynamicList = true;
182 expect("{");
183 std::vector<SymbolVersion> Locals;
184 std::vector<SymbolVersion> Globals;
185 std::tie(Locals, Globals) = readSymbols();
186 expect(";");
187
188 if (!atEOF()) {
189 setError("EOF expected, but got " + next());
190 return;
191 }
192 if (!Locals.empty()) {
193 setError("\"local:\" scope not supported in --dynamic-list");
194 return;
195 }
196
197 for (SymbolVersion V : Globals)
198 Config->DynamicList.push_back(V);
199}
200
201void ScriptParser::readVersionScript() {
202 readVersionScriptCommand();
203 if (!atEOF())
204 setError("EOF expected, but got " + next());
205}
206
207void ScriptParser::readVersionScriptCommand() {
208 if (consume("{")) {
209 readAnonymousDeclaration();
210 return;
211 }
212
213 while (!atEOF() && !errorCount() && peek() != "}") {
214 StringRef VerStr = next();
215 if (VerStr == "{") {
216 setError("anonymous version definition is used in "
217 "combination with other version definitions");
218 return;
219 }
220 expect("{");
221 readVersionDeclaration(VerStr);
222 }
223}
224
225void ScriptParser::readVersion() {
226 expect("{");
227 readVersionScriptCommand();
228 expect("}");
229}
230
231void ScriptParser::readLinkerScript() {
232 while (!atEOF()) {
233 StringRef Tok = next();
234 if (Tok == ";")
235 continue;
236
237 if (Tok == "ASSERT") {
238 Script->SectionCommands.push_back(readAssert());
239 } else if (Tok == "ENTRY") {
240 readEntry();
241 } else if (Tok == "EXTERN") {
242 readExtern();
243 } else if (Tok == "GROUP" || Tok == "INPUT") {
244 readGroup();
245 } else if (Tok == "INCLUDE") {
246 readInclude();
247 } else if (Tok == "MEMORY") {
248 readMemory();
249 } else if (Tok == "OUTPUT") {
250 readOutput();
251 } else if (Tok == "OUTPUT_ARCH") {
252 readOutputArch();
253 } else if (Tok == "OUTPUT_FORMAT") {
254 readOutputFormat();
255 } else if (Tok == "PHDRS") {
256 readPhdrs();
257 } else if (Tok == "REGION_ALIAS") {
258 readRegionAlias();
259 } else if (Tok == "SEARCH_DIR") {
260 readSearchDir();
261 } else if (Tok == "SECTIONS") {
262 readSections();
263 } else if (Tok == "VERSION") {
264 readVersion();
265 } else if (SymbolAssignment *Cmd = readProvideOrAssignment(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 expect("(");
337 while (!errorCount() && !consume(")")) {
338 if (consume("AS_NEEDED"))
339 readAsNeeded();
340 else
341 addFile(unquote(next()));
342 }
343}
344
345void ScriptParser::readInclude() {
346 StringRef Tok = unquote(next());
347
348 if (!Seen.insert(Tok).second) {
349 setError("there is a cycle in linker script INCLUDEs");
350 return;
351 }
352
353 if (Optional<std::string> Path = searchLinkerScript(Tok)) {
354 if (Optional<MemoryBufferRef> MB = readFile(*Path))
355 tokenize(*MB);
356 return;
357 }
358 setError("cannot find linker script " + Tok);
359}
360
361void ScriptParser::readOutput() {
362 // -o <file> takes predecence over OUTPUT(<file>).
363 expect("(");
364 StringRef Tok = next();
365 if (Config->OutputFile.empty())
366 Config->OutputFile = unquote(Tok);
367 expect(")");
368}
369
370void ScriptParser::readOutputArch() {
371 // OUTPUT_ARCH is ignored for now.
372 expect("(");
373 while (!errorCount() && !consume(")"))
374 skip();
375}
376
377void ScriptParser::readOutputFormat() {
378 // Error checking only for now.
379 expect("(");
380 skip();
381 if (consume(")"))
382 return;
383 expect(",");
384 skip();
385 expect(",");
386 skip();
387 expect(")");
388}
389
390void ScriptParser::readPhdrs() {
391 expect("{");
392
393 while (!errorCount() && !consume("}")) {
394 PhdrsCommand Cmd;
395 Cmd.Name = next();
396 Cmd.Type = readPhdrType();
397
398 while (!errorCount() && !consume(";")) {
399 if (consume("FILEHDR"))
400 Cmd.HasFilehdr = true;
401 else if (consume("PHDRS"))
402 Cmd.HasPhdrs = true;
403 else if (consume("AT"))
404 Cmd.LMAExpr = readParenExpr();
405 else if (consume("FLAGS"))
406 Cmd.Flags = readParenExpr()().getValue();
407 else
408 setError("unexpected header attribute: " + next());
409 }
410
411 Script->PhdrsCommands.push_back(Cmd);
412 }
413}
414
415void ScriptParser::readRegionAlias() {
416 expect("(");
417 StringRef Alias = unquote(next());
418 expect(",");
419 StringRef Name = next();
420 expect(")");
421
422 if (Script->MemoryRegions.count(Alias))
423 setError("redefinition of memory region '" + Alias + "'");
424 if (!Script->MemoryRegions.count(Name))
425 setError("memory region '" + Name + "' is not defined");
426 Script->MemoryRegions.insert({Alias, Script->MemoryRegions[Name]});
427}
428
429void ScriptParser::readSearchDir() {
430 expect("(");
431 StringRef Tok = next();
432 if (!Config->Nostdlib)
433 Config->SearchPaths.push_back(unquote(Tok));
434 expect(")");
435}
436
437void ScriptParser::readSections() {
438 Script->HasSectionsCommand = true;
439
440 // -no-rosegment is used to avoid placing read only non-executable sections in
441 // their own segment. We do the same if SECTIONS command is present in linker
442 // script. See comment for computeFlags().
443 Config->SingleRoRx = true;
444
445 expect("{");
446 while (!errorCount() && !consume("}")) {
1
Assuming the condition is true
2
Assuming the condition is true
3
Loop condition is true. Entering loop body
7
Assuming the condition is true
8
Assuming the condition is true
9
Loop condition is true. Entering loop body
13
Assuming the condition is true
14
Assuming the condition is true
15
Loop condition is true. Entering loop body
19
Assuming the condition is true
20
Assuming the condition is true
21
Loop condition is true. Entering loop body
447 StringRef Tok = next();
448 BaseCommand *Cmd = readProvideOrAssignment(Tok);
449 if (!Cmd) {
4
Taking true branch
10
Taking true branch
16
Taking true branch
22
Taking true branch
450 if (Tok == "ASSERT")
5
Assuming the condition is false
6
Taking false branch
11
Assuming the condition is false
12
Taking false branch
17
Assuming the condition is false
18
Taking false branch
23
Assuming the condition is false
24
Taking false branch
451 Cmd = readAssert();
452 else
453 Cmd = readOutputSectionDescription(Tok);
25
Calling 'ScriptParser::readOutputSectionDescription'
454 }
455 Script->SectionCommands.push_back(Cmd);
456 }
457}
458
459static int precedence(StringRef Op) {
460 return StringSwitch<int>(Op)
461 .Cases("*", "/", 5)
462 .Cases("+", "-", 4)
463 .Cases("<<", ">>", 3)
464 .Cases("<", "<=", ">", ">=", "==", "!=", 2)
465 .Cases("&", "|", 1)
466 .Default(-1);
467}
468
469StringMatcher ScriptParser::readFilePatterns() {
470 std::vector<StringRef> V;
471 while (!errorCount() && !consume(")"))
472 V.push_back(next());
473 return StringMatcher(V);
474}
475
476SortSectionPolicy ScriptParser::readSortKind() {
477 if (consume("SORT") || consume("SORT_BY_NAME"))
478 return SortSectionPolicy::Name;
479 if (consume("SORT_BY_ALIGNMENT"))
480 return SortSectionPolicy::Alignment;
481 if (consume("SORT_BY_INIT_PRIORITY"))
482 return SortSectionPolicy::Priority;
483 if (consume("SORT_NONE"))
484 return SortSectionPolicy::None;
485 return SortSectionPolicy::Default;
486}
487
488// Reads SECTIONS command contents in the following form:
489//
490// <contents> ::= <elem>*
491// <elem> ::= <exclude>? <glob-pattern>
492// <exclude> ::= "EXCLUDE_FILE" "(" <glob-pattern>+ ")"
493//
494// For example,
495//
496// *(.foo EXCLUDE_FILE (a.o) .bar EXCLUDE_FILE (b.o) .baz)
497//
498// is parsed as ".foo", ".bar" with "a.o", and ".baz" with "b.o".
499// The semantics of that is section .foo in any file, section .bar in
500// any file but a.o, and section .baz in any file but b.o.
501std::vector<SectionPattern> ScriptParser::readInputSectionsList() {
502 std::vector<SectionPattern> Ret;
503 while (!errorCount() && peek() != ")") {
504 StringMatcher ExcludeFilePat;
505 if (consume("EXCLUDE_FILE")) {
506 expect("(");
507 ExcludeFilePat = readFilePatterns();
508 }
509
510 std::vector<StringRef> V;
511 while (!errorCount() && peek() != ")" && peek() != "EXCLUDE_FILE")
512 V.push_back(next());
513
514 if (!V.empty())
515 Ret.push_back({std::move(ExcludeFilePat), StringMatcher(V)});
516 else
517 setError("section pattern is expected");
518 }
519 return Ret;
520}
521
522// Reads contents of "SECTIONS" directive. That directive contains a
523// list of glob patterns for input sections. The grammar is as follows.
524//
525// <patterns> ::= <section-list>
526// | <sort> "(" <section-list> ")"
527// | <sort> "(" <sort> "(" <section-list> ")" ")"
528//
529// <sort> ::= "SORT" | "SORT_BY_NAME" | "SORT_BY_ALIGNMENT"
530// | "SORT_BY_INIT_PRIORITY" | "SORT_NONE"
531//
532// <section-list> is parsed by readInputSectionsList().
533InputSectionDescription *
534ScriptParser::readInputSectionRules(StringRef FilePattern) {
535 auto *Cmd = make<InputSectionDescription>(FilePattern);
536 expect("(");
537
538 while (!errorCount() && !consume(")")) {
539 SortSectionPolicy Outer = readSortKind();
540 SortSectionPolicy Inner = SortSectionPolicy::Default;
541 std::vector<SectionPattern> V;
542 if (Outer != SortSectionPolicy::Default) {
543 expect("(");
544 Inner = readSortKind();
545 if (Inner != SortSectionPolicy::Default) {
546 expect("(");
547 V = readInputSectionsList();
548 expect(")");
549 } else {
550 V = readInputSectionsList();
551 }
552 expect(")");
553 } else {
554 V = readInputSectionsList();
555 }
556
557 for (SectionPattern &Pat : V) {
558 Pat.SortInner = Inner;
559 Pat.SortOuter = Outer;
560 }
561
562 std::move(V.begin(), V.end(), std::back_inserter(Cmd->SectionPatterns));
563 }
564 return Cmd;
565}
566
567InputSectionDescription *
568ScriptParser::readInputSectionDescription(StringRef Tok) {
569 // Input section wildcard can be surrounded by KEEP.
570 // https://sourceware.org/binutils/docs/ld/Input-Section-Keep.html#Input-Section-Keep
571 if (Tok == "KEEP") {
572 expect("(");
573 StringRef FilePattern = next();
574 InputSectionDescription *Cmd = readInputSectionRules(FilePattern);
575 expect(")");
576 Script->KeptSections.push_back(Cmd);
577 return Cmd;
578 }
579 return readInputSectionRules(Tok);
580}
581
582void ScriptParser::readSort() {
583 expect("(");
584 expect("CONSTRUCTORS");
585 expect(")");
586}
587
588AssertCommand *ScriptParser::readAssert() {
589 return make<AssertCommand>(readAssertExpr());
590}
591
592Expr ScriptParser::readAssertExpr() {
593 expect("(");
594 Expr E = readExpr();
595 expect(",");
596 StringRef Msg = unquote(next());
597 expect(")");
598
599 return [=] {
600 if (!E().getValue())
601 error(Msg);
602 return Script->getDot();
603 };
604}
605
606// Reads a FILL(expr) command. We handle the FILL command as an
607// alias for =fillexp section attribute, which is different from
608// what GNU linkers do.
609// https://sourceware.org/binutils/docs/ld/Output-Section-Data.html
610uint32_t ScriptParser::readFill() {
611 expect("(");
612 uint32_t V = parseFill(next());
613 expect(")");
614 return V;
615}
616
617// Reads an expression and/or the special directive "(NOLOAD)" for an
618// output section definition.
619//
620// An output section name can be followed by an address expression
621// and/or by "(NOLOAD)". This grammar is not LL(1) because "(" can be
622// interpreted as either the beginning of some expression or "(NOLOAD)".
623//
624// https://sourceware.org/binutils/docs/ld/Output-Section-Address.html
625// https://sourceware.org/binutils/docs/ld/Output-Section-Type.html
626void ScriptParser::readSectionAddressType(OutputSection *Cmd) {
627 if (consume("(")) {
628 if (consume("NOLOAD")) {
629 expect(")");
630 Cmd->Noload = true;
631 return;
632 }
633 Cmd->AddrExpr = readExpr();
634 expect(")");
635 } else {
636 Cmd->AddrExpr = readExpr();
637 }
638
639 if (consume("(")) {
640 expect("NOLOAD");
641 expect(")");
642 Cmd->Noload = true;
643 }
644}
645
646static Expr checkAlignment(Expr E, std::string &Loc) {
647 return [=] {
648 uint64_t Alignment = std::max((uint64_t)1, E().getValue());
649 if (!isPowerOf2_64(Alignment)) {
650 error(Loc + ": alignment must be power of 2");
651 return (uint64_t)1; // Return a dummy value.
652 }
653 return Alignment;
654 };
655}
656
657OutputSection *ScriptParser::readOutputSectionDescription(StringRef OutSec) {
658 OutputSection *Cmd =
659 Script->createOutputSection(OutSec, getCurrentLocation());
660
661 if (peek() != ":")
26
Taking false branch
662 readSectionAddressType(Cmd);
663 expect(":");
664
665 std::string Location = getCurrentLocation();
666 if (consume("AT"))
27
Assuming the condition is false
28
Taking false branch
667 Cmd->LMAExpr = readParenExpr();
668 if (consume("ALIGN"))
29
Assuming the condition is false
30
Taking false branch
669 Cmd->AlignExpr = checkAlignment(readParenExpr(), Location);
670 if (consume("SUBALIGN"))
31
Assuming the condition is false
32
Taking false branch
671 Cmd->SubalignExpr = checkAlignment(readParenExpr(), Location);
672
673 // Parse constraints.
674 if (consume("ONLY_IF_RO"))
33
Assuming the condition is false
34
Taking false branch
675 Cmd->Constraint = ConstraintKind::ReadOnly;
676 if (consume("ONLY_IF_RW"))
35
Assuming the condition is false
36
Taking false branch
677 Cmd->Constraint = ConstraintKind::ReadWrite;
678 expect("{");
679
680 while (!errorCount() && !consume("}")) {
37
Assuming the condition is false
38
Loop condition is false. Execution continues on line 706
681 StringRef Tok = next();
682 if (Tok == ";") {
683 // Empty commands are allowed. Do nothing here.
684 } else if (SymbolAssignment *Assign = readProvideOrAssignment(Tok)) {
685 Cmd->SectionCommands.push_back(Assign);
686 } else if (ByteCommand *Data = readByteCommand(Tok)) {
687 Cmd->SectionCommands.push_back(Data);
688 } else if (Tok == "ASSERT") {
689 Cmd->SectionCommands.push_back(readAssert());
690 expect(";");
691 } else if (Tok == "CONSTRUCTORS") {
692 // CONSTRUCTORS is a keyword to make the linker recognize C++ ctors/dtors
693 // by name. This is for very old file formats such as ECOFF/XCOFF.
694 // For ELF, we should ignore.
695 } else if (Tok == "FILL") {
696 Cmd->Filler = readFill();
697 } else if (Tok == "SORT") {
698 readSort();
699 } else if (peek() == "(") {
700 Cmd->SectionCommands.push_back(readInputSectionDescription(Tok));
701 } else {
702 setError("unknown command " + Tok);
703 }
704 }
705
706 if (consume(">"))
39
Assuming the condition is false
40
Taking false branch
707 Cmd->MemoryRegionName = next();
708 else if (peek().startswith(">"))
41
Assuming the condition is false
42
Taking false branch
709 Cmd->MemoryRegionName = next().drop_front();
710
711 Cmd->Phdrs = readOutputSectionPhdrs();
712
713 if (consume("="))
43
Assuming the condition is true
44
Taking true branch
714 Cmd->Filler = parseFill(next());
45
Calling 'ScriptParser::parseFill'
715 else if (peek().startswith("="))
716 Cmd->Filler = parseFill(next().drop_front());
717
718 // Consume optional comma following output section command.
719 consume(",");
720
721 return Cmd;
722}
723
724// Parses a given string as a octal/decimal/hexadecimal number and
725// returns it as a big-endian number. Used for `=<fillexp>`.
726// https://sourceware.org/binutils/docs/ld/Output-Section-Fill.html
727//
728// When reading a hexstring, ld.bfd handles it as a blob of arbitrary
729// size, while ld.gold always handles it as a 32-bit big-endian number.
730// We are compatible with ld.gold because it's easier to implement.
731uint32_t ScriptParser::parseFill(StringRef Tok) {
732 uint32_t V = 0;
733 if (!to_integer(Tok, V))
46
Taking false branch
734 setError("invalid filler expression: " + Tok);
735
736 uint32_t Buf;
47
'Buf' declared without an initial value
737 write32be(&Buf, V);
48
Calling 'write32be'
62
Returning from 'write32be'
738 return Buf;
63
Undefined or garbage value returned to caller
739}
740
741SymbolAssignment *ScriptParser::readProvideHidden(bool Provide, bool Hidden) {
742 expect("(");
743 SymbolAssignment *Cmd = readAssignment(next());
744 Cmd->Provide = Provide;
745 Cmd->Hidden = Hidden;
746 expect(")");
747 expect(";");
748 return Cmd;
749}
750
751SymbolAssignment *ScriptParser::readProvideOrAssignment(StringRef Tok) {
752 SymbolAssignment *Cmd = nullptr;
753 if (peek() == "=" || peek() == "+=") {
754 Cmd = readAssignment(Tok);
755 expect(";");
756 } else if (Tok == "PROVIDE") {
757 Cmd = readProvideHidden(true, false);
758 } else if (Tok == "HIDDEN") {
759 Cmd = readProvideHidden(false, true);
760 } else if (Tok == "PROVIDE_HIDDEN") {
761 Cmd = readProvideHidden(true, true);
762 }
763 return Cmd;
764}
765
766SymbolAssignment *ScriptParser::readAssignment(StringRef Name) {
767 StringRef Op = next();
768 assert(Op == "=" || Op == "+=")(static_cast <bool> (Op == "=" || Op == "+=") ? void (0
) : __assert_fail ("Op == \"=\" || Op == \"+=\"", "/build/llvm-toolchain-snapshot-6.0~svn318882/tools/lld/ELF/ScriptParser.cpp"
, 768, __extension__ __PRETTY_FUNCTION__))
;
769 Expr E = readExpr();
770 if (Op == "+=") {
771 std::string Loc = getCurrentLocation();
772 E = [=] { return add(Script->getSymbolValue(Name, Loc), E()); };
773 }
774 return make<SymbolAssignment>(Name, E, getCurrentLocation());
775}
776
777// This is an operator-precedence parser to parse a linker
778// script expression.
779Expr ScriptParser::readExpr() {
780 // Our lexer is context-aware. Set the in-expression bit so that
781 // they apply different tokenization rules.
782 bool Orig = InExpr;
783 InExpr = true;
784 Expr E = readExpr1(readPrimary(), 0);
785 InExpr = Orig;
786 return E;
787}
788
789static Expr combine(StringRef Op, Expr L, Expr R) {
790 if (Op == "+")
791 return [=] { return add(L(), R()); };
792 if (Op == "-")
793 return [=] { return sub(L(), R()); };
794 if (Op == "*")
795 return [=] { return mul(L(), R()); };
796 if (Op == "/")
797 return [=] { return div(L(), R()); };
798 if (Op == "<<")
799 return [=] { return L().getValue() << R().getValue(); };
800 if (Op == ">>")
801 return [=] { return L().getValue() >> R().getValue(); };
802 if (Op == "<")
803 return [=] { return L().getValue() < R().getValue(); };
804 if (Op == ">")
805 return [=] { return L().getValue() > R().getValue(); };
806 if (Op == ">=")
807 return [=] { return L().getValue() >= R().getValue(); };
808 if (Op == "<=")
809 return [=] { return L().getValue() <= R().getValue(); };
810 if (Op == "==")
811 return [=] { return L().getValue() == R().getValue(); };
812 if (Op == "!=")
813 return [=] { return L().getValue() != R().getValue(); };
814 if (Op == "&")
815 return [=] { return bitAnd(L(), R()); };
816 if (Op == "|")
817 return [=] { return bitOr(L(), R()); };
818 llvm_unreachable("invalid operator")::llvm::llvm_unreachable_internal("invalid operator", "/build/llvm-toolchain-snapshot-6.0~svn318882/tools/lld/ELF/ScriptParser.cpp"
, 818)
;
819}
820
821// This is a part of the operator-precedence parser. This function
822// assumes that the remaining token stream starts with an operator.
823Expr ScriptParser::readExpr1(Expr Lhs, int MinPrec) {
824 while (!atEOF() && !errorCount()) {
825 // Read an operator and an expression.
826 if (consume("?"))
827 return readTernary(Lhs);
828 StringRef Op1 = peek();
829 if (precedence(Op1) < MinPrec)
830 break;
831 skip();
832 Expr Rhs = readPrimary();
833
834 // Evaluate the remaining part of the expression first if the
835 // next operator has greater precedence than the previous one.
836 // For example, if we have read "+" and "3", and if the next
837 // operator is "*", then we'll evaluate 3 * ... part first.
838 while (!atEOF()) {
839 StringRef Op2 = peek();
840 if (precedence(Op2) <= precedence(Op1))
841 break;
842 Rhs = readExpr1(Rhs, precedence(Op2));
843 }
844
845 Lhs = combine(Op1, Lhs, Rhs);
846 }
847 return Lhs;
848}
849
850Expr ScriptParser::getPageSize() {
851 std::string Location = getCurrentLocation();
852 return [=]() -> uint64_t {
853 if (Target)
854 return Target->PageSize;
855 error(Location + ": unable to calculate page size");
856 return 4096; // Return a dummy value.
857 };
858}
859
860Expr ScriptParser::readConstant() {
861 StringRef S = readParenLiteral();
862 if (S == "COMMONPAGESIZE")
863 return getPageSize();
864 if (S == "MAXPAGESIZE")
865 return [] { return Config->MaxPageSize; };
866 setError("unknown constant: " + S);
867 return {};
868}
869
870// Parses Tok as an integer. It recognizes hexadecimal (prefixed with
871// "0x" or suffixed with "H") and decimal numbers. Decimal numbers may
872// have "K" (Ki) or "M" (Mi) suffixes.
873static Optional<uint64_t> parseInt(StringRef Tok) {
874 // Negative number
875 if (Tok.startswith("-")) {
876 if (Optional<uint64_t> Val = parseInt(Tok.substr(1)))
877 return -*Val;
878 return None;
879 }
880
881 // Hexadecimal
882 uint64_t Val;
883 if (Tok.startswith_lower("0x")) {
884 if (!to_integer(Tok.substr(2), Val, 16))
885 return None;
886 return Val;
887 }
888 if (Tok.endswith_lower("H")) {
889 if (!to_integer(Tok.drop_back(), Val, 16))
890 return None;
891 return Val;
892 }
893
894 // Decimal
895 if (Tok.endswith_lower("K")) {
896 if (!to_integer(Tok.drop_back(), Val, 10))
897 return None;
898 return Val * 1024;
899 }
900 if (Tok.endswith_lower("M")) {
901 if (!to_integer(Tok.drop_back(), Val, 10))
902 return None;
903 return Val * 1024 * 1024;
904 }
905 if (!to_integer(Tok, Val, 10))
906 return None;
907 return Val;
908}
909
910ByteCommand *ScriptParser::readByteCommand(StringRef Tok) {
911 int Size = StringSwitch<int>(Tok)
912 .Case("BYTE", 1)
913 .Case("SHORT", 2)
914 .Case("LONG", 4)
915 .Case("QUAD", 8)
916 .Default(-1);
917 if (Size == -1)
918 return nullptr;
919 return make<ByteCommand>(readParenExpr(), Size);
920}
921
922StringRef ScriptParser::readParenLiteral() {
923 expect("(");
924 StringRef Tok = next();
925 expect(")");
926 return Tok;
927}
928
929static void checkIfExists(OutputSection *Cmd, StringRef Location) {
930 if (Cmd->Location.empty() && Script->ErrorOnMissingSection)
931 error(Location + ": undefined section " + Cmd->Name);
932}
933
934Expr ScriptParser::readPrimary() {
935 if (peek() == "(")
936 return readParenExpr();
937
938 if (consume("~")) {
939 Expr E = readPrimary();
940 return [=] { return ~E().getValue(); };
941 }
942 if (consume("!")) {
943 Expr E = readPrimary();
944 return [=] { return !E().getValue(); };
945 }
946 if (consume("-")) {
947 Expr E = readPrimary();
948 return [=] { return -E().getValue(); };
949 }
950
951 StringRef Tok = next();
952 std::string Location = getCurrentLocation();
953
954 // Built-in functions are parsed here.
955 // https://sourceware.org/binutils/docs/ld/Builtin-Functions.html.
956 if (Tok == "ABSOLUTE") {
957 Expr Inner = readParenExpr();
958 return [=] {
959 ExprValue I = Inner();
960 I.ForceAbsolute = true;
961 return I;
962 };
963 }
964 if (Tok == "ADDR") {
965 StringRef Name = readParenLiteral();
966 OutputSection *Sec = Script->getOrCreateOutputSection(Name);
967 return [=]() -> ExprValue {
968 checkIfExists(Sec, Location);
969 return {Sec, false, 0, Location};
970 };
971 }
972 if (Tok == "ALIGN") {
973 expect("(");
974 Expr E = readExpr();
975 if (consume(")")) {
976 E = checkAlignment(E, Location);
977 return [=] { return alignTo(Script->getDot(), E().getValue()); };
978 }
979 expect(",");
980 Expr E2 = checkAlignment(readExpr(), Location);
981 expect(")");
982 return [=] {
983 ExprValue V = E();
984 V.Alignment = E2().getValue();
985 return V;
986 };
987 }
988 if (Tok == "ALIGNOF") {
989 StringRef Name = readParenLiteral();
990 OutputSection *Cmd = Script->getOrCreateOutputSection(Name);
991 return [=] {
992 checkIfExists(Cmd, Location);
993 return Cmd->Alignment;
994 };
995 }
996 if (Tok == "ASSERT")
997 return readAssertExpr();
998 if (Tok == "CONSTANT")
999 return readConstant();
1000 if (Tok == "DATA_SEGMENT_ALIGN") {
1001 expect("(");
1002 Expr E = readExpr();
1003 expect(",");
1004 readExpr();
1005 expect(")");
1006 return [=] {
1007 return alignTo(Script->getDot(), std::max((uint64_t)1, E().getValue()));
1008 };
1009 }
1010 if (Tok == "DATA_SEGMENT_END") {
1011 expect("(");
1012 expect(".");
1013 expect(")");
1014 return [] { return Script->getDot(); };
1015 }
1016 if (Tok == "DATA_SEGMENT_RELRO_END") {
1017 // GNU linkers implements more complicated logic to handle
1018 // DATA_SEGMENT_RELRO_END. We instead ignore the arguments and
1019 // just align to the next page boundary for simplicity.
1020 expect("(");
1021 readExpr();
1022 expect(",");
1023 readExpr();
1024 expect(")");
1025 Expr E = getPageSize();
1026 return [=] { return alignTo(Script->getDot(), E().getValue()); };
1027 }
1028 if (Tok == "DEFINED") {
1029 StringRef Name = readParenLiteral();
1030 return [=] { return Symtab->find(Name) ? 1 : 0; };
1031 }
1032 if (Tok == "LENGTH") {
1033 StringRef Name = readParenLiteral();
1034 if (Script->MemoryRegions.count(Name) == 0)
1035 setError("memory region not defined: " + Name);
1036 return [=] { return Script->MemoryRegions[Name]->Length; };
1037 }
1038 if (Tok == "LOADADDR") {
1039 StringRef Name = readParenLiteral();
1040 OutputSection *Cmd = Script->getOrCreateOutputSection(Name);
1041 return [=] {
1042 checkIfExists(Cmd, Location);
1043 return Cmd->getLMA();
1044 };
1045 }
1046 if (Tok == "ORIGIN") {
1047 StringRef Name = readParenLiteral();
1048 if (Script->MemoryRegions.count(Name) == 0)
1049 setError("memory region not defined: " + Name);
1050 return [=] { return Script->MemoryRegions[Name]->Origin; };
1051 }
1052 if (Tok == "SEGMENT_START") {
1053 expect("(");
1054 skip();
1055 expect(",");
1056 Expr E = readExpr();
1057 expect(")");
1058 return [=] { return E(); };
1059 }
1060 if (Tok == "SIZEOF") {
1061 StringRef Name = readParenLiteral();
1062 OutputSection *Cmd = Script->getOrCreateOutputSection(Name);
1063 // Linker script does not create an output section if its content is empty.
1064 // We want to allow SIZEOF(.foo) where .foo is a section which happened to
1065 // be empty.
1066 return [=] { return Cmd->Size; };
1067 }
1068 if (Tok == "SIZEOF_HEADERS")
1069 return [=] { return elf::getHeaderSize(); };
1070
1071 // Tok is the dot.
1072 if (Tok == ".")
1073 return [=] { return Script->getSymbolValue(Tok, Location); };
1074
1075 // Tok is a literal number.
1076 if (Optional<uint64_t> Val = parseInt(Tok))
1077 return [=] { return *Val; };
1078
1079 // Tok is a symbol name.
1080 if (!isValidCIdentifier(Tok))
1081 setError("malformed number: " + Tok);
1082 Script->ReferencedSymbols.push_back(Tok);
1083 return [=] { return Script->getSymbolValue(Tok, Location); };
1084}
1085
1086Expr ScriptParser::readTernary(Expr Cond) {
1087 Expr L = readExpr();
1088 expect(":");
1089 Expr R = readExpr();
1090 return [=] { return Cond().getValue() ? L() : R(); };
1091}
1092
1093Expr ScriptParser::readParenExpr() {
1094 expect("(");
1095 Expr E = readExpr();
1096 expect(")");
1097 return E;
1098}
1099
1100std::vector<StringRef> ScriptParser::readOutputSectionPhdrs() {
1101 std::vector<StringRef> Phdrs;
1102 while (!errorCount() && peek().startswith(":")) {
1103 StringRef Tok = next();
1104 Phdrs.push_back((Tok.size() == 1) ? next() : Tok.substr(1));
1105 }
1106 return Phdrs;
1107}
1108
1109// Read a program header type name. The next token must be a
1110// name of a program header type or a constant (e.g. "0x3").
1111unsigned ScriptParser::readPhdrType() {
1112 StringRef Tok = next();
1113 if (Optional<uint64_t> Val = parseInt(Tok))
1114 return *Val;
1115
1116 unsigned Ret = StringSwitch<unsigned>(Tok)
1117 .Case("PT_NULL", PT_NULL)
1118 .Case("PT_LOAD", PT_LOAD)
1119 .Case("PT_DYNAMIC", PT_DYNAMIC)
1120 .Case("PT_INTERP", PT_INTERP)
1121 .Case("PT_NOTE", PT_NOTE)
1122 .Case("PT_SHLIB", PT_SHLIB)
1123 .Case("PT_PHDR", PT_PHDR)
1124 .Case("PT_TLS", PT_TLS)
1125 .Case("PT_GNU_EH_FRAME", PT_GNU_EH_FRAME)
1126 .Case("PT_GNU_STACK", PT_GNU_STACK)
1127 .Case("PT_GNU_RELRO", PT_GNU_RELRO)
1128 .Case("PT_OPENBSD_RANDOMIZE", PT_OPENBSD_RANDOMIZE)
1129 .Case("PT_OPENBSD_WXNEEDED", PT_OPENBSD_WXNEEDED)
1130 .Case("PT_OPENBSD_BOOTDATA", PT_OPENBSD_BOOTDATA)
1131 .Default(-1);
1132
1133 if (Ret == (unsigned)-1) {
1134 setError("invalid program header type: " + Tok);
1135 return PT_NULL;
1136 }
1137 return Ret;
1138}
1139
1140// Reads an anonymous version declaration.
1141void ScriptParser::readAnonymousDeclaration() {
1142 std::vector<SymbolVersion> Locals;
1143 std::vector<SymbolVersion> Globals;
1144 std::tie(Locals, Globals) = readSymbols();
1145
1146 for (SymbolVersion V : Locals) {
1147 if (V.Name == "*")
1148 Config->DefaultSymbolVersion = VER_NDX_LOCAL;
1149 else
1150 Config->VersionScriptLocals.push_back(V);
1151 }
1152
1153 for (SymbolVersion V : Globals)
1154 Config->VersionScriptGlobals.push_back(V);
1155
1156 expect(";");
1157}
1158
1159// Reads a non-anonymous version definition,
1160// e.g. "VerStr { global: foo; bar; local: *; };".
1161void ScriptParser::readVersionDeclaration(StringRef VerStr) {
1162 // Read a symbol list.
1163 std::vector<SymbolVersion> Locals;
1164 std::vector<SymbolVersion> Globals;
1165 std::tie(Locals, Globals) = readSymbols();
1166
1167 for (SymbolVersion V : Locals) {
1168 if (V.Name == "*")
1169 Config->DefaultSymbolVersion = VER_NDX_LOCAL;
1170 else
1171 Config->VersionScriptLocals.push_back(V);
1172 }
1173
1174 // Create a new version definition and add that to the global symbols.
1175 VersionDefinition Ver;
1176 Ver.Name = VerStr;
1177 Ver.Globals = Globals;
1178
1179 // User-defined version number starts from 2 because 0 and 1 are
1180 // reserved for VER_NDX_LOCAL and VER_NDX_GLOBAL, respectively.
1181 Ver.Id = Config->VersionDefinitions.size() + 2;
1182 Config->VersionDefinitions.push_back(Ver);
1183
1184 // Each version may have a parent version. For example, "Ver2"
1185 // defined as "Ver2 { global: foo; local: *; } Ver1;" has "Ver1"
1186 // as a parent. This version hierarchy is, probably against your
1187 // instinct, purely for hint; the runtime doesn't care about it
1188 // at all. In LLD, we simply ignore it.
1189 if (peek() != ";")
1190 skip();
1191 expect(";");
1192}
1193
1194static bool hasWildcard(StringRef S) {
1195 return S.find_first_of("?*[") != StringRef::npos;
1196}
1197
1198// Reads a list of symbols, e.g. "{ global: foo; bar; local: *; };".
1199std::pair<std::vector<SymbolVersion>, std::vector<SymbolVersion>>
1200ScriptParser::readSymbols() {
1201 std::vector<SymbolVersion> Locals;
1202 std::vector<SymbolVersion> Globals;
1203 std::vector<SymbolVersion> *V = &Globals;
1204
1205 while (!errorCount()) {
1206 if (consume("}"))
1207 break;
1208 if (consumeLabel("local")) {
1209 V = &Locals;
1210 continue;
1211 }
1212 if (consumeLabel("global")) {
1213 V = &Globals;
1214 continue;
1215 }
1216
1217 if (consume("extern")) {
1218 std::vector<SymbolVersion> Ext = readVersionExtern();
1219 V->insert(V->end(), Ext.begin(), Ext.end());
1220 } else {
1221 StringRef Tok = next();
1222 V->push_back({unquote(Tok), false, hasWildcard(Tok)});
1223 }
1224 expect(";");
1225 }
1226 return {Locals, Globals};
1227}
1228
1229// Reads an "extern C++" directive, e.g.,
1230// "extern "C++" { ns::*; "f(int, double)"; };"
1231std::vector<SymbolVersion> ScriptParser::readVersionExtern() {
1232 StringRef Tok = next();
1233 bool IsCXX = Tok == "\"C++\"";
1234 if (!IsCXX && Tok != "\"C\"")
1235 setError("Unknown language");
1236 expect("{");
1237
1238 std::vector<SymbolVersion> Ret;
1239 while (!errorCount() && peek() != "}") {
1240 StringRef Tok = next();
1241 bool HasWildcard = !Tok.startswith("\"") && hasWildcard(Tok);
1242 Ret.push_back({unquote(Tok), IsCXX, HasWildcard});
1243 expect(";");
1244 }
1245
1246 expect("}");
1247 return Ret;
1248}
1249
1250uint64_t ScriptParser::readMemoryAssignment(StringRef S1, StringRef S2,
1251 StringRef S3) {
1252 if (!consume(S1) && !consume(S2) && !consume(S3)) {
1253 setError("expected one of: " + S1 + ", " + S2 + ", or " + S3);
1254 return 0;
1255 }
1256 expect("=");
1257 return readExpr()().getValue();
1258}
1259
1260// Parse the MEMORY command as specified in:
1261// https://sourceware.org/binutils/docs/ld/MEMORY.html
1262//
1263// MEMORY { name [(attr)] : ORIGIN = origin, LENGTH = len ... }
1264void ScriptParser::readMemory() {
1265 expect("{");
1266 while (!errorCount() && !consume("}")) {
1267 StringRef Name = next();
1268
1269 uint32_t Flags = 0;
1270 uint32_t NegFlags = 0;
1271 if (consume("(")) {
1272 std::tie(Flags, NegFlags) = readMemoryAttributes();
1273 expect(")");
1274 }
1275 expect(":");
1276
1277 uint64_t Origin = readMemoryAssignment("ORIGIN", "org", "o");
1278 expect(",");
1279 uint64_t Length = readMemoryAssignment("LENGTH", "len", "l");
1280
1281 // Add the memory region to the region map.
1282 if (Script->MemoryRegions.count(Name))
1283 setError("region '" + Name + "' already defined");
1284 MemoryRegion *MR = make<MemoryRegion>();
1285 *MR = {Name, Origin, Length, Flags, NegFlags};
1286 Script->MemoryRegions[Name] = MR;
1287 }
1288}
1289
1290// This function parses the attributes used to match against section
1291// flags when placing output sections in a memory region. These flags
1292// are only used when an explicit memory region name is not used.
1293std::pair<uint32_t, uint32_t> ScriptParser::readMemoryAttributes() {
1294 uint32_t Flags = 0;
1295 uint32_t NegFlags = 0;
1296 bool Invert = false;
1297
1298 for (char C : next().lower()) {
1299 uint32_t Flag = 0;
1300 if (C == '!')
1301 Invert = !Invert;
1302 else if (C == 'w')
1303 Flag = SHF_WRITE;
1304 else if (C == 'x')
1305 Flag = SHF_EXECINSTR;
1306 else if (C == 'a')
1307 Flag = SHF_ALLOC;
1308 else if (C != 'r')
1309 setError("invalid memory region attribute");
1310
1311 if (Invert)
1312 NegFlags |= Flag;
1313 else
1314 Flags |= Flag;
1315 }
1316 return {Flags, NegFlags};
1317}
1318
1319void elf::readLinkerScript(MemoryBufferRef MB) {
1320 ScriptParser(MB).readLinkerScript();
1321}
1322
1323void elf::readVersionScript(MemoryBufferRef MB) {
1324 ScriptParser(MB).readVersionScript();
1325}
1326
1327void elf::readDynamicList(MemoryBufferRef MB) {
1328 ScriptParser(MB).readDynamicList();
1329}
1330
1331void elf::readDefsym(StringRef Name, MemoryBufferRef MB) {
1332 ScriptParser(MB).readDefsym(Name);
1333}

/build/llvm-toolchain-snapshot-6.0~svn318882/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/// \brief ::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()))
55
Assuming 'endian' is equal to native
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);
54
Calling 'byte_swap'
56
Returning from 'byte_swap'
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);
53
Calling 'write'
57
Returning from 'write'
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)(static_cast <bool> (startBit < 8) ? void (0) : __assert_fail
("startBit < 8", "/build/llvm-toolchain-snapshot-6.0~svn318882/include/llvm/Support/Endian.h"
, 121, __extension__ __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)(static_cast <bool> (startBit < 8) ? void (0) : __assert_fail
("startBit < 8", "/build/llvm-toolchain-snapshot-6.0~svn318882/include/llvm/Support/Endian.h"
, 156, __extension__ __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>(
52
Calling 'write'
58
Returning from 'write'
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;
51
Calling 'packed_endian_specific_integral::operator='
59
Returning from 'packed_endian_specific_integral::operator='
381}
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);
50
Calling 'write'
60
Returning from 'write'
398}
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); }
49
Calling 'write32'
61
Returning from 'write32'
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