35 template<
bool (ELFAsmParser::*HandlerMethod)(StringRef, SMLoc)>
36 void addDirectiveHandler(StringRef Directive) {
38 this, HandleDirective<ELFAsmParser, HandlerMethod>);
40 getParser().addDirectiveHandler(Directive, Handler);
43 bool parseSectionSwitch(StringRef Section,
unsigned Type,
unsigned Flags,
47 ELFAsmParser() { BracketExpressionsSupported =
true; }
49 void Initialize(MCAsmParser &Parser)
override {
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<&ELFAsmParser::parseDirectiveSection>(
".section");
61 &ELFAsmParser::parseDirectivePushSection>(
".pushsection");
62 addDirectiveHandler<&ELFAsmParser::parseDirectivePopSection>(
".popsection");
63 addDirectiveHandler<&ELFAsmParser::parseDirectiveSize>(
".size");
64 addDirectiveHandler<&ELFAsmParser::parseDirectivePrevious>(
".previous");
65 addDirectiveHandler<&ELFAsmParser::parseDirectiveType>(
".type");
66 addDirectiveHandler<&ELFAsmParser::parseDirectiveIdent>(
".ident");
67 addDirectiveHandler<&ELFAsmParser::parseDirectiveSymver>(
".symver");
68 addDirectiveHandler<&ELFAsmParser::parseDirectiveVersion>(
".version");
69 addDirectiveHandler<&ELFAsmParser::parseDirectiveWeakref>(
".weakref");
70 addDirectiveHandler<&ELFAsmParser::parseDirectiveSymbolAttribute>(
".weak");
71 addDirectiveHandler<&ELFAsmParser::parseDirectiveSymbolAttribute>(
".local");
73 &ELFAsmParser::parseDirectiveSymbolAttribute>(
".protected");
75 &ELFAsmParser::parseDirectiveSymbolAttribute>(
".internal");
77 &ELFAsmParser::parseDirectiveSymbolAttribute>(
".hidden");
78 addDirectiveHandler<&ELFAsmParser::parseDirectiveSubsection>(
".subsection");
79 addDirectiveHandler<&ELFAsmParser::parseDirectiveCGProfile>(
".cg_profile");
84 bool parseSectionDirectiveData(StringRef, SMLoc) {
89 bool parseSectionDirectiveText(StringRef, SMLoc) {
94 bool parseSectionDirectiveBSS(StringRef, SMLoc) {
99 bool parseSectionDirectiveRoData(StringRef, SMLoc) {
104 bool parseSectionDirectiveTData(StringRef, SMLoc) {
110 bool parseSectionDirectiveTBSS(StringRef, SMLoc) {
116 bool parseDirectivePushSection(StringRef, SMLoc);
117 bool parseDirectivePopSection(StringRef, SMLoc);
118 bool parseDirectiveSection(StringRef, SMLoc);
119 bool parseDirectiveSize(StringRef, SMLoc);
120 bool parseDirectivePrevious(StringRef, SMLoc);
121 bool parseDirectiveType(StringRef, SMLoc);
122 bool parseDirectiveIdent(StringRef, SMLoc);
123 bool parseDirectiveSymver(StringRef, SMLoc);
124 bool parseDirectiveVersion(StringRef, SMLoc);
125 bool parseDirectiveWeakref(StringRef, SMLoc);
126 bool parseDirectiveSymbolAttribute(StringRef, SMLoc);
127 bool parseDirectiveSubsection(StringRef, SMLoc);
128 bool parseDirectiveCGProfile(StringRef, SMLoc);
131 bool parseSectionName(StringRef &SectionName);
132 bool parseSectionArguments(
bool IsPush, SMLoc loc);
133 unsigned parseSunStyleSectionFlags();
134 bool maybeParseSectionType(StringRef &TypeName);
135 bool parseMergeSize(int64_t &
Size);
136 bool parseGroup(StringRef &GroupName,
bool &IsComdat);
137 bool parseLinkedToSym(MCSymbolELF *&LinkedToSym);
145 MCSymbolAttr Attr = StringSwitch<MCSymbolAttr>(Directive)
157 if (getParser().parseIdentifier(Name))
158 return TokError(
"expected identifier");
160 if (getParser().discardLTOSymbol(Name)) {
168 getStreamer().emitSymbolAttribute(Sym, Attr);
174 return TokError(
"expected comma");
183bool ELFAsmParser::parseSectionSwitch(StringRef Section,
unsigned Type,
184 unsigned Flags, SectionKind Kind) {
185 const MCExpr *Subsection =
nullptr;
187 if (getParser().parseExpression(Subsection))
192 getStreamer().switchSection(
getContext().getELFSection(Section,
Type, Flags),
198bool ELFAsmParser::parseDirectiveSize(StringRef, SMLoc) {
201 return TokError(
"expected identifier");
204 return TokError(
"expected comma");
208 if (getParser().parseExpression(Expr))
212 return TokError(
"unexpected token");
215 getStreamer().emitELFSize(Sym, Expr);
219bool ELFAsmParser::parseSectionName(StringRef &SectionName) {
222 SMLoc FirstLoc = getLexer().getLoc();
231 while (!getParser().hasPendingError()) {
232 SMLoc PrevLoc = getLexer().getLoc();
239 CurSize = getTok().getIdentifier().size() + 2;
242 CurSize = getTok().getIdentifier().size();
245 CurSize = getTok().getString().size();
252 if (PrevLoc.
getPointer() + CurSize != getTok().getLoc().getPointer())
262 bool *UseLastGroup) {
269 for (
char i : flagsStr) {
306 if (TT.isARM() || TT.isThumb())
308 else if (TT.isAArch64())
327 if (TT.isOSSolaris())
333 *UseLastGroup =
true;
343unsigned ELFAsmParser::parseSunStyleSectionFlags() {
351 StringRef flagId = getTok().getIdentifier();
352 if (flagId ==
"alloc")
354 else if (flagId ==
"execinstr")
356 else if (flagId ==
"write")
358 else if (flagId ==
"tls")
373bool ELFAsmParser::parseDirectivePushSection(StringRef s, SMLoc loc) {
374 getStreamer().pushSection();
376 if (parseSectionArguments(
true, loc)) {
377 getStreamer().popSection();
384bool ELFAsmParser::parseDirectivePopSection(StringRef, SMLoc) {
385 if (!getStreamer().popSection())
386 return TokError(
".popsection without corresponding .pushsection");
390bool ELFAsmParser::parseDirectiveSection(StringRef, SMLoc loc) {
391 return parseSectionArguments(
false, loc);
394bool ELFAsmParser::maybeParseSectionType(StringRef &TypeName) {
395 AsmLexer &
L = getLexer();
402 return TokError(
"expected '%<type>' or \"<type>\"");
404 return TokError(
"expected '@<type>', '%<type>' or \"<type>\"");
411 }
else if (getParser().parseIdentifier(TypeName))
412 return TokError(
"expected identifier");
416bool ELFAsmParser::parseMergeSize(int64_t &
Size) {
418 return TokError(
"expected the entry size");
420 if (getParser().parseAbsoluteExpression(
Size))
423 return TokError(
"entry size must be positive");
427bool ELFAsmParser::parseGroup(StringRef &GroupName,
bool &IsComdat) {
428 AsmLexer &
L = getLexer();
430 return TokError(
"expected group name");
433 GroupName = getTok().getString();
435 }
else if (getParser().parseIdentifier(GroupName)) {
436 return TokError(
"invalid group name");
441 if (getParser().parseIdentifier(
Linkage))
442 return TokError(
"invalid linkage");
444 return TokError(
"Linkage must be 'comdat'");
452bool ELFAsmParser::parseLinkedToSym(MCSymbolELF *&LinkedToSym) {
453 AsmLexer &
L = getLexer();
455 return TokError(
"expected linked-to symbol");
458 SMLoc StartLoc =
L.getLoc();
459 if (getParser().parseIdentifier(Name)) {
460 if (getParser().getTok().getString() ==
"0") {
462 LinkedToSym =
nullptr;
465 return TokError(
"invalid linked-to symbol");
467 LinkedToSym =
static_cast<MCSymbolELF *
>(
getContext().lookupSymbol(Name));
469 return Error(StartLoc,
"linked-to symbol is not in a section: " + Name);
495bool ELFAsmParser::parseSectionArguments(
bool IsPush, SMLoc loc) {
498 if (parseSectionName(SectionName))
499 return TokError(
"expected identifier");
504 bool IsComdat =
false;
506 unsigned extraFlags = 0;
507 const MCExpr *Subsection =
nullptr;
508 bool UseLastGroup =
false;
509 MCSymbolELF *LinkedToSym =
nullptr;
510 int64_t UniqueID = ~0;
513 if (
hasPrefix(SectionName,
".rodata") || SectionName ==
".rodata1")
515 else if (SectionName ==
".fini" || SectionName ==
".init" ||
518 else if (
hasPrefix(SectionName,
".data") || SectionName ==
".data1" ||
522 hasPrefix(SectionName,
".preinit_array"))
531 if (getParser().parseExpression(Subsection))
540 return TokError(
"expected string");
541 extraFlags = parseSunStyleSectionFlags();
543 StringRef FlagsStr = getTok().getStringContents();
549 if (extraFlags == -1U)
550 return TokError(
"unknown flag");
555 if (Group && UseLastGroup)
556 return TokError(
"Section cannot specifiy a group name while also acting "
557 "as a member of the last group");
559 if (maybeParseSectionType(TypeName))
562 AsmLexer &
L = getLexer();
565 return TokError(
"Mergeable section must specify the type");
567 return TokError(
"Group section must specify the type");
569 return TokError(
"expected end of directive");
572 if (Mergeable || TypeName ==
"llvm_cfi_jump_table")
573 if (parseMergeSize(
Size))
576 if (parseLinkedToSym(LinkedToSym))
579 if (parseGroup(GroupName, IsComdat))
581 if (maybeParseUniqueID(UniqueID))
587 return TokError(
"expected end of directive");
595 else if (
hasPrefix(SectionName,
".init_array"))
599 else if (
hasPrefix(SectionName,
".tbss"))
601 else if (
hasPrefix(SectionName,
".fini_array"))
603 else if (
hasPrefix(SectionName,
".preinit_array"))
606 if (TypeName ==
"init_array")
608 else if (TypeName ==
"fini_array")
610 else if (TypeName ==
"preinit_array")
612 else if (TypeName ==
"nobits")
614 else if (TypeName ==
"progbits")
616 else if (TypeName ==
"note")
618 else if (TypeName ==
"unwind")
620 else if (TypeName ==
"llvm_odrtab")
622 else if (TypeName ==
"llvm_linker_options")
624 else if (TypeName ==
"llvm_call_graph_profile")
626 else if (TypeName ==
"llvm_dependent_libraries")
628 else if (TypeName ==
"llvm_sympart")
630 else if (TypeName ==
"llvm_bb_addr_map")
632 else if (TypeName ==
"llvm_offloading")
634 else if (TypeName ==
"llvm_lto")
636 else if (TypeName ==
"llvm_jt_sizes")
638 else if (TypeName ==
"llvm_cfi_jump_table")
641 return TokError(
"unknown section type");
645 if (
auto *Section =
static_cast<const MCSectionELF *
>(
646 getStreamer().getCurrentSectionOnly()))
647 if (
const MCSymbol *Group =
Section->getGroup()) {
648 GroupName = Group->getName();
649 IsComdat =
Section->isComdat();
656 IsComdat, UniqueID, LinkedToSym);
657 getStreamer().switchSection(Section, Subsection);
664 Error(loc,
"changed section type for " + SectionName +
", expected: 0x" +
667 Error(loc,
"changed section flags for " + SectionName +
", expected: 0x" +
671 Error(loc,
"changed section entsize for " + SectionName +
672 ", expected: " + Twine(
Section->getEntrySize()));
677 bool InsertResult =
getContext().addGenDwarfSection(Section);
679 Warning(loc,
"DWARF2 only supports one section per compilation unit");
685bool ELFAsmParser::parseDirectivePrevious(StringRef DirName, SMLoc) {
687 if (PreviousSection.first ==
nullptr)
688 return TokError(
".previous without corresponding .section");
689 getStreamer().switchSection(PreviousSection.first, PreviousSection.second);
701 .
Cases(
"STT_GNU_IFUNC",
"gnu_indirect_function",
713bool ELFAsmParser::parseDirectiveType(StringRef, SMLoc) {
716 return TokError(
"expected identifier");
718 bool AllowAt = getLexer().getAllowAtInIdentifier();
721 getLexer().setAllowAtInIdentifier(
true);
723 make_scope_exit([&]() { getLexer().setAllowAtInIdentifier(AllowAt); });
737 if (!getLexer().getAllowAtInIdentifier())
738 return TokError(
"expected STT_<TYPE_IN_UPPER_CASE>, '#<type>', "
739 "'%<type>' or \"<type>\"");
741 return TokError(
"expected STT_<TYPE_IN_UPPER_CASE>, '#<type>', '@<type>', "
742 "'%<type>' or \"<type>\"");
749 SMLoc TypeLoc = getLexer().getLoc();
752 if (getParser().parseIdentifier(
Type))
753 return TokError(
"expected symbol type");
757 return Error(TypeLoc,
"unsupported attribute");
760 return TokError(
"expected end of directive");
763 getStreamer().emitSymbolAttribute(Sym, Attr);
770bool ELFAsmParser::parseDirectiveIdent(StringRef, SMLoc) {
772 return TokError(
"expected string");
774 StringRef
Data = getTok().getIdentifier();
779 return TokError(
"expected end of directive");
782 getStreamer().emitIdent(
Data);
788bool ELFAsmParser::parseDirectiveSymver(StringRef, SMLoc) {
790 StringRef
Name, Action;
792 return TokError(
"expected identifier");
795 return TokError(
"expected a comma");
801 const bool AllowAtInIdentifier = getLexer().getAllowAtInIdentifier();
802 getLexer().setAllowAtInIdentifier(
true);
804 getLexer().setAllowAtInIdentifier(AllowAtInIdentifier);
806 if (getParser().parseIdentifier(Name))
807 return TokError(
"expected identifier");
809 if (!
Name.contains(
'@'))
810 return TokError(
"expected a '@' in the name");
811 bool KeepOriginalSym = !
Name.contains(
"@@@");
813 if (getParser().parseIdentifier(Action) || Action !=
"remove")
814 return TokError(
"expected 'remove'");
815 KeepOriginalSym =
false;
819 getStreamer().emitELFSymverDirective(OriginalSym, Name, KeepOriginalSym);
825bool ELFAsmParser::parseDirectiveVersion(StringRef, SMLoc) {
827 return TokError(
"expected string");
829 StringRef
Data = getTok().getIdentifier();
835 getStreamer().pushSection();
836 getStreamer().switchSection(
Note);
837 getStreamer().emitInt32(
Data.size() + 1);
838 getStreamer().emitInt32(0);
839 getStreamer().emitInt32(1);
840 getStreamer().emitBytes(
Data);
841 getStreamer().emitInt8(0);
842 getStreamer().emitValueToAlignment(
Align(4));
843 getStreamer().popSection();
849bool ELFAsmParser::parseDirectiveWeakref(StringRef, SMLoc) {
854 return TokError(
"expected identifier");
857 return TokError(
"expected a comma");
863 return TokError(
"expected identifier");
865 getStreamer().emitWeakReference(Alias, Sym);
869bool ELFAsmParser::parseDirectiveSubsection(StringRef, SMLoc) {
872 if (getParser().parseExpression(Subsection))
877 return TokError(
"expected end of directive");
881 return getStreamer().switchSection(getStreamer().getCurrentSectionOnly(),
885bool ELFAsmParser::parseDirectiveCGProfile(StringRef S, SMLoc Loc) {
892 return new ELFAsmParser;
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
static bool isNot(const MachineRegisterInfo &MRI, const MachineInstr &MI)
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)
This file defines the make_scope_exit function, which executes user-defined cleanup logic at scope ex...
This file implements the StringSwitch template, which mimics a switch() statement whose cases are str...
static bool hasPrefix(StringRef SectionName, StringRef Prefix)
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>
std::pair< MCAsmParserExtension *, DirectiveHandler > ExtensionDirectiveHandler
static LLVM_ABI const MCConstantExpr * create(int64_t Value, MCContext &Ctx, bool PrintInHex=false, unsigned SizeInBytes=0)
bool isInSection() const
isInSection - Check if this symbol is defined in some section (i.e., it is defined but not absolute).
Represents a location in source code.
constexpr const char * getPointer() const
static SectionKind getThreadData()
static SectionKind getText()
static SectionKind getData()
static SectionKind getBSS()
static SectionKind getThreadBSS()
static SectionKind getReadOnly()
StringRef - Represent a constant reference to a string, i.e.
bool getAsInteger(unsigned Radix, T &Result) const
Parse the current string as an integer of the specified radix.
A switch()-like statement whose cases are string literals.
StringSwitch & Case(StringLiteral S, T Value)
StringSwitch & Cases(StringLiteral S0, StringLiteral S1, T Value)
Triple - Helper class for working with autoconf configuration names.
The instances of the Type class are immutable: once they are created, they are never changed.
constexpr char Align[]
Key for Kernel::Arg::Metadata::mAlign.
constexpr char TypeName[]
Key for Kernel::Arg::Metadata::mTypeName.
@ SHT_LLVM_DEPENDENT_LIBRARIES
@ SHT_LLVM_LINKER_OPTIONS
@ SHT_LLVM_CALL_GRAPH_PROFILE
@ SHT_LLVM_CFI_JUMP_TABLE
@ XCORE_SHF_DP_SECTION
All sections with the "d" flag are grouped together by the linker to form the data section and the dp...
@ XCORE_SHF_CP_SECTION
All sections with the "c" flag are grouped together by the linker to form the constant pool and the c...
LLVM_ABI SimpleSymbol parseSymbol(StringRef SymName)
Get symbol classification by parsing the name of a symbol.
LLVM_ABI int getDwarfVersion()
Context & getContext() const
This is an optimization pass for GlobalISel generic memory operations.
detail::scope_exit< std::decay_t< Callable > > make_scope_exit(Callable &&F)
std::string utohexstr(uint64_t X, bool LowerCase=false, unsigned Width=0)
FunctionAddr VTableAddr uintptr_t uintptr_t Data
std::pair< MCSection *, uint32_t > MCSectionSubPair
MCAsmParserExtension * createELFAsmParser()
@ MCSA_Protected
.protected (ELF)
@ MCSA_Internal
.internal (ELF)
@ MCSA_ELF_TypeIndFunction
.type _foo, STT_GNU_IFUNC
@ MCSA_ELF_TypeNoType
.type _foo, STT_NOTYPE # aka @notype
@ MCSA_ELF_TypeTLS
.type _foo, STT_TLS # aka @tls_object
@ MCSA_ELF_TypeCommon
.type _foo, STT_COMMON # aka @common
@ MCSA_ELF_TypeObject
.type _foo, STT_OBJECT # aka @object
@ MCSA_ELF_TypeGnuUniqueObject
@ MCSA_ELF_TypeFunction
.type _foo, STT_FUNC # aka @function
@ MCSA_Hidden
.hidden (ELF)
@ MCSA_Invalid
Not a valid directive.