LLVM  8.0.1
ELFAsmParser.cpp
Go to the documentation of this file.
1 //===- ELFAsmParser.cpp - ELF Assembly Parser -----------------------------===//
2 //
3 // The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 
10 #include "llvm/ADT/StringRef.h"
11 #include "llvm/ADT/StringSwitch.h"
12 #include "llvm/BinaryFormat/ELF.h"
13 #include "llvm/MC/MCAsmInfo.h"
14 #include "llvm/MC/MCContext.h"
15 #include "llvm/MC/MCDirectives.h"
16 #include "llvm/MC/MCExpr.h"
20 #include "llvm/MC/MCSection.h"
21 #include "llvm/MC/MCSectionELF.h"
22 #include "llvm/MC/MCStreamer.h"
23 #include "llvm/MC/MCSymbol.h"
24 #include "llvm/MC/MCSymbolELF.h"
25 #include "llvm/MC/SectionKind.h"
26 #include "llvm/Support/Casting.h"
28 #include "llvm/Support/SMLoc.h"
29 #include <cassert>
30 #include <cstdint>
31 #include <utility>
32 
33 using namespace llvm;
34 
35 namespace {
36 
37 class ELFAsmParser : public MCAsmParserExtension {
38  template<bool (ELFAsmParser::*HandlerMethod)(StringRef, SMLoc)>
39  void addDirectiveHandler(StringRef Directive) {
40  MCAsmParser::ExtensionDirectiveHandler Handler = std::make_pair(
41  this, HandleDirective<ELFAsmParser, HandlerMethod>);
42 
43  getParser().addDirectiveHandler(Directive, Handler);
44  }
45 
46  bool ParseSectionSwitch(StringRef Section, unsigned Type, unsigned Flags,
48 
49 public:
50  ELFAsmParser() { BracketExpressionsSupported = true; }
51 
52  void Initialize(MCAsmParser &Parser) override {
53  // Call the base implementation.
55 
56  addDirectiveHandler<&ELFAsmParser::ParseSectionDirectiveData>(".data");
57  addDirectiveHandler<&ELFAsmParser::ParseSectionDirectiveText>(".text");
58  addDirectiveHandler<&ELFAsmParser::ParseSectionDirectiveBSS>(".bss");
59  addDirectiveHandler<&ELFAsmParser::ParseSectionDirectiveRoData>(".rodata");
60  addDirectiveHandler<&ELFAsmParser::ParseSectionDirectiveTData>(".tdata");
61  addDirectiveHandler<&ELFAsmParser::ParseSectionDirectiveTBSS>(".tbss");
62  addDirectiveHandler<
63  &ELFAsmParser::ParseSectionDirectiveDataRel>(".data.rel");
64  addDirectiveHandler<
65  &ELFAsmParser::ParseSectionDirectiveDataRelRo>(".data.rel.ro");
66  addDirectiveHandler<
67  &ELFAsmParser::ParseSectionDirectiveEhFrame>(".eh_frame");
68  addDirectiveHandler<&ELFAsmParser::ParseDirectiveSection>(".section");
69  addDirectiveHandler<
70  &ELFAsmParser::ParseDirectivePushSection>(".pushsection");
71  addDirectiveHandler<&ELFAsmParser::ParseDirectivePopSection>(".popsection");
72  addDirectiveHandler<&ELFAsmParser::ParseDirectiveSize>(".size");
73  addDirectiveHandler<&ELFAsmParser::ParseDirectivePrevious>(".previous");
74  addDirectiveHandler<&ELFAsmParser::ParseDirectiveType>(".type");
75  addDirectiveHandler<&ELFAsmParser::ParseDirectiveIdent>(".ident");
76  addDirectiveHandler<&ELFAsmParser::ParseDirectiveSymver>(".symver");
77  addDirectiveHandler<&ELFAsmParser::ParseDirectiveVersion>(".version");
78  addDirectiveHandler<&ELFAsmParser::ParseDirectiveWeakref>(".weakref");
79  addDirectiveHandler<&ELFAsmParser::ParseDirectiveSymbolAttribute>(".weak");
80  addDirectiveHandler<&ELFAsmParser::ParseDirectiveSymbolAttribute>(".local");
81  addDirectiveHandler<
82  &ELFAsmParser::ParseDirectiveSymbolAttribute>(".protected");
83  addDirectiveHandler<
84  &ELFAsmParser::ParseDirectiveSymbolAttribute>(".internal");
85  addDirectiveHandler<
86  &ELFAsmParser::ParseDirectiveSymbolAttribute>(".hidden");
87  addDirectiveHandler<&ELFAsmParser::ParseDirectiveSubsection>(".subsection");
88  addDirectiveHandler<&ELFAsmParser::ParseDirectiveCGProfile>(".cg_profile");
89  }
90 
91  // FIXME: Part of this logic is duplicated in the MCELFStreamer. What is
92  // the best way for us to get access to it?
93  bool ParseSectionDirectiveData(StringRef, SMLoc) {
94  return ParseSectionSwitch(".data", ELF::SHT_PROGBITS,
97  }
98  bool ParseSectionDirectiveText(StringRef, SMLoc) {
99  return ParseSectionSwitch(".text", ELF::SHT_PROGBITS,
102  }
103  bool ParseSectionDirectiveBSS(StringRef, SMLoc) {
104  return ParseSectionSwitch(".bss", ELF::SHT_NOBITS,
107  }
108  bool ParseSectionDirectiveRoData(StringRef, SMLoc) {
109  return ParseSectionSwitch(".rodata", ELF::SHT_PROGBITS,
112  }
113  bool ParseSectionDirectiveTData(StringRef, SMLoc) {
114  return ParseSectionSwitch(".tdata", ELF::SHT_PROGBITS,
118  }
119  bool ParseSectionDirectiveTBSS(StringRef, SMLoc) {
120  return ParseSectionSwitch(".tbss", ELF::SHT_NOBITS,
124  }
125  bool ParseSectionDirectiveDataRel(StringRef, SMLoc) {
126  return ParseSectionSwitch(".data.rel", ELF::SHT_PROGBITS,
129  }
130  bool ParseSectionDirectiveDataRelRo(StringRef, SMLoc) {
131  return ParseSectionSwitch(".data.rel.ro", ELF::SHT_PROGBITS,
135  }
136  bool ParseSectionDirectiveEhFrame(StringRef, SMLoc) {
137  return ParseSectionSwitch(".eh_frame", ELF::SHT_PROGBITS,
140  }
141  bool ParseDirectivePushSection(StringRef, SMLoc);
142  bool ParseDirectivePopSection(StringRef, SMLoc);
143  bool ParseDirectiveSection(StringRef, SMLoc);
144  bool ParseDirectiveSize(StringRef, SMLoc);
145  bool ParseDirectivePrevious(StringRef, SMLoc);
146  bool ParseDirectiveType(StringRef, SMLoc);
147  bool ParseDirectiveIdent(StringRef, SMLoc);
148  bool ParseDirectiveSymver(StringRef, SMLoc);
149  bool ParseDirectiveVersion(StringRef, SMLoc);
150  bool ParseDirectiveWeakref(StringRef, SMLoc);
151  bool ParseDirectiveSymbolAttribute(StringRef, SMLoc);
152  bool ParseDirectiveSubsection(StringRef, SMLoc);
153  bool ParseDirectiveCGProfile(StringRef, SMLoc);
154 
155 private:
156  bool ParseSectionName(StringRef &SectionName);
157  bool ParseSectionArguments(bool IsPush, SMLoc loc);
158  unsigned parseSunStyleSectionFlags();
159  bool maybeParseSectionType(StringRef &TypeName);
160  bool parseMergeSize(int64_t &Size);
161  bool parseGroup(StringRef &GroupName);
162  bool parseMetadataSym(MCSymbolELF *&Associated);
163  bool maybeParseUniqueID(int64_t &UniqueID);
164 };
165 
166 } // end anonymous namespace
167 
168 /// ParseDirectiveSymbolAttribute
169 /// ::= { ".local", ".weak", ... } [ identifier ( , identifier )* ]
170 bool ELFAsmParser::ParseDirectiveSymbolAttribute(StringRef Directive, SMLoc) {
171  MCSymbolAttr Attr = StringSwitch<MCSymbolAttr>(Directive)
172  .Case(".weak", MCSA_Weak)
173  .Case(".local", MCSA_Local)
174  .Case(".hidden", MCSA_Hidden)
175  .Case(".internal", MCSA_Internal)
176  .Case(".protected", MCSA_Protected)
178  assert(Attr != MCSA_Invalid && "unexpected symbol attribute directive!");
179  if (getLexer().isNot(AsmToken::EndOfStatement)) {
180  while (true) {
181  StringRef Name;
182 
183  if (getParser().parseIdentifier(Name))
184  return TokError("expected identifier in directive");
185 
186  MCSymbol *Sym = getContext().getOrCreateSymbol(Name);
187 
188  getStreamer().EmitSymbolAttribute(Sym, Attr);
189 
190  if (getLexer().is(AsmToken::EndOfStatement))
191  break;
192 
193  if (getLexer().isNot(AsmToken::Comma))
194  return TokError("unexpected token in directive");
195  Lex();
196  }
197  }
198 
199  Lex();
200  return false;
201 }
202 
203 bool ELFAsmParser::ParseSectionSwitch(StringRef Section, unsigned Type,
204  unsigned Flags, SectionKind Kind) {
205  const MCExpr *Subsection = nullptr;
206  if (getLexer().isNot(AsmToken::EndOfStatement)) {
207  if (getParser().parseExpression(Subsection))
208  return true;
209  }
210  Lex();
211 
212  getStreamer().SwitchSection(getContext().getELFSection(Section, Type, Flags),
213  Subsection);
214 
215  return false;
216 }
217 
218 bool ELFAsmParser::ParseDirectiveSize(StringRef, SMLoc) {
219  StringRef Name;
220  if (getParser().parseIdentifier(Name))
221  return TokError("expected identifier in directive");
222  MCSymbolELF *Sym = cast<MCSymbolELF>(getContext().getOrCreateSymbol(Name));
223 
224  if (getLexer().isNot(AsmToken::Comma))
225  return TokError("unexpected token in directive");
226  Lex();
227 
228  const MCExpr *Expr;
229  if (getParser().parseExpression(Expr))
230  return true;
231 
232  if (getLexer().isNot(AsmToken::EndOfStatement))
233  return TokError("unexpected token in directive");
234  Lex();
235 
236  getStreamer().emitELFSize(Sym, Expr);
237  return false;
238 }
239 
240 bool ELFAsmParser::ParseSectionName(StringRef &SectionName) {
241  // A section name can contain -, so we cannot just use
242  // parseIdentifier.
243  SMLoc FirstLoc = getLexer().getLoc();
244  unsigned Size = 0;
245 
246  if (getLexer().is(AsmToken::String)) {
247  SectionName = getTok().getIdentifier();
248  Lex();
249  return false;
250  }
251 
252  while (!getParser().hasPendingError()) {
253  SMLoc PrevLoc = getLexer().getLoc();
254  if (getLexer().is(AsmToken::Comma) ||
255  getLexer().is(AsmToken::EndOfStatement))
256  break;
257 
258  unsigned CurSize;
259  if (getLexer().is(AsmToken::String)) {
260  CurSize = getTok().getIdentifier().size() + 2;
261  Lex();
262  } else if (getLexer().is(AsmToken::Identifier)) {
263  CurSize = getTok().getIdentifier().size();
264  Lex();
265  } else {
266  CurSize = getTok().getString().size();
267  Lex();
268  }
269  Size += CurSize;
270  SectionName = StringRef(FirstLoc.getPointer(), Size);
271 
272  // Make sure the following token is adjacent.
273  if (PrevLoc.getPointer() + CurSize != getTok().getLoc().getPointer())
274  break;
275  }
276  if (Size == 0)
277  return true;
278 
279  return false;
280 }
281 
282 static unsigned parseSectionFlags(StringRef flagsStr, bool *UseLastGroup) {
283  unsigned flags = 0;
284 
285  // If a valid numerical value is set for the section flag, use it verbatim
286  if (!flagsStr.getAsInteger(0, flags))
287  return flags;
288 
289  for (char i : flagsStr) {
290  switch (i) {
291  case 'a':
292  flags |= ELF::SHF_ALLOC;
293  break;
294  case 'e':
295  flags |= ELF::SHF_EXCLUDE;
296  break;
297  case 'x':
298  flags |= ELF::SHF_EXECINSTR;
299  break;
300  case 'w':
301  flags |= ELF::SHF_WRITE;
302  break;
303  case 'o':
304  flags |= ELF::SHF_LINK_ORDER;
305  break;
306  case 'M':
307  flags |= ELF::SHF_MERGE;
308  break;
309  case 'S':
310  flags |= ELF::SHF_STRINGS;
311  break;
312  case 'T':
313  flags |= ELF::SHF_TLS;
314  break;
315  case 'c':
316  flags |= ELF::XCORE_SHF_CP_SECTION;
317  break;
318  case 'd':
319  flags |= ELF::XCORE_SHF_DP_SECTION;
320  break;
321  case 'y':
322  flags |= ELF::SHF_ARM_PURECODE;
323  break;
324  case 's':
325  flags |= ELF::SHF_HEX_GPREL;
326  break;
327  case 'G':
328  flags |= ELF::SHF_GROUP;
329  break;
330  case '?':
331  *UseLastGroup = true;
332  break;
333  default:
334  return -1U;
335  }
336  }
337 
338  return flags;
339 }
340 
341 unsigned ELFAsmParser::parseSunStyleSectionFlags() {
342  unsigned flags = 0;
343  while (getLexer().is(AsmToken::Hash)) {
344  Lex(); // Eat the #.
345 
346  if (!getLexer().is(AsmToken::Identifier))
347  return -1U;
348 
349  StringRef flagId = getTok().getIdentifier();
350  if (flagId == "alloc")
351  flags |= ELF::SHF_ALLOC;
352  else if (flagId == "execinstr")
353  flags |= ELF::SHF_EXECINSTR;
354  else if (flagId == "write")
355  flags |= ELF::SHF_WRITE;
356  else if (flagId == "tls")
357  flags |= ELF::SHF_TLS;
358  else
359  return -1U;
360 
361  Lex(); // Eat the flag.
362 
363  if (!getLexer().is(AsmToken::Comma))
364  break;
365  Lex(); // Eat the comma.
366  }
367  return flags;
368 }
369 
370 
371 bool ELFAsmParser::ParseDirectivePushSection(StringRef s, SMLoc loc) {
372  getStreamer().PushSection();
373 
374  if (ParseSectionArguments(/*IsPush=*/true, loc)) {
375  getStreamer().PopSection();
376  return true;
377  }
378 
379  return false;
380 }
381 
382 bool ELFAsmParser::ParseDirectivePopSection(StringRef, SMLoc) {
383  if (!getStreamer().PopSection())
384  return TokError(".popsection without corresponding .pushsection");
385  return false;
386 }
387 
388 bool ELFAsmParser::ParseDirectiveSection(StringRef, SMLoc loc) {
389  return ParseSectionArguments(/*IsPush=*/false, loc);
390 }
391 
392 bool ELFAsmParser::maybeParseSectionType(StringRef &TypeName) {
393  MCAsmLexer &L = getLexer();
394  if (L.isNot(AsmToken::Comma))
395  return false;
396  Lex();
397  if (L.isNot(AsmToken::At) && L.isNot(AsmToken::Percent) &&
398  L.isNot(AsmToken::String)) {
399  if (L.getAllowAtInIdentifier())
400  return TokError("expected '@<type>', '%<type>' or \"<type>\"");
401  else
402  return TokError("expected '%<type>' or \"<type>\"");
403  }
404  if (!L.is(AsmToken::String))
405  Lex();
406  if (L.is(AsmToken::Integer)) {
407  TypeName = getTok().getString();
408  Lex();
409  } else if (getParser().parseIdentifier(TypeName))
410  return TokError("expected identifier in directive");
411  return false;
412 }
413 
414 bool ELFAsmParser::parseMergeSize(int64_t &Size) {
415  if (getLexer().isNot(AsmToken::Comma))
416  return TokError("expected the entry size");
417  Lex();
418  if (getParser().parseAbsoluteExpression(Size))
419  return true;
420  if (Size <= 0)
421  return TokError("entry size must be positive");
422  return false;
423 }
424 
425 bool ELFAsmParser::parseGroup(StringRef &GroupName) {
426  MCAsmLexer &L = getLexer();
427  if (L.isNot(AsmToken::Comma))
428  return TokError("expected group name");
429  Lex();
430  if (L.is(AsmToken::Integer)) {
431  GroupName = getTok().getString();
432  Lex();
433  } else if (getParser().parseIdentifier(GroupName)) {
434  return TokError("invalid group name");
435  }
436  if (L.is(AsmToken::Comma)) {
437  Lex();
438  StringRef Linkage;
439  if (getParser().parseIdentifier(Linkage))
440  return TokError("invalid linkage");
441  if (Linkage != "comdat")
442  return TokError("Linkage must be 'comdat'");
443  }
444  return false;
445 }
446 
447 bool ELFAsmParser::parseMetadataSym(MCSymbolELF *&Associated) {
448  MCAsmLexer &L = getLexer();
449  if (L.isNot(AsmToken::Comma))
450  return TokError("expected metadata symbol");
451  Lex();
452  StringRef Name;
453  if (getParser().parseIdentifier(Name))
454  return TokError("invalid metadata symbol");
455  Associated = dyn_cast_or_null<MCSymbolELF>(getContext().lookupSymbol(Name));
456  if (!Associated || !Associated->isInSection())
457  return TokError("symbol is not in a section: " + Name);
458  return false;
459 }
460 
461 bool ELFAsmParser::maybeParseUniqueID(int64_t &UniqueID) {
462  MCAsmLexer &L = getLexer();
463  if (L.isNot(AsmToken::Comma))
464  return false;
465  Lex();
466  StringRef UniqueStr;
467  if (getParser().parseIdentifier(UniqueStr))
468  return TokError("expected identifier in directive");
469  if (UniqueStr != "unique")
470  return TokError("expected 'unique'");
471  if (L.isNot(AsmToken::Comma))
472  return TokError("expected commma");
473  Lex();
474  if (getParser().parseAbsoluteExpression(UniqueID))
475  return true;
476  if (UniqueID < 0)
477  return TokError("unique id must be positive");
478  if (!isUInt<32>(UniqueID) || UniqueID == ~0U)
479  return TokError("unique id is too large");
480  return false;
481 }
482 
483 static bool hasPrefix(StringRef SectionName, StringRef Prefix) {
484  return SectionName.startswith(Prefix) || SectionName == Prefix.drop_back();
485 }
486 
487 bool ELFAsmParser::ParseSectionArguments(bool IsPush, SMLoc loc) {
489 
490  if (ParseSectionName(SectionName))
491  return TokError("expected identifier in directive");
492 
494  int64_t Size = 0;
495  StringRef GroupName;
496  unsigned Flags = 0;
497  const MCExpr *Subsection = nullptr;
498  bool UseLastGroup = false;
499  MCSymbolELF *Associated = nullptr;
500  int64_t UniqueID = ~0;
501 
502  // Set the defaults first.
503  if (hasPrefix(SectionName, ".rodata.") || SectionName == ".rodata1")
504  Flags |= ELF::SHF_ALLOC;
505  else if (SectionName == ".fini" || SectionName == ".init" ||
506  hasPrefix(SectionName, ".text."))
508  else if (hasPrefix(SectionName, ".data.") || SectionName == ".data1" ||
509  hasPrefix(SectionName, ".bss.") ||
510  hasPrefix(SectionName, ".init_array.") ||
511  hasPrefix(SectionName, ".fini_array.") ||
512  hasPrefix(SectionName, ".preinit_array."))
513  Flags |= ELF::SHF_ALLOC | ELF::SHF_WRITE;
514  else if (hasPrefix(SectionName, ".tdata.") ||
515  hasPrefix(SectionName, ".tbss."))
517 
518  if (getLexer().is(AsmToken::Comma)) {
519  Lex();
520 
521  if (IsPush && getLexer().isNot(AsmToken::String)) {
522  if (getParser().parseExpression(Subsection))
523  return true;
524  if (getLexer().isNot(AsmToken::Comma))
525  goto EndStmt;
526  Lex();
527  }
528 
529  unsigned extraFlags;
530 
531  if (getLexer().isNot(AsmToken::String)) {
532  if (!getContext().getAsmInfo()->usesSunStyleELFSectionSwitchSyntax()
533  || getLexer().isNot(AsmToken::Hash))
534  return TokError("expected string in directive");
535  extraFlags = parseSunStyleSectionFlags();
536  } else {
537  StringRef FlagsStr = getTok().getStringContents();
538  Lex();
539  extraFlags = parseSectionFlags(FlagsStr, &UseLastGroup);
540  }
541 
542  if (extraFlags == -1U)
543  return TokError("unknown flag");
544  Flags |= extraFlags;
545 
546  bool Mergeable = Flags & ELF::SHF_MERGE;
547  bool Group = Flags & ELF::SHF_GROUP;
548  if (Group && UseLastGroup)
549  return TokError("Section cannot specifiy a group name while also acting "
550  "as a member of the last group");
551 
552  if (maybeParseSectionType(TypeName))
553  return true;
554 
555  MCAsmLexer &L = getLexer();
556  if (TypeName.empty()) {
557  if (Mergeable)
558  return TokError("Mergeable section must specify the type");
559  if (Group)
560  return TokError("Group section must specify the type");
562  return TokError("unexpected token in directive");
563  }
564 
565  if (Mergeable)
566  if (parseMergeSize(Size))
567  return true;
568  if (Group)
569  if (parseGroup(GroupName))
570  return true;
571  if (Flags & ELF::SHF_LINK_ORDER)
572  if (parseMetadataSym(Associated))
573  return true;
574  if (maybeParseUniqueID(UniqueID))
575  return true;
576  }
577 
578 EndStmt:
579  if (getLexer().isNot(AsmToken::EndOfStatement))
580  return TokError("unexpected token in directive");
581  Lex();
582 
583  unsigned Type = ELF::SHT_PROGBITS;
584 
585  if (TypeName.empty()) {
586  if (SectionName.startswith(".note"))
587  Type = ELF::SHT_NOTE;
588  else if (hasPrefix(SectionName, ".init_array."))
589  Type = ELF::SHT_INIT_ARRAY;
590  else if (hasPrefix(SectionName, ".bss."))
591  Type = ELF::SHT_NOBITS;
592  else if (hasPrefix(SectionName, ".tbss."))
593  Type = ELF::SHT_NOBITS;
594  else if (hasPrefix(SectionName, ".fini_array."))
595  Type = ELF::SHT_FINI_ARRAY;
596  else if (hasPrefix(SectionName, ".preinit_array."))
597  Type = ELF::SHT_PREINIT_ARRAY;
598  } else {
599  if (TypeName == "init_array")
600  Type = ELF::SHT_INIT_ARRAY;
601  else if (TypeName == "fini_array")
602  Type = ELF::SHT_FINI_ARRAY;
603  else if (TypeName == "preinit_array")
604  Type = ELF::SHT_PREINIT_ARRAY;
605  else if (TypeName == "nobits")
606  Type = ELF::SHT_NOBITS;
607  else if (TypeName == "progbits")
608  Type = ELF::SHT_PROGBITS;
609  else if (TypeName == "note")
610  Type = ELF::SHT_NOTE;
611  else if (TypeName == "unwind")
612  Type = ELF::SHT_X86_64_UNWIND;
613  else if (TypeName == "llvm_odrtab")
614  Type = ELF::SHT_LLVM_ODRTAB;
615  else if (TypeName == "llvm_linker_options")
617  else if (TypeName == "llvm_call_graph_profile")
619  else if (TypeName.getAsInteger(0, Type))
620  return TokError("unknown section type");
621  }
622 
623  if (UseLastGroup) {
624  MCSectionSubPair CurrentSection = getStreamer().getCurrentSection();
625  if (const MCSectionELF *Section =
626  cast_or_null<MCSectionELF>(CurrentSection.first))
627  if (const MCSymbol *Group = Section->getGroup()) {
628  GroupName = Group->getName();
629  Flags |= ELF::SHF_GROUP;
630  }
631  }
632 
633  MCSection *ELFSection =
634  getContext().getELFSection(SectionName, Type, Flags, Size, GroupName,
635  UniqueID, Associated);
636  getStreamer().SwitchSection(ELFSection, Subsection);
637 
638  if (getContext().getGenDwarfForAssembly()) {
639  bool InsertResult = getContext().addGenDwarfSection(ELFSection);
640  if (InsertResult) {
641  if (getContext().getDwarfVersion() <= 2)
642  Warning(loc, "DWARF2 only supports one section per compilation unit");
643 
644  if (!ELFSection->getBeginSymbol()) {
645  MCSymbol *SectionStartSymbol = getContext().createTempSymbol();
646  getStreamer().EmitLabel(SectionStartSymbol);
647  ELFSection->setBeginSymbol(SectionStartSymbol);
648  }
649  }
650  }
651 
652  return false;
653 }
654 
655 bool ELFAsmParser::ParseDirectivePrevious(StringRef DirName, SMLoc) {
656  MCSectionSubPair PreviousSection = getStreamer().getPreviousSection();
657  if (PreviousSection.first == nullptr)
658  return TokError(".previous without corresponding .section");
659  getStreamer().SwitchSection(PreviousSection.first, PreviousSection.second);
660 
661  return false;
662 }
663 
665  return StringSwitch<MCSymbolAttr>(Type)
666  .Cases("STT_FUNC", "function", MCSA_ELF_TypeFunction)
667  .Cases("STT_OBJECT", "object", MCSA_ELF_TypeObject)
668  .Cases("STT_TLS", "tls_object", MCSA_ELF_TypeTLS)
669  .Cases("STT_COMMON", "common", MCSA_ELF_TypeCommon)
670  .Cases("STT_NOTYPE", "notype", MCSA_ELF_TypeNoType)
671  .Cases("STT_GNU_IFUNC", "gnu_indirect_function",
673  .Case("gnu_unique_object", MCSA_ELF_TypeGnuUniqueObject)
675 }
676 
677 /// ParseDirectiveELFType
678 /// ::= .type identifier , STT_<TYPE_IN_UPPER_CASE>
679 /// ::= .type identifier , #attribute
680 /// ::= .type identifier , @attribute
681 /// ::= .type identifier , %attribute
682 /// ::= .type identifier , "attribute"
683 bool ELFAsmParser::ParseDirectiveType(StringRef, SMLoc) {
684  StringRef Name;
685  if (getParser().parseIdentifier(Name))
686  return TokError("expected identifier in directive");
687 
688  // Handle the identifier as the key symbol.
689  MCSymbol *Sym = getContext().getOrCreateSymbol(Name);
690 
691  // NOTE the comma is optional in all cases. It is only documented as being
692  // optional in the first case, however, GAS will silently treat the comma as
693  // optional in all cases. Furthermore, although the documentation states that
694  // the first form only accepts STT_<TYPE_IN_UPPER_CASE>, in reality, GAS
695  // accepts both the upper case name as well as the lower case aliases.
696  if (getLexer().is(AsmToken::Comma))
697  Lex();
698 
699  if (getLexer().isNot(AsmToken::Identifier) &&
700  getLexer().isNot(AsmToken::Hash) &&
701  getLexer().isNot(AsmToken::Percent) &&
702  getLexer().isNot(AsmToken::String)) {
703  if (!getLexer().getAllowAtInIdentifier())
704  return TokError("expected STT_<TYPE_IN_UPPER_CASE>, '#<type>', "
705  "'%<type>' or \"<type>\"");
706  else if (getLexer().isNot(AsmToken::At))
707  return TokError("expected STT_<TYPE_IN_UPPER_CASE>, '#<type>', '@<type>', "
708  "'%<type>' or \"<type>\"");
709  }
710 
711  if (getLexer().isNot(AsmToken::String) &&
712  getLexer().isNot(AsmToken::Identifier))
713  Lex();
714 
715  SMLoc TypeLoc = getLexer().getLoc();
716 
717  StringRef Type;
718  if (getParser().parseIdentifier(Type))
719  return TokError("expected symbol type in directive");
720 
721  MCSymbolAttr Attr = MCAttrForString(Type);
722  if (Attr == MCSA_Invalid)
723  return Error(TypeLoc, "unsupported attribute in '.type' directive");
724 
725  if (getLexer().isNot(AsmToken::EndOfStatement))
726  return TokError("unexpected token in '.type' directive");
727  Lex();
728 
729  getStreamer().EmitSymbolAttribute(Sym, Attr);
730 
731  return false;
732 }
733 
734 /// ParseDirectiveIdent
735 /// ::= .ident string
736 bool ELFAsmParser::ParseDirectiveIdent(StringRef, SMLoc) {
737  if (getLexer().isNot(AsmToken::String))
738  return TokError("unexpected token in '.ident' directive");
739 
740  StringRef Data = getTok().getIdentifier();
741 
742  Lex();
743 
744  if (getLexer().isNot(AsmToken::EndOfStatement))
745  return TokError("unexpected token in '.ident' directive");
746  Lex();
747 
748  getStreamer().EmitIdent(Data);
749  return false;
750 }
751 
752 /// ParseDirectiveSymver
753 /// ::= .symver foo, bar2@zed
754 bool ELFAsmParser::ParseDirectiveSymver(StringRef, SMLoc) {
755  StringRef Name;
756  if (getParser().parseIdentifier(Name))
757  return TokError("expected identifier in directive");
758 
759  if (getLexer().isNot(AsmToken::Comma))
760  return TokError("expected a comma");
761 
762  // ARM assembly uses @ for a comment...
763  // except when parsing the second parameter of the .symver directive.
764  // Force the next symbol to allow @ in the identifier, which is
765  // required for this directive and then reset it to its initial state.
766  const bool AllowAtInIdentifier = getLexer().getAllowAtInIdentifier();
767  getLexer().setAllowAtInIdentifier(true);
768  Lex();
769  getLexer().setAllowAtInIdentifier(AllowAtInIdentifier);
770 
771  StringRef AliasName;
772  if (getParser().parseIdentifier(AliasName))
773  return TokError("expected identifier in directive");
774 
775  if (AliasName.find('@') == StringRef::npos)
776  return TokError("expected a '@' in the name");
777 
778  MCSymbol *Sym = getContext().getOrCreateSymbol(Name);
779  getStreamer().emitELFSymverDirective(AliasName, Sym);
780  return false;
781 }
782 
783 /// ParseDirectiveVersion
784 /// ::= .version string
785 bool ELFAsmParser::ParseDirectiveVersion(StringRef, SMLoc) {
786  if (getLexer().isNot(AsmToken::String))
787  return TokError("unexpected token in '.version' directive");
788 
789  StringRef Data = getTok().getIdentifier();
790 
791  Lex();
792 
793  MCSection *Note = getContext().getELFSection(".note", ELF::SHT_NOTE, 0);
794 
795  getStreamer().PushSection();
796  getStreamer().SwitchSection(Note);
797  getStreamer().EmitIntValue(Data.size()+1, 4); // namesz.
798  getStreamer().EmitIntValue(0, 4); // descsz = 0 (no description).
799  getStreamer().EmitIntValue(1, 4); // type = NT_VERSION.
800  getStreamer().EmitBytes(Data); // name.
801  getStreamer().EmitIntValue(0, 1); // terminate the string.
802  getStreamer().EmitValueToAlignment(4); // ensure 4 byte alignment.
803  getStreamer().PopSection();
804  return false;
805 }
806 
807 /// ParseDirectiveWeakref
808 /// ::= .weakref foo, bar
809 bool ELFAsmParser::ParseDirectiveWeakref(StringRef, SMLoc) {
810  // FIXME: Share code with the other alias building directives.
811 
812  StringRef AliasName;
813  if (getParser().parseIdentifier(AliasName))
814  return TokError("expected identifier in directive");
815 
816  if (getLexer().isNot(AsmToken::Comma))
817  return TokError("expected a comma");
818 
819  Lex();
820 
821  StringRef Name;
822  if (getParser().parseIdentifier(Name))
823  return TokError("expected identifier in directive");
824 
825  MCSymbol *Alias = getContext().getOrCreateSymbol(AliasName);
826 
827  MCSymbol *Sym = getContext().getOrCreateSymbol(Name);
828 
829  getStreamer().EmitWeakReference(Alias, Sym);
830  return false;
831 }
832 
833 bool ELFAsmParser::ParseDirectiveSubsection(StringRef, SMLoc) {
834  const MCExpr *Subsection = nullptr;
835  if (getLexer().isNot(AsmToken::EndOfStatement)) {
836  if (getParser().parseExpression(Subsection))
837  return true;
838  }
839 
840  if (getLexer().isNot(AsmToken::EndOfStatement))
841  return TokError("unexpected token in directive");
842 
843  Lex();
844 
845  getStreamer().SubSection(Subsection);
846  return false;
847 }
848 
849 /// ParseDirectiveCGProfile
850 /// ::= .cg_profile identifier, identifier, <number>
851 bool ELFAsmParser::ParseDirectiveCGProfile(StringRef, SMLoc) {
852  StringRef From;
853  SMLoc FromLoc = getLexer().getLoc();
854  if (getParser().parseIdentifier(From))
855  return TokError("expected identifier in directive");
856 
857  if (getLexer().isNot(AsmToken::Comma))
858  return TokError("expected a comma");
859  Lex();
860 
861  StringRef To;
862  SMLoc ToLoc = getLexer().getLoc();
863  if (getParser().parseIdentifier(To))
864  return TokError("expected identifier in directive");
865 
866  if (getLexer().isNot(AsmToken::Comma))
867  return TokError("expected a comma");
868  Lex();
869 
870  int64_t Count;
871  if (getParser().parseIntToken(
872  Count, "expected integer count in '.cg_profile' directive"))
873  return true;
874 
875  if (getLexer().isNot(AsmToken::EndOfStatement))
876  return TokError("unexpected token in directive");
877 
878  MCSymbol *FromSym = getContext().getOrCreateSymbol(From);
879  MCSymbol *ToSym = getContext().getOrCreateSymbol(To);
880 
881  getStreamer().emitCGProfileEntry(
882  MCSymbolRefExpr::create(FromSym, MCSymbolRefExpr::VK_None, getContext(),
883  FromLoc),
885  ToLoc),
886  Count);
887  return false;
888 }
889 
890 namespace llvm {
891 
893  return new ELFAsmParser;
894 }
895 
896 } // end namespace llvm
constexpr bool isUInt< 32 >(uint64_t x)
Definition: MathExtras.h:349
Instances of this class represent a uniqued identifier for a section in the current translation unit...
Definition: MCSection.h:39
static SectionKind getData()
Definition: SectionKind.h:202
static const MCSymbolRefExpr * create(const MCSymbol *Symbol, MCContext &Ctx)
Definition: MCExpr.h:323
This class represents lattice values for constants.
Definition: AllocatorList.h:24
.type _foo, STT_OBJECT # aka
Definition: MCDirectives.h:25
bool is(AsmToken::TokenKind K) const
Check if the current token has kind K.
Definition: MCAsmLexer.h:136
MCSymbol - Instances of this class represent a symbol name in the MC file, and MCSymbols are created ...
Definition: MCSymbol.h:42
All sections with the "d" flag are grouped together by the linker to form the data section and the dp...
Definition: ELF.h:926
Not a valid directive.
Definition: MCDirectives.h:20
Generic assembler parser interface, for use by target specific assembly parsers.
Definition: MCAsmParser.h:110
virtual void Initialize(MCAsmParser &Parser)
Initialize the extension for parsing using the given Parser.
LLVM_NODISCARD LLVM_ATTRIBUTE_ALWAYS_INLINE size_t size() const
size - Get the string size.
Definition: StringRef.h:138
static unsigned parseSectionFlags(StringRef flagsStr, bool *UseLastGroup)
static MCSymbolAttr MCAttrForString(StringRef Type)
.type _foo, STT_NOTYPE # aka
Definition: MCDirectives.h:28
All sections with the "c" flag are grouped together by the linker to form the constant pool and the c...
Definition: ELF.h:931
MCAsmParserExtension * createELFAsmParser()
amdgpu Simplify well known AMD library false Value Value const Twine & Name
static SectionKind getBSS()
Definition: SectionKind.h:198
Generic assembler lexer interface, for use by target specific assembly lexers.
Definition: MCAsmLexer.h:40
static bool hasPrefix(StringRef SectionName, StringRef Prefix)
Base class for the full range of assembler expressions which are needed for parsing.
Definition: MCExpr.h:36
bool isInSection() const
isInSection - Check if this symbol is defined in some section (i.e., it is defined but not absolute)...
Definition: MCSymbol.h:252
.local (ELF)
Definition: MCDirectives.h:35
LLVM_NODISCARD LLVM_ATTRIBUTE_ALWAYS_INLINE R Default(T Value)
Definition: StringSwitch.h:203
LLVM_NODISCARD LLVM_ATTRIBUTE_ALWAYS_INLINE bool startswith(StringRef Prefix) const
Check if this string starts with the given Prefix.
Definition: StringRef.h:267
.type _foo, STT_GNU_IFUNC
Definition: MCDirectives.h:24
LLVM_NODISCARD LLVM_ATTRIBUTE_ALWAYS_INLINE bool empty() const
empty - Check if the string is empty.
Definition: StringRef.h:133
.protected (ELF)
Definition: MCDirectives.h:40
static SectionKind getThreadData()
Definition: SectionKind.h:197
.hidden (ELF)
Definition: MCDirectives.h:31
const char * getPointer() const
Definition: SMLoc.h:35
A switch()-like statement whose cases are string literals.
Definition: StringSwitch.h:43
The instances of the Type class are immutable: once they are created, they are never changed...
Definition: Type.h:46
constexpr char TypeName[]
Key for Kernel::Arg::Metadata::mTypeName.
SectionKind - This is a simple POD value that classifies the properties of a section.
Definition: SectionKind.h:23
bool getAllowAtInIdentifier()
Definition: MCAsmLexer.h:144
LLVM_NODISCARD LLVM_ATTRIBUTE_ALWAYS_INLINE StringRef drop_back(size_t N=1) const
Return a StringRef equal to &#39;this&#39; but with the last N elements dropped.
Definition: StringRef.h:654
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.
Definition: StringRef.h:497
static SectionKind getThreadBSS()
Definition: SectionKind.h:196
std::pair< MCSection *, const MCExpr * > MCSectionSubPair
Definition: MCStreamer.h:57
BlockVerifier::State From
.type _foo, STT_TLS # aka
Definition: MCDirectives.h:26
static SectionKind getReadOnlyWithRel()
Definition: SectionKind.h:203
MCSymbol * getBeginSymbol()
Definition: MCSection.h:110
MCSymbolAttr
Definition: MCDirectives.h:19
.internal (ELF)
Definition: MCDirectives.h:33
LLVM_ATTRIBUTE_ALWAYS_INLINE StringSwitch & Case(StringLiteral S, T Value)
Definition: StringSwitch.h:70
.type _foo, STT_COMMON # aka
Definition: MCDirectives.h:27
static const size_t npos
Definition: StringRef.h:51
.type _foo, STT_FUNC # aka
Definition: MCDirectives.h:23
This represents a section on linux, lots of unix variants and some bare metal systems.
Definition: MCSectionELF.h:28
LLVM_ATTRIBUTE_ALWAYS_INLINE StringSwitch & Cases(StringLiteral S0, StringLiteral S1, T Value)
Definition: StringSwitch.h:94
uint32_t Size
Definition: Profile.cpp:47
bool isNot(AsmToken::TokenKind K) const
Check if the current token has kind K.
Definition: MCAsmLexer.h:139
const unsigned Kind
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
Generic interface for extending the MCAsmParser, which is implemented by target and object file assem...
std::pair< MCAsmParserExtension *, DirectiveHandler > ExtensionDirectiveHandler
Definition: MCAsmParser.h:114
const char SectionName[]
Definition: AMDGPUPTNote.h:24
StringRef - Represent a constant reference to a string, i.e.
Definition: StringRef.h:49
Represents a location in source code.
Definition: SMLoc.h:24
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.
Definition: StringRef.h:298
static SectionKind getReadOnly()
Definition: SectionKind.h:182
static SectionKind getText()
Definition: SectionKind.h:180
void setBeginSymbol(MCSymbol *Sym)
Definition: MCSection.h:114