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) {
200 if (getParser().parseIdentifier(Name))
201 return TokError(
"expected identifier");
202 auto *Sym =
static_cast<MCSymbolELF *
>(
getContext().getOrCreateSymbol(Name));
205 return TokError(
"expected comma");
209 if (getParser().parseExpression(Expr))
213 return TokError(
"unexpected token");
216 getStreamer().emitELFSize(Sym, Expr);
220bool ELFAsmParser::parseSectionName(StringRef &SectionName) {
223 SMLoc FirstLoc = getLexer().getLoc();
232 while (!getParser().hasPendingError()) {
233 SMLoc PrevLoc = getLexer().getLoc();
240 CurSize = getTok().getIdentifier().size() + 2;
243 CurSize = getTok().getIdentifier().size();
246 CurSize = getTok().getString().size();
253 if (PrevLoc.
getPointer() + CurSize != getTok().getLoc().getPointer())
263 bool *UseLastGroup) {
270 for (
char i : flagsStr) {
307 if (TT.isARM() || TT.isThumb())
309 else if (TT.isAArch64())
328 if (TT.isOSSolaris())
334 *UseLastGroup =
true;
344unsigned ELFAsmParser::parseSunStyleSectionFlags() {
352 StringRef flagId = getTok().getIdentifier();
353 if (flagId ==
"alloc")
355 else if (flagId ==
"execinstr")
357 else if (flagId ==
"write")
359 else if (flagId ==
"tls")
374bool ELFAsmParser::parseDirectivePushSection(StringRef s, SMLoc loc) {
375 getStreamer().pushSection();
377 if (parseSectionArguments(
true, loc)) {
378 getStreamer().popSection();
385bool ELFAsmParser::parseDirectivePopSection(StringRef, SMLoc) {
386 if (!getStreamer().popSection())
387 return TokError(
".popsection without corresponding .pushsection");
391bool ELFAsmParser::parseDirectiveSection(StringRef, SMLoc loc) {
392 return parseSectionArguments(
false, loc);
395bool ELFAsmParser::maybeParseSectionType(StringRef &TypeName) {
396 AsmLexer &
L = getLexer();
403 return TokError(
"expected '%<type>' or \"<type>\"");
405 return TokError(
"expected '@<type>', '%<type>' or \"<type>\"");
412 }
else if (getParser().parseIdentifier(TypeName))
413 return TokError(
"expected identifier");
417bool ELFAsmParser::parseMergeSize(int64_t &
Size) {
419 return TokError(
"expected the entry size");
421 if (getParser().parseAbsoluteExpression(
Size))
424 return TokError(
"entry size must be positive");
428bool ELFAsmParser::parseGroup(StringRef &GroupName,
bool &IsComdat) {
429 AsmLexer &
L = getLexer();
431 return TokError(
"expected group name");
434 GroupName = getTok().getString();
436 }
else if (getParser().parseIdentifier(GroupName)) {
437 return TokError(
"invalid group name");
442 if (getParser().parseIdentifier(
Linkage))
443 return TokError(
"invalid linkage");
445 return TokError(
"Linkage must be 'comdat'");
453bool ELFAsmParser::parseLinkedToSym(MCSymbolELF *&LinkedToSym) {
454 AsmLexer &
L = getLexer();
456 return TokError(
"expected linked-to symbol");
459 SMLoc StartLoc =
L.getLoc();
460 if (getParser().parseIdentifier(Name)) {
461 if (getParser().getTok().getString() ==
"0") {
463 LinkedToSym =
nullptr;
466 return TokError(
"invalid linked-to symbol");
468 LinkedToSym =
static_cast<MCSymbolELF *
>(
getContext().lookupSymbol(Name));
470 return Error(StartLoc,
"linked-to symbol is not in a section: " + Name);
496bool ELFAsmParser::parseSectionArguments(
bool IsPush, SMLoc loc) {
499 if (parseSectionName(SectionName))
500 return TokError(
"expected identifier");
505 bool IsComdat =
false;
507 unsigned extraFlags = 0;
508 const MCExpr *Subsection =
nullptr;
509 bool UseLastGroup =
false;
510 MCSymbolELF *LinkedToSym =
nullptr;
511 int64_t UniqueID = ~0;
514 if (
hasPrefix(SectionName,
".rodata") || SectionName ==
".rodata1")
516 else if (SectionName ==
".fini" || SectionName ==
".init" ||
519 else if (
hasPrefix(SectionName,
".data") || SectionName ==
".data1" ||
523 hasPrefix(SectionName,
".preinit_array"))
532 if (getParser().parseExpression(Subsection))
541 return TokError(
"expected string");
542 extraFlags = parseSunStyleSectionFlags();
544 StringRef FlagsStr = getTok().getStringContents();
550 if (extraFlags == -1U)
551 return TokError(
"unknown flag");
556 if (Group && UseLastGroup)
557 return TokError(
"Section cannot specifiy a group name while also acting "
558 "as a member of the last group");
560 if (maybeParseSectionType(TypeName))
563 AsmLexer &
L = getLexer();
566 return TokError(
"Mergeable section must specify the type");
568 return TokError(
"Group section must specify the type");
570 return TokError(
"expected end of directive");
573 if (Mergeable || TypeName ==
"llvm_cfi_jump_table")
574 if (parseMergeSize(
Size))
577 if (parseLinkedToSym(LinkedToSym))
580 if (parseGroup(GroupName, IsComdat))
582 if (maybeParseUniqueID(UniqueID))
588 return TokError(
"expected end of directive");
596 else if (
hasPrefix(SectionName,
".init_array"))
600 else if (
hasPrefix(SectionName,
".tbss"))
602 else if (
hasPrefix(SectionName,
".fini_array"))
604 else if (
hasPrefix(SectionName,
".preinit_array"))
607 if (TypeName ==
"init_array")
609 else if (TypeName ==
"fini_array")
611 else if (TypeName ==
"preinit_array")
613 else if (TypeName ==
"nobits")
615 else if (TypeName ==
"progbits")
617 else if (TypeName ==
"note")
619 else if (TypeName ==
"unwind")
621 else if (TypeName ==
"llvm_odrtab")
623 else if (TypeName ==
"llvm_linker_options")
625 else if (TypeName ==
"llvm_call_graph_profile")
627 else if (TypeName ==
"llvm_dependent_libraries")
629 else if (TypeName ==
"llvm_sympart")
631 else if (TypeName ==
"llvm_bb_addr_map")
633 else if (TypeName ==
"llvm_offloading")
635 else if (TypeName ==
"llvm_lto")
637 else if (TypeName ==
"llvm_jt_sizes")
639 else if (TypeName ==
"llvm_cfi_jump_table")
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) {
716 if (getParser().parseIdentifier(Name))
717 return TokError(
"expected identifier");
722 bool AllowAt = getLexer().getAllowAtInIdentifier();
725 getLexer().setAllowAtInIdentifier(
true);
727 make_scope_exit([&]() { getLexer().setAllowAtInIdentifier(AllowAt); });
741 if (!getLexer().getAllowAtInIdentifier())
742 return TokError(
"expected STT_<TYPE_IN_UPPER_CASE>, '#<type>', "
743 "'%<type>' or \"<type>\"");
745 return TokError(
"expected STT_<TYPE_IN_UPPER_CASE>, '#<type>', '@<type>', "
746 "'%<type>' or \"<type>\"");
753 SMLoc TypeLoc = getLexer().getLoc();
756 if (getParser().parseIdentifier(
Type))
757 return TokError(
"expected symbol type");
761 return Error(TypeLoc,
"unsupported attribute");
764 return TokError(
"expected end of directive");
767 getStreamer().emitSymbolAttribute(Sym, Attr);
774bool ELFAsmParser::parseDirectiveIdent(StringRef, SMLoc) {
776 return TokError(
"expected string");
778 StringRef
Data = getTok().getIdentifier();
783 return TokError(
"expected end of directive");
786 getStreamer().emitIdent(
Data);
792bool ELFAsmParser::parseDirectiveSymver(StringRef, SMLoc) {
793 StringRef OriginalName,
Name, Action;
794 if (getParser().parseIdentifier(OriginalName))
795 return TokError(
"expected identifier");
798 return TokError(
"expected a comma");
804 const bool AllowAtInIdentifier = getLexer().getAllowAtInIdentifier();
805 getLexer().setAllowAtInIdentifier(
true);
807 getLexer().setAllowAtInIdentifier(AllowAtInIdentifier);
809 if (getParser().parseIdentifier(Name))
810 return TokError(
"expected identifier");
812 if (!
Name.contains(
'@'))
813 return TokError(
"expected a '@' in the name");
814 bool KeepOriginalSym = !
Name.contains(
"@@@");
816 if (getParser().parseIdentifier(Action) || Action !=
"remove")
817 return TokError(
"expected 'remove'");
818 KeepOriginalSym =
false;
822 getStreamer().emitELFSymverDirective(
823 getContext().getOrCreateSymbol(OriginalName), Name, KeepOriginalSym);
829bool ELFAsmParser::parseDirectiveVersion(StringRef, SMLoc) {
831 return TokError(
"expected string");
833 StringRef
Data = getTok().getIdentifier();
839 getStreamer().pushSection();
840 getStreamer().switchSection(
Note);
841 getStreamer().emitInt32(
Data.size() + 1);
842 getStreamer().emitInt32(0);
843 getStreamer().emitInt32(1);
844 getStreamer().emitBytes(
Data);
845 getStreamer().emitInt8(0);
846 getStreamer().emitValueToAlignment(
Align(4));
847 getStreamer().popSection();
853bool ELFAsmParser::parseDirectiveWeakref(StringRef, SMLoc) {
857 if (getParser().parseIdentifier(AliasName))
858 return TokError(
"expected identifier");
861 return TokError(
"expected a comma");
866 if (getParser().parseIdentifier(Name))
867 return TokError(
"expected identifier");
873 getStreamer().emitWeakReference(Alias, Sym);
877bool ELFAsmParser::parseDirectiveSubsection(StringRef, SMLoc) {
880 if (getParser().parseExpression(Subsection))
885 return TokError(
"expected end of directive");
889 return getStreamer().switchSection(getStreamer().getCurrentSectionOnly(),
893bool ELFAsmParser::parseDirectiveCGProfile(StringRef S, SMLoc Loc) {
900 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 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.