ELFAsmParser.cpp 30 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924
  1. //===- ELFAsmParser.cpp - ELF Assembly Parser -----------------------------===//
  2. //
  3. // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
  4. // See https://llvm.org/LICENSE.txt for license information.
  5. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
  6. //
  7. //===----------------------------------------------------------------------===//
  8. #include "llvm/ADT/StringRef.h"
  9. #include "llvm/ADT/StringSwitch.h"
  10. #include "llvm/BinaryFormat/ELF.h"
  11. #include "llvm/MC/MCAsmInfo.h"
  12. #include "llvm/MC/MCContext.h"
  13. #include "llvm/MC/MCDirectives.h"
  14. #include "llvm/MC/MCExpr.h"
  15. #include "llvm/MC/MCParser/MCAsmLexer.h"
  16. #include "llvm/MC/MCParser/MCAsmParser.h"
  17. #include "llvm/MC/MCParser/MCAsmParserExtension.h"
  18. #include "llvm/MC/MCSection.h"
  19. #include "llvm/MC/MCSectionELF.h"
  20. #include "llvm/MC/MCStreamer.h"
  21. #include "llvm/MC/MCSymbol.h"
  22. #include "llvm/MC/MCSymbolELF.h"
  23. #include "llvm/MC/SectionKind.h"
  24. #include "llvm/Support/Casting.h"
  25. #include "llvm/Support/MathExtras.h"
  26. #include "llvm/Support/SMLoc.h"
  27. #include <cassert>
  28. #include <cstdint>
  29. #include <utility>
  30. using namespace llvm;
  31. namespace {
  32. class ELFAsmParser : public MCAsmParserExtension {
  33. template<bool (ELFAsmParser::*HandlerMethod)(StringRef, SMLoc)>
  34. void addDirectiveHandler(StringRef Directive) {
  35. MCAsmParser::ExtensionDirectiveHandler Handler = std::make_pair(
  36. this, HandleDirective<ELFAsmParser, HandlerMethod>);
  37. getParser().addDirectiveHandler(Directive, Handler);
  38. }
  39. bool ParseSectionSwitch(StringRef Section, unsigned Type, unsigned Flags,
  40. SectionKind Kind);
  41. public:
  42. ELFAsmParser() { BracketExpressionsSupported = true; }
  43. void Initialize(MCAsmParser &Parser) override {
  44. // Call the base implementation.
  45. this->MCAsmParserExtension::Initialize(Parser);
  46. addDirectiveHandler<&ELFAsmParser::ParseSectionDirectiveData>(".data");
  47. addDirectiveHandler<&ELFAsmParser::ParseSectionDirectiveText>(".text");
  48. addDirectiveHandler<&ELFAsmParser::ParseSectionDirectiveBSS>(".bss");
  49. addDirectiveHandler<&ELFAsmParser::ParseSectionDirectiveRoData>(".rodata");
  50. addDirectiveHandler<&ELFAsmParser::ParseSectionDirectiveTData>(".tdata");
  51. addDirectiveHandler<&ELFAsmParser::ParseSectionDirectiveTBSS>(".tbss");
  52. addDirectiveHandler<
  53. &ELFAsmParser::ParseSectionDirectiveDataRel>(".data.rel");
  54. addDirectiveHandler<
  55. &ELFAsmParser::ParseSectionDirectiveDataRelRo>(".data.rel.ro");
  56. addDirectiveHandler<
  57. &ELFAsmParser::ParseSectionDirectiveEhFrame>(".eh_frame");
  58. addDirectiveHandler<&ELFAsmParser::ParseDirectiveSection>(".section");
  59. addDirectiveHandler<
  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");
  71. addDirectiveHandler<
  72. &ELFAsmParser::ParseDirectiveSymbolAttribute>(".protected");
  73. addDirectiveHandler<
  74. &ELFAsmParser::ParseDirectiveSymbolAttribute>(".internal");
  75. addDirectiveHandler<
  76. &ELFAsmParser::ParseDirectiveSymbolAttribute>(".hidden");
  77. addDirectiveHandler<&ELFAsmParser::ParseDirectiveSubsection>(".subsection");
  78. addDirectiveHandler<&ELFAsmParser::ParseDirectiveCGProfile>(".cg_profile");
  79. }
  80. // FIXME: Part of this logic is duplicated in the MCELFStreamer. What is
  81. // the best way for us to get access to it?
  82. bool ParseSectionDirectiveData(StringRef, SMLoc) {
  83. return ParseSectionSwitch(".data", ELF::SHT_PROGBITS,
  84. ELF::SHF_WRITE | ELF::SHF_ALLOC,
  85. SectionKind::getData());
  86. }
  87. bool ParseSectionDirectiveText(StringRef, SMLoc) {
  88. return ParseSectionSwitch(".text", ELF::SHT_PROGBITS,
  89. ELF::SHF_EXECINSTR |
  90. ELF::SHF_ALLOC, SectionKind::getText());
  91. }
  92. bool ParseSectionDirectiveBSS(StringRef, SMLoc) {
  93. return ParseSectionSwitch(".bss", ELF::SHT_NOBITS,
  94. ELF::SHF_WRITE |
  95. ELF::SHF_ALLOC, SectionKind::getBSS());
  96. }
  97. bool ParseSectionDirectiveRoData(StringRef, SMLoc) {
  98. return ParseSectionSwitch(".rodata", ELF::SHT_PROGBITS,
  99. ELF::SHF_ALLOC,
  100. SectionKind::getReadOnly());
  101. }
  102. bool ParseSectionDirectiveTData(StringRef, SMLoc) {
  103. return ParseSectionSwitch(".tdata", ELF::SHT_PROGBITS,
  104. ELF::SHF_ALLOC |
  105. ELF::SHF_TLS | ELF::SHF_WRITE,
  106. SectionKind::getThreadData());
  107. }
  108. bool ParseSectionDirectiveTBSS(StringRef, SMLoc) {
  109. return ParseSectionSwitch(".tbss", ELF::SHT_NOBITS,
  110. ELF::SHF_ALLOC |
  111. ELF::SHF_TLS | ELF::SHF_WRITE,
  112. SectionKind::getThreadBSS());
  113. }
  114. bool ParseSectionDirectiveDataRel(StringRef, SMLoc) {
  115. return ParseSectionSwitch(".data.rel", ELF::SHT_PROGBITS,
  116. ELF::SHF_ALLOC | ELF::SHF_WRITE,
  117. SectionKind::getData());
  118. }
  119. bool ParseSectionDirectiveDataRelRo(StringRef, SMLoc) {
  120. return ParseSectionSwitch(".data.rel.ro", ELF::SHT_PROGBITS,
  121. ELF::SHF_ALLOC |
  122. ELF::SHF_WRITE,
  123. SectionKind::getReadOnlyWithRel());
  124. }
  125. bool ParseSectionDirectiveEhFrame(StringRef, SMLoc) {
  126. return ParseSectionSwitch(".eh_frame", ELF::SHT_PROGBITS,
  127. ELF::SHF_ALLOC | ELF::SHF_WRITE,
  128. SectionKind::getData());
  129. }
  130. bool ParseDirectivePushSection(StringRef, SMLoc);
  131. bool ParseDirectivePopSection(StringRef, SMLoc);
  132. bool ParseDirectiveSection(StringRef, SMLoc);
  133. bool ParseDirectiveSize(StringRef, SMLoc);
  134. bool ParseDirectivePrevious(StringRef, SMLoc);
  135. bool ParseDirectiveType(StringRef, SMLoc);
  136. bool ParseDirectiveIdent(StringRef, SMLoc);
  137. bool ParseDirectiveSymver(StringRef, SMLoc);
  138. bool ParseDirectiveVersion(StringRef, SMLoc);
  139. bool ParseDirectiveWeakref(StringRef, SMLoc);
  140. bool ParseDirectiveSymbolAttribute(StringRef, SMLoc);
  141. bool ParseDirectiveSubsection(StringRef, SMLoc);
  142. bool ParseDirectiveCGProfile(StringRef, SMLoc);
  143. private:
  144. bool ParseSectionName(StringRef &SectionName);
  145. bool ParseSectionArguments(bool IsPush, SMLoc loc);
  146. unsigned parseSunStyleSectionFlags();
  147. bool maybeParseSectionType(StringRef &TypeName);
  148. bool parseMergeSize(int64_t &Size);
  149. bool parseGroup(StringRef &GroupName, bool &IsComdat);
  150. bool parseLinkedToSym(MCSymbolELF *&LinkedToSym);
  151. bool maybeParseUniqueID(int64_t &UniqueID);
  152. };
  153. } // end anonymous namespace
  154. /// ParseDirectiveSymbolAttribute
  155. /// ::= { ".local", ".weak", ... } [ identifier ( , identifier )* ]
  156. bool ELFAsmParser::ParseDirectiveSymbolAttribute(StringRef Directive, SMLoc) {
  157. MCSymbolAttr Attr = StringSwitch<MCSymbolAttr>(Directive)
  158. .Case(".weak", MCSA_Weak)
  159. .Case(".local", MCSA_Local)
  160. .Case(".hidden", MCSA_Hidden)
  161. .Case(".internal", MCSA_Internal)
  162. .Case(".protected", MCSA_Protected)
  163. .Default(MCSA_Invalid);
  164. assert(Attr != MCSA_Invalid && "unexpected symbol attribute directive!");
  165. if (getLexer().isNot(AsmToken::EndOfStatement)) {
  166. while (true) {
  167. StringRef Name;
  168. if (getParser().parseIdentifier(Name))
  169. return TokError("expected identifier in directive");
  170. if (getParser().discardLTOSymbol(Name)) {
  171. if (getLexer().is(AsmToken::EndOfStatement))
  172. break;
  173. continue;
  174. }
  175. MCSymbol *Sym = getContext().getOrCreateSymbol(Name);
  176. getStreamer().emitSymbolAttribute(Sym, Attr);
  177. if (getLexer().is(AsmToken::EndOfStatement))
  178. break;
  179. if (getLexer().isNot(AsmToken::Comma))
  180. return TokError("unexpected token in directive");
  181. Lex();
  182. }
  183. }
  184. Lex();
  185. return false;
  186. }
  187. bool ELFAsmParser::ParseSectionSwitch(StringRef Section, unsigned Type,
  188. unsigned Flags, SectionKind Kind) {
  189. const MCExpr *Subsection = nullptr;
  190. if (getLexer().isNot(AsmToken::EndOfStatement)) {
  191. if (getParser().parseExpression(Subsection))
  192. return true;
  193. }
  194. Lex();
  195. getStreamer().SwitchSection(getContext().getELFSection(Section, Type, Flags),
  196. Subsection);
  197. return false;
  198. }
  199. bool ELFAsmParser::ParseDirectiveSize(StringRef, SMLoc) {
  200. StringRef Name;
  201. if (getParser().parseIdentifier(Name))
  202. return TokError("expected identifier in directive");
  203. MCSymbolELF *Sym = cast<MCSymbolELF>(getContext().getOrCreateSymbol(Name));
  204. if (getLexer().isNot(AsmToken::Comma))
  205. return TokError("unexpected token in directive");
  206. Lex();
  207. const MCExpr *Expr;
  208. if (getParser().parseExpression(Expr))
  209. return true;
  210. if (getLexer().isNot(AsmToken::EndOfStatement))
  211. return TokError("unexpected token in directive");
  212. Lex();
  213. getStreamer().emitELFSize(Sym, Expr);
  214. return false;
  215. }
  216. bool ELFAsmParser::ParseSectionName(StringRef &SectionName) {
  217. // A section name can contain -, so we cannot just use
  218. // parseIdentifier.
  219. SMLoc FirstLoc = getLexer().getLoc();
  220. unsigned Size = 0;
  221. if (getLexer().is(AsmToken::String)) {
  222. SectionName = getTok().getIdentifier();
  223. Lex();
  224. return false;
  225. }
  226. while (!getParser().hasPendingError()) {
  227. SMLoc PrevLoc = getLexer().getLoc();
  228. if (getLexer().is(AsmToken::Comma) ||
  229. getLexer().is(AsmToken::EndOfStatement))
  230. break;
  231. unsigned CurSize;
  232. if (getLexer().is(AsmToken::String)) {
  233. CurSize = getTok().getIdentifier().size() + 2;
  234. Lex();
  235. } else if (getLexer().is(AsmToken::Identifier)) {
  236. CurSize = getTok().getIdentifier().size();
  237. Lex();
  238. } else {
  239. CurSize = getTok().getString().size();
  240. Lex();
  241. }
  242. Size += CurSize;
  243. SectionName = StringRef(FirstLoc.getPointer(), Size);
  244. // Make sure the following token is adjacent.
  245. if (PrevLoc.getPointer() + CurSize != getTok().getLoc().getPointer())
  246. break;
  247. }
  248. if (Size == 0)
  249. return true;
  250. return false;
  251. }
  252. static unsigned parseSectionFlags(StringRef flagsStr, bool *UseLastGroup) {
  253. unsigned flags = 0;
  254. // If a valid numerical value is set for the section flag, use it verbatim
  255. if (!flagsStr.getAsInteger(0, flags))
  256. return flags;
  257. for (char i : flagsStr) {
  258. switch (i) {
  259. case 'a':
  260. flags |= ELF::SHF_ALLOC;
  261. break;
  262. case 'e':
  263. flags |= ELF::SHF_EXCLUDE;
  264. break;
  265. case 'x':
  266. flags |= ELF::SHF_EXECINSTR;
  267. break;
  268. case 'w':
  269. flags |= ELF::SHF_WRITE;
  270. break;
  271. case 'o':
  272. flags |= ELF::SHF_LINK_ORDER;
  273. break;
  274. case 'M':
  275. flags |= ELF::SHF_MERGE;
  276. break;
  277. case 'S':
  278. flags |= ELF::SHF_STRINGS;
  279. break;
  280. case 'T':
  281. flags |= ELF::SHF_TLS;
  282. break;
  283. case 'c':
  284. flags |= ELF::XCORE_SHF_CP_SECTION;
  285. break;
  286. case 'd':
  287. flags |= ELF::XCORE_SHF_DP_SECTION;
  288. break;
  289. case 'y':
  290. flags |= ELF::SHF_ARM_PURECODE;
  291. break;
  292. case 's':
  293. flags |= ELF::SHF_HEX_GPREL;
  294. break;
  295. case 'G':
  296. flags |= ELF::SHF_GROUP;
  297. break;
  298. case 'R':
  299. flags |= ELF::SHF_GNU_RETAIN;
  300. break;
  301. case '?':
  302. *UseLastGroup = true;
  303. break;
  304. default:
  305. return -1U;
  306. }
  307. }
  308. return flags;
  309. }
  310. unsigned ELFAsmParser::parseSunStyleSectionFlags() {
  311. unsigned flags = 0;
  312. while (getLexer().is(AsmToken::Hash)) {
  313. Lex(); // Eat the #.
  314. if (!getLexer().is(AsmToken::Identifier))
  315. return -1U;
  316. StringRef flagId = getTok().getIdentifier();
  317. if (flagId == "alloc")
  318. flags |= ELF::SHF_ALLOC;
  319. else if (flagId == "execinstr")
  320. flags |= ELF::SHF_EXECINSTR;
  321. else if (flagId == "write")
  322. flags |= ELF::SHF_WRITE;
  323. else if (flagId == "tls")
  324. flags |= ELF::SHF_TLS;
  325. else
  326. return -1U;
  327. Lex(); // Eat the flag.
  328. if (!getLexer().is(AsmToken::Comma))
  329. break;
  330. Lex(); // Eat the comma.
  331. }
  332. return flags;
  333. }
  334. bool ELFAsmParser::ParseDirectivePushSection(StringRef s, SMLoc loc) {
  335. getStreamer().PushSection();
  336. if (ParseSectionArguments(/*IsPush=*/true, loc)) {
  337. getStreamer().PopSection();
  338. return true;
  339. }
  340. return false;
  341. }
  342. bool ELFAsmParser::ParseDirectivePopSection(StringRef, SMLoc) {
  343. if (!getStreamer().PopSection())
  344. return TokError(".popsection without corresponding .pushsection");
  345. return false;
  346. }
  347. bool ELFAsmParser::ParseDirectiveSection(StringRef, SMLoc loc) {
  348. return ParseSectionArguments(/*IsPush=*/false, loc);
  349. }
  350. bool ELFAsmParser::maybeParseSectionType(StringRef &TypeName) {
  351. MCAsmLexer &L = getLexer();
  352. if (L.isNot(AsmToken::Comma))
  353. return false;
  354. Lex();
  355. if (L.isNot(AsmToken::At) && L.isNot(AsmToken::Percent) &&
  356. L.isNot(AsmToken::String)) {
  357. if (L.getAllowAtInIdentifier())
  358. return TokError("expected '@<type>', '%<type>' or \"<type>\"");
  359. else
  360. return TokError("expected '%<type>' or \"<type>\"");
  361. }
  362. if (!L.is(AsmToken::String))
  363. Lex();
  364. if (L.is(AsmToken::Integer)) {
  365. TypeName = getTok().getString();
  366. Lex();
  367. } else if (getParser().parseIdentifier(TypeName))
  368. return TokError("expected identifier in directive");
  369. return false;
  370. }
  371. bool ELFAsmParser::parseMergeSize(int64_t &Size) {
  372. if (getLexer().isNot(AsmToken::Comma))
  373. return TokError("expected the entry size");
  374. Lex();
  375. if (getParser().parseAbsoluteExpression(Size))
  376. return true;
  377. if (Size <= 0)
  378. return TokError("entry size must be positive");
  379. return false;
  380. }
  381. bool ELFAsmParser::parseGroup(StringRef &GroupName, bool &IsComdat) {
  382. MCAsmLexer &L = getLexer();
  383. if (L.isNot(AsmToken::Comma))
  384. return TokError("expected group name");
  385. Lex();
  386. if (L.is(AsmToken::Integer)) {
  387. GroupName = getTok().getString();
  388. Lex();
  389. } else if (getParser().parseIdentifier(GroupName)) {
  390. return TokError("invalid group name");
  391. }
  392. if (L.is(AsmToken::Comma)) {
  393. Lex();
  394. StringRef Linkage;
  395. if (getParser().parseIdentifier(Linkage))
  396. return TokError("invalid linkage");
  397. if (Linkage != "comdat")
  398. return TokError("Linkage must be 'comdat'");
  399. IsComdat = true;
  400. } else {
  401. IsComdat = false;
  402. }
  403. return false;
  404. }
  405. bool ELFAsmParser::parseLinkedToSym(MCSymbolELF *&LinkedToSym) {
  406. MCAsmLexer &L = getLexer();
  407. if (L.isNot(AsmToken::Comma))
  408. return TokError("expected linked-to symbol");
  409. Lex();
  410. StringRef Name;
  411. SMLoc StartLoc = L.getLoc();
  412. if (getParser().parseIdentifier(Name)) {
  413. if (getParser().getTok().getString() == "0") {
  414. getParser().Lex();
  415. LinkedToSym = nullptr;
  416. return false;
  417. }
  418. return TokError("invalid linked-to symbol");
  419. }
  420. LinkedToSym = dyn_cast_or_null<MCSymbolELF>(getContext().lookupSymbol(Name));
  421. if (!LinkedToSym || !LinkedToSym->isInSection())
  422. return Error(StartLoc, "linked-to symbol is not in a section: " + Name);
  423. return false;
  424. }
  425. bool ELFAsmParser::maybeParseUniqueID(int64_t &UniqueID) {
  426. MCAsmLexer &L = getLexer();
  427. if (L.isNot(AsmToken::Comma))
  428. return false;
  429. Lex();
  430. StringRef UniqueStr;
  431. if (getParser().parseIdentifier(UniqueStr))
  432. return TokError("expected identifier in directive");
  433. if (UniqueStr != "unique")
  434. return TokError("expected 'unique'");
  435. if (L.isNot(AsmToken::Comma))
  436. return TokError("expected commma");
  437. Lex();
  438. if (getParser().parseAbsoluteExpression(UniqueID))
  439. return true;
  440. if (UniqueID < 0)
  441. return TokError("unique id must be positive");
  442. if (!isUInt<32>(UniqueID) || UniqueID == ~0U)
  443. return TokError("unique id is too large");
  444. return false;
  445. }
  446. static bool hasPrefix(StringRef SectionName, StringRef Prefix) {
  447. return SectionName.consume_front(Prefix) &&
  448. (SectionName.empty() || SectionName[0] == '.');
  449. }
  450. static bool allowSectionTypeMismatch(const Triple &TT, StringRef SectionName,
  451. unsigned Type) {
  452. if (TT.getArch() == Triple::x86_64) {
  453. // x86-64 psABI names SHT_X86_64_UNWIND as the canonical type for .eh_frame,
  454. // but GNU as emits SHT_PROGBITS .eh_frame for .cfi_* directives. Don't
  455. // error for SHT_PROGBITS .eh_frame
  456. return SectionName == ".eh_frame" && Type == ELF::SHT_PROGBITS;
  457. }
  458. if (TT.isMIPS()) {
  459. // MIPS .debug_* sections should have SHT_MIPS_DWARF section type to
  460. // distinguish among sections contain DWARF and ECOFF debug formats,
  461. // but in assembly files these sections have SHT_PROGBITS type.
  462. return SectionName.startswith(".debug_") && Type == ELF::SHT_PROGBITS;
  463. }
  464. return false;
  465. }
  466. bool ELFAsmParser::ParseSectionArguments(bool IsPush, SMLoc loc) {
  467. StringRef SectionName;
  468. if (ParseSectionName(SectionName))
  469. return TokError("expected identifier in directive");
  470. StringRef TypeName;
  471. int64_t Size = 0;
  472. StringRef GroupName;
  473. bool IsComdat = false;
  474. unsigned Flags = 0;
  475. unsigned extraFlags = 0;
  476. const MCExpr *Subsection = nullptr;
  477. bool UseLastGroup = false;
  478. MCSymbolELF *LinkedToSym = nullptr;
  479. int64_t UniqueID = ~0;
  480. // Set the defaults first.
  481. if (hasPrefix(SectionName, ".rodata") || SectionName == ".rodata1")
  482. Flags |= ELF::SHF_ALLOC;
  483. else if (SectionName == ".fini" || SectionName == ".init" ||
  484. hasPrefix(SectionName, ".text"))
  485. Flags |= ELF::SHF_ALLOC | ELF::SHF_EXECINSTR;
  486. else if (hasPrefix(SectionName, ".data") || SectionName == ".data1" ||
  487. hasPrefix(SectionName, ".bss") ||
  488. hasPrefix(SectionName, ".init_array") ||
  489. hasPrefix(SectionName, ".fini_array") ||
  490. hasPrefix(SectionName, ".preinit_array"))
  491. Flags |= ELF::SHF_ALLOC | ELF::SHF_WRITE;
  492. else if (hasPrefix(SectionName, ".tdata") || hasPrefix(SectionName, ".tbss"))
  493. Flags |= ELF::SHF_ALLOC | ELF::SHF_WRITE | ELF::SHF_TLS;
  494. if (getLexer().is(AsmToken::Comma)) {
  495. Lex();
  496. if (IsPush && getLexer().isNot(AsmToken::String)) {
  497. if (getParser().parseExpression(Subsection))
  498. return true;
  499. if (getLexer().isNot(AsmToken::Comma))
  500. goto EndStmt;
  501. Lex();
  502. }
  503. if (getLexer().isNot(AsmToken::String)) {
  504. if (!getContext().getAsmInfo()->usesSunStyleELFSectionSwitchSyntax()
  505. || getLexer().isNot(AsmToken::Hash))
  506. return TokError("expected string in directive");
  507. extraFlags = parseSunStyleSectionFlags();
  508. } else {
  509. StringRef FlagsStr = getTok().getStringContents();
  510. Lex();
  511. extraFlags = parseSectionFlags(FlagsStr, &UseLastGroup);
  512. }
  513. if (extraFlags == -1U)
  514. return TokError("unknown flag");
  515. Flags |= extraFlags;
  516. bool Mergeable = Flags & ELF::SHF_MERGE;
  517. bool Group = Flags & ELF::SHF_GROUP;
  518. if (Group && UseLastGroup)
  519. return TokError("Section cannot specifiy a group name while also acting "
  520. "as a member of the last group");
  521. if (maybeParseSectionType(TypeName))
  522. return true;
  523. MCAsmLexer &L = getLexer();
  524. if (TypeName.empty()) {
  525. if (Mergeable)
  526. return TokError("Mergeable section must specify the type");
  527. if (Group)
  528. return TokError("Group section must specify the type");
  529. if (L.isNot(AsmToken::EndOfStatement))
  530. return TokError("unexpected token in directive");
  531. }
  532. if (Mergeable)
  533. if (parseMergeSize(Size))
  534. return true;
  535. if (Group)
  536. if (parseGroup(GroupName, IsComdat))
  537. return true;
  538. if (Flags & ELF::SHF_LINK_ORDER)
  539. if (parseLinkedToSym(LinkedToSym))
  540. return true;
  541. if (maybeParseUniqueID(UniqueID))
  542. return true;
  543. }
  544. EndStmt:
  545. if (getLexer().isNot(AsmToken::EndOfStatement))
  546. return TokError("unexpected token in directive");
  547. Lex();
  548. unsigned Type = ELF::SHT_PROGBITS;
  549. if (TypeName.empty()) {
  550. if (SectionName.startswith(".note"))
  551. Type = ELF::SHT_NOTE;
  552. else if (hasPrefix(SectionName, ".init_array"))
  553. Type = ELF::SHT_INIT_ARRAY;
  554. else if (hasPrefix(SectionName, ".bss"))
  555. Type = ELF::SHT_NOBITS;
  556. else if (hasPrefix(SectionName, ".tbss"))
  557. Type = ELF::SHT_NOBITS;
  558. else if (hasPrefix(SectionName, ".fini_array"))
  559. Type = ELF::SHT_FINI_ARRAY;
  560. else if (hasPrefix(SectionName, ".preinit_array"))
  561. Type = ELF::SHT_PREINIT_ARRAY;
  562. } else {
  563. if (TypeName == "init_array")
  564. Type = ELF::SHT_INIT_ARRAY;
  565. else if (TypeName == "fini_array")
  566. Type = ELF::SHT_FINI_ARRAY;
  567. else if (TypeName == "preinit_array")
  568. Type = ELF::SHT_PREINIT_ARRAY;
  569. else if (TypeName == "nobits")
  570. Type = ELF::SHT_NOBITS;
  571. else if (TypeName == "progbits")
  572. Type = ELF::SHT_PROGBITS;
  573. else if (TypeName == "note")
  574. Type = ELF::SHT_NOTE;
  575. else if (TypeName == "unwind")
  576. Type = ELF::SHT_X86_64_UNWIND;
  577. else if (TypeName == "llvm_odrtab")
  578. Type = ELF::SHT_LLVM_ODRTAB;
  579. else if (TypeName == "llvm_linker_options")
  580. Type = ELF::SHT_LLVM_LINKER_OPTIONS;
  581. else if (TypeName == "llvm_call_graph_profile")
  582. Type = ELF::SHT_LLVM_CALL_GRAPH_PROFILE;
  583. else if (TypeName == "llvm_dependent_libraries")
  584. Type = ELF::SHT_LLVM_DEPENDENT_LIBRARIES;
  585. else if (TypeName == "llvm_sympart")
  586. Type = ELF::SHT_LLVM_SYMPART;
  587. else if (TypeName == "llvm_bb_addr_map")
  588. Type = ELF::SHT_LLVM_BB_ADDR_MAP;
  589. else if (TypeName.getAsInteger(0, Type))
  590. return TokError("unknown section type");
  591. }
  592. if (UseLastGroup) {
  593. MCSectionSubPair CurrentSection = getStreamer().getCurrentSection();
  594. if (const MCSectionELF *Section =
  595. cast_or_null<MCSectionELF>(CurrentSection.first))
  596. if (const MCSymbol *Group = Section->getGroup()) {
  597. GroupName = Group->getName();
  598. IsComdat = Section->isComdat();
  599. Flags |= ELF::SHF_GROUP;
  600. }
  601. }
  602. MCSectionELF *Section =
  603. getContext().getELFSection(SectionName, Type, Flags, Size, GroupName,
  604. IsComdat, UniqueID, LinkedToSym);
  605. getStreamer().SwitchSection(Section, Subsection);
  606. // Check that flags are used consistently. However, the GNU assembler permits
  607. // to leave out in subsequent uses of the same sections; for compatibility,
  608. // do likewise.
  609. if (!TypeName.empty() && Section->getType() != Type &&
  610. !allowSectionTypeMismatch(getContext().getTargetTriple(), SectionName,
  611. Type))
  612. Error(loc, "changed section type for " + SectionName + ", expected: 0x" +
  613. utohexstr(Section->getType()));
  614. if ((extraFlags || Size || !TypeName.empty()) && Section->getFlags() != Flags)
  615. Error(loc, "changed section flags for " + SectionName + ", expected: 0x" +
  616. utohexstr(Section->getFlags()));
  617. if ((extraFlags || Size || !TypeName.empty()) &&
  618. Section->getEntrySize() != Size)
  619. Error(loc, "changed section entsize for " + SectionName +
  620. ", expected: " + Twine(Section->getEntrySize()));
  621. if (getContext().getGenDwarfForAssembly() &&
  622. (Section->getFlags() & ELF::SHF_ALLOC) &&
  623. (Section->getFlags() & ELF::SHF_EXECINSTR)) {
  624. bool InsertResult = getContext().addGenDwarfSection(Section);
  625. if (InsertResult) {
  626. if (getContext().getDwarfVersion() <= 2)
  627. Warning(loc, "DWARF2 only supports one section per compilation unit");
  628. if (!Section->getBeginSymbol()) {
  629. MCSymbol *SectionStartSymbol = getContext().createTempSymbol();
  630. getStreamer().emitLabel(SectionStartSymbol);
  631. Section->setBeginSymbol(SectionStartSymbol);
  632. }
  633. }
  634. }
  635. return false;
  636. }
  637. bool ELFAsmParser::ParseDirectivePrevious(StringRef DirName, SMLoc) {
  638. MCSectionSubPair PreviousSection = getStreamer().getPreviousSection();
  639. if (PreviousSection.first == nullptr)
  640. return TokError(".previous without corresponding .section");
  641. getStreamer().SwitchSection(PreviousSection.first, PreviousSection.second);
  642. return false;
  643. }
  644. static MCSymbolAttr MCAttrForString(StringRef Type) {
  645. return StringSwitch<MCSymbolAttr>(Type)
  646. .Cases("STT_FUNC", "function", MCSA_ELF_TypeFunction)
  647. .Cases("STT_OBJECT", "object", MCSA_ELF_TypeObject)
  648. .Cases("STT_TLS", "tls_object", MCSA_ELF_TypeTLS)
  649. .Cases("STT_COMMON", "common", MCSA_ELF_TypeCommon)
  650. .Cases("STT_NOTYPE", "notype", MCSA_ELF_TypeNoType)
  651. .Cases("STT_GNU_IFUNC", "gnu_indirect_function",
  652. MCSA_ELF_TypeIndFunction)
  653. .Case("gnu_unique_object", MCSA_ELF_TypeGnuUniqueObject)
  654. .Default(MCSA_Invalid);
  655. }
  656. /// ParseDirectiveELFType
  657. /// ::= .type identifier , STT_<TYPE_IN_UPPER_CASE>
  658. /// ::= .type identifier , #attribute
  659. /// ::= .type identifier , @attribute
  660. /// ::= .type identifier , %attribute
  661. /// ::= .type identifier , "attribute"
  662. bool ELFAsmParser::ParseDirectiveType(StringRef, SMLoc) {
  663. StringRef Name;
  664. if (getParser().parseIdentifier(Name))
  665. return TokError("expected identifier in directive");
  666. // Handle the identifier as the key symbol.
  667. MCSymbol *Sym = getContext().getOrCreateSymbol(Name);
  668. // NOTE the comma is optional in all cases. It is only documented as being
  669. // optional in the first case, however, GAS will silently treat the comma as
  670. // optional in all cases. Furthermore, although the documentation states that
  671. // the first form only accepts STT_<TYPE_IN_UPPER_CASE>, in reality, GAS
  672. // accepts both the upper case name as well as the lower case aliases.
  673. if (getLexer().is(AsmToken::Comma))
  674. Lex();
  675. if (getLexer().isNot(AsmToken::Identifier) &&
  676. getLexer().isNot(AsmToken::Hash) &&
  677. getLexer().isNot(AsmToken::Percent) &&
  678. getLexer().isNot(AsmToken::String)) {
  679. if (!getLexer().getAllowAtInIdentifier())
  680. return TokError("expected STT_<TYPE_IN_UPPER_CASE>, '#<type>', "
  681. "'%<type>' or \"<type>\"");
  682. else if (getLexer().isNot(AsmToken::At))
  683. return TokError("expected STT_<TYPE_IN_UPPER_CASE>, '#<type>', '@<type>', "
  684. "'%<type>' or \"<type>\"");
  685. }
  686. if (getLexer().isNot(AsmToken::String) &&
  687. getLexer().isNot(AsmToken::Identifier))
  688. Lex();
  689. SMLoc TypeLoc = getLexer().getLoc();
  690. StringRef Type;
  691. if (getParser().parseIdentifier(Type))
  692. return TokError("expected symbol type in directive");
  693. MCSymbolAttr Attr = MCAttrForString(Type);
  694. if (Attr == MCSA_Invalid)
  695. return Error(TypeLoc, "unsupported attribute in '.type' directive");
  696. if (getLexer().isNot(AsmToken::EndOfStatement))
  697. return TokError("unexpected token in '.type' directive");
  698. Lex();
  699. getStreamer().emitSymbolAttribute(Sym, Attr);
  700. return false;
  701. }
  702. /// ParseDirectiveIdent
  703. /// ::= .ident string
  704. bool ELFAsmParser::ParseDirectiveIdent(StringRef, SMLoc) {
  705. if (getLexer().isNot(AsmToken::String))
  706. return TokError("unexpected token in '.ident' directive");
  707. StringRef Data = getTok().getIdentifier();
  708. Lex();
  709. if (getLexer().isNot(AsmToken::EndOfStatement))
  710. return TokError("unexpected token in '.ident' directive");
  711. Lex();
  712. getStreamer().emitIdent(Data);
  713. return false;
  714. }
  715. /// ParseDirectiveSymver
  716. /// ::= .symver foo, bar2@zed
  717. bool ELFAsmParser::ParseDirectiveSymver(StringRef, SMLoc) {
  718. StringRef OriginalName, Name, Action;
  719. if (getParser().parseIdentifier(OriginalName))
  720. return TokError("expected identifier in directive");
  721. if (getLexer().isNot(AsmToken::Comma))
  722. return TokError("expected a comma");
  723. // ARM assembly uses @ for a comment...
  724. // except when parsing the second parameter of the .symver directive.
  725. // Force the next symbol to allow @ in the identifier, which is
  726. // required for this directive and then reset it to its initial state.
  727. const bool AllowAtInIdentifier = getLexer().getAllowAtInIdentifier();
  728. getLexer().setAllowAtInIdentifier(true);
  729. Lex();
  730. getLexer().setAllowAtInIdentifier(AllowAtInIdentifier);
  731. if (getParser().parseIdentifier(Name))
  732. return TokError("expected identifier in directive");
  733. if (!Name.contains('@'))
  734. return TokError("expected a '@' in the name");
  735. bool KeepOriginalSym = !Name.contains("@@@");
  736. if (parseOptionalToken(AsmToken::Comma)) {
  737. if (getParser().parseIdentifier(Action) || Action != "remove")
  738. return TokError("expected 'remove'");
  739. KeepOriginalSym = false;
  740. }
  741. (void)parseOptionalToken(AsmToken::EndOfStatement);
  742. getStreamer().emitELFSymverDirective(
  743. getContext().getOrCreateSymbol(OriginalName), Name, KeepOriginalSym);
  744. return false;
  745. }
  746. /// ParseDirectiveVersion
  747. /// ::= .version string
  748. bool ELFAsmParser::ParseDirectiveVersion(StringRef, SMLoc) {
  749. if (getLexer().isNot(AsmToken::String))
  750. return TokError("unexpected token in '.version' directive");
  751. StringRef Data = getTok().getIdentifier();
  752. Lex();
  753. MCSection *Note = getContext().getELFSection(".note", ELF::SHT_NOTE, 0);
  754. getStreamer().PushSection();
  755. getStreamer().SwitchSection(Note);
  756. getStreamer().emitInt32(Data.size() + 1); // namesz
  757. getStreamer().emitInt32(0); // descsz = 0 (no description).
  758. getStreamer().emitInt32(1); // type = NT_VERSION
  759. getStreamer().emitBytes(Data); // name
  760. getStreamer().emitInt8(0); // NUL
  761. getStreamer().emitValueToAlignment(4);
  762. getStreamer().PopSection();
  763. return false;
  764. }
  765. /// ParseDirectiveWeakref
  766. /// ::= .weakref foo, bar
  767. bool ELFAsmParser::ParseDirectiveWeakref(StringRef, SMLoc) {
  768. // FIXME: Share code with the other alias building directives.
  769. StringRef AliasName;
  770. if (getParser().parseIdentifier(AliasName))
  771. return TokError("expected identifier in directive");
  772. if (getLexer().isNot(AsmToken::Comma))
  773. return TokError("expected a comma");
  774. Lex();
  775. StringRef Name;
  776. if (getParser().parseIdentifier(Name))
  777. return TokError("expected identifier in directive");
  778. MCSymbol *Alias = getContext().getOrCreateSymbol(AliasName);
  779. MCSymbol *Sym = getContext().getOrCreateSymbol(Name);
  780. getStreamer().emitWeakReference(Alias, Sym);
  781. return false;
  782. }
  783. bool ELFAsmParser::ParseDirectiveSubsection(StringRef, SMLoc) {
  784. const MCExpr *Subsection = nullptr;
  785. if (getLexer().isNot(AsmToken::EndOfStatement)) {
  786. if (getParser().parseExpression(Subsection))
  787. return true;
  788. }
  789. if (getLexer().isNot(AsmToken::EndOfStatement))
  790. return TokError("unexpected token in directive");
  791. Lex();
  792. getStreamer().SubSection(Subsection);
  793. return false;
  794. }
  795. bool ELFAsmParser::ParseDirectiveCGProfile(StringRef S, SMLoc Loc) {
  796. return MCAsmParserExtension::ParseDirectiveCGProfile(S, Loc);
  797. }
  798. namespace llvm {
  799. MCAsmParserExtension *createELFAsmParser() {
  800. return new ELFAsmParser;
  801. }
  802. } // end namespace llvm