Line data Source code
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"
17 : #include "llvm/MC/MCParser/MCAsmLexer.h"
18 : #include "llvm/MC/MCParser/MCAsmParser.h"
19 : #include "llvm/MC/MCParser/MCAsmParserExtension.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"
27 : #include "llvm/Support/MathExtras.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 17253 : getParser().addDirectiveHandler(Directive, Handler);
44 : }
45 :
46 : bool ParseSectionSwitch(StringRef Section, unsigned Type, unsigned Flags,
47 : SectionKind Kind);
48 :
49 : public:
50 17253 : ELFAsmParser() { BracketExpressionsSupported = true; }
51 :
52 17253 : void Initialize(MCAsmParser &Parser) override {
53 : // Call the base implementation.
54 17253 : this->MCAsmParserExtension::Initialize(Parser);
55 :
56 17253 : addDirectiveHandler<&ELFAsmParser::ParseSectionDirectiveData>(".data");
57 17253 : addDirectiveHandler<&ELFAsmParser::ParseSectionDirectiveText>(".text");
58 17253 : addDirectiveHandler<&ELFAsmParser::ParseSectionDirectiveBSS>(".bss");
59 17253 : addDirectiveHandler<&ELFAsmParser::ParseSectionDirectiveRoData>(".rodata");
60 17253 : addDirectiveHandler<&ELFAsmParser::ParseSectionDirectiveTData>(".tdata");
61 17253 : addDirectiveHandler<&ELFAsmParser::ParseSectionDirectiveTBSS>(".tbss");
62 : addDirectiveHandler<
63 17253 : &ELFAsmParser::ParseSectionDirectiveDataRel>(".data.rel");
64 : addDirectiveHandler<
65 17253 : &ELFAsmParser::ParseSectionDirectiveDataRelRo>(".data.rel.ro");
66 : addDirectiveHandler<
67 17253 : &ELFAsmParser::ParseSectionDirectiveEhFrame>(".eh_frame");
68 17253 : addDirectiveHandler<&ELFAsmParser::ParseDirectiveSection>(".section");
69 : addDirectiveHandler<
70 17253 : &ELFAsmParser::ParseDirectivePushSection>(".pushsection");
71 17253 : addDirectiveHandler<&ELFAsmParser::ParseDirectivePopSection>(".popsection");
72 17253 : addDirectiveHandler<&ELFAsmParser::ParseDirectiveSize>(".size");
73 17253 : addDirectiveHandler<&ELFAsmParser::ParseDirectivePrevious>(".previous");
74 17253 : addDirectiveHandler<&ELFAsmParser::ParseDirectiveType>(".type");
75 17253 : addDirectiveHandler<&ELFAsmParser::ParseDirectiveIdent>(".ident");
76 17253 : addDirectiveHandler<&ELFAsmParser::ParseDirectiveSymver>(".symver");
77 17253 : addDirectiveHandler<&ELFAsmParser::ParseDirectiveVersion>(".version");
78 17253 : addDirectiveHandler<&ELFAsmParser::ParseDirectiveWeakref>(".weakref");
79 17253 : addDirectiveHandler<&ELFAsmParser::ParseDirectiveSymbolAttribute>(".weak");
80 17253 : addDirectiveHandler<&ELFAsmParser::ParseDirectiveSymbolAttribute>(".local");
81 : addDirectiveHandler<
82 17253 : &ELFAsmParser::ParseDirectiveSymbolAttribute>(".protected");
83 : addDirectiveHandler<
84 17253 : &ELFAsmParser::ParseDirectiveSymbolAttribute>(".internal");
85 : addDirectiveHandler<
86 17253 : &ELFAsmParser::ParseDirectiveSymbolAttribute>(".hidden");
87 17253 : addDirectiveHandler<&ELFAsmParser::ParseDirectiveSubsection>(".subsection");
88 17253 : addDirectiveHandler<&ELFAsmParser::ParseDirectiveCGProfile>(".cg_profile");
89 17253 : }
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 0 : bool ParseSectionDirectiveData(StringRef, SMLoc) {
94 301 : return ParseSectionSwitch(".data", ELF::SHT_PROGBITS,
95 : ELF::SHF_WRITE | ELF::SHF_ALLOC,
96 0 : SectionKind::getData());
97 : }
98 0 : bool ParseSectionDirectiveText(StringRef, SMLoc) {
99 11048 : return ParseSectionSwitch(".text", ELF::SHT_PROGBITS,
100 : ELF::SHF_EXECINSTR |
101 0 : ELF::SHF_ALLOC, SectionKind::getText());
102 : }
103 0 : bool ParseSectionDirectiveBSS(StringRef, SMLoc) {
104 48 : return ParseSectionSwitch(".bss", ELF::SHT_NOBITS,
105 : ELF::SHF_WRITE |
106 0 : ELF::SHF_ALLOC, SectionKind::getBSS());
107 : }
108 0 : bool ParseSectionDirectiveRoData(StringRef, SMLoc) {
109 17 : return ParseSectionSwitch(".rodata", ELF::SHT_PROGBITS,
110 : ELF::SHF_ALLOC,
111 0 : SectionKind::getReadOnly());
112 : }
113 0 : bool ParseSectionDirectiveTData(StringRef, SMLoc) {
114 1 : return ParseSectionSwitch(".tdata", ELF::SHT_PROGBITS,
115 : ELF::SHF_ALLOC |
116 : ELF::SHF_TLS | ELF::SHF_WRITE,
117 0 : SectionKind::getThreadData());
118 : }
119 0 : bool ParseSectionDirectiveTBSS(StringRef, SMLoc) {
120 3 : return ParseSectionSwitch(".tbss", ELF::SHT_NOBITS,
121 : ELF::SHF_ALLOC |
122 : ELF::SHF_TLS | ELF::SHF_WRITE,
123 0 : SectionKind::getThreadBSS());
124 : }
125 0 : bool ParseSectionDirectiveDataRel(StringRef, SMLoc) {
126 1 : return ParseSectionSwitch(".data.rel", ELF::SHT_PROGBITS,
127 : ELF::SHF_ALLOC | ELF::SHF_WRITE,
128 0 : SectionKind::getData());
129 : }
130 0 : bool ParseSectionDirectiveDataRelRo(StringRef, SMLoc) {
131 1 : return ParseSectionSwitch(".data.rel.ro", ELF::SHT_PROGBITS,
132 : ELF::SHF_ALLOC |
133 : ELF::SHF_WRITE,
134 0 : SectionKind::getReadOnlyWithRel());
135 : }
136 0 : bool ParseSectionDirectiveEhFrame(StringRef, SMLoc) {
137 1 : return ParseSectionSwitch(".eh_frame", ELF::SHT_PROGBITS,
138 : ELF::SHF_ALLOC | ELF::SHF_WRITE,
139 0 : SectionKind::getData());
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 0 : bool ELFAsmParser::ParseDirectiveSymbolAttribute(StringRef Directive, SMLoc) {
171 0 : MCSymbolAttr Attr = StringSwitch<MCSymbolAttr>(Directive)
172 0 : .Case(".weak", MCSA_Weak)
173 0 : .Case(".local", MCSA_Local)
174 0 : .Case(".hidden", MCSA_Hidden)
175 0 : .Case(".internal", MCSA_Internal)
176 0 : .Case(".protected", MCSA_Protected)
177 : .Default(MCSA_Invalid);
178 : assert(Attr != MCSA_Invalid && "unexpected symbol attribute directive!");
179 0 : if (getLexer().isNot(AsmToken::EndOfStatement)) {
180 : while (true) {
181 0 : StringRef Name;
182 :
183 0 : if (getParser().parseIdentifier(Name))
184 0 : return TokError("expected identifier in directive");
185 :
186 0 : MCSymbol *Sym = getContext().getOrCreateSymbol(Name);
187 :
188 0 : getStreamer().EmitSymbolAttribute(Sym, Attr);
189 :
190 0 : if (getLexer().is(AsmToken::EndOfStatement))
191 : break;
192 :
193 0 : if (getLexer().isNot(AsmToken::Comma))
194 0 : return TokError("unexpected token in directive");
195 : Lex();
196 0 : }
197 : }
198 :
199 : Lex();
200 0 : return false;
201 : }
202 :
203 0 : bool ELFAsmParser::ParseSectionSwitch(StringRef Section, unsigned Type,
204 : unsigned Flags, SectionKind Kind) {
205 0 : const MCExpr *Subsection = nullptr;
206 0 : if (getLexer().isNot(AsmToken::EndOfStatement)) {
207 0 : if (getParser().parseExpression(Subsection))
208 0 : return true;
209 : }
210 : Lex();
211 :
212 0 : getStreamer().SwitchSection(getContext().getELFSection(Section, Type, Flags),
213 0 : Subsection);
214 :
215 0 : return false;
216 : }
217 :
218 0 : bool ELFAsmParser::ParseDirectiveSize(StringRef, SMLoc) {
219 0 : StringRef Name;
220 0 : if (getParser().parseIdentifier(Name))
221 0 : return TokError("expected identifier in directive");
222 0 : MCSymbolELF *Sym = cast<MCSymbolELF>(getContext().getOrCreateSymbol(Name));
223 :
224 0 : if (getLexer().isNot(AsmToken::Comma))
225 0 : return TokError("unexpected token in directive");
226 : Lex();
227 :
228 : const MCExpr *Expr;
229 0 : if (getParser().parseExpression(Expr))
230 0 : return true;
231 :
232 0 : if (getLexer().isNot(AsmToken::EndOfStatement))
233 0 : return TokError("unexpected token in directive");
234 : Lex();
235 :
236 0 : getStreamer().emitELFSize(Sym, Expr);
237 0 : return false;
238 : }
239 :
240 397274 : bool ELFAsmParser::ParseSectionName(StringRef &SectionName) {
241 : // A section name can contain -, so we cannot just use
242 : // parseIdentifier.
243 397274 : SMLoc FirstLoc = getLexer().getLoc();
244 : unsigned Size = 0;
245 :
246 397274 : if (getLexer().is(AsmToken::String)) {
247 135 : SectionName = getTok().getIdentifier();
248 : Lex();
249 135 : return false;
250 : }
251 :
252 1191571 : while (!getParser().hasPendingError()) {
253 794432 : SMLoc PrevLoc = getLexer().getLoc();
254 1518963 : if (getLexer().is(AsmToken::Comma) ||
255 : getLexer().is(AsmToken::EndOfStatement))
256 : break;
257 :
258 : unsigned CurSize;
259 397294 : if (getLexer().is(AsmToken::String)) {
260 3 : CurSize = getTok().getIdentifier().size() + 2;
261 : Lex();
262 397291 : } else if (getLexer().is(AsmToken::Identifier)) {
263 397188 : CurSize = getTok().getIdentifier().size();
264 : Lex();
265 : } else {
266 103 : CurSize = getTok().getString().size();
267 : Lex();
268 : }
269 397294 : Size += CurSize;
270 397294 : SectionName = StringRef(FirstLoc.getPointer(), Size);
271 :
272 : // Make sure the following token is adjacent.
273 397294 : if (PrevLoc.getPointer() + CurSize != getTok().getLoc().getPointer())
274 : break;
275 : }
276 397139 : if (Size == 0)
277 0 : return true;
278 :
279 : return false;
280 : }
281 :
282 69998 : 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 69998 : if (!flagsStr.getAsInteger(0, flags))
287 : return flags;
288 :
289 143475 : for (char i : flagsStr) {
290 73479 : switch (i) {
291 69319 : case 'a':
292 69319 : flags |= ELF::SHF_ALLOC;
293 69319 : break;
294 8 : case 'e':
295 8 : flags |= ELF::SHF_EXCLUDE;
296 8 : break;
297 3231 : case 'x':
298 3231 : flags |= ELF::SHF_EXECINSTR;
299 3231 : break;
300 374 : case 'w':
301 374 : flags |= ELF::SHF_WRITE;
302 374 : break;
303 31 : case 'o':
304 31 : flags |= ELF::SHF_LINK_ORDER;
305 31 : break;
306 177 : case 'M':
307 177 : flags |= ELF::SHF_MERGE;
308 177 : break;
309 131 : case 'S':
310 131 : flags |= ELF::SHF_STRINGS;
311 131 : break;
312 146 : case 'T':
313 146 : flags |= ELF::SHF_TLS;
314 146 : break;
315 0 : case 'c':
316 0 : flags |= ELF::XCORE_SHF_CP_SECTION;
317 0 : break;
318 0 : case 'd':
319 0 : flags |= ELF::XCORE_SHF_DP_SECTION;
320 0 : break;
321 4 : case 'y':
322 4 : flags |= ELF::SHF_ARM_PURECODE;
323 4 : break;
324 57 : case 'G':
325 57 : flags |= ELF::SHF_GROUP;
326 57 : break;
327 1 : case '?':
328 1 : *UseLastGroup = true;
329 1 : break;
330 : default:
331 : return -1U;
332 : }
333 : }
334 :
335 : return flags;
336 : }
337 :
338 11 : unsigned ELFAsmParser::parseSunStyleSectionFlags() {
339 : unsigned flags = 0;
340 43 : while (getLexer().is(AsmToken::Hash)) {
341 : Lex(); // Eat the #.
342 :
343 27 : if (!getLexer().is(AsmToken::Identifier))
344 : return -1U;
345 :
346 : StringRef flagId = getTok().getIdentifier();
347 : if (flagId == "alloc")
348 11 : flags |= ELF::SHF_ALLOC;
349 : else if (flagId == "execinstr")
350 0 : flags |= ELF::SHF_EXECINSTR;
351 : else if (flagId == "write")
352 10 : flags |= ELF::SHF_WRITE;
353 : else if (flagId == "tls")
354 6 : flags |= ELF::SHF_TLS;
355 : else
356 : return -1U;
357 :
358 : Lex(); // Eat the flag.
359 :
360 27 : if (!getLexer().is(AsmToken::Comma))
361 : break;
362 : Lex(); // Eat the comma.
363 : }
364 : return flags;
365 : }
366 :
367 :
368 0 : bool ELFAsmParser::ParseDirectivePushSection(StringRef s, SMLoc loc) {
369 0 : getStreamer().PushSection();
370 :
371 0 : if (ParseSectionArguments(/*IsPush=*/true, loc)) {
372 0 : getStreamer().PopSection();
373 0 : return true;
374 : }
375 :
376 : return false;
377 : }
378 :
379 0 : bool ELFAsmParser::ParseDirectivePopSection(StringRef, SMLoc) {
380 0 : if (!getStreamer().PopSection())
381 0 : return TokError(".popsection without corresponding .pushsection");
382 : return false;
383 : }
384 :
385 0 : bool ELFAsmParser::ParseDirectiveSection(StringRef, SMLoc loc) {
386 397264 : return ParseSectionArguments(/*IsPush=*/false, loc);
387 : }
388 :
389 70009 : bool ELFAsmParser::maybeParseSectionType(StringRef &TypeName) {
390 : MCAsmLexer &L = getLexer();
391 70009 : if (L.isNot(AsmToken::Comma))
392 : return false;
393 : Lex();
394 2094 : if (L.isNot(AsmToken::At) && L.isNot(AsmToken::Percent) &&
395 : L.isNot(AsmToken::String)) {
396 1 : if (L.getAllowAtInIdentifier())
397 0 : return TokError("expected '@<type>', '%<type>' or \"<type>\"");
398 : else
399 1 : return TokError("expected '%<type>' or \"<type>\"");
400 : }
401 2093 : if (!L.is(AsmToken::String))
402 : Lex();
403 2093 : if (L.is(AsmToken::Integer)) {
404 13 : TypeName = getTok().getString();
405 : Lex();
406 2080 : } else if (getParser().parseIdentifier(TypeName))
407 0 : return TokError("expected identifier in directive");
408 : return false;
409 : }
410 :
411 177 : bool ELFAsmParser::parseMergeSize(int64_t &Size) {
412 177 : if (getLexer().isNot(AsmToken::Comma))
413 0 : return TokError("expected the entry size");
414 : Lex();
415 177 : if (getParser().parseAbsoluteExpression(Size))
416 : return true;
417 177 : if (Size <= 0)
418 0 : return TokError("entry size must be positive");
419 : return false;
420 : }
421 :
422 57 : bool ELFAsmParser::parseGroup(StringRef &GroupName) {
423 : MCAsmLexer &L = getLexer();
424 57 : if (L.isNot(AsmToken::Comma))
425 0 : return TokError("expected group name");
426 : Lex();
427 57 : if (L.is(AsmToken::Integer)) {
428 1 : GroupName = getTok().getString();
429 : Lex();
430 56 : } else if (getParser().parseIdentifier(GroupName)) {
431 1 : return TokError("invalid group name");
432 : }
433 56 : if (L.is(AsmToken::Comma)) {
434 : Lex();
435 56 : StringRef Linkage;
436 56 : if (getParser().parseIdentifier(Linkage))
437 1 : return TokError("invalid linkage");
438 : if (Linkage != "comdat")
439 0 : return TokError("Linkage must be 'comdat'");
440 : }
441 : return false;
442 : }
443 :
444 31 : bool ELFAsmParser::parseMetadataSym(MCSymbolELF *&Associated) {
445 : MCAsmLexer &L = getLexer();
446 31 : if (L.isNot(AsmToken::Comma))
447 1 : return TokError("expected metadata symbol");
448 : Lex();
449 30 : StringRef Name;
450 30 : if (getParser().parseIdentifier(Name))
451 1 : return TokError("invalid metadata symbol");
452 29 : Associated = dyn_cast_or_null<MCSymbolELF>(getContext().lookupSymbol(Name));
453 29 : if (!Associated || !Associated->isInSection())
454 3 : return TokError("symbol is not in a section: " + Name);
455 : return false;
456 : }
457 :
458 70001 : bool ELFAsmParser::maybeParseUniqueID(int64_t &UniqueID) {
459 : MCAsmLexer &L = getLexer();
460 70001 : if (L.isNot(AsmToken::Comma))
461 : return false;
462 : Lex();
463 93 : StringRef UniqueStr;
464 93 : if (getParser().parseIdentifier(UniqueStr))
465 0 : return TokError("expected identifier in directive");
466 : if (UniqueStr != "unique")
467 0 : return TokError("expected 'unique'");
468 93 : if (L.isNot(AsmToken::Comma))
469 1 : return TokError("expected commma");
470 : Lex();
471 92 : if (getParser().parseAbsoluteExpression(UniqueID))
472 : return true;
473 91 : if (UniqueID < 0)
474 1 : return TokError("unique id must be positive");
475 90 : if (!isUInt<32>(UniqueID) || UniqueID == ~0U)
476 1 : return TokError("unique id is too large");
477 : return false;
478 : }
479 :
480 5544626 : static bool hasPrefix(StringRef SectionName, StringRef Prefix) {
481 5544626 : return SectionName.startswith(Prefix) || SectionName == Prefix.drop_back();
482 : }
483 :
484 397274 : bool ELFAsmParser::ParseSectionArguments(bool IsPush, SMLoc loc) {
485 397274 : StringRef SectionName;
486 :
487 397274 : if (ParseSectionName(SectionName))
488 0 : return TokError("expected identifier in directive");
489 :
490 397274 : StringRef TypeName;
491 397274 : int64_t Size = 0;
492 397274 : StringRef GroupName;
493 : unsigned Flags = 0;
494 397274 : const MCExpr *Subsection = nullptr;
495 397274 : bool UseLastGroup = false;
496 397274 : MCSymbolELF *Associated = nullptr;
497 397274 : int64_t UniqueID = ~0;
498 :
499 : // Set the defaults first.
500 794436 : if (hasPrefix(SectionName, ".rodata.") || SectionName == ".rodata1")
501 : Flags |= ELF::SHF_ALLOC;
502 397149 : else if (SectionName == ".fini" || SectionName == ".init" ||
503 794310 : hasPrefix(SectionName, ".text."))
504 : Flags |= ELF::SHF_ALLOC | ELF::SHF_EXECINSTR;
505 792806 : else if (hasPrefix(SectionName, ".data.") || SectionName == ".data1" ||
506 792727 : hasPrefix(SectionName, ".bss.") ||
507 792693 : hasPrefix(SectionName, ".init_array.") ||
508 1189101 : hasPrefix(SectionName, ".fini_array.") ||
509 792763 : hasPrefix(SectionName, ".preinit_array."))
510 : Flags |= ELF::SHF_ALLOC | ELF::SHF_WRITE;
511 792581 : else if (hasPrefix(SectionName, ".tdata.") ||
512 792581 : hasPrefix(SectionName, ".tbss."))
513 : Flags |= ELF::SHF_ALLOC | ELF::SHF_WRITE | ELF::SHF_TLS;
514 :
515 397274 : if (getLexer().is(AsmToken::Comma)) {
516 : Lex();
517 :
518 70011 : if (IsPush && getLexer().isNot(AsmToken::String)) {
519 1 : if (getParser().parseExpression(Subsection))
520 : return true;
521 1 : if (getLexer().isNot(AsmToken::Comma))
522 : goto EndStmt;
523 : Lex();
524 : }
525 :
526 : unsigned extraFlags;
527 :
528 70009 : if (getLexer().isNot(AsmToken::String)) {
529 11 : if (!getContext().getAsmInfo()->usesSunStyleELFSectionSwitchSyntax()
530 22 : || getLexer().isNot(AsmToken::Hash))
531 0 : return TokError("expected string in directive");
532 11 : extraFlags = parseSunStyleSectionFlags();
533 : } else {
534 69998 : StringRef FlagsStr = getTok().getStringContents();
535 : Lex();
536 69998 : extraFlags = parseSectionFlags(FlagsStr, &UseLastGroup);
537 : }
538 :
539 70009 : if (extraFlags == -1U)
540 0 : return TokError("unknown flag");
541 70009 : Flags |= extraFlags;
542 :
543 70009 : bool Mergeable = Flags & ELF::SHF_MERGE;
544 70009 : bool Group = Flags & ELF::SHF_GROUP;
545 70009 : if (Group && UseLastGroup)
546 0 : return TokError("Section cannot specifiy a group name while also acting "
547 : "as a member of the last group");
548 :
549 70009 : if (maybeParseSectionType(TypeName))
550 : return true;
551 :
552 : MCAsmLexer &L = getLexer();
553 70008 : if (TypeName.empty()) {
554 67915 : if (Mergeable)
555 0 : return TokError("Mergeable section must specify the type");
556 67915 : if (Group)
557 0 : return TokError("Group section must specify the type");
558 67915 : if (L.isNot(AsmToken::EndOfStatement))
559 0 : return TokError("unexpected token in directive");
560 : }
561 :
562 70008 : if (Mergeable)
563 177 : if (parseMergeSize(Size))
564 : return true;
565 70008 : if (Group)
566 57 : if (parseGroup(GroupName))
567 : return true;
568 70006 : if (Flags & ELF::SHF_LINK_ORDER)
569 31 : if (parseMetadataSym(Associated))
570 : return true;
571 70001 : if (maybeParseUniqueID(UniqueID))
572 : return true;
573 : }
574 :
575 397262 : EndStmt:
576 397262 : if (getLexer().isNot(AsmToken::EndOfStatement))
577 2 : return TokError("unexpected token in directive");
578 : Lex();
579 :
580 : unsigned Type = ELF::SHT_PROGBITS;
581 :
582 397260 : if (TypeName.empty()) {
583 : if (SectionName.startswith(".note"))
584 : Type = ELF::SHT_NOTE;
585 395171 : else if (hasPrefix(SectionName, ".init_array."))
586 : Type = ELF::SHT_INIT_ARRAY;
587 395168 : else if (hasPrefix(SectionName, ".bss."))
588 : Type = ELF::SHT_NOBITS;
589 395160 : else if (hasPrefix(SectionName, ".tbss."))
590 : Type = ELF::SHT_NOBITS;
591 395148 : else if (hasPrefix(SectionName, ".fini_array."))
592 : Type = ELF::SHT_FINI_ARRAY;
593 395147 : else if (hasPrefix(SectionName, ".preinit_array."))
594 : Type = ELF::SHT_PREINIT_ARRAY;
595 : } else {
596 : if (TypeName == "init_array")
597 : Type = ELF::SHT_INIT_ARRAY;
598 : else if (TypeName == "fini_array")
599 : Type = ELF::SHT_FINI_ARRAY;
600 : else if (TypeName == "preinit_array")
601 : Type = ELF::SHT_PREINIT_ARRAY;
602 : else if (TypeName == "nobits")
603 : Type = ELF::SHT_NOBITS;
604 : else if (TypeName == "progbits")
605 : Type = ELF::SHT_PROGBITS;
606 : else if (TypeName == "note")
607 : Type = ELF::SHT_NOTE;
608 : else if (TypeName == "unwind")
609 : Type = ELF::SHT_X86_64_UNWIND;
610 : else if (TypeName == "llvm_odrtab")
611 : Type = ELF::SHT_LLVM_ODRTAB;
612 : else if (TypeName == "llvm_linker_options")
613 : Type = ELF::SHT_LLVM_LINKER_OPTIONS;
614 : else if (TypeName == "llvm_call_graph_profile")
615 : Type = ELF::SHT_LLVM_CALL_GRAPH_PROFILE;
616 13 : else if (TypeName.getAsInteger(0, Type))
617 0 : return TokError("unknown section type");
618 : }
619 :
620 397260 : if (UseLastGroup) {
621 : MCSectionSubPair CurrentSection = getStreamer().getCurrentSection();
622 : if (const MCSectionELF *Section =
623 : cast_or_null<MCSectionELF>(CurrentSection.first))
624 1 : if (const MCSymbol *Group = Section->getGroup()) {
625 1 : GroupName = Group->getName();
626 1 : Flags |= ELF::SHF_GROUP;
627 : }
628 : }
629 :
630 : MCSection *ELFSection =
631 1191780 : getContext().getELFSection(SectionName, Type, Flags, Size, GroupName,
632 : UniqueID, Associated);
633 397260 : getStreamer().SwitchSection(ELFSection, Subsection);
634 :
635 397258 : if (getContext().getGenDwarfForAssembly()) {
636 13 : bool InsertResult = getContext().addGenDwarfSection(ELFSection);
637 13 : if (InsertResult) {
638 7 : if (getContext().getDwarfVersion() <= 2)
639 2 : Warning(loc, "DWARF2 only supports one section per compilation unit");
640 :
641 7 : if (!ELFSection->getBeginSymbol()) {
642 0 : MCSymbol *SectionStartSymbol = getContext().createTempSymbol();
643 0 : getStreamer().EmitLabel(SectionStartSymbol);
644 : ELFSection->setBeginSymbol(SectionStartSymbol);
645 : }
646 : }
647 : }
648 :
649 : return false;
650 : }
651 :
652 0 : bool ELFAsmParser::ParseDirectivePrevious(StringRef DirName, SMLoc) {
653 : MCSectionSubPair PreviousSection = getStreamer().getPreviousSection();
654 0 : if (PreviousSection.first == nullptr)
655 0 : return TokError(".previous without corresponding .section");
656 0 : getStreamer().SwitchSection(PreviousSection.first, PreviousSection.second);
657 :
658 0 : return false;
659 : }
660 :
661 2310 : static MCSymbolAttr MCAttrForString(StringRef Type) {
662 2310 : return StringSwitch<MCSymbolAttr>(Type)
663 : .Cases("STT_FUNC", "function", MCSA_ELF_TypeFunction)
664 : .Cases("STT_OBJECT", "object", MCSA_ELF_TypeObject)
665 : .Cases("STT_TLS", "tls_object", MCSA_ELF_TypeTLS)
666 : .Cases("STT_COMMON", "common", MCSA_ELF_TypeCommon)
667 : .Cases("STT_NOTYPE", "notype", MCSA_ELF_TypeNoType)
668 : .Cases("STT_GNU_IFUNC", "gnu_indirect_function",
669 : MCSA_ELF_TypeIndFunction)
670 2310 : .Case("gnu_unique_object", MCSA_ELF_TypeGnuUniqueObject)
671 2310 : .Default(MCSA_Invalid);
672 : }
673 :
674 : /// ParseDirectiveELFType
675 : /// ::= .type identifier , STT_<TYPE_IN_UPPER_CASE>
676 : /// ::= .type identifier , #attribute
677 : /// ::= .type identifier , @attribute
678 : /// ::= .type identifier , %attribute
679 : /// ::= .type identifier , "attribute"
680 0 : bool ELFAsmParser::ParseDirectiveType(StringRef, SMLoc) {
681 0 : StringRef Name;
682 0 : if (getParser().parseIdentifier(Name))
683 0 : return TokError("expected identifier in directive");
684 :
685 : // Handle the identifier as the key symbol.
686 0 : MCSymbol *Sym = getContext().getOrCreateSymbol(Name);
687 :
688 : // NOTE the comma is optional in all cases. It is only documented as being
689 : // optional in the first case, however, GAS will silently treat the comma as
690 : // optional in all cases. Furthermore, although the documentation states that
691 : // the first form only accepts STT_<TYPE_IN_UPPER_CASE>, in reality, GAS
692 : // accepts both the upper case name as well as the lower case aliases.
693 0 : if (getLexer().is(AsmToken::Comma))
694 : Lex();
695 :
696 0 : if (getLexer().isNot(AsmToken::Identifier) &&
697 0 : getLexer().isNot(AsmToken::Hash) &&
698 0 : getLexer().isNot(AsmToken::Percent) &&
699 : getLexer().isNot(AsmToken::String)) {
700 0 : if (!getLexer().getAllowAtInIdentifier())
701 0 : return TokError("expected STT_<TYPE_IN_UPPER_CASE>, '#<type>', "
702 : "'%<type>' or \"<type>\"");
703 0 : else if (getLexer().isNot(AsmToken::At))
704 0 : return TokError("expected STT_<TYPE_IN_UPPER_CASE>, '#<type>', '@<type>', "
705 : "'%<type>' or \"<type>\"");
706 : }
707 :
708 0 : if (getLexer().isNot(AsmToken::String) &&
709 : getLexer().isNot(AsmToken::Identifier))
710 : Lex();
711 :
712 0 : SMLoc TypeLoc = getLexer().getLoc();
713 :
714 0 : StringRef Type;
715 0 : if (getParser().parseIdentifier(Type))
716 0 : return TokError("expected symbol type in directive");
717 :
718 0 : MCSymbolAttr Attr = MCAttrForString(Type);
719 0 : if (Attr == MCSA_Invalid)
720 0 : return Error(TypeLoc, "unsupported attribute in '.type' directive");
721 :
722 0 : if (getLexer().isNot(AsmToken::EndOfStatement))
723 0 : return TokError("unexpected token in '.type' directive");
724 : Lex();
725 :
726 0 : getStreamer().EmitSymbolAttribute(Sym, Attr);
727 :
728 0 : return false;
729 : }
730 :
731 : /// ParseDirectiveIdent
732 : /// ::= .ident string
733 0 : bool ELFAsmParser::ParseDirectiveIdent(StringRef, SMLoc) {
734 0 : if (getLexer().isNot(AsmToken::String))
735 0 : return TokError("unexpected token in '.ident' directive");
736 :
737 0 : StringRef Data = getTok().getIdentifier();
738 :
739 : Lex();
740 :
741 0 : if (getLexer().isNot(AsmToken::EndOfStatement))
742 0 : return TokError("unexpected token in '.ident' directive");
743 : Lex();
744 :
745 0 : getStreamer().EmitIdent(Data);
746 0 : return false;
747 : }
748 :
749 : /// ParseDirectiveSymver
750 : /// ::= .symver foo, bar2@zed
751 0 : bool ELFAsmParser::ParseDirectiveSymver(StringRef, SMLoc) {
752 0 : StringRef Name;
753 0 : if (getParser().parseIdentifier(Name))
754 0 : return TokError("expected identifier in directive");
755 :
756 0 : if (getLexer().isNot(AsmToken::Comma))
757 0 : return TokError("expected a comma");
758 :
759 : // ARM assembly uses @ for a comment...
760 : // except when parsing the second parameter of the .symver directive.
761 : // Force the next symbol to allow @ in the identifier, which is
762 : // required for this directive and then reset it to its initial state.
763 0 : const bool AllowAtInIdentifier = getLexer().getAllowAtInIdentifier();
764 : getLexer().setAllowAtInIdentifier(true);
765 : Lex();
766 : getLexer().setAllowAtInIdentifier(AllowAtInIdentifier);
767 :
768 0 : StringRef AliasName;
769 0 : if (getParser().parseIdentifier(AliasName))
770 0 : return TokError("expected identifier in directive");
771 :
772 0 : if (AliasName.find('@') == StringRef::npos)
773 0 : return TokError("expected a '@' in the name");
774 :
775 0 : MCSymbol *Sym = getContext().getOrCreateSymbol(Name);
776 0 : getStreamer().emitELFSymverDirective(AliasName, Sym);
777 0 : return false;
778 : }
779 :
780 : /// ParseDirectiveVersion
781 : /// ::= .version string
782 0 : bool ELFAsmParser::ParseDirectiveVersion(StringRef, SMLoc) {
783 0 : if (getLexer().isNot(AsmToken::String))
784 0 : return TokError("unexpected token in '.version' directive");
785 :
786 0 : StringRef Data = getTok().getIdentifier();
787 :
788 : Lex();
789 :
790 0 : MCSection *Note = getContext().getELFSection(".note", ELF::SHT_NOTE, 0);
791 :
792 0 : getStreamer().PushSection();
793 0 : getStreamer().SwitchSection(Note);
794 0 : getStreamer().EmitIntValue(Data.size()+1, 4); // namesz.
795 0 : getStreamer().EmitIntValue(0, 4); // descsz = 0 (no description).
796 0 : getStreamer().EmitIntValue(1, 4); // type = NT_VERSION.
797 0 : getStreamer().EmitBytes(Data); // name.
798 0 : getStreamer().EmitIntValue(0, 1); // terminate the string.
799 0 : getStreamer().EmitValueToAlignment(4); // ensure 4 byte alignment.
800 0 : getStreamer().PopSection();
801 0 : return false;
802 : }
803 :
804 : /// ParseDirectiveWeakref
805 : /// ::= .weakref foo, bar
806 0 : bool ELFAsmParser::ParseDirectiveWeakref(StringRef, SMLoc) {
807 : // FIXME: Share code with the other alias building directives.
808 :
809 0 : StringRef AliasName;
810 0 : if (getParser().parseIdentifier(AliasName))
811 0 : return TokError("expected identifier in directive");
812 :
813 0 : if (getLexer().isNot(AsmToken::Comma))
814 0 : return TokError("expected a comma");
815 :
816 : Lex();
817 :
818 0 : StringRef Name;
819 0 : if (getParser().parseIdentifier(Name))
820 0 : return TokError("expected identifier in directive");
821 :
822 0 : MCSymbol *Alias = getContext().getOrCreateSymbol(AliasName);
823 :
824 0 : MCSymbol *Sym = getContext().getOrCreateSymbol(Name);
825 :
826 0 : getStreamer().EmitWeakReference(Alias, Sym);
827 0 : return false;
828 : }
829 :
830 0 : bool ELFAsmParser::ParseDirectiveSubsection(StringRef, SMLoc) {
831 0 : const MCExpr *Subsection = nullptr;
832 0 : if (getLexer().isNot(AsmToken::EndOfStatement)) {
833 0 : if (getParser().parseExpression(Subsection))
834 0 : return true;
835 : }
836 :
837 0 : if (getLexer().isNot(AsmToken::EndOfStatement))
838 0 : return TokError("unexpected token in directive");
839 :
840 : Lex();
841 :
842 0 : getStreamer().SubSection(Subsection);
843 : return false;
844 : }
845 :
846 : /// ParseDirectiveCGProfile
847 : /// ::= .cg_profile identifier, identifier, <number>
848 0 : bool ELFAsmParser::ParseDirectiveCGProfile(StringRef, SMLoc) {
849 0 : StringRef From;
850 0 : SMLoc FromLoc = getLexer().getLoc();
851 0 : if (getParser().parseIdentifier(From))
852 0 : return TokError("expected identifier in directive");
853 :
854 0 : if (getLexer().isNot(AsmToken::Comma))
855 0 : return TokError("expected a comma");
856 : Lex();
857 :
858 0 : StringRef To;
859 0 : SMLoc ToLoc = getLexer().getLoc();
860 0 : if (getParser().parseIdentifier(To))
861 0 : return TokError("expected identifier in directive");
862 :
863 0 : if (getLexer().isNot(AsmToken::Comma))
864 0 : return TokError("expected a comma");
865 : Lex();
866 :
867 : int64_t Count;
868 0 : if (getParser().parseIntToken(
869 : Count, "expected integer count in '.cg_profile' directive"))
870 0 : return true;
871 :
872 0 : if (getLexer().isNot(AsmToken::EndOfStatement))
873 0 : return TokError("unexpected token in directive");
874 :
875 0 : MCSymbol *FromSym = getContext().getOrCreateSymbol(From);
876 0 : MCSymbol *ToSym = getContext().getOrCreateSymbol(To);
877 :
878 0 : getStreamer().emitCGProfileEntry(
879 : MCSymbolRefExpr::create(FromSym, MCSymbolRefExpr::VK_None, getContext(),
880 : FromLoc),
881 : MCSymbolRefExpr::create(ToSym, MCSymbolRefExpr::VK_None, getContext(),
882 : ToLoc),
883 0 : Count);
884 0 : return false;
885 : }
886 :
887 : namespace llvm {
888 :
889 17253 : MCAsmParserExtension *createELFAsmParser() {
890 17253 : return new ELFAsmParser;
891 : }
892 :
893 : } // end namespace llvm
|