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