26 template<
bool (ELFAsmParser::*HandlerMethod)(StringRef, SMLoc)>
27 void addDirectiveHandler(
StringRef Directive) {
29 this, HandleDirective<ELFAsmParser, HandlerMethod>);
31 getParser().addDirectiveHandler(Directive, Handler);
38 ELFAsmParser() { BracketExpressionsSupported =
true; }
44 addDirectiveHandler<&ELFAsmParser::ParseSectionDirectiveData>(
".data");
45 addDirectiveHandler<&ELFAsmParser::ParseSectionDirectiveText>(
".text");
46 addDirectiveHandler<&ELFAsmParser::ParseSectionDirectiveBSS>(
".bss");
47 addDirectiveHandler<&ELFAsmParser::ParseSectionDirectiveRoData>(
".rodata");
48 addDirectiveHandler<&ELFAsmParser::ParseSectionDirectiveTData>(
".tdata");
49 addDirectiveHandler<&ELFAsmParser::ParseSectionDirectiveTBSS>(
".tbss");
51 &ELFAsmParser::ParseSectionDirectiveDataRel>(
".data.rel");
53 &ELFAsmParser::ParseSectionDirectiveDataRelRo>(
".data.rel.ro");
55 &ELFAsmParser::ParseSectionDirectiveEhFrame>(
".eh_frame");
56 addDirectiveHandler<&ELFAsmParser::ParseDirectiveSection>(
".section");
58 &ELFAsmParser::ParseDirectivePushSection>(
".pushsection");
59 addDirectiveHandler<&ELFAsmParser::ParseDirectivePopSection>(
".popsection");
60 addDirectiveHandler<&ELFAsmParser::ParseDirectiveSize>(
".size");
61 addDirectiveHandler<&ELFAsmParser::ParseDirectivePrevious>(
".previous");
62 addDirectiveHandler<&ELFAsmParser::ParseDirectiveType>(
".type");
63 addDirectiveHandler<&ELFAsmParser::ParseDirectiveIdent>(
".ident");
64 addDirectiveHandler<&ELFAsmParser::ParseDirectiveSymver>(
".symver");
65 addDirectiveHandler<&ELFAsmParser::ParseDirectiveVersion>(
".version");
66 addDirectiveHandler<&ELFAsmParser::ParseDirectiveWeakref>(
".weakref");
67 addDirectiveHandler<&ELFAsmParser::ParseDirectiveSymbolAttribute>(
".weak");
68 addDirectiveHandler<&ELFAsmParser::ParseDirectiveSymbolAttribute>(
".local");
70 &ELFAsmParser::ParseDirectiveSymbolAttribute>(
".protected");
72 &ELFAsmParser::ParseDirectiveSymbolAttribute>(
".internal");
74 &ELFAsmParser::ParseDirectiveSymbolAttribute>(
".hidden");
75 addDirectiveHandler<&ELFAsmParser::ParseDirectiveSubsection>(
".subsection");
143 bool ParseSectionArguments(
bool IsPush,
SMLoc loc);
144 unsigned parseSunStyleSectionFlags();
151 bool ELFAsmParser::ParseDirectiveSymbolAttribute(
StringRef Directive,
SMLoc) {
164 if (getParser().parseIdentifier(Name))
165 return TokError(
"expected identifier in directive");
167 MCSymbol *Sym = getContext().getOrCreateSymbol(Name);
169 getStreamer().EmitSymbolAttribute(Sym, Attr);
175 return TokError(
"unexpected token in directive");
186 const MCExpr *Subsection =
nullptr;
188 if (getParser().parseExpression(Subsection))
193 getStreamer().SwitchSection(getContext().getELFSection(Section, Type, Flags),
201 if (getParser().parseIdentifier(Name))
202 return TokError(
"expected identifier in directive");
203 MCSymbolELF *Sym = cast<MCSymbolELF>(getContext().getOrCreateSymbol(Name));
206 return TokError(
"unexpected token in directive");
210 if (getParser().parseExpression(Expr))
214 return TokError(
"unexpected token in directive");
217 getStreamer().emitELFSize(Sym, Expr);
224 SMLoc FirstLoc = getLexer().getLoc();
228 SectionName = getTok().getIdentifier();
235 SMLoc PrevLoc = getLexer().getLoc();
242 CurSize = getTok().getIdentifier().size() + 2;
245 CurSize = getTok().getIdentifier().size();
248 CurSize = getTok().getString().size();
255 if (PrevLoc.
getPointer() + CurSize != getTok().getLoc().getPointer())
271 for (
char i : flagsStr) {
307 *UseLastGroup =
true;
317 unsigned ELFAsmParser::parseSunStyleSectionFlags() {
325 StringRef flagId = getTok().getIdentifier();
326 if (flagId ==
"alloc")
328 else if (flagId ==
"execinstr")
330 else if (flagId ==
"write")
332 else if (flagId ==
"tls")
347 bool ELFAsmParser::ParseDirectivePushSection(
StringRef s,
SMLoc loc) {
348 getStreamer().PushSection();
350 if (ParseSectionArguments(
true, loc)) {
351 getStreamer().PopSection();
359 if (!getStreamer().PopSection())
360 return TokError(
".popsection without corresponding .pushsection");
366 return ParseSectionArguments(
false, loc);
369 bool ELFAsmParser::ParseSectionArguments(
bool IsPush,
SMLoc loc) {
372 if (ParseSectionName(SectionName))
373 return TokError(
"expected identifier in directive");
379 const MCExpr *Subsection =
nullptr;
380 bool UseLastGroup =
false;
382 int64_t UniqueID = ~0;
385 if (SectionName ==
".fini" || SectionName ==
".init" ||
386 SectionName ==
".rodata")
388 if (SectionName ==
".fini" || SectionName ==
".init")
395 if (getParser().parseExpression(Subsection))
405 if (!getContext().getAsmInfo()->usesSunStyleELFSectionSwitchSyntax()
407 return TokError(
"expected string in directive");
408 extraFlags = parseSunStyleSectionFlags();
410 StringRef FlagsStr = getTok().getStringContents();
415 if (extraFlags == -1U)
416 return TokError(
"unknown flag");
421 if (Group && UseLastGroup)
422 return TokError(
"Section cannot specifiy a group name while also acting "
423 "as a member of the last group");
427 return TokError(
"Mergeable section must specify the type");
429 return TokError(
"Group section must specify the type");
437 return TokError(
"expected '@<type>', '%<type>' or \"<type>\"");
439 if (getParser().parseIdentifier(TypeName))
440 return TokError(
"expected identifier in directive");
444 return TokError(
"expected the entry size");
446 if (getParser().parseAbsoluteExpression(Size))
449 return TokError(
"entry size must be positive");
454 return TokError(
"expected group name");
456 if (getParser().parseIdentifier(GroupName))
461 if (getParser().parseIdentifier(Linkage))
463 if (Linkage !=
"comdat")
464 return TokError(
"Linkage must be 'comdat'");
469 if (getParser().parseIdentifier(UniqueStr))
470 return TokError(
"expected identifier in directive");
471 if (UniqueStr !=
"unique")
472 return TokError(
"expected 'unique'");
474 return TokError(
"expected commma");
476 if (getParser().parseAbsoluteExpression(UniqueID))
479 return TokError(
"unique id must be positive");
481 return TokError(
"unique id is too large");
488 return TokError(
"unexpected token in directive");
493 if (TypeName.
empty()) {
496 else if (SectionName ==
".init_array")
498 else if (SectionName ==
".fini_array")
500 else if (SectionName ==
".preinit_array")
503 if (TypeName ==
"init_array")
505 else if (TypeName ==
"fini_array")
507 else if (TypeName ==
"preinit_array")
509 else if (TypeName ==
"nobits")
511 else if (TypeName ==
"progbits")
513 else if (TypeName ==
"note")
515 else if (TypeName ==
"unwind")
518 return TokError(
"unknown section type");
524 cast_or_null<MCSectionELF>(CurrentSection.first))
525 if (
const MCSymbol *Group = Section->getGroup()) {
526 GroupName = Group->getName();
531 MCSection *ELFSection = getContext().getELFSection(SectionName, Type, Flags,
532 Size, GroupName, UniqueID);
533 getStreamer().SwitchSection(ELFSection, Subsection);
535 if (getContext().getGenDwarfForAssembly()) {
536 bool InsertResult = getContext().addGenDwarfSection(ELFSection);
538 if (getContext().getDwarfVersion() <= 2)
539 Warning(loc,
"DWARF2 only supports one section per compilation unit");
542 MCSymbol *SectionStartSymbol = getContext().createTempSymbol();
543 getStreamer().EmitLabel(SectionStartSymbol);
554 if (PreviousSection.first ==
nullptr)
555 return TokError(
".previous without corresponding .section");
556 getStreamer().SwitchSection(PreviousSection.first, PreviousSection.second);
568 .Cases(
"STT_GNU_IFUNC",
"gnu_indirect_function",
582 if (getParser().parseIdentifier(Name))
583 return TokError(
"expected identifier in directive");
586 MCSymbol *Sym = getContext().getOrCreateSymbol(Name);
600 if (!getLexer().getAllowAtInIdentifier())
601 return TokError(
"expected STT_<TYPE_IN_UPPER_CASE>, '#<type>', "
602 "'%<type>' or \"<type>\"");
604 return TokError(
"expected STT_<TYPE_IN_UPPER_CASE>, '#<type>', '@<type>', "
605 "'%<type>' or \"<type>\"");
612 SMLoc TypeLoc = getLexer().getLoc();
615 if (getParser().parseIdentifier(Type))
616 return TokError(
"expected symbol type in directive");
620 return Error(TypeLoc,
"unsupported attribute in '.type' directive");
623 return TokError(
"unexpected token in '.type' directive");
626 getStreamer().EmitSymbolAttribute(Sym, Attr);
635 return TokError(
"unexpected token in '.ident' directive");
642 return TokError(
"unexpected token in '.ident' directive");
645 getStreamer().EmitIdent(Data);
653 if (getParser().parseIdentifier(Name))
654 return TokError(
"expected identifier in directive");
657 return TokError(
"expected a comma");
663 const bool AllowAtInIdentifier = getLexer().getAllowAtInIdentifier();
664 getLexer().setAllowAtInIdentifier(
true);
666 getLexer().setAllowAtInIdentifier(AllowAtInIdentifier);
669 if (getParser().parseIdentifier(AliasName))
670 return TokError(
"expected identifier in directive");
673 return TokError(
"expected a '@' in the name");
675 MCSymbol *Alias = getContext().getOrCreateSymbol(AliasName);
676 MCSymbol *Sym = getContext().getOrCreateSymbol(Name);
679 getStreamer().EmitAssignment(Alias, Value);
687 return TokError(
"unexpected token in '.version' directive");
689 StringRef Data = getTok().getIdentifier();
695 getStreamer().PushSection();
696 getStreamer().SwitchSection(Note);
697 getStreamer().EmitIntValue(Data.
size()+1, 4);
698 getStreamer().EmitIntValue(0, 4);
699 getStreamer().EmitIntValue(1, 4);
700 getStreamer().EmitBytes(Data);
701 getStreamer().EmitIntValue(0, 1);
702 getStreamer().EmitValueToAlignment(4);
703 getStreamer().PopSection();
713 if (getParser().parseIdentifier(AliasName))
714 return TokError(
"expected identifier in directive");
717 return TokError(
"expected a comma");
722 if (getParser().parseIdentifier(Name))
723 return TokError(
"expected identifier in directive");
725 MCSymbol *Alias = getContext().getOrCreateSymbol(AliasName);
727 MCSymbol *Sym = getContext().getOrCreateSymbol(Name);
729 getStreamer().EmitWeakReference(Alias, Sym);
734 const MCExpr *Subsection =
nullptr;
736 if (getParser().parseExpression(Subsection))
741 return TokError(
"unexpected token in directive");
745 getStreamer().SubSection(Subsection);
752 return new ELFAsmParser;
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.
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)
const char * getPointer() const
.type _foo, STT_OBJECT # aka
MCSymbol - Instances of this class represent a symbol name in the MC file, and MCSymbols are created ...
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.
static unsigned parseSectionFlags(StringRef flagsStr, bool *UseLastGroup)
static MCSymbolAttr MCAttrForString(StringRef Type)
.type _foo, STT_NOTYPE # aka
XCORE_SHF_CP_SECTION - All sections with the "c" flag are grouped together by the linker to form the ...
MCAsmParserExtension * createELFAsmParser()
static SectionKind getBSS()
struct fuzzer::@269 Flags
Base class for the full range of assembler expressions which are needed for parsing.
LLVM_ATTRIBUTE_ALWAYS_INLINE R Default(const T &Value) const
LLVM_ATTRIBUTE_ALWAYS_INLINE StringSwitch & Case(const char(&S)[N], const 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
std::pair< MCSection *, const MCExpr * > MCSectionSubPair
static SectionKind getThreadData()
LLVM_NODISCARD LLVM_ATTRIBUTE_ALWAYS_INLINE size_t size() const
size - Get the string size.
A switch()-like statement whose cases are string literals.
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.
The instances of the Type class are immutable: once they are created, they are never changed...
XCORE_SHF_DP_SECTION - All sections with the "d" flag are grouped together by the linker to form the ...
SectionKind - This is a simple POD value that classifies the properties of a section.
std::pair< MCAsmParserExtension *, DirectiveHandler > ExtensionDirectiveHandler
static SectionKind getThreadBSS()
.type _foo, STT_TLS # aka
static SectionKind getReadOnlyWithRel()
MCSymbol * getBeginSymbol()
LLVM_NODISCARD LLVM_ATTRIBUTE_ALWAYS_INLINE bool empty() const
empty - Check if the string is empty.
.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.
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
Generic interface for extending the MCAsmParser, which is implemented by target and object file assem...
std::string DirName(const std::string &FileName)
LLVM Value Representation.
StringRef - Represent a constant reference to a string, i.e.
Represents a location in source code.
static SectionKind getReadOnly()
static SectionKind getText()
void setBeginSymbol(MCSymbol *Sym)