35 template<
bool (ELFAsmParser::*HandlerMethod)(StringRef, SMLoc)>
38 this, HandleDirective<ELFAsmParser, HandlerMethod>);
43 bool parseSectionSwitch(
StringRef Section,
unsigned Type,
unsigned Flags,
47 ELFAsmParser() { BracketExpressionsSupported =
true; }
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");
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);
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,
185 const MCExpr *Subsection =
nullptr;
187 if (getParser().parseExpression(Subsection))
192 getStreamer().switchSection(getContext().getELFSection(Section,
Type, Flags),
200 if (getParser().parseIdentifier(
Name))
201 return TokError(
"expected identifier");
205 return TokError(
"expected comma");
209 if (getParser().parseExpression(Expr))
213 return TokError(
"unexpected token");
216 getStreamer().emitELFSize(
Sym, Expr);
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();
386 if (!getStreamer().popSection())
387 return TokError(
".popsection without corresponding .pushsection");
392 return parseSectionArguments(
false, loc);
395bool ELFAsmParser::maybeParseSectionType(
StringRef &TypeName) {
402 if (getContext().getAsmInfo()->getCommentString().
starts_with(
'@'))
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) {
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");
444 if (Linkage !=
"comdat")
445 return TokError(
"Linkage must be 'comdat'");
453bool ELFAsmParser::parseLinkedToSym(
MCSymbolELF *&LinkedToSym) {
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) {
500 return TokError(
"expected identifier");
505 bool IsComdat =
false;
507 unsigned extraFlags = 0;
508 const MCExpr *Subsection =
nullptr;
509 bool UseLastGroup =
false;
511 int64_t UniqueID = ~0;
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))
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");
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");
647 getStreamer().getCurrentSectionOnly()))
649 GroupName = Group->getName();
650 IsComdat =
Section->isComdat();
657 IsComdat, UniqueID, LinkedToSym);
658 getStreamer().switchSection(Section, Subsection);
666 utohexstr(
Section->getType()));
669 utohexstr(
Section->getFlags()));
675 if (getContext().getGenDwarfForAssembly() &&
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",
716 if (getParser().parseIdentifier(
Name))
717 return TokError(
"expected identifier");
722 bool AllowAt = getLexer().getAllowAtInIdentifier();
724 !getContext().getAsmInfo()->getCommentString().
starts_with(
"@"))
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);
776 return TokError(
"expected string");
778 StringRef Data = getTok().getIdentifier();
783 return TokError(
"expected end of directive");
786 getStreamer().emitIdent(Data);
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);
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();
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");
869 MCSymbol *Alias = getContext().getOrCreateSymbol(AliasName);
873 getStreamer().emitWeakReference(Alias,
Sym);
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 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)
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...
Lightweight error class with error context and mandatory checking.
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>
MCAsmParser & getParser()
Generic assembler parser interface, for use by target specific assembly parsers.
std::pair< MCAsmParserExtension *, DirectiveHandler > ExtensionDirectiveHandler
virtual void addDirectiveHandler(StringRef Directive, ExtensionDirectiveHandler Handler)=0
static LLVM_ABI const MCConstantExpr * create(int64_t Value, MCContext &Ctx, bool PrintInHex=false, unsigned SizeInBytes=0)
Base class for the full range of assembler expressions which are needed for parsing.
This represents a section on linux, lots of unix variants and some bare metal systems.
Instances of this class represent a uniqued identifier for a section in the current translation unit.
MCSymbol - Instances of this class represent a symbol name in the MC file, and MCSymbols are created ...
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
SectionKind - This is a simple POD value that classifies the properties of a section.
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.
Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...
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.
@ 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...
Linkage
Describes symbol linkage. This can be used to resolve definition clashes.
LLVM_ABI int getDwarfVersion()
This is an optimization pass for GlobalISel generic memory operations.
detail::scope_exit< std::decay_t< Callable > > make_scope_exit(Callable &&F)
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.
This struct is a compact representation of a valid (non-zero power of two) alignment.