LLVM 17.0.0git
ELFAsmParser.cpp
Go to the documentation of this file.
1//===- ELFAsmParser.cpp - ELF Assembly Parser -----------------------------===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8
12#include "llvm/MC/MCAsmInfo.h"
13#include "llvm/MC/MCContext.h"
19#include "llvm/MC/MCStreamer.h"
20#include "llvm/MC/MCSymbol.h"
21#include "llvm/MC/MCSymbolELF.h"
22#include "llvm/MC/SectionKind.h"
25#include "llvm/Support/SMLoc.h"
26#include <cassert>
27#include <cstdint>
28#include <utility>
29
30using namespace llvm;
31
32namespace {
33
34class ELFAsmParser : public MCAsmParserExtension {
35 template<bool (ELFAsmParser::*HandlerMethod)(StringRef, SMLoc)>
36 void addDirectiveHandler(StringRef Directive) {
37 MCAsmParser::ExtensionDirectiveHandler Handler = std::make_pair(
38 this, HandleDirective<ELFAsmParser, HandlerMethod>);
39
41 }
42
43 bool ParseSectionSwitch(StringRef Section, unsigned Type, unsigned Flags,
44 SectionKind Kind);
45
46public:
47 ELFAsmParser() { BracketExpressionsSupported = true; }
48
49 void Initialize(MCAsmParser &Parser) override {
50 // Call the base implementation.
52
53 addDirectiveHandler<&ELFAsmParser::ParseSectionDirectiveData>(".data");
54 addDirectiveHandler<&ELFAsmParser::ParseSectionDirectiveText>(".text");
55 addDirectiveHandler<&ELFAsmParser::ParseSectionDirectiveBSS>(".bss");
56 addDirectiveHandler<&ELFAsmParser::ParseSectionDirectiveRoData>(".rodata");
57 addDirectiveHandler<&ELFAsmParser::ParseSectionDirectiveTData>(".tdata");
58 addDirectiveHandler<&ELFAsmParser::ParseSectionDirectiveTBSS>(".tbss");
59 addDirectiveHandler<
60 &ELFAsmParser::ParseSectionDirectiveDataRel>(".data.rel");
61 addDirectiveHandler<
62 &ELFAsmParser::ParseSectionDirectiveDataRelRo>(".data.rel.ro");
63 addDirectiveHandler<
64 &ELFAsmParser::ParseSectionDirectiveEhFrame>(".eh_frame");
65 addDirectiveHandler<&ELFAsmParser::ParseDirectiveSection>(".section");
66 addDirectiveHandler<
67 &ELFAsmParser::ParseDirectivePushSection>(".pushsection");
68 addDirectiveHandler<&ELFAsmParser::ParseDirectivePopSection>(".popsection");
69 addDirectiveHandler<&ELFAsmParser::ParseDirectiveSize>(".size");
70 addDirectiveHandler<&ELFAsmParser::ParseDirectivePrevious>(".previous");
71 addDirectiveHandler<&ELFAsmParser::ParseDirectiveType>(".type");
72 addDirectiveHandler<&ELFAsmParser::ParseDirectiveIdent>(".ident");
73 addDirectiveHandler<&ELFAsmParser::ParseDirectiveSymver>(".symver");
74 addDirectiveHandler<&ELFAsmParser::ParseDirectiveVersion>(".version");
75 addDirectiveHandler<&ELFAsmParser::ParseDirectiveWeakref>(".weakref");
76 addDirectiveHandler<&ELFAsmParser::ParseDirectiveSymbolAttribute>(".weak");
77 addDirectiveHandler<&ELFAsmParser::ParseDirectiveSymbolAttribute>(".local");
78 addDirectiveHandler<
79 &ELFAsmParser::ParseDirectiveSymbolAttribute>(".protected");
80 addDirectiveHandler<
81 &ELFAsmParser::ParseDirectiveSymbolAttribute>(".internal");
82 addDirectiveHandler<
83 &ELFAsmParser::ParseDirectiveSymbolAttribute>(".hidden");
84 addDirectiveHandler<&ELFAsmParser::ParseDirectiveSubsection>(".subsection");
85 addDirectiveHandler<&ELFAsmParser::ParseDirectiveCGProfile>(".cg_profile");
86 }
87
88 // FIXME: Part of this logic is duplicated in the MCELFStreamer. What is
89 // the best way for us to get access to it?
90 bool ParseSectionDirectiveData(StringRef, SMLoc) {
91 return ParseSectionSwitch(".data", ELF::SHT_PROGBITS,
94 }
95 bool ParseSectionDirectiveText(StringRef, SMLoc) {
96 return ParseSectionSwitch(".text", ELF::SHT_PROGBITS,
99 }
100 bool ParseSectionDirectiveBSS(StringRef, SMLoc) {
101 return ParseSectionSwitch(".bss", ELF::SHT_NOBITS,
104 }
105 bool ParseSectionDirectiveRoData(StringRef, SMLoc) {
106 return ParseSectionSwitch(".rodata", ELF::SHT_PROGBITS,
109 }
110 bool ParseSectionDirectiveTData(StringRef, SMLoc) {
111 return ParseSectionSwitch(".tdata", ELF::SHT_PROGBITS,
115 }
116 bool ParseSectionDirectiveTBSS(StringRef, SMLoc) {
117 return ParseSectionSwitch(".tbss", ELF::SHT_NOBITS,
121 }
122 bool ParseSectionDirectiveDataRel(StringRef, SMLoc) {
123 return ParseSectionSwitch(".data.rel", ELF::SHT_PROGBITS,
126 }
127 bool ParseSectionDirectiveDataRelRo(StringRef, SMLoc) {
128 return ParseSectionSwitch(".data.rel.ro", ELF::SHT_PROGBITS,
132 }
133 bool ParseSectionDirectiveEhFrame(StringRef, SMLoc) {
134 return ParseSectionSwitch(".eh_frame", ELF::SHT_PROGBITS,
137 }
138 bool ParseDirectivePushSection(StringRef, SMLoc);
139 bool ParseDirectivePopSection(StringRef, SMLoc);
140 bool ParseDirectiveSection(StringRef, SMLoc);
141 bool ParseDirectiveSize(StringRef, SMLoc);
142 bool ParseDirectivePrevious(StringRef, SMLoc);
143 bool ParseDirectiveType(StringRef, SMLoc);
144 bool ParseDirectiveIdent(StringRef, SMLoc);
145 bool ParseDirectiveSymver(StringRef, SMLoc);
146 bool ParseDirectiveVersion(StringRef, SMLoc);
147 bool ParseDirectiveWeakref(StringRef, SMLoc);
148 bool ParseDirectiveSymbolAttribute(StringRef, SMLoc);
149 bool ParseDirectiveSubsection(StringRef, SMLoc);
151
152private:
153 bool ParseSectionName(StringRef &SectionName);
154 bool ParseSectionArguments(bool IsPush, SMLoc loc);
155 unsigned parseSunStyleSectionFlags();
156 bool maybeParseSectionType(StringRef &TypeName);
157 bool parseMergeSize(int64_t &Size);
158 bool parseGroup(StringRef &GroupName, bool &IsComdat);
159 bool parseLinkedToSym(MCSymbolELF *&LinkedToSym);
160 bool maybeParseUniqueID(int64_t &UniqueID);
161};
162
163} // end anonymous namespace
164
165/// ParseDirectiveSymbolAttribute
166/// ::= { ".local", ".weak", ... } [ identifier ( , identifier )* ]
167bool ELFAsmParser::ParseDirectiveSymbolAttribute(StringRef Directive, SMLoc) {
169 .Case(".weak", MCSA_Weak)
170 .Case(".local", MCSA_Local)
171 .Case(".hidden", MCSA_Hidden)
172 .Case(".internal", MCSA_Internal)
173 .Case(".protected", MCSA_Protected)
175 assert(Attr != MCSA_Invalid && "unexpected symbol attribute directive!");
176 if (getLexer().isNot(AsmToken::EndOfStatement)) {
177 while (true) {
179
180 if (getParser().parseIdentifier(Name))
181 return TokError("expected identifier");
182
183 if (getParser().discardLTOSymbol(Name)) {
184 if (getLexer().is(AsmToken::EndOfStatement))
185 break;
186 continue;
187 }
188
189 MCSymbol *Sym = getContext().getOrCreateSymbol(Name);
190
191 getStreamer().emitSymbolAttribute(Sym, Attr);
192
193 if (getLexer().is(AsmToken::EndOfStatement))
194 break;
195
196 if (getLexer().isNot(AsmToken::Comma))
197 return TokError("expected comma");
198 Lex();
199 }
200 }
201
202 Lex();
203 return false;
204}
205
206bool ELFAsmParser::ParseSectionSwitch(StringRef Section, unsigned Type,
207 unsigned Flags, SectionKind Kind) {
208 const MCExpr *Subsection = nullptr;
209 if (getLexer().isNot(AsmToken::EndOfStatement)) {
210 if (getParser().parseExpression(Subsection))
211 return true;
212 }
213 Lex();
214
215 getStreamer().switchSection(getContext().getELFSection(Section, Type, Flags),
216 Subsection);
217
218 return false;
219}
220
221bool ELFAsmParser::ParseDirectiveSize(StringRef, SMLoc) {
223 if (getParser().parseIdentifier(Name))
224 return TokError("expected identifier");
225 MCSymbolELF *Sym = cast<MCSymbolELF>(getContext().getOrCreateSymbol(Name));
226
227 if (getLexer().isNot(AsmToken::Comma))
228 return TokError("expected comma");
229 Lex();
230
231 const MCExpr *Expr;
232 if (getParser().parseExpression(Expr))
233 return true;
234
235 if (getLexer().isNot(AsmToken::EndOfStatement))
236 return TokError("unexpected token");
237 Lex();
238
239 getStreamer().emitELFSize(Sym, Expr);
240 return false;
241}
242
243bool ELFAsmParser::ParseSectionName(StringRef &SectionName) {
244 // A section name can contain -, so we cannot just use
245 // parseIdentifier.
246 SMLoc FirstLoc = getLexer().getLoc();
247 unsigned Size = 0;
248
249 if (getLexer().is(AsmToken::String)) {
250 SectionName = getTok().getIdentifier();
251 Lex();
252 return false;
253 }
254
255 while (!getParser().hasPendingError()) {
256 SMLoc PrevLoc = getLexer().getLoc();
257 if (getLexer().is(AsmToken::Comma) ||
258 getLexer().is(AsmToken::EndOfStatement))
259 break;
260
261 unsigned CurSize;
262 if (getLexer().is(AsmToken::String)) {
263 CurSize = getTok().getIdentifier().size() + 2;
264 Lex();
265 } else if (getLexer().is(AsmToken::Identifier)) {
266 CurSize = getTok().getIdentifier().size();
267 Lex();
268 } else {
269 CurSize = getTok().getString().size();
270 Lex();
271 }
272 Size += CurSize;
273 SectionName = StringRef(FirstLoc.getPointer(), Size);
274
275 // Make sure the following token is adjacent.
276 if (PrevLoc.getPointer() + CurSize != getTok().getLoc().getPointer())
277 break;
278 }
279 if (Size == 0)
280 return true;
281
282 return false;
283}
284
285static unsigned parseSectionFlags(const Triple &TT, StringRef flagsStr,
286 bool *UseLastGroup) {
287 unsigned flags = 0;
288
289 // If a valid numerical value is set for the section flag, use it verbatim
290 if (!flagsStr.getAsInteger(0, flags))
291 return flags;
292
293 for (char i : flagsStr) {
294 switch (i) {
295 case 'a':
296 flags |= ELF::SHF_ALLOC;
297 break;
298 case 'e':
299 flags |= ELF::SHF_EXCLUDE;
300 break;
301 case 'x':
302 flags |= ELF::SHF_EXECINSTR;
303 break;
304 case 'w':
305 flags |= ELF::SHF_WRITE;
306 break;
307 case 'o':
308 flags |= ELF::SHF_LINK_ORDER;
309 break;
310 case 'M':
311 flags |= ELF::SHF_MERGE;
312 break;
313 case 'S':
314 flags |= ELF::SHF_STRINGS;
315 break;
316 case 'T':
317 flags |= ELF::SHF_TLS;
318 break;
319 case 'c':
321 break;
322 case 'd':
324 break;
325 case 'y':
326 flags |= ELF::SHF_ARM_PURECODE;
327 break;
328 case 's':
329 flags |= ELF::SHF_HEX_GPREL;
330 break;
331 case 'G':
332 flags |= ELF::SHF_GROUP;
333 break;
334 case 'R':
335 if (TT.isOSSolaris())
337 else
338 flags |= ELF::SHF_GNU_RETAIN;
339 break;
340 case '?':
341 *UseLastGroup = true;
342 break;
343 default:
344 return -1U;
345 }
346 }
347
348 return flags;
349}
350
351unsigned ELFAsmParser::parseSunStyleSectionFlags() {
352 unsigned flags = 0;
353 while (getLexer().is(AsmToken::Hash)) {
354 Lex(); // Eat the #.
355
356 if (!getLexer().is(AsmToken::Identifier))
357 return -1U;
358
359 StringRef flagId = getTok().getIdentifier();
360 if (flagId == "alloc")
361 flags |= ELF::SHF_ALLOC;
362 else if (flagId == "execinstr")
363 flags |= ELF::SHF_EXECINSTR;
364 else if (flagId == "write")
365 flags |= ELF::SHF_WRITE;
366 else if (flagId == "tls")
367 flags |= ELF::SHF_TLS;
368 else
369 return -1U;
370
371 Lex(); // Eat the flag.
372
373 if (!getLexer().is(AsmToken::Comma))
374 break;
375 Lex(); // Eat the comma.
376 }
377 return flags;
378}
379
380
381bool ELFAsmParser::ParseDirectivePushSection(StringRef s, SMLoc loc) {
382 getStreamer().pushSection();
383
384 if (ParseSectionArguments(/*IsPush=*/true, loc)) {
385 getStreamer().popSection();
386 return true;
387 }
388
389 return false;
390}
391
392bool ELFAsmParser::ParseDirectivePopSection(StringRef, SMLoc) {
393 if (!getStreamer().popSection())
394 return TokError(".popsection without corresponding .pushsection");
395 return false;
396}
397
398bool ELFAsmParser::ParseDirectiveSection(StringRef, SMLoc loc) {
399 return ParseSectionArguments(/*IsPush=*/false, loc);
400}
401
402bool ELFAsmParser::maybeParseSectionType(StringRef &TypeName) {
403 MCAsmLexer &L = getLexer();
404 if (L.isNot(AsmToken::Comma))
405 return false;
406 Lex();
410 return TokError("expected '@<type>', '%<type>' or \"<type>\"");
411 else
412 return TokError("expected '%<type>' or \"<type>\"");
413 }
414 if (!L.is(AsmToken::String))
415 Lex();
416 if (L.is(AsmToken::Integer)) {
417 TypeName = getTok().getString();
418 Lex();
419 } else if (getParser().parseIdentifier(TypeName))
420 return TokError("expected identifier");
421 return false;
422}
423
424bool ELFAsmParser::parseMergeSize(int64_t &Size) {
425 if (getLexer().isNot(AsmToken::Comma))
426 return TokError("expected the entry size");
427 Lex();
428 if (getParser().parseAbsoluteExpression(Size))
429 return true;
430 if (Size <= 0)
431 return TokError("entry size must be positive");
432 return false;
433}
434
435bool ELFAsmParser::parseGroup(StringRef &GroupName, bool &IsComdat) {
436 MCAsmLexer &L = getLexer();
437 if (L.isNot(AsmToken::Comma))
438 return TokError("expected group name");
439 Lex();
440 if (L.is(AsmToken::Integer)) {
441 GroupName = getTok().getString();
442 Lex();
443 } else if (getParser().parseIdentifier(GroupName)) {
444 return TokError("invalid group name");
445 }
446 if (L.is(AsmToken::Comma)) {
447 Lex();
449 if (getParser().parseIdentifier(Linkage))
450 return TokError("invalid linkage");
451 if (Linkage != "comdat")
452 return TokError("Linkage must be 'comdat'");
453 IsComdat = true;
454 } else {
455 IsComdat = false;
456 }
457 return false;
458}
459
460bool ELFAsmParser::parseLinkedToSym(MCSymbolELF *&LinkedToSym) {
461 MCAsmLexer &L = getLexer();
462 if (L.isNot(AsmToken::Comma))
463 return TokError("expected linked-to symbol");
464 Lex();
466 SMLoc StartLoc = L.getLoc();
467 if (getParser().parseIdentifier(Name)) {
468 if (getParser().getTok().getString() == "0") {
469 getParser().Lex();
470 LinkedToSym = nullptr;
471 return false;
472 }
473 return TokError("invalid linked-to symbol");
474 }
475 LinkedToSym = dyn_cast_or_null<MCSymbolELF>(getContext().lookupSymbol(Name));
476 if (!LinkedToSym || !LinkedToSym->isInSection())
477 return Error(StartLoc, "linked-to symbol is not in a section: " + Name);
478 return false;
479}
480
481bool ELFAsmParser::maybeParseUniqueID(int64_t &UniqueID) {
482 MCAsmLexer &L = getLexer();
483 if (L.isNot(AsmToken::Comma))
484 return false;
485 Lex();
486 StringRef UniqueStr;
487 if (getParser().parseIdentifier(UniqueStr))
488 return TokError("expected identifier");
489 if (UniqueStr != "unique")
490 return TokError("expected 'unique'");
491 if (L.isNot(AsmToken::Comma))
492 return TokError("expected commma");
493 Lex();
494 if (getParser().parseAbsoluteExpression(UniqueID))
495 return true;
496 if (UniqueID < 0)
497 return TokError("unique id must be positive");
498 if (!isUInt<32>(UniqueID) || UniqueID == ~0U)
499 return TokError("unique id is too large");
500 return false;
501}
502
504 return SectionName.consume_front(Prefix) &&
505 (SectionName.empty() || SectionName[0] == '.');
506}
507
509 unsigned Type) {
510 if (TT.getArch() == Triple::x86_64) {
511 // x86-64 psABI names SHT_X86_64_UNWIND as the canonical type for .eh_frame,
512 // but GNU as emits SHT_PROGBITS .eh_frame for .cfi_* directives. Don't
513 // error for SHT_PROGBITS .eh_frame
514 return SectionName == ".eh_frame" && Type == ELF::SHT_PROGBITS;
515 }
516 if (TT.isMIPS()) {
517 // MIPS .debug_* sections should have SHT_MIPS_DWARF section type to
518 // distinguish among sections contain DWARF and ECOFF debug formats,
519 // but in assembly files these sections have SHT_PROGBITS type.
520 return SectionName.startswith(".debug_") && Type == ELF::SHT_PROGBITS;
521 }
522 return false;
523}
524
525bool ELFAsmParser::ParseSectionArguments(bool IsPush, SMLoc loc) {
527
528 if (ParseSectionName(SectionName))
529 return TokError("expected identifier");
530
532 int64_t Size = 0;
533 StringRef GroupName;
534 bool IsComdat = false;
535 unsigned Flags = 0;
536 unsigned extraFlags = 0;
537 const MCExpr *Subsection = nullptr;
538 bool UseLastGroup = false;
539 MCSymbolELF *LinkedToSym = nullptr;
540 int64_t UniqueID = ~0;
541
542 // Set the defaults first.
543 if (hasPrefix(SectionName, ".rodata") || SectionName == ".rodata1")
545 else if (SectionName == ".fini" || SectionName == ".init" ||
546 hasPrefix(SectionName, ".text"))
548 else if (hasPrefix(SectionName, ".data") || SectionName == ".data1" ||
549 hasPrefix(SectionName, ".bss") ||
550 hasPrefix(SectionName, ".init_array") ||
551 hasPrefix(SectionName, ".fini_array") ||
552 hasPrefix(SectionName, ".preinit_array"))
554 else if (hasPrefix(SectionName, ".tdata") || hasPrefix(SectionName, ".tbss"))
556
557 if (getLexer().is(AsmToken::Comma)) {
558 Lex();
559
560 if (IsPush && getLexer().isNot(AsmToken::String)) {
561 if (getParser().parseExpression(Subsection))
562 return true;
563 if (getLexer().isNot(AsmToken::Comma))
564 goto EndStmt;
565 Lex();
566 }
567
568 if (getLexer().isNot(AsmToken::String)) {
569 if (getLexer().isNot(AsmToken::Hash))
570 return TokError("expected string");
571 extraFlags = parseSunStyleSectionFlags();
572 } else {
573 StringRef FlagsStr = getTok().getStringContents();
574 Lex();
575 extraFlags = parseSectionFlags(getContext().getTargetTriple(), FlagsStr,
576 &UseLastGroup);
577 }
578
579 if (extraFlags == -1U)
580 return TokError("unknown flag");
581 Flags |= extraFlags;
582
583 bool Mergeable = Flags & ELF::SHF_MERGE;
584 bool Group = Flags & ELF::SHF_GROUP;
585 if (Group && UseLastGroup)
586 return TokError("Section cannot specifiy a group name while also acting "
587 "as a member of the last group");
588
589 if (maybeParseSectionType(TypeName))
590 return true;
591
592 MCAsmLexer &L = getLexer();
593 if (TypeName.empty()) {
594 if (Mergeable)
595 return TokError("Mergeable section must specify the type");
596 if (Group)
597 return TokError("Group section must specify the type");
599 return TokError("expected end of directive");
600 }
601
602 if (Mergeable)
603 if (parseMergeSize(Size))
604 return true;
605 if (Group)
606 if (parseGroup(GroupName, IsComdat))
607 return true;
608 if (Flags & ELF::SHF_LINK_ORDER)
609 if (parseLinkedToSym(LinkedToSym))
610 return true;
611 if (maybeParseUniqueID(UniqueID))
612 return true;
613 }
614
615EndStmt:
616 if (getLexer().isNot(AsmToken::EndOfStatement))
617 return TokError("expected end of directive");
618 Lex();
619
620 unsigned Type = ELF::SHT_PROGBITS;
621
622 if (TypeName.empty()) {
623 if (SectionName.startswith(".note"))
625 else if (hasPrefix(SectionName, ".init_array"))
627 else if (hasPrefix(SectionName, ".bss"))
629 else if (hasPrefix(SectionName, ".tbss"))
631 else if (hasPrefix(SectionName, ".fini_array"))
633 else if (hasPrefix(SectionName, ".preinit_array"))
635 } else {
636 if (TypeName == "init_array")
638 else if (TypeName == "fini_array")
640 else if (TypeName == "preinit_array")
642 else if (TypeName == "nobits")
644 else if (TypeName == "progbits")
646 else if (TypeName == "note")
648 else if (TypeName == "unwind")
650 else if (TypeName == "llvm_odrtab")
652 else if (TypeName == "llvm_linker_options")
654 else if (TypeName == "llvm_call_graph_profile")
656 else if (TypeName == "llvm_dependent_libraries")
658 else if (TypeName == "llvm_sympart")
660 else if (TypeName == "llvm_bb_addr_map")
662 else if (TypeName == "llvm_offloading")
664 else if (TypeName.getAsInteger(0, Type))
665 return TokError("unknown section type");
666 }
667
668 if (UseLastGroup) {
669 MCSectionSubPair CurrentSection = getStreamer().getCurrentSection();
670 if (const MCSectionELF *Section =
671 cast_or_null<MCSectionELF>(CurrentSection.first))
672 if (const MCSymbol *Group = Section->getGroup()) {
673 GroupName = Group->getName();
674 IsComdat = Section->isComdat();
676 }
677 }
678
680 getContext().getELFSection(SectionName, Type, Flags, Size, GroupName,
681 IsComdat, UniqueID, LinkedToSym);
682 getStreamer().switchSection(Section, Subsection);
683 // Check that flags are used consistently. However, the GNU assembler permits
684 // to leave out in subsequent uses of the same sections; for compatibility,
685 // do likewise.
686 if (!TypeName.empty() && Section->getType() != Type &&
687 !allowSectionTypeMismatch(getContext().getTargetTriple(), SectionName,
688 Type))
689 Error(loc, "changed section type for " + SectionName + ", expected: 0x" +
690 utohexstr(Section->getType()));
691 if ((extraFlags || Size || !TypeName.empty()) && Section->getFlags() != Flags)
692 Error(loc, "changed section flags for " + SectionName + ", expected: 0x" +
693 utohexstr(Section->getFlags()));
694 if ((extraFlags || Size || !TypeName.empty()) &&
695 Section->getEntrySize() != Size)
696 Error(loc, "changed section entsize for " + SectionName +
697 ", expected: " + Twine(Section->getEntrySize()));
698
699 if (getContext().getGenDwarfForAssembly() &&
700 (Section->getFlags() & ELF::SHF_ALLOC) &&
701 (Section->getFlags() & ELF::SHF_EXECINSTR)) {
702 bool InsertResult = getContext().addGenDwarfSection(Section);
703 if (InsertResult) {
704 if (getContext().getDwarfVersion() <= 2)
705 Warning(loc, "DWARF2 only supports one section per compilation unit");
706
707 if (!Section->getBeginSymbol()) {
708 MCSymbol *SectionStartSymbol = getContext().createTempSymbol();
709 getStreamer().emitLabel(SectionStartSymbol);
710 Section->setBeginSymbol(SectionStartSymbol);
711 }
712 }
713 }
714
715 return false;
716}
717
718bool ELFAsmParser::ParseDirectivePrevious(StringRef DirName, SMLoc) {
719 MCSectionSubPair PreviousSection = getStreamer().getPreviousSection();
720 if (PreviousSection.first == nullptr)
721 return TokError(".previous without corresponding .section");
722 getStreamer().switchSection(PreviousSection.first, PreviousSection.second);
723
724 return false;
725}
726
729 .Cases("STT_FUNC", "function", MCSA_ELF_TypeFunction)
730 .Cases("STT_OBJECT", "object", MCSA_ELF_TypeObject)
731 .Cases("STT_TLS", "tls_object", MCSA_ELF_TypeTLS)
732 .Cases("STT_COMMON", "common", MCSA_ELF_TypeCommon)
733 .Cases("STT_NOTYPE", "notype", MCSA_ELF_TypeNoType)
734 .Cases("STT_GNU_IFUNC", "gnu_indirect_function",
736 .Case("gnu_unique_object", MCSA_ELF_TypeGnuUniqueObject)
738}
739
740/// ParseDirectiveELFType
741/// ::= .type identifier , STT_<TYPE_IN_UPPER_CASE>
742/// ::= .type identifier , #attribute
743/// ::= .type identifier , @attribute
744/// ::= .type identifier , %attribute
745/// ::= .type identifier , "attribute"
746bool ELFAsmParser::ParseDirectiveType(StringRef, SMLoc) {
748 if (getParser().parseIdentifier(Name))
749 return TokError("expected identifier");
750
751 // Handle the identifier as the key symbol.
752 MCSymbol *Sym = getContext().getOrCreateSymbol(Name);
753
754 // NOTE the comma is optional in all cases. It is only documented as being
755 // optional in the first case, however, GAS will silently treat the comma as
756 // optional in all cases. Furthermore, although the documentation states that
757 // the first form only accepts STT_<TYPE_IN_UPPER_CASE>, in reality, GAS
758 // accepts both the upper case name as well as the lower case aliases.
759 if (getLexer().is(AsmToken::Comma))
760 Lex();
761
762 if (getLexer().isNot(AsmToken::Identifier) &&
763 getLexer().isNot(AsmToken::Hash) &&
764 getLexer().isNot(AsmToken::Percent) &&
765 getLexer().isNot(AsmToken::String)) {
766 if (!getLexer().getAllowAtInIdentifier())
767 return TokError("expected STT_<TYPE_IN_UPPER_CASE>, '#<type>', "
768 "'%<type>' or \"<type>\"");
769 else if (getLexer().isNot(AsmToken::At))
770 return TokError("expected STT_<TYPE_IN_UPPER_CASE>, '#<type>', '@<type>', "
771 "'%<type>' or \"<type>\"");
772 }
773
774 if (getLexer().isNot(AsmToken::String) &&
775 getLexer().isNot(AsmToken::Identifier))
776 Lex();
777
778 SMLoc TypeLoc = getLexer().getLoc();
779
781 if (getParser().parseIdentifier(Type))
782 return TokError("expected symbol type");
783
785 if (Attr == MCSA_Invalid)
786 return Error(TypeLoc, "unsupported attribute");
787
788 if (getLexer().isNot(AsmToken::EndOfStatement))
789 return TokError("expected end of directive");
790 Lex();
791
792 getStreamer().emitSymbolAttribute(Sym, Attr);
793
794 return false;
795}
796
797/// ParseDirectiveIdent
798/// ::= .ident string
799bool ELFAsmParser::ParseDirectiveIdent(StringRef, SMLoc) {
800 if (getLexer().isNot(AsmToken::String))
801 return TokError("expected string");
802
803 StringRef Data = getTok().getIdentifier();
804
805 Lex();
806
807 if (getLexer().isNot(AsmToken::EndOfStatement))
808 return TokError("expected end of directive");
809 Lex();
810
811 getStreamer().emitIdent(Data);
812 return false;
813}
814
815/// ParseDirectiveSymver
816/// ::= .symver foo, bar2@zed
817bool ELFAsmParser::ParseDirectiveSymver(StringRef, SMLoc) {
818 StringRef OriginalName, Name, Action;
819 if (getParser().parseIdentifier(OriginalName))
820 return TokError("expected identifier");
821
822 if (getLexer().isNot(AsmToken::Comma))
823 return TokError("expected a comma");
824
825 // ARM assembly uses @ for a comment...
826 // except when parsing the second parameter of the .symver directive.
827 // Force the next symbol to allow @ in the identifier, which is
828 // required for this directive and then reset it to its initial state.
829 const bool AllowAtInIdentifier = getLexer().getAllowAtInIdentifier();
830 getLexer().setAllowAtInIdentifier(true);
831 Lex();
832 getLexer().setAllowAtInIdentifier(AllowAtInIdentifier);
833
834 if (getParser().parseIdentifier(Name))
835 return TokError("expected identifier");
836
837 if (!Name.contains('@'))
838 return TokError("expected a '@' in the name");
839 bool KeepOriginalSym = !Name.contains("@@@");
840 if (parseOptionalToken(AsmToken::Comma)) {
841 if (getParser().parseIdentifier(Action) || Action != "remove")
842 return TokError("expected 'remove'");
843 KeepOriginalSym = false;
844 }
845 (void)parseOptionalToken(AsmToken::EndOfStatement);
846
847 getStreamer().emitELFSymverDirective(
848 getContext().getOrCreateSymbol(OriginalName), Name, KeepOriginalSym);
849 return false;
850}
851
852/// ParseDirectiveVersion
853/// ::= .version string
854bool ELFAsmParser::ParseDirectiveVersion(StringRef, SMLoc) {
855 if (getLexer().isNot(AsmToken::String))
856 return TokError("expected string");
857
858 StringRef Data = getTok().getIdentifier();
859
860 Lex();
861
862 MCSection *Note = getContext().getELFSection(".note", ELF::SHT_NOTE, 0);
863
864 getStreamer().pushSection();
865 getStreamer().switchSection(Note);
866 getStreamer().emitInt32(Data.size() + 1); // namesz
867 getStreamer().emitInt32(0); // descsz = 0 (no description).
868 getStreamer().emitInt32(1); // type = NT_VERSION
869 getStreamer().emitBytes(Data); // name
870 getStreamer().emitInt8(0); // NUL
871 getStreamer().emitValueToAlignment(Align(4));
872 getStreamer().popSection();
873 return false;
874}
875
876/// ParseDirectiveWeakref
877/// ::= .weakref foo, bar
878bool ELFAsmParser::ParseDirectiveWeakref(StringRef, SMLoc) {
879 // FIXME: Share code with the other alias building directives.
880
881 StringRef AliasName;
882 if (getParser().parseIdentifier(AliasName))
883 return TokError("expected identifier");
884
885 if (getLexer().isNot(AsmToken::Comma))
886 return TokError("expected a comma");
887
888 Lex();
889
891 if (getParser().parseIdentifier(Name))
892 return TokError("expected identifier");
893
894 MCSymbol *Alias = getContext().getOrCreateSymbol(AliasName);
895
896 MCSymbol *Sym = getContext().getOrCreateSymbol(Name);
897
898 getStreamer().emitWeakReference(Alias, Sym);
899 return false;
900}
901
902bool ELFAsmParser::ParseDirectiveSubsection(StringRef, SMLoc) {
903 const MCExpr *Subsection = nullptr;
904 if (getLexer().isNot(AsmToken::EndOfStatement)) {
905 if (getParser().parseExpression(Subsection))
906 return true;
907 }
908
909 if (getLexer().isNot(AsmToken::EndOfStatement))
910 return TokError("expected end of directive");
911
912 Lex();
913
914 getStreamer().subSection(Subsection);
915 return false;
916}
917
918bool ELFAsmParser::ParseDirectiveCGProfile(StringRef S, SMLoc Loc) {
920}
921
922namespace llvm {
923
925 return new ELFAsmParser;
926}
927
928} // end namespace llvm
static bool isNot(const MachineRegisterInfo &MRI, const MachineInstr &MI)
static bool hasPrefix(StringRef SectionName, StringRef Prefix)
static bool allowSectionTypeMismatch(const Triple &TT, StringRef SectionName, unsigned Type)
static unsigned parseSectionFlags(const Triple &TT, StringRef flagsStr, bool *UseLastGroup)
static MCSymbolAttr MCAttrForString(StringRef Type)
std::string Name
uint64_t Size
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
This file implements the StringSwitch template, which mimics a switch() statement whose cases are str...
Lightweight error class with error context and mandatory checking.
Definition: Error.h:156
Generic assembler lexer interface, for use by target specific assembly lexers.
Definition: MCAsmLexer.h:37
bool isNot(AsmToken::TokenKind K) const
Check if the current token has kind K.
Definition: MCAsmLexer.h:144
bool getAllowAtInIdentifier()
Definition: MCAsmLexer.h:149
SMLoc getLoc() const
Get the current source location.
Definition: MCAsmLexer.cpp:22
bool is(AsmToken::TokenKind K) const
Check if the current token has kind K.
Definition: MCAsmLexer.h:141
Generic interface for extending the MCAsmParser, which is implemented by target and object file assem...
virtual void Initialize(MCAsmParser &Parser)
Initialize the extension for parsing using the given Parser.
bool ParseDirectiveCGProfile(StringRef, SMLoc)
ParseDirectiveCGProfile ::= .cg_profile identifier, identifier, <number>
Generic assembler parser interface, for use by target specific assembly parsers.
Definition: MCAsmParser.h:123
std::pair< MCAsmParserExtension *, DirectiveHandler > ExtensionDirectiveHandler
Definition: MCAsmParser.h:127
virtual void addDirectiveHandler(StringRef Directive, ExtensionDirectiveHandler Handler)=0
Base class for the full range of assembler expressions which are needed for parsing.
Definition: MCExpr.h:35
This represents a section on linux, lots of unix variants and some bare metal systems.
Definition: MCSectionELF.h:26
Instances of this class represent a uniqued identifier for a section in the current translation unit.
Definition: MCSection.h:39
MCSymbol - Instances of this class represent a symbol name in the MC file, and MCSymbols are created ...
Definition: MCSymbol.h:41
bool isInSection() const
isInSection - Check if this symbol is defined in some section (i.e., it is defined but not absolute).
Definition: MCSymbol.h:252
Represents a location in source code.
Definition: SMLoc.h:23
const char * getPointer() const
Definition: SMLoc.h:34
SectionKind - This is a simple POD value that classifies the properties of a section.
Definition: SectionKind.h:22
static SectionKind getThreadData()
Definition: SectionKind.h:207
static SectionKind getText()
Definition: SectionKind.h:190
static SectionKind getReadOnlyWithRel()
Definition: SectionKind.h:214
static SectionKind getData()
Definition: SectionKind.h:213
static SectionKind getBSS()
Definition: SectionKind.h:209
static SectionKind getThreadBSS()
Definition: SectionKind.h:206
static SectionKind getReadOnly()
Definition: SectionKind.h:192
StringRef - Represent a constant reference to a string, i.e.
Definition: StringRef.h:50
bool getAsInteger(unsigned Radix, T &Result) const
Parse the current string as an integer of the specified radix.
Definition: StringRef.h:469
A switch()-like statement whose cases are string literals.
Definition: StringSwitch.h:44
StringSwitch & Case(StringLiteral S, T Value)
Definition: StringSwitch.h:69
R Default(T Value)
Definition: StringSwitch.h:182
StringSwitch & Cases(StringLiteral S0, StringLiteral S1, T Value)
Definition: StringSwitch.h:90
Triple - Helper class for working with autoconf configuration names.
Definition: Triple.h:44
Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...
Definition: Twine.h:81
The instances of the Type class are immutable: once they are created, they are never changed.
Definition: Type.h:45
constexpr char TypeName[]
Key for Kernel::Arg::Metadata::mTypeName.
@ XCORE_SHF_DP_SECTION
All sections with the "d" flag are grouped together by the linker to form the data section and the dp...
Definition: ELF.h:1132
@ SHF_MERGE
Definition: ELF.h:1089
@ SHF_STRINGS
Definition: ELF.h:1092
@ XCORE_SHF_CP_SECTION
All sections with the "c" flag are grouped together by the linker to form the constant pool and the c...
Definition: ELF.h:1137
@ SHF_EXCLUDE
Definition: ELF.h:1117
@ SHF_ALLOC
Definition: ELF.h:1083
@ SHF_LINK_ORDER
Definition: ELF.h:1098
@ SHF_HEX_GPREL
Definition: ELF.h:1150
@ SHF_GROUP
Definition: ELF.h:1105
@ SHF_SUNW_NODISCARD
Definition: ELF.h:1124
@ SHF_GNU_RETAIN
Definition: ELF.h:1114
@ SHF_WRITE
Definition: ELF.h:1080
@ SHF_TLS
Definition: ELF.h:1108
@ SHF_ARM_PURECODE
Definition: ELF.h:1178
@ SHF_EXECINSTR
Definition: ELF.h:1086
@ SHT_LLVM_DEPENDENT_LIBRARIES
Definition: ELF.h:1023
@ SHT_PROGBITS
Definition: ELF.h:995
@ SHT_LLVM_LINKER_OPTIONS
Definition: ELF.h:1020
@ SHT_LLVM_CALL_GRAPH_PROFILE
Definition: ELF.h:1031
@ SHT_NOBITS
Definition: ELF.h:1002
@ SHT_LLVM_ODRTAB
Definition: ELF.h:1019
@ SHT_LLVM_OFFLOADING
Definition: ELF.h:1033
@ SHT_PREINIT_ARRAY
Definition: ELF.h:1008
@ SHT_LLVM_BB_ADDR_MAP
Definition: ELF.h:1032
@ SHT_INIT_ARRAY
Definition: ELF.h:1006
@ SHT_NOTE
Definition: ELF.h:1001
@ SHT_X86_64_UNWIND
Definition: ELF.h:1059
@ SHT_LLVM_SYMPART
Definition: ELF.h:1025
@ SHT_FINI_ARRAY
Definition: ELF.h:1007
int getDwarfVersion()
This is an optimization pass for GlobalISel generic memory operations.
Definition: AddressRanges.h:18
std::pair< MCSection *, const MCExpr * > MCSectionSubPair
Definition: MCStreamer.h:66
MCAsmParserExtension * createELFAsmParser()
MCSymbolAttr
Definition: MCDirectives.h:18
@ MCSA_Local
.local (ELF)
Definition: MCDirectives.h:38
@ MCSA_Protected
.protected (ELF)
Definition: MCDirectives.h:43
@ MCSA_Internal
.internal (ELF)
Definition: MCDirectives.h:36
@ MCSA_ELF_TypeIndFunction
.type _foo, STT_GNU_IFUNC
Definition: MCDirectives.h:24
@ MCSA_ELF_TypeNoType
.type _foo, STT_NOTYPE # aka @notype
Definition: MCDirectives.h:28
@ MCSA_Weak
.weak
Definition: MCDirectives.h:45
@ MCSA_ELF_TypeTLS
.type _foo, STT_TLS # aka @tls_object
Definition: MCDirectives.h:26
@ MCSA_ELF_TypeCommon
.type _foo, STT_COMMON # aka @common
Definition: MCDirectives.h:27
@ MCSA_ELF_TypeObject
.type _foo, STT_OBJECT # aka @object
Definition: MCDirectives.h:25
@ MCSA_ELF_TypeGnuUniqueObject
Definition: MCDirectives.h:29
@ MCSA_ELF_TypeFunction
.type _foo, STT_FUNC # aka @function
Definition: MCDirectives.h:23
@ MCSA_Hidden
.hidden (ELF)
Definition: MCDirectives.h:33
@ MCSA_Invalid
Not a valid directive.
Definition: MCDirectives.h:19
This struct is a compact representation of a valid (non-zero power of two) alignment.
Definition: Alignment.h:39