34 template<
bool (ELFAsmParser::*HandlerMethod)(StringRef, SMLoc)>
35 void addDirectiveHandler(StringRef Directive) {
37 this, HandleDirective<ELFAsmParser, HandlerMethod>);
39 getParser().addDirectiveHandler(Directive, Handler);
42 bool parseSectionSwitch(StringRef Section,
unsigned Type,
unsigned Flags,
46 ELFAsmParser() { BracketExpressionsSupported =
true; }
48 void Initialize(MCAsmParser &Parser)
override {
52 addDirectiveHandler<&ELFAsmParser::parseSectionDirectiveData>(
".data");
53 addDirectiveHandler<&ELFAsmParser::parseSectionDirectiveText>(
".text");
54 addDirectiveHandler<&ELFAsmParser::parseSectionDirectiveBSS>(
".bss");
55 addDirectiveHandler<&ELFAsmParser::parseSectionDirectiveRoData>(
".rodata");
56 addDirectiveHandler<&ELFAsmParser::parseSectionDirectiveTData>(
".tdata");
57 addDirectiveHandler<&ELFAsmParser::parseSectionDirectiveTBSS>(
".tbss");
58 addDirectiveHandler<&ELFAsmParser::parseDirectiveSection>(
".section");
60 &ELFAsmParser::parseDirectivePushSection>(
".pushsection");
61 addDirectiveHandler<&ELFAsmParser::parseDirectivePopSection>(
".popsection");
62 addDirectiveHandler<&ELFAsmParser::parseDirectiveSize>(
".size");
63 addDirectiveHandler<&ELFAsmParser::parseDirectivePrevious>(
".previous");
64 addDirectiveHandler<&ELFAsmParser::parseDirectiveType>(
".type");
65 addDirectiveHandler<&ELFAsmParser::parseDirectiveIdent>(
".ident");
66 addDirectiveHandler<&ELFAsmParser::parseDirectiveSymver>(
".symver");
67 addDirectiveHandler<&ELFAsmParser::parseDirectiveVersion>(
".version");
68 addDirectiveHandler<&ELFAsmParser::parseDirectiveWeakref>(
".weakref");
69 addDirectiveHandler<&ELFAsmParser::parseDirectiveSymbolAttribute>(
".weak");
70 addDirectiveHandler<&ELFAsmParser::parseDirectiveSymbolAttribute>(
".local");
72 &ELFAsmParser::parseDirectiveSymbolAttribute>(
".protected");
74 &ELFAsmParser::parseDirectiveSymbolAttribute>(
".internal");
76 &ELFAsmParser::parseDirectiveSymbolAttribute>(
".hidden");
77 addDirectiveHandler<&ELFAsmParser::parseDirectiveSubsection>(
".subsection");
78 addDirectiveHandler<&ELFAsmParser::parseDirectiveCGProfile>(
".cg_profile");
83 bool parseSectionDirectiveData(StringRef, SMLoc) {
88 bool parseSectionDirectiveText(StringRef, SMLoc) {
93 bool parseSectionDirectiveBSS(StringRef, SMLoc) {
98 bool parseSectionDirectiveRoData(StringRef, SMLoc) {
103 bool parseSectionDirectiveTData(StringRef, SMLoc) {
109 bool parseSectionDirectiveTBSS(StringRef, SMLoc) {
115 bool parseDirectivePushSection(StringRef, SMLoc);
116 bool parseDirectivePopSection(StringRef, SMLoc);
117 bool parseDirectiveSection(StringRef, SMLoc);
118 bool parseDirectiveSize(StringRef, SMLoc);
119 bool parseDirectivePrevious(StringRef, SMLoc);
120 bool parseDirectiveType(StringRef, SMLoc);
121 bool parseDirectiveIdent(StringRef, SMLoc);
122 bool parseDirectiveSymver(StringRef, SMLoc);
123 bool parseDirectiveVersion(StringRef, SMLoc);
124 bool parseDirectiveWeakref(StringRef, SMLoc);
125 bool parseDirectiveSymbolAttribute(StringRef, SMLoc);
126 bool parseDirectiveSubsection(StringRef, SMLoc);
127 bool parseDirectiveCGProfile(StringRef, SMLoc);
130 bool parseSectionName(StringRef &SectionName);
131 bool parseSectionArguments(
bool IsPush, SMLoc loc);
132 unsigned parseSunStyleSectionFlags();
133 bool maybeParseSectionType(StringRef &TypeName);
134 bool parseMergeSize(int64_t &
Size);
135 bool parseGroup(StringRef &GroupName,
bool &IsComdat);
136 bool parseLinkedToSym(MCSymbolELF *&LinkedToSym);
144 MCSymbolAttr Attr = StringSwitch<MCSymbolAttr>(Directive)
156 if (getParser().parseIdentifier(Name))
157 return TokError(
"expected identifier");
159 if (getParser().discardLTOSymbol(Name)) {
167 getStreamer().emitSymbolAttribute(Sym, Attr);
173 return TokError(
"expected comma");
182bool ELFAsmParser::parseSectionSwitch(StringRef Section,
unsigned Type,
183 unsigned Flags, SectionKind Kind) {
184 const MCExpr *Subsection =
nullptr;
186 if (getParser().parseExpression(Subsection))
191 getStreamer().switchSection(
getContext().getELFSection(Section,
Type, Flags),
197bool ELFAsmParser::parseDirectiveSize(StringRef, SMLoc) {
200 return TokError(
"expected identifier");
203 return TokError(
"expected comma");
207 if (getParser().parseExpression(Expr))
211 return TokError(
"unexpected token");
214 getStreamer().emitELFSize(Sym, Expr);
218bool ELFAsmParser::parseSectionName(StringRef &SectionName) {
221 SMLoc FirstLoc = getLexer().getLoc();
230 while (!getParser().hasPendingError()) {
231 SMLoc PrevLoc = getLexer().getLoc();
238 CurSize = getTok().getIdentifier().size() + 2;
241 CurSize = getTok().getIdentifier().size();
244 CurSize = getTok().getString().size();
261 bool *UseLastGroup) {
268 for (
char i : flagsStr) {
305 if (TT.isARM() || TT.isThumb())
307 else if (TT.isAArch64())
326 if (TT.isOSSolaris())
332 *UseLastGroup =
true;
342unsigned ELFAsmParser::parseSunStyleSectionFlags() {
350 StringRef flagId = getTok().getIdentifier();
351 if (flagId ==
"alloc")
353 else if (flagId ==
"execinstr")
355 else if (flagId ==
"write")
357 else if (flagId ==
"tls")
372bool ELFAsmParser::parseDirectivePushSection(StringRef s, SMLoc loc) {
373 getStreamer().pushSection();
375 if (parseSectionArguments(
true, loc)) {
376 getStreamer().popSection();
383bool ELFAsmParser::parseDirectivePopSection(StringRef, SMLoc) {
384 if (!getStreamer().popSection())
385 return TokError(
".popsection without corresponding .pushsection");
389bool ELFAsmParser::parseDirectiveSection(StringRef, SMLoc loc) {
390 return parseSectionArguments(
false, loc);
393bool ELFAsmParser::maybeParseSectionType(StringRef &TypeName) {
394 AsmLexer &
L = getLexer();
401 return TokError(
"expected '%<type>' or \"<type>\"");
403 return TokError(
"expected '@<type>', '%<type>' or \"<type>\"");
410 }
else if (getParser().parseIdentifier(TypeName))
411 return TokError(
"expected identifier");
415bool ELFAsmParser::parseMergeSize(int64_t &
Size) {
417 return TokError(
"expected the entry size");
419 if (getParser().parseAbsoluteExpression(
Size))
422 return TokError(
"entry size must be positive");
426bool ELFAsmParser::parseGroup(StringRef &GroupName,
bool &IsComdat) {
427 AsmLexer &
L = getLexer();
429 return TokError(
"expected group name");
432 GroupName = getTok().getString();
434 }
else if (getParser().parseIdentifier(GroupName)) {
435 return TokError(
"invalid group name");
440 if (getParser().parseIdentifier(
Linkage))
441 return TokError(
"invalid linkage");
443 return TokError(
"Linkage must be 'comdat'");
451bool ELFAsmParser::parseLinkedToSym(MCSymbolELF *&LinkedToSym) {
452 AsmLexer &
L = getLexer();
454 return TokError(
"expected linked-to symbol");
457 SMLoc StartLoc =
L.getLoc();
458 if (getParser().parseIdentifier(Name)) {
459 if (getParser().getTok().getString() ==
"0") {
461 LinkedToSym =
nullptr;
464 return TokError(
"invalid linked-to symbol");
466 LinkedToSym =
static_cast<MCSymbolELF *
>(
getContext().lookupSymbol(Name));
468 return Error(StartLoc,
"linked-to symbol is not in a section: " + Name);
494bool ELFAsmParser::parseSectionArguments(
bool IsPush, SMLoc loc) {
497 if (parseSectionName(SectionName))
498 return TokError(
"expected identifier");
503 bool IsComdat =
false;
505 unsigned extraFlags = 0;
506 const MCExpr *Subsection =
nullptr;
507 bool UseLastGroup =
false;
508 MCSymbolELF *LinkedToSym =
nullptr;
509 int64_t UniqueID = ~0;
512 if (
hasPrefix(SectionName,
".rodata") || SectionName ==
".rodata1")
514 else if (SectionName ==
".fini" || SectionName ==
".init" ||
517 else if (
hasPrefix(SectionName,
".data") || SectionName ==
".data1" ||
521 hasPrefix(SectionName,
".preinit_array"))
530 if (getParser().parseExpression(Subsection))
539 return TokError(
"expected string");
540 extraFlags = parseSunStyleSectionFlags();
542 StringRef FlagsStr = getTok().getStringContents();
548 if (extraFlags == -1U)
549 return TokError(
"unknown flag");
554 if (Group && UseLastGroup)
555 return TokError(
"Section cannot specifiy a group name while also acting "
556 "as a member of the last group");
558 if (maybeParseSectionType(TypeName))
561 AsmLexer &
L = getLexer();
564 return TokError(
"Mergeable section must specify the type");
566 return TokError(
"Group section must specify the type");
568 return TokError(
"expected end of directive");
571 if (Mergeable || TypeName ==
"llvm_cfi_jump_table")
572 if (parseMergeSize(
Size))
575 if (parseLinkedToSym(LinkedToSym))
578 if (parseGroup(GroupName, IsComdat))
580 if (maybeParseUniqueID(UniqueID))
586 return TokError(
"expected end of directive");
594 else if (
hasPrefix(SectionName,
".init_array"))
598 else if (
hasPrefix(SectionName,
".tbss"))
600 else if (
hasPrefix(SectionName,
".fini_array"))
602 else if (
hasPrefix(SectionName,
".preinit_array"))
605 if (TypeName ==
"init_array")
607 else if (TypeName ==
"fini_array")
609 else if (TypeName ==
"preinit_array")
611 else if (TypeName ==
"nobits")
613 else if (TypeName ==
"progbits")
615 else if (TypeName ==
"note")
617 else if (TypeName ==
"unwind")
619 else if (TypeName ==
"llvm_odrtab")
621 else if (TypeName ==
"llvm_linker_options")
623 else if (TypeName ==
"llvm_call_graph_profile")
625 else if (TypeName ==
"llvm_dependent_libraries")
627 else if (TypeName ==
"llvm_sympart")
629 else if (TypeName ==
"llvm_bb_addr_map")
631 else if (TypeName ==
"llvm_offloading")
633 else if (TypeName ==
"llvm_lto")
635 else if (TypeName ==
"llvm_jt_sizes")
637 else if (TypeName ==
"llvm_cfi_jump_table")
639 else if (TypeName ==
"llvm_call_graph")
642 return TokError(
"unknown section type");
646 if (
auto *Section =
static_cast<const MCSectionELF *
>(
647 getStreamer().getCurrentSectionOnly()))
648 if (
const MCSymbol *Group =
Section->getGroup()) {
649 GroupName = Group->getName();
650 IsComdat =
Section->isComdat();
657 IsComdat, UniqueID, LinkedToSym);
658 getStreamer().switchSection(Section, Subsection);
665 Error(loc,
"changed section type for " + SectionName +
", expected: 0x" +
668 Error(loc,
"changed section flags for " + SectionName +
", expected: 0x" +
672 Error(loc,
"changed section entsize for " + SectionName +
673 ", expected: " + Twine(
Section->getEntrySize()));
678 bool InsertResult =
getContext().addGenDwarfSection(Section);
680 Warning(loc,
"DWARF2 only supports one section per compilation unit");
686bool ELFAsmParser::parseDirectivePrevious(StringRef DirName, SMLoc) {
688 if (PreviousSection.first ==
nullptr)
689 return TokError(
".previous without corresponding .section");
690 getStreamer().switchSection(PreviousSection.first, PreviousSection.second);
702 .Cases({
"STT_GNU_IFUNC",
"gnu_indirect_function"},
714bool ELFAsmParser::parseDirectiveType(StringRef, SMLoc) {
717 return TokError(
"expected identifier");
719 bool AllowAt = getLexer().getAllowAtInIdentifier();
722 getLexer().setAllowAtInIdentifier(
true);
724 make_scope_exit([&]() { getLexer().setAllowAtInIdentifier(AllowAt); });
738 if (!getLexer().getAllowAtInIdentifier())
739 return TokError(
"expected STT_<TYPE_IN_UPPER_CASE>, '#<type>', "
740 "'%<type>' or \"<type>\"");
742 return TokError(
"expected STT_<TYPE_IN_UPPER_CASE>, '#<type>', '@<type>', "
743 "'%<type>' or \"<type>\"");
750 SMLoc TypeLoc = getLexer().getLoc();
753 if (getParser().parseIdentifier(
Type))
754 return TokError(
"expected symbol type");
758 return Error(TypeLoc,
"unsupported attribute");
761 return TokError(
"expected end of directive");
764 getStreamer().emitSymbolAttribute(Sym, Attr);
771bool ELFAsmParser::parseDirectiveIdent(StringRef, SMLoc) {
773 return TokError(
"expected string");
775 StringRef
Data = getTok().getIdentifier();
780 return TokError(
"expected end of directive");
783 getStreamer().emitIdent(
Data);
789bool ELFAsmParser::parseDirectiveSymver(StringRef, SMLoc) {
791 StringRef
Name, Action;
793 return TokError(
"expected identifier");
796 return TokError(
"expected a comma");
802 const bool AllowAtInIdentifier = getLexer().getAllowAtInIdentifier();
803 getLexer().setAllowAtInIdentifier(
true);
805 getLexer().setAllowAtInIdentifier(AllowAtInIdentifier);
807 if (getParser().parseIdentifier(Name))
808 return TokError(
"expected identifier");
810 if (!
Name.contains(
'@'))
811 return TokError(
"expected a '@' in the name");
812 bool KeepOriginalSym = !
Name.contains(
"@@@");
814 if (getParser().parseIdentifier(Action) || Action !=
"remove")
815 return TokError(
"expected 'remove'");
816 KeepOriginalSym =
false;
820 getStreamer().emitELFSymverDirective(OriginalSym, Name, KeepOriginalSym);
826bool ELFAsmParser::parseDirectiveVersion(StringRef, SMLoc) {
828 return TokError(
"expected string");
830 StringRef
Data = getTok().getIdentifier();
836 getStreamer().pushSection();
837 getStreamer().switchSection(
Note);
838 getStreamer().emitInt32(
Data.size() + 1);
839 getStreamer().emitInt32(0);
840 getStreamer().emitInt32(1);
841 getStreamer().emitBytes(
Data);
842 getStreamer().emitInt8(0);
843 getStreamer().emitValueToAlignment(
Align(4));
844 getStreamer().popSection();
850bool ELFAsmParser::parseDirectiveWeakref(StringRef, SMLoc) {
855 return TokError(
"expected identifier");
858 return TokError(
"expected a comma");
864 return TokError(
"expected identifier");
866 getStreamer().emitWeakReference(Alias, Sym);
870bool ELFAsmParser::parseDirectiveSubsection(StringRef, SMLoc) {
873 if (getParser().parseExpression(Subsection))
878 return TokError(
"expected end of directive");
882 return getStreamer().switchSection(getStreamer().getCurrentSectionOnly(),
886bool ELFAsmParser::parseDirectiveCGProfile(StringRef S, SMLoc Loc) {
893 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)
Value * getPointer(Value *Ptr)
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 & Cases(std::initializer_list< StringLiteral > CaseStrings, 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.
@ 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...
@ SHT_LLVM_DEPENDENT_LIBRARIES
@ SHT_LLVM_LINKER_OPTIONS
@ SHT_LLVM_CALL_GRAPH_PROFILE
@ SHT_LLVM_CFI_JUMP_TABLE
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.