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::ParseSectionDirectiveDataRelRoLocal>(
".data.rel.ro.local");
57 &ELFAsmParser::ParseSectionDirectiveEhFrame>(
".eh_frame");
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");
152 bool ParseSectionName(
StringRef &SectionName);
153 bool ParseSectionArguments(
bool IsPush,
SMLoc loc);
154 unsigned parseSunStyleSectionFlags();
161 bool ELFAsmParser::ParseDirectiveSymbolAttribute(
StringRef Directive,
SMLoc) {
169 assert(Attr !=
MCSA_Invalid &&
"unexpected symbol attribute directive!");
174 if (getParser().parseIdentifier(Name))
175 return TokError(
"expected identifier in directive");
177 MCSymbol *Sym = getContext().getOrCreateSymbol(Name);
179 getStreamer().EmitSymbolAttribute(Sym, Attr);
185 return TokError(
"unexpected token in directive");
196 const MCExpr *Subsection =
nullptr;
198 if (getParser().parseExpression(Subsection))
202 getStreamer().SwitchSection(getContext().getELFSection(Section, Type, Flags),
210 if (getParser().parseIdentifier(Name))
211 return TokError(
"expected identifier in directive");
212 MCSymbolELF *Sym = cast<MCSymbolELF>(getContext().getOrCreateSymbol(Name));
215 return TokError(
"unexpected token in directive");
219 if (getParser().parseExpression(Expr))
223 return TokError(
"unexpected token in directive");
225 getStreamer().emitELFSize(Sym, Expr);
229 bool ELFAsmParser::ParseSectionName(
StringRef &SectionName) {
232 SMLoc FirstLoc = getLexer().getLoc();
236 SectionName = getTok().getIdentifier();
244 SMLoc PrevLoc = getLexer().getLoc();
249 CurSize = getTok().getIdentifier().size() + 2;
252 CurSize = getTok().getIdentifier().size();
262 if (PrevLoc.
getPointer() + CurSize != getTok().getLoc().getPointer())
274 for (
unsigned i = 0; i < flagsStr.
size(); i++) {
275 switch (flagsStr[i]) {
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");
492 if (TypeName.
empty()) {
495 else if (SectionName ==
".init_array")
497 else if (SectionName ==
".fini_array")
499 else if (SectionName ==
".preinit_array")
502 if (TypeName ==
"init_array")
504 else if (TypeName ==
"fini_array")
506 else if (TypeName ==
"preinit_array")
508 else if (TypeName ==
"nobits")
510 else if (TypeName ==
"progbits")
512 else if (TypeName ==
"note")
514 else if (TypeName ==
"unwind")
517 return TokError(
"unknown section type");
523 cast_or_null<MCSectionELF>(CurrentSection.first))
524 if (
const MCSymbol *Group = Section->getGroup()) {
525 GroupName = Group->getName();
530 MCSection *ELFSection = getContext().getELFSection(SectionName, Type, Flags,
531 Size, GroupName, UniqueID);
532 getStreamer().SwitchSection(ELFSection, Subsection);
534 if (getContext().getGenDwarfForAssembly()) {
535 bool InsertResult = getContext().addGenDwarfSection(ELFSection);
537 if (getContext().getDwarfVersion() <= 2)
538 Warning(loc,
"DWARF2 only supports one section per compilation unit");
541 MCSymbol *SectionStartSymbol = getContext().createTempSymbol();
542 getStreamer().EmitLabel(SectionStartSymbol);
551 bool ELFAsmParser::ParseDirectivePrevious(
StringRef DirName,
SMLoc) {
553 if (PreviousSection.first ==
nullptr)
554 return TokError(
".previous without corresponding .section");
555 getStreamer().SwitchSection(PreviousSection.first, PreviousSection.second);
567 .
Cases(
"STT_GNU_IFUNC",
"gnu_indirect_function",
581 if (getParser().parseIdentifier(Name))
582 return TokError(
"expected identifier in directive");
585 MCSymbol *Sym = getContext().getOrCreateSymbol(Name);
599 if (!getLexer().getAllowAtInIdentifier())
600 return TokError(
"expected STT_<TYPE_IN_UPPER_CASE>, '#<type>', "
601 "'%<type>' or \"<type>\"");
603 return TokError(
"expected STT_<TYPE_IN_UPPER_CASE>, '#<type>', '@<type>', "
604 "'%<type>' or \"<type>\"");
611 SMLoc TypeLoc = getLexer().getLoc();
614 if (getParser().parseIdentifier(Type))
615 return TokError(
"expected symbol type in directive");
619 return Error(TypeLoc,
"unsupported attribute in '.type' directive");
622 return TokError(
"unexpected token in '.type' directive");
625 getStreamer().EmitSymbolAttribute(Sym, Attr);
634 return TokError(
"unexpected token in '.ident' directive");
640 getStreamer().EmitIdent(Data);
648 if (getParser().parseIdentifier(Name))
649 return TokError(
"expected identifier in directive");
652 return TokError(
"expected a comma");
658 const bool AllowAtInIdentifier = getLexer().getAllowAtInIdentifier();
659 getLexer().setAllowAtInIdentifier(
true);
661 getLexer().setAllowAtInIdentifier(AllowAtInIdentifier);
664 if (getParser().parseIdentifier(AliasName))
665 return TokError(
"expected identifier in directive");
668 return TokError(
"expected a '@' in the name");
670 MCSymbol *Alias = getContext().getOrCreateSymbol(AliasName);
671 MCSymbol *Sym = getContext().getOrCreateSymbol(Name);
674 getStreamer().EmitAssignment(Alias, Value);
682 return TokError(
"unexpected token in '.version' directive");
684 StringRef Data = getTok().getIdentifier();
690 getStreamer().PushSection();
691 getStreamer().SwitchSection(Note);
692 getStreamer().EmitIntValue(Data.
size()+1, 4);
693 getStreamer().EmitIntValue(0, 4);
694 getStreamer().EmitIntValue(1, 4);
695 getStreamer().EmitBytes(Data);
696 getStreamer().EmitIntValue(0, 1);
697 getStreamer().EmitValueToAlignment(4);
698 getStreamer().PopSection();
708 if (getParser().parseIdentifier(AliasName))
709 return TokError(
"expected identifier in directive");
712 return TokError(
"expected a comma");
717 if (getParser().parseIdentifier(Name))
718 return TokError(
"expected identifier in directive");
720 MCSymbol *Alias = getContext().getOrCreateSymbol(AliasName);
722 MCSymbol *Sym = getContext().getOrCreateSymbol(Name);
724 getStreamer().EmitWeakReference(Alias, Sym);
729 const MCExpr *Subsection =
nullptr;
731 if (getParser().parseExpression(Subsection))
736 return TokError(
"unexpected token in directive");
738 getStreamer().SubSection(Subsection);
745 return new ELFAsmParser;
static SectionKind getReadOnlyWithRelLocal()
Instances of this class represent a uniqued identifier for a section in the current translation unit...
static const MCSymbolRefExpr * create(const MCSymbol *Symbol, MCContext &Ctx)
const char * getPointer() const
size_t size() const
size - Get the string size.
.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.
size_t find(char C, size_t From=0) const
Search for the first character C in the string.
static SectionKind getDataRel()
static unsigned parseSectionFlags(StringRef flagsStr, bool *UseLastGroup)
static MCSymbolAttr MCAttrForString(StringRef Type)
.type _foo, STT_NOTYPE # aka
StringSwitch & Case(const char(&S)[N], const T &Value)
MCAsmParserExtension * createELFAsmParser()
static SectionKind getBSS()
Base class for the full range of assembler expressions which are needed for parsing.
.type _foo, STT_GNU_IFUNC
std::pair< MCSection *, const MCExpr * > MCSectionSubPair
static SectionKind getThreadData()
A switch()-like statement whose cases are string literals.
The instances of the Type class are immutable: once they are created, they are never changed...
SectionKind - This is a simple POD value that classifies the properties of a section.
std::pair< MCAsmParserExtension *, DirectiveHandler > ExtensionDirectiveHandler
bool startswith(StringRef Prefix) const
Check if this string starts with the given Prefix.
static SectionKind getThreadBSS()
.type _foo, STT_TLS # aka
static SectionKind getReadOnlyWithRel()
MCSymbol * getBeginSymbol()
R Default(const T &Value) const
bool isUInt< 32 >(uint64_t x)
.type _foo, STT_COMMON # aka
.type _foo, STT_FUNC # aka
MCSectionELF - This represents a section on linux, lots of unix variants and some bare metal systems...
const ARM::ArchExtKind Kind
Generic interface for extending the MCAsmParser, which is implemented by target and object file assem...
LLVM Value Representation.
StringSwitch & Cases(const char(&S0)[N0], const char(&S1)[N1], const T &Value)
XCORE_SHF_CP_SECTION - All sections with the "c" flag are grouped together by the linker to form the ...
StringRef - Represent a constant reference to a string, i.e.
Represents a location in source code.
static SectionKind getReadOnly()
XCORE_SHF_DP_SECTION - All sections with the "d" flag are grouped together by the linker to form the ...
bool empty() const
empty - Check if the string is empty.
static SectionKind getText()
void setBeginSymbol(MCSymbol *Sym)