38 template<
bool (ELFAsmParser::*HandlerMethod)(StringRef, SMLoc)>
39 void addDirectiveHandler(
StringRef Directive) {
41 this, HandleDirective<ELFAsmParser, HandlerMethod>);
43 getParser().addDirectiveHandler(Directive, Handler);
50 ELFAsmParser() { BracketExpressionsSupported =
true; }
56 addDirectiveHandler<&ELFAsmParser::ParseSectionDirectiveData>(
".data");
57 addDirectiveHandler<&ELFAsmParser::ParseSectionDirectiveText>(
".text");
58 addDirectiveHandler<&ELFAsmParser::ParseSectionDirectiveBSS>(
".bss");
59 addDirectiveHandler<&ELFAsmParser::ParseSectionDirectiveRoData>(
".rodata");
60 addDirectiveHandler<&ELFAsmParser::ParseSectionDirectiveTData>(
".tdata");
61 addDirectiveHandler<&ELFAsmParser::ParseSectionDirectiveTBSS>(
".tbss");
63 &ELFAsmParser::ParseSectionDirectiveDataRel>(
".data.rel");
65 &ELFAsmParser::ParseSectionDirectiveDataRelRo>(
".data.rel.ro");
67 &ELFAsmParser::ParseSectionDirectiveEhFrame>(
".eh_frame");
68 addDirectiveHandler<&ELFAsmParser::ParseDirectiveSection>(
".section");
70 &ELFAsmParser::ParseDirectivePushSection>(
".pushsection");
71 addDirectiveHandler<&ELFAsmParser::ParseDirectivePopSection>(
".popsection");
72 addDirectiveHandler<&ELFAsmParser::ParseDirectiveSize>(
".size");
73 addDirectiveHandler<&ELFAsmParser::ParseDirectivePrevious>(
".previous");
74 addDirectiveHandler<&ELFAsmParser::ParseDirectiveType>(
".type");
75 addDirectiveHandler<&ELFAsmParser::ParseDirectiveIdent>(
".ident");
76 addDirectiveHandler<&ELFAsmParser::ParseDirectiveSymver>(
".symver");
77 addDirectiveHandler<&ELFAsmParser::ParseDirectiveVersion>(
".version");
78 addDirectiveHandler<&ELFAsmParser::ParseDirectiveWeakref>(
".weakref");
79 addDirectiveHandler<&ELFAsmParser::ParseDirectiveSymbolAttribute>(
".weak");
80 addDirectiveHandler<&ELFAsmParser::ParseDirectiveSymbolAttribute>(
".local");
82 &ELFAsmParser::ParseDirectiveSymbolAttribute>(
".protected");
84 &ELFAsmParser::ParseDirectiveSymbolAttribute>(
".internal");
86 &ELFAsmParser::ParseDirectiveSymbolAttribute>(
".hidden");
87 addDirectiveHandler<&ELFAsmParser::ParseDirectiveSubsection>(
".subsection");
88 addDirectiveHandler<&ELFAsmParser::ParseDirectiveCGProfile>(
".cg_profile");
157 bool ParseSectionArguments(
bool IsPush,
SMLoc loc);
158 unsigned parseSunStyleSectionFlags();
160 bool parseMergeSize(int64_t &
Size);
163 bool maybeParseUniqueID(int64_t &UniqueID);
170 bool ELFAsmParser::ParseDirectiveSymbolAttribute(
StringRef Directive,
SMLoc) {
183 if (getParser().parseIdentifier(Name))
184 return TokError(
"expected identifier in directive");
186 MCSymbol *Sym = getContext().getOrCreateSymbol(Name);
188 getStreamer().EmitSymbolAttribute(Sym, Attr);
194 return TokError(
"unexpected token in directive");
205 const MCExpr *Subsection =
nullptr;
207 if (getParser().parseExpression(Subsection))
212 getStreamer().SwitchSection(getContext().getELFSection(Section, Type, Flags),
220 if (getParser().parseIdentifier(Name))
221 return TokError(
"expected identifier in directive");
222 MCSymbolELF *Sym = cast<MCSymbolELF>(getContext().getOrCreateSymbol(Name));
225 return TokError(
"unexpected token in directive");
229 if (getParser().parseExpression(Expr))
233 return TokError(
"unexpected token in directive");
236 getStreamer().emitELFSize(Sym, Expr);
243 SMLoc FirstLoc = getLexer().getLoc();
247 SectionName = getTok().getIdentifier();
252 while (!getParser().hasPendingError()) {
253 SMLoc PrevLoc = getLexer().getLoc();
260 CurSize = getTok().getIdentifier().size() + 2;
263 CurSize = getTok().getIdentifier().size();
266 CurSize = getTok().getString().size();
273 if (PrevLoc.
getPointer() + CurSize != getTok().getLoc().getPointer())
289 for (
char i : flagsStr) {
331 *UseLastGroup =
true;
341 unsigned ELFAsmParser::parseSunStyleSectionFlags() {
349 StringRef flagId = getTok().getIdentifier();
350 if (flagId ==
"alloc")
352 else if (flagId ==
"execinstr")
354 else if (flagId ==
"write")
356 else if (flagId ==
"tls")
371 bool ELFAsmParser::ParseDirectivePushSection(
StringRef s,
SMLoc loc) {
372 getStreamer().PushSection();
374 if (ParseSectionArguments(
true, loc)) {
375 getStreamer().PopSection();
383 if (!getStreamer().PopSection())
384 return TokError(
".popsection without corresponding .pushsection");
389 return ParseSectionArguments(
false, loc);
400 return TokError(
"expected '@<type>', '%<type>' or \"<type>\"");
402 return TokError(
"expected '%<type>' or \"<type>\"");
407 TypeName = getTok().getString();
409 }
else if (getParser().parseIdentifier(TypeName))
410 return TokError(
"expected identifier in directive");
414 bool ELFAsmParser::parseMergeSize(int64_t &Size) {
416 return TokError(
"expected the entry size");
418 if (getParser().parseAbsoluteExpression(Size))
421 return TokError(
"entry size must be positive");
425 bool ELFAsmParser::parseGroup(
StringRef &GroupName) {
428 return TokError(
"expected group name");
431 GroupName = getTok().getString();
433 }
else if (getParser().parseIdentifier(GroupName)) {
434 return TokError(
"invalid group name");
439 if (getParser().parseIdentifier(Linkage))
440 return TokError(
"invalid linkage");
441 if (Linkage !=
"comdat")
442 return TokError(
"Linkage must be 'comdat'");
447 bool ELFAsmParser::parseMetadataSym(
MCSymbolELF *&Associated) {
450 return TokError(
"expected metadata symbol");
453 if (getParser().parseIdentifier(Name))
454 return TokError(
"invalid metadata symbol");
455 Associated = dyn_cast_or_null<MCSymbolELF>(getContext().lookupSymbol(Name));
457 return TokError(
"symbol is not in a section: " + Name);
461 bool ELFAsmParser::maybeParseUniqueID(int64_t &UniqueID) {
467 if (getParser().parseIdentifier(UniqueStr))
468 return TokError(
"expected identifier in directive");
469 if (UniqueStr !=
"unique")
470 return TokError(
"expected 'unique'");
472 return TokError(
"expected commma");
474 if (getParser().parseAbsoluteExpression(UniqueID))
477 return TokError(
"unique id must be positive");
479 return TokError(
"unique id is too large");
487 bool ELFAsmParser::ParseSectionArguments(
bool IsPush,
SMLoc loc) {
490 if (ParseSectionName(SectionName))
491 return TokError(
"expected identifier in directive");
497 const MCExpr *Subsection =
nullptr;
498 bool UseLastGroup =
false;
500 int64_t UniqueID = ~0;
503 if (
hasPrefix(SectionName,
".rodata.") || SectionName ==
".rodata1")
505 else if (SectionName ==
".fini" || SectionName ==
".init" ||
508 else if (
hasPrefix(SectionName,
".data.") || SectionName ==
".data1" ||
510 hasPrefix(SectionName,
".init_array.") ||
511 hasPrefix(SectionName,
".fini_array.") ||
512 hasPrefix(SectionName,
".preinit_array."))
514 else if (
hasPrefix(SectionName,
".tdata.") ||
522 if (getParser().parseExpression(Subsection))
532 if (!getContext().getAsmInfo()->usesSunStyleELFSectionSwitchSyntax()
534 return TokError(
"expected string in directive");
535 extraFlags = parseSunStyleSectionFlags();
537 StringRef FlagsStr = getTok().getStringContents();
542 if (extraFlags == -1U)
543 return TokError(
"unknown flag");
548 if (Group && UseLastGroup)
549 return TokError(
"Section cannot specifiy a group name while also acting " 550 "as a member of the last group");
552 if (maybeParseSectionType(TypeName))
556 if (TypeName.
empty()) {
558 return TokError(
"Mergeable section must specify the type");
560 return TokError(
"Group section must specify the type");
562 return TokError(
"unexpected token in directive");
566 if (parseMergeSize(Size))
569 if (parseGroup(GroupName))
572 if (parseMetadataSym(Associated))
574 if (maybeParseUniqueID(UniqueID))
580 return TokError(
"unexpected token in directive");
585 if (TypeName.
empty()) {
588 else if (
hasPrefix(SectionName,
".init_array."))
590 else if (
hasPrefix(SectionName,
".bss."))
592 else if (
hasPrefix(SectionName,
".tbss."))
594 else if (
hasPrefix(SectionName,
".fini_array."))
596 else if (
hasPrefix(SectionName,
".preinit_array."))
599 if (TypeName ==
"init_array")
601 else if (TypeName ==
"fini_array")
603 else if (TypeName ==
"preinit_array")
605 else if (TypeName ==
"nobits")
607 else if (TypeName ==
"progbits")
609 else if (TypeName ==
"note")
611 else if (TypeName ==
"unwind")
613 else if (TypeName ==
"llvm_odrtab")
615 else if (TypeName ==
"llvm_linker_options")
617 else if (TypeName ==
"llvm_call_graph_profile")
620 return TokError(
"unknown section type");
626 cast_or_null<MCSectionELF>(CurrentSection.first))
627 if (
const MCSymbol *Group = Section->getGroup()) {
628 GroupName = Group->getName();
634 getContext().getELFSection(SectionName, Type, Flags, Size, GroupName,
635 UniqueID, Associated);
636 getStreamer().SwitchSection(ELFSection, Subsection);
638 if (getContext().getGenDwarfForAssembly()) {
639 bool InsertResult = getContext().addGenDwarfSection(ELFSection);
641 if (getContext().getDwarfVersion() <= 2)
642 Warning(loc,
"DWARF2 only supports one section per compilation unit");
645 MCSymbol *SectionStartSymbol = getContext().createTempSymbol();
646 getStreamer().EmitLabel(SectionStartSymbol);
655 bool ELFAsmParser::ParseDirectivePrevious(
StringRef DirName,
SMLoc) {
657 if (PreviousSection.first ==
nullptr)
658 return TokError(
".previous without corresponding .section");
659 getStreamer().SwitchSection(PreviousSection.first, PreviousSection.second);
671 .
Cases(
"STT_GNU_IFUNC",
"gnu_indirect_function",
685 if (getParser().parseIdentifier(Name))
686 return TokError(
"expected identifier in directive");
689 MCSymbol *Sym = getContext().getOrCreateSymbol(Name);
703 if (!getLexer().getAllowAtInIdentifier())
704 return TokError(
"expected STT_<TYPE_IN_UPPER_CASE>, '#<type>', " 705 "'%<type>' or \"<type>\"");
707 return TokError(
"expected STT_<TYPE_IN_UPPER_CASE>, '#<type>', '@<type>', " 708 "'%<type>' or \"<type>\"");
715 SMLoc TypeLoc = getLexer().getLoc();
718 if (getParser().parseIdentifier(Type))
719 return TokError(
"expected symbol type in directive");
723 return Error(TypeLoc,
"unsupported attribute in '.type' directive");
726 return TokError(
"unexpected token in '.type' directive");
729 getStreamer().EmitSymbolAttribute(Sym, Attr);
738 return TokError(
"unexpected token in '.ident' directive");
745 return TokError(
"unexpected token in '.ident' directive");
748 getStreamer().EmitIdent(Data);
756 if (getParser().parseIdentifier(Name))
757 return TokError(
"expected identifier in directive");
760 return TokError(
"expected a comma");
766 const bool AllowAtInIdentifier = getLexer().getAllowAtInIdentifier();
767 getLexer().setAllowAtInIdentifier(
true);
769 getLexer().setAllowAtInIdentifier(AllowAtInIdentifier);
772 if (getParser().parseIdentifier(AliasName))
773 return TokError(
"expected identifier in directive");
776 return TokError(
"expected a '@' in the name");
778 MCSymbol *Sym = getContext().getOrCreateSymbol(Name);
779 getStreamer().emitELFSymverDirective(AliasName, Sym);
787 return TokError(
"unexpected token in '.version' directive");
795 getStreamer().PushSection();
796 getStreamer().SwitchSection(Note);
797 getStreamer().EmitIntValue(Data.
size()+1, 4);
798 getStreamer().EmitIntValue(0, 4);
799 getStreamer().EmitIntValue(1, 4);
800 getStreamer().EmitBytes(Data);
801 getStreamer().EmitIntValue(0, 1);
802 getStreamer().EmitValueToAlignment(4);
803 getStreamer().PopSection();
813 if (getParser().parseIdentifier(AliasName))
814 return TokError(
"expected identifier in directive");
817 return TokError(
"expected a comma");
822 if (getParser().parseIdentifier(Name))
823 return TokError(
"expected identifier in directive");
825 MCSymbol *Alias = getContext().getOrCreateSymbol(AliasName);
827 MCSymbol *Sym = getContext().getOrCreateSymbol(Name);
829 getStreamer().EmitWeakReference(Alias, Sym);
834 const MCExpr *Subsection =
nullptr;
836 if (getParser().parseExpression(Subsection))
841 return TokError(
"unexpected token in directive");
845 getStreamer().SubSection(Subsection);
853 SMLoc FromLoc = getLexer().getLoc();
854 if (getParser().parseIdentifier(From))
855 return TokError(
"expected identifier in directive");
858 return TokError(
"expected a comma");
862 SMLoc ToLoc = getLexer().getLoc();
863 if (getParser().parseIdentifier(To))
864 return TokError(
"expected identifier in directive");
867 return TokError(
"expected a comma");
871 if (getParser().parseIntToken(
872 Count,
"expected integer count in '.cg_profile' directive"))
876 return TokError(
"unexpected token in directive");
878 MCSymbol *FromSym = getContext().getOrCreateSymbol(From);
879 MCSymbol *ToSym = getContext().getOrCreateSymbol(To);
881 getStreamer().emitCGProfileEntry(
893 return new ELFAsmParser;
constexpr bool isUInt< 32 >(uint64_t x)
Instances of this class represent a uniqued identifier for a section in the current translation unit...
static SectionKind getData()
static const MCSymbolRefExpr * create(const MCSymbol *Symbol, MCContext &Ctx)
This class represents lattice values for constants.
.type _foo, STT_OBJECT # aka
bool is(AsmToken::TokenKind K) const
Check if the current token has kind K.
MCSymbol - Instances of this class represent a symbol name in the MC file, and MCSymbols are created ...
All sections with the "d" flag are grouped together by the linker to form the data section and the dp...
Generic assembler parser interface, for use by target specific assembly parsers.
virtual void Initialize(MCAsmParser &Parser)
Initialize the extension for parsing using the given Parser.
LLVM_NODISCARD LLVM_ATTRIBUTE_ALWAYS_INLINE size_t size() const
size - Get the string size.
static unsigned parseSectionFlags(StringRef flagsStr, bool *UseLastGroup)
static MCSymbolAttr MCAttrForString(StringRef Type)
.type _foo, STT_NOTYPE # aka
All sections with the "c" flag are grouped together by the linker to form the constant pool and the c...
MCAsmParserExtension * createELFAsmParser()
amdgpu Simplify well known AMD library false Value Value const Twine & Name
static SectionKind getBSS()
Generic assembler lexer interface, for use by target specific assembly lexers.
static bool hasPrefix(StringRef SectionName, StringRef Prefix)
Base class for the full range of assembler expressions which are needed for parsing.
bool isInSection() const
isInSection - Check if this symbol is defined in some section (i.e., it is defined but not absolute)...
LLVM_NODISCARD LLVM_ATTRIBUTE_ALWAYS_INLINE R Default(T Value)
LLVM_NODISCARD LLVM_ATTRIBUTE_ALWAYS_INLINE bool startswith(StringRef Prefix) const
Check if this string starts with the given Prefix.
.type _foo, STT_GNU_IFUNC
LLVM_NODISCARD LLVM_ATTRIBUTE_ALWAYS_INLINE bool empty() const
empty - Check if the string is empty.
static SectionKind getThreadData()
const char * getPointer() const
A switch()-like statement whose cases are string literals.
The instances of the Type class are immutable: once they are created, they are never changed...
constexpr char TypeName[]
Key for Kernel::Arg::Metadata::mTypeName.
SectionKind - This is a simple POD value that classifies the properties of a section.
bool getAllowAtInIdentifier()
LLVM_NODISCARD LLVM_ATTRIBUTE_ALWAYS_INLINE StringRef drop_back(size_t N=1) const
Return a StringRef equal to 'this' but with the last N elements dropped.
std::enable_if< std::numeric_limits< T >::is_signed, bool >::type getAsInteger(unsigned Radix, T &Result) const
Parse the current string as an integer of the specified radix.
static SectionKind getThreadBSS()
std::pair< MCSection *, const MCExpr * > MCSectionSubPair
BlockVerifier::State From
.type _foo, STT_TLS # aka
static SectionKind getReadOnlyWithRel()
MCSymbol * getBeginSymbol()
LLVM_ATTRIBUTE_ALWAYS_INLINE StringSwitch & Case(StringLiteral S, T Value)
.type _foo, STT_COMMON # aka
.type _foo, STT_FUNC # aka
This represents a section on linux, lots of unix variants and some bare metal systems.
LLVM_ATTRIBUTE_ALWAYS_INLINE StringSwitch & Cases(StringLiteral S0, StringLiteral S1, T Value)
bool isNot(AsmToken::TokenKind K) const
Check if the current token has kind K.
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
Generic interface for extending the MCAsmParser, which is implemented by target and object file assem...
std::pair< MCAsmParserExtension *, DirectiveHandler > ExtensionDirectiveHandler
StringRef - Represent a constant reference to a string, i.e.
Represents a location in source code.
LLVM_NODISCARD LLVM_ATTRIBUTE_ALWAYS_INLINE size_t find(char C, size_t From=0) const
Search for the first character C in the string.
static SectionKind getReadOnly()
static SectionKind getText()
void setBeginSymbol(MCSymbol *Sym)