35 template<
bool (ELFAsmParser::*HandlerMethod)(StringRef, SMLoc)>
38 this, HandleDirective<ELFAsmParser, HandlerMethod>);
40 getParser().addDirectiveHandler(
Directive, Handler);
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");
60 &ELFAsmParser::ParseSectionDirectiveDataRel>(
".data.rel");
62 &ELFAsmParser::ParseSectionDirectiveDataRelRo>(
".data.rel.ro");
64 &ELFAsmParser::ParseSectionDirectiveEhFrame>(
".eh_frame");
65 addDirectiveHandler<&ELFAsmParser::ParseDirectiveSection>(
".section");
67 &ELFAsmParser::ParseDirectivePushSection>(
".pushsection");
68 addDirectiveHandler<&ELFAsmParser::ParseDirectivePopSection>(
".popsection");
69 addDirectiveHandler<&ELFAsmParser::ParseDirectiveSize>(
".size");
70 addDirectiveHandler<&ELFAsmParser::ParseDirectivePrevious>(
".previous");
71 addDirectiveHandler<&ELFAsmParser::ParseDirectiveType>(
".type");
72 addDirectiveHandler<&ELFAsmParser::ParseDirectiveIdent>(
".ident");
73 addDirectiveHandler<&ELFAsmParser::ParseDirectiveSymver>(
".symver");
74 addDirectiveHandler<&ELFAsmParser::ParseDirectiveVersion>(
".version");
75 addDirectiveHandler<&ELFAsmParser::ParseDirectiveWeakref>(
".weakref");
76 addDirectiveHandler<&ELFAsmParser::ParseDirectiveSymbolAttribute>(
".weak");
77 addDirectiveHandler<&ELFAsmParser::ParseDirectiveSymbolAttribute>(
".local");
79 &ELFAsmParser::ParseDirectiveSymbolAttribute>(
".protected");
81 &ELFAsmParser::ParseDirectiveSymbolAttribute>(
".internal");
83 &ELFAsmParser::ParseDirectiveSymbolAttribute>(
".hidden");
84 addDirectiveHandler<&ELFAsmParser::ParseDirectiveSubsection>(
".subsection");
85 addDirectiveHandler<&ELFAsmParser::ParseDirectiveCGProfile>(
".cg_profile");
154 bool ParseSectionArguments(
bool IsPush,
SMLoc loc);
155 unsigned parseSunStyleSectionFlags();
157 bool parseMergeSize(int64_t &Size);
158 bool parseGroup(
StringRef &GroupName,
bool &IsComdat);
160 bool maybeParseUniqueID(int64_t &UniqueID);
180 if (getParser().parseIdentifier(
Name))
181 return TokError(
"expected identifier in directive");
183 if (getParser().discardLTOSymbol(
Name)) {
191 getStreamer().emitSymbolAttribute(Sym, Attr);
197 return TokError(
"unexpected token in directive");
206 bool ELFAsmParser::ParseSectionSwitch(
StringRef Section,
unsigned Type,
208 const MCExpr *Subsection =
nullptr;
210 if (getParser().parseExpression(Subsection))
215 getStreamer().SwitchSection(getContext().getELFSection(Section,
Type, Flags),
223 if (getParser().parseIdentifier(
Name))
224 return TokError(
"expected identifier in directive");
225 MCSymbolELF *Sym = cast<MCSymbolELF>(getContext().getOrCreateSymbol(
Name));
228 return TokError(
"unexpected token in directive");
232 if (getParser().parseExpression(Expr))
236 return TokError(
"unexpected token in directive");
239 getStreamer().emitELFSize(Sym, Expr);
246 SMLoc FirstLoc = getLexer().getLoc();
255 while (!getParser().hasPendingError()) {
256 SMLoc PrevLoc = getLexer().getLoc();
263 CurSize = getTok().getIdentifier().size() + 2;
266 CurSize = getTok().getIdentifier().size();
269 CurSize = getTok().getString().size();
276 if (PrevLoc.
getPointer() + CurSize != getTok().getLoc().getPointer())
286 bool *UseLastGroup) {
293 for (
char i : flagsStr) {
335 if (TT.isOSSolaris())
341 *UseLastGroup =
true;
351 unsigned ELFAsmParser::parseSunStyleSectionFlags() {
359 StringRef flagId = getTok().getIdentifier();
360 if (flagId ==
"alloc")
362 else if (flagId ==
"execinstr")
364 else if (flagId ==
"write")
366 else if (flagId ==
"tls")
382 getStreamer().PushSection();
384 if (ParseSectionArguments(
true, loc)) {
385 getStreamer().PopSection();
393 if (!getStreamer().PopSection())
394 return TokError(
".popsection without corresponding .pushsection");
399 return ParseSectionArguments(
false, loc);
410 return TokError(
"expected '@<type>', '%<type>' or \"<type>\"");
412 return TokError(
"expected '%<type>' or \"<type>\"");
419 }
else if (getParser().parseIdentifier(
TypeName))
420 return TokError(
"expected identifier in directive");
424 bool ELFAsmParser::parseMergeSize(int64_t &Size) {
426 return TokError(
"expected the entry size");
428 if (getParser().parseAbsoluteExpression(Size))
431 return TokError(
"entry size must be positive");
435 bool ELFAsmParser::parseGroup(
StringRef &GroupName,
bool &IsComdat) {
438 return TokError(
"expected group name");
441 GroupName = getTok().getString();
443 }
else if (getParser().parseIdentifier(GroupName)) {
444 return TokError(
"invalid group name");
449 if (getParser().parseIdentifier(Linkage))
450 return TokError(
"invalid linkage");
451 if (Linkage !=
"comdat")
452 return TokError(
"Linkage must be 'comdat'");
460 bool ELFAsmParser::parseLinkedToSym(
MCSymbolELF *&LinkedToSym) {
463 return TokError(
"expected linked-to symbol");
467 if (getParser().parseIdentifier(
Name)) {
468 if (getParser().getTok().getString() ==
"0") {
470 LinkedToSym =
nullptr;
473 return TokError(
"invalid linked-to symbol");
475 LinkedToSym = dyn_cast_or_null<MCSymbolELF>(getContext().lookupSymbol(
Name));
477 return Error(StartLoc,
"linked-to symbol is not in a section: " +
Name);
481 bool ELFAsmParser::maybeParseUniqueID(int64_t &UniqueID) {
487 if (getParser().parseIdentifier(UniqueStr))
488 return TokError(
"expected identifier in directive");
489 if (UniqueStr !=
"unique")
490 return TokError(
"expected 'unique'");
492 return TokError(
"expected commma");
494 if (getParser().parseAbsoluteExpression(UniqueID))
497 return TokError(
"unique id must be positive");
499 return TokError(
"unique id is too large");
525 bool ELFAsmParser::ParseSectionArguments(
bool IsPush,
SMLoc loc) {
529 return TokError(
"expected identifier in directive");
534 bool IsComdat =
false;
536 unsigned extraFlags = 0;
537 const MCExpr *Subsection =
nullptr;
538 bool UseLastGroup =
false;
540 int64_t UniqueID = ~0;
561 if (getParser().parseExpression(Subsection))
569 if (!getContext().getAsmInfo()->usesSunStyleELFSectionSwitchSyntax()
571 return TokError(
"expected string in directive");
572 extraFlags = parseSunStyleSectionFlags();
574 StringRef FlagsStr = getTok().getStringContents();
580 if (extraFlags == -1U)
581 return TokError(
"unknown flag");
586 if (Group && UseLastGroup)
587 return TokError(
"Section cannot specifiy a group name while also acting "
588 "as a member of the last group");
590 if (maybeParseSectionType(
TypeName))
596 return TokError(
"Mergeable section must specify the type");
598 return TokError(
"Group section must specify the type");
600 return TokError(
"unexpected token in directive");
604 if (parseMergeSize(Size))
607 if (parseGroup(GroupName, IsComdat))
610 if (parseLinkedToSym(LinkedToSym))
612 if (maybeParseUniqueID(UniqueID))
618 return TokError(
"unexpected token in directive");
641 else if (
TypeName ==
"preinit_array")
653 else if (
TypeName ==
"llvm_linker_options")
655 else if (
TypeName ==
"llvm_call_graph_profile")
657 else if (
TypeName ==
"llvm_dependent_libraries")
659 else if (
TypeName ==
"llvm_sympart")
661 else if (
TypeName ==
"llvm_bb_addr_map")
664 return TokError(
"unknown section type");
670 cast_or_null<MCSectionELF>(CurrentSection.first))
672 GroupName = Group->getName();
673 IsComdat =
Section->isComdat();
680 IsComdat, UniqueID, LinkedToSym);
681 getStreamer().SwitchSection(Section, Subsection);
689 utohexstr(
Section->getType()));
690 if ((extraFlags || Size || !
TypeName.empty()) &&
Section->getFlags() != Flags)
692 utohexstr(
Section->getFlags()));
693 if ((extraFlags || Size || !
TypeName.empty()) &&
694 Section->getEntrySize() != Size)
698 if (getContext().getGenDwarfForAssembly() &&
701 bool InsertResult = getContext().addGenDwarfSection(Section);
704 Warning(loc,
"DWARF2 only supports one section per compilation unit");
706 if (!
Section->getBeginSymbol()) {
707 MCSymbol *SectionStartSymbol = getContext().createTempSymbol();
708 getStreamer().emitLabel(SectionStartSymbol);
709 Section->setBeginSymbol(SectionStartSymbol);
717 bool ELFAsmParser::ParseDirectivePrevious(
StringRef DirName,
SMLoc) {
719 if (PreviousSection.first ==
nullptr)
720 return TokError(
".previous without corresponding .section");
721 getStreamer().SwitchSection(PreviousSection.first, PreviousSection.second);
733 .
Cases(
"STT_GNU_IFUNC",
"gnu_indirect_function",
747 if (getParser().parseIdentifier(
Name))
748 return TokError(
"expected identifier in directive");
765 if (!getLexer().getAllowAtInIdentifier())
766 return TokError(
"expected STT_<TYPE_IN_UPPER_CASE>, '#<type>', "
767 "'%<type>' or \"<type>\"");
769 return TokError(
"expected STT_<TYPE_IN_UPPER_CASE>, '#<type>', '@<type>', "
770 "'%<type>' or \"<type>\"");
777 SMLoc TypeLoc = getLexer().getLoc();
780 if (getParser().parseIdentifier(
Type))
781 return TokError(
"expected symbol type in directive");
785 return Error(TypeLoc,
"unsupported attribute in '.type' directive");
788 return TokError(
"unexpected token in '.type' directive");
791 getStreamer().emitSymbolAttribute(Sym, Attr);
800 return TokError(
"unexpected token in '.ident' directive");
807 return TokError(
"unexpected token in '.ident' directive");
810 getStreamer().emitIdent(
Data);
818 if (getParser().parseIdentifier(OriginalName))
819 return TokError(
"expected identifier in directive");
822 return TokError(
"expected a comma");
828 const bool AllowAtInIdentifier = getLexer().getAllowAtInIdentifier();
829 getLexer().setAllowAtInIdentifier(
true);
831 getLexer().setAllowAtInIdentifier(AllowAtInIdentifier);
833 if (getParser().parseIdentifier(
Name))
834 return TokError(
"expected identifier in directive");
836 if (!
Name.contains(
'@'))
837 return TokError(
"expected a '@' in the name");
838 bool KeepOriginalSym = !
Name.contains(
"@@@");
840 if (getParser().parseIdentifier(Action) || Action !=
"remove")
841 return TokError(
"expected 'remove'");
842 KeepOriginalSym =
false;
846 getStreamer().emitELFSymverDirective(
847 getContext().getOrCreateSymbol(OriginalName),
Name, KeepOriginalSym);
855 return TokError(
"unexpected token in '.version' directive");
863 getStreamer().PushSection();
864 getStreamer().SwitchSection(Note);
865 getStreamer().emitInt32(
Data.size() + 1);
866 getStreamer().emitInt32(0);
867 getStreamer().emitInt32(1);
868 getStreamer().emitBytes(
Data);
869 getStreamer().emitInt8(0);
870 getStreamer().emitValueToAlignment(4);
871 getStreamer().PopSection();
881 if (getParser().parseIdentifier(AliasName))
882 return TokError(
"expected identifier in directive");
885 return TokError(
"expected a comma");
890 if (getParser().parseIdentifier(
Name))
891 return TokError(
"expected identifier in directive");
893 MCSymbol *Alias = getContext().getOrCreateSymbol(AliasName);
897 getStreamer().emitWeakReference(Alias, Sym);
902 const MCExpr *Subsection =
nullptr;
904 if (getParser().parseExpression(Subsection))
909 return TokError(
"unexpected token in directive");
913 getStreamer().SubSection(Subsection);
924 return new ELFAsmParser;