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");
83 return ParseSectionSwitch(
".data", ELF::SHT_PROGBITS,
84 ELF::SHF_WRITE |ELF::SHF_ALLOC,
88 return ParseSectionSwitch(
".text", ELF::SHT_PROGBITS,
93 return ParseSectionSwitch(
".bss", ELF::SHT_NOBITS,
98 return ParseSectionSwitch(
".rodata", ELF::SHT_PROGBITS,
103 return ParseSectionSwitch(
".tdata", ELF::SHT_PROGBITS,
105 ELF::SHF_TLS | ELF::SHF_WRITE,
109 return ParseSectionSwitch(
".tbss", ELF::SHT_NOBITS,
111 ELF::SHF_TLS | ELF::SHF_WRITE,
115 return ParseSectionSwitch(
".data.rel", ELF::SHT_PROGBITS,
121 return ParseSectionSwitch(
".data.rel.ro", ELF::SHT_PROGBITS,
127 return ParseSectionSwitch(
".data.rel.ro.local", ELF::SHT_PROGBITS,
133 return ParseSectionSwitch(
".eh_frame", ELF::SHT_PROGBITS,
152 bool ParseSectionName(
StringRef &SectionName);
153 bool ParseSectionArguments(
bool IsPush);
160 bool ELFAsmParser::ParseDirectiveSymbolAttribute(
StringRef Directive,
SMLoc) {
168 assert(Attr !=
MCSA_Invalid &&
"unexpected symbol attribute directive!");
173 if (getParser().parseIdentifier(Name))
174 return TokError(
"expected identifier in directive");
176 MCSymbol *Sym = getContext().GetOrCreateSymbol(Name);
178 getStreamer().EmitSymbolAttribute(Sym, Attr);
184 return TokError(
"unexpected token in directive");
195 const MCExpr *Subsection = 0;
197 if (getParser().parseExpression(Subsection))
201 getStreamer().SwitchSection(getContext().getELFSection(
202 Section, Type, Flags, Kind),
210 if (getParser().parseIdentifier(Name))
211 return TokError(
"expected identifier in directive");
212 MCSymbol *Sym = 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())
272 if (Flags & ELF::SHF_EXECINSTR)
274 if (Flags & ELF::SHF_TLS)
282 for (
unsigned i = 0; i < flagsStr.
size(); i++) {
283 switch (flagsStr[i]) {
285 flags |= ELF::SHF_ALLOC;
288 flags |= ELF::SHF_EXCLUDE;
291 flags |= ELF::SHF_EXECINSTR;
294 flags |= ELF::SHF_WRITE;
297 flags |= ELF::SHF_MERGE;
300 flags |= ELF::SHF_STRINGS;
303 flags |= ELF::SHF_TLS;
306 flags |= ELF::XCORE_SHF_CP_SECTION;
309 flags |= ELF::XCORE_SHF_DP_SECTION;
312 flags |= ELF::SHF_GROUP;
315 *UseLastGroup =
true;
325 bool ELFAsmParser::ParseDirectivePushSection(
StringRef s,
SMLoc loc) {
326 getStreamer().PushSection();
328 if (ParseSectionArguments(
true)) {
329 getStreamer().PopSection();
337 if (!getStreamer().PopSection())
338 return TokError(
".popsection without corresponding .pushsection");
344 return ParseSectionArguments(
false);
347 bool ELFAsmParser::ParseSectionArguments(
bool IsPush) {
350 if (ParseSectionName(SectionName))
351 return TokError(
"expected identifier in directive");
357 const MCExpr *Subsection = 0;
358 bool UseLastGroup =
false;
361 if (SectionName ==
".fini" || SectionName ==
".init" ||
362 SectionName ==
".rodata")
363 Flags |= ELF::SHF_ALLOC;
364 if (SectionName ==
".fini" || SectionName ==
".init")
365 Flags |= ELF::SHF_EXECINSTR;
371 if (getParser().parseExpression(Subsection))
379 return TokError(
"expected string in directive");
381 StringRef FlagsStr = getTok().getStringContents();
385 if (extraFlags == -1U)
386 return TokError(
"unknown flag");
389 bool Mergeable = Flags & ELF::SHF_MERGE;
390 bool Group = Flags & ELF::SHF_GROUP;
391 if (Group && UseLastGroup)
392 return TokError(
"Section cannot specifiy a group name while also acting "
393 "as a member of the last group");
397 return TokError(
"Mergeable section must specify the type");
399 return TokError(
"Group section must specify the type");
407 return TokError(
"expected '@<type>', '%<type>' or \"<type>\"");
409 if (getParser().parseIdentifier(TypeName))
410 return TokError(
"expected identifier in directive");
414 return TokError(
"expected the entry size");
416 if (getParser().parseAbsoluteExpression(Size))
419 return TokError(
"entry size must be positive");
424 return TokError(
"expected group name");
426 if (getParser().parseIdentifier(GroupName))
431 if (getParser().parseIdentifier(Linkage))
433 if (Linkage !=
"comdat")
434 return TokError(
"Linkage must be 'comdat'");
442 return TokError(
"unexpected token in directive");
444 unsigned Type = ELF::SHT_PROGBITS;
446 if (TypeName.
empty()) {
448 Type = ELF::SHT_NOTE;
449 else if (SectionName ==
".init_array")
450 Type = ELF::SHT_INIT_ARRAY;
451 else if (SectionName ==
".fini_array")
452 Type = ELF::SHT_FINI_ARRAY;
453 else if (SectionName ==
".preinit_array")
454 Type = ELF::SHT_PREINIT_ARRAY;
456 if (TypeName ==
"init_array")
457 Type = ELF::SHT_INIT_ARRAY;
458 else if (TypeName ==
"fini_array")
459 Type = ELF::SHT_FINI_ARRAY;
460 else if (TypeName ==
"preinit_array")
461 Type = ELF::SHT_PREINIT_ARRAY;
462 else if (TypeName ==
"nobits")
463 Type = ELF::SHT_NOBITS;
464 else if (TypeName ==
"progbits")
465 Type = ELF::SHT_PROGBITS;
466 else if (TypeName ==
"note")
467 Type = ELF::SHT_NOTE;
468 else if (TypeName ==
"unwind")
469 Type = ELF::SHT_X86_64_UNWIND;
471 return TokError(
"unknown section type");
477 cast_or_null<MCSectionELF>(CurrentSection.first))
478 if (
const MCSymbol *Group = Section->getGroup()) {
479 GroupName = Group->getName();
480 Flags |= ELF::SHF_GROUP;
485 getStreamer().SwitchSection(getContext().getELFSection(SectionName, Type,
492 bool ELFAsmParser::ParseDirectivePrevious(
StringRef DirName,
SMLoc) {
494 if (PreviousSection.first == NULL)
495 return TokError(
".previous without corresponding .section");
496 getStreamer().SwitchSection(PreviousSection.first, PreviousSection.second);
509 if (getParser().parseIdentifier(Name))
510 return TokError(
"expected identifier in directive");
513 MCSymbol *Sym = getContext().GetOrCreateSymbol(Name);
516 return TokError(
"unexpected token in '.type' directive");
523 TypeLoc = getLexer().getLoc();
524 if (getParser().parseIdentifier(Type))
525 return TokError(
"expected symbol type in directive");
540 TypeLoc = getLexer().getLoc();
541 if (getParser().parseIdentifier(Type))
542 return TokError(
"expected symbol type in directive");
553 return TokError(
"expected STT_<TYPE_IN_UPPER_CASE>, '#<type>', '@<type>', "
554 "'%<type>' or \"<type>\"");
557 return Error(TypeLoc,
"unsupported attribute in '.type' directive");
560 return TokError(
"unexpected token in '.type' directive");
564 getStreamer().EmitSymbolAttribute(Sym, Attr);
573 return TokError(
"unexpected token in '.ident' directive");
575 StringRef Data = getTok().getIdentifier();
579 getStreamer().EmitIdent(Data);
587 if (getParser().parseIdentifier(Name))
588 return TokError(
"expected identifier in directive");
591 return TokError(
"expected a comma");
596 if (getParser().parseIdentifier(AliasName))
597 return TokError(
"expected identifier in directive");
600 return TokError(
"expected a '@' in the name");
602 MCSymbol *Alias = getContext().GetOrCreateSymbol(AliasName);
603 MCSymbol *Sym = getContext().GetOrCreateSymbol(Name);
606 getStreamer().EmitAssignment(Alias, Value);
614 return TokError(
"unexpected token in '.version' directive");
616 StringRef Data = getTok().getIdentifier();
621 getContext().getELFSection(
".note", ELF::SHT_NOTE, 0,
624 getStreamer().PushSection();
625 getStreamer().SwitchSection(Note);
626 getStreamer().EmitIntValue(Data.
size()+1, 4);
627 getStreamer().EmitIntValue(0, 4);
628 getStreamer().EmitIntValue(1, 4);
629 getStreamer().EmitBytes(Data);
630 getStreamer().EmitIntValue(0, 1);
631 getStreamer().EmitValueToAlignment(4);
632 getStreamer().PopSection();
642 if (getParser().parseIdentifier(AliasName))
643 return TokError(
"expected identifier in directive");
646 return TokError(
"expected a comma");
651 if (getParser().parseIdentifier(Name))
652 return TokError(
"expected identifier in directive");
654 MCSymbol *Alias = getContext().GetOrCreateSymbol(AliasName);
656 MCSymbol *Sym = getContext().GetOrCreateSymbol(Name);
658 getStreamer().EmitWeakReference(Alias, Sym);
663 const MCExpr *Subsection = 0;
665 if (getParser().parseExpression(Subsection))
670 return TokError(
"unexpected token in directive");
672 getStreamer().SubSection(Subsection);
679 return new ELFAsmParser;
static SectionKind getReadOnlyWithRelLocal()
COFF::RelocationTypeX86 Type
const char * getPointer() const
size_t size() const
size - Get the string size.
.type _foo, STT_OBJECT # aka
virtual void Initialize(MCAsmParser &Parser)
Initialize the extension for parsing using the given Parser. The extension should use the AsmParser i...
size_t find(char C, size_t From=0) const
static SectionKind getDataRel()
static unsigned parseSectionFlags(StringRef flagsStr, bool *UseLastGroup)
.type _foo, STT_NOTYPE # aka
StringSwitch & Case(const char(&S)[N], const T &Value)
MCAsmParserExtension * createELFAsmParser()
static SectionKind getBSS()
static SectionKind computeSectionKind(unsigned Flags)
.type _foo, STT_GNU_IFUNC
static SectionKind getThreadData()
static const MCSymbolRefExpr * Create(const MCSymbol *Symbol, MCContext &Ctx)
A switch()-like statement whose cases are string literals.
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()
std::pair< const MCSection *, const MCExpr * > MCSectionSubPair
R Default(const T &Value) const
.type _foo, STT_COMMON # aka
.type _foo, STT_FUNC # aka
Generic interface for extending the MCAsmParser, which is implemented by target and object file assem...
LLVM Value Representation.
Represents a location in source code.
static SectionKind getReadOnly()
bool empty() const
empty - Check if the string is empty.
static SectionKind getText()