1 //===- ELFAsmParser.cpp - ELF Assembly Parser -----------------------------===//
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
7 //===----------------------------------------------------------------------===//
9 #include "llvm/ADT/StringExtras.h"
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/MCParser/MCAsmLexer.h"
17 #include "llvm/MC/MCParser/MCAsmParser.h"
18 #include "llvm/MC/MCParser/MCAsmParserExtension.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"
35 class ELFAsmParser
: public MCAsmParserExtension
{
36 template<bool (ELFAsmParser::*HandlerMethod
)(StringRef
, SMLoc
)>
37 void addDirectiveHandler(StringRef Directive
) {
38 MCAsmParser::ExtensionDirectiveHandler Handler
= std::make_pair(
39 this, HandleDirective
<ELFAsmParser
, HandlerMethod
>);
41 getParser().addDirectiveHandler(Directive
, Handler
);
44 bool parseSectionSwitch(StringRef Section
, unsigned Type
, unsigned Flags
,
48 ELFAsmParser() { BracketExpressionsSupported
= true; }
50 void Initialize(MCAsmParser
&Parser
) override
{
51 // Call the base implementation.
52 this->MCAsmParserExtension::Initialize(Parser
);
54 addDirectiveHandler
<&ELFAsmParser::parseSectionDirectiveData
>(".data");
55 addDirectiveHandler
<&ELFAsmParser::parseSectionDirectiveText
>(".text");
56 addDirectiveHandler
<&ELFAsmParser::parseSectionDirectiveBSS
>(".bss");
57 addDirectiveHandler
<&ELFAsmParser::parseSectionDirectiveRoData
>(".rodata");
58 addDirectiveHandler
<&ELFAsmParser::parseSectionDirectiveTData
>(".tdata");
59 addDirectiveHandler
<&ELFAsmParser::parseSectionDirectiveTBSS
>(".tbss");
61 &ELFAsmParser::parseSectionDirectiveDataRel
>(".data.rel");
63 &ELFAsmParser::parseSectionDirectiveDataRelRo
>(".data.rel.ro");
65 &ELFAsmParser::parseSectionDirectiveEhFrame
>(".eh_frame");
66 addDirectiveHandler
<&ELFAsmParser::parseDirectiveSection
>(".section");
68 &ELFAsmParser::parseDirectivePushSection
>(".pushsection");
69 addDirectiveHandler
<&ELFAsmParser::parseDirectivePopSection
>(".popsection");
70 addDirectiveHandler
<&ELFAsmParser::parseDirectiveSize
>(".size");
71 addDirectiveHandler
<&ELFAsmParser::parseDirectivePrevious
>(".previous");
72 addDirectiveHandler
<&ELFAsmParser::parseDirectiveType
>(".type");
73 addDirectiveHandler
<&ELFAsmParser::parseDirectiveIdent
>(".ident");
74 addDirectiveHandler
<&ELFAsmParser::parseDirectiveSymver
>(".symver");
75 addDirectiveHandler
<&ELFAsmParser::parseDirectiveVersion
>(".version");
76 addDirectiveHandler
<&ELFAsmParser::parseDirectiveWeakref
>(".weakref");
77 addDirectiveHandler
<&ELFAsmParser::parseDirectiveSymbolAttribute
>(".weak");
78 addDirectiveHandler
<&ELFAsmParser::parseDirectiveSymbolAttribute
>(".local");
80 &ELFAsmParser::parseDirectiveSymbolAttribute
>(".protected");
82 &ELFAsmParser::parseDirectiveSymbolAttribute
>(".internal");
84 &ELFAsmParser::parseDirectiveSymbolAttribute
>(".hidden");
85 addDirectiveHandler
<&ELFAsmParser::parseDirectiveSubsection
>(".subsection");
86 addDirectiveHandler
<&ELFAsmParser::parseDirectiveCGProfile
>(".cg_profile");
89 // FIXME: Part of this logic is duplicated in the MCELFStreamer. What is
90 // the best way for us to get access to it?
91 bool parseSectionDirectiveData(StringRef
, SMLoc
) {
92 return parseSectionSwitch(".data", ELF::SHT_PROGBITS
,
93 ELF::SHF_WRITE
| ELF::SHF_ALLOC
,
94 SectionKind::getData());
96 bool parseSectionDirectiveText(StringRef
, SMLoc
) {
97 return parseSectionSwitch(".text", ELF::SHT_PROGBITS
,
99 ELF::SHF_ALLOC
, SectionKind::getText());
101 bool parseSectionDirectiveBSS(StringRef
, SMLoc
) {
102 return parseSectionSwitch(".bss", ELF::SHT_NOBITS
,
104 ELF::SHF_ALLOC
, SectionKind::getBSS());
106 bool parseSectionDirectiveRoData(StringRef
, SMLoc
) {
107 return parseSectionSwitch(".rodata", ELF::SHT_PROGBITS
,
109 SectionKind::getReadOnly());
111 bool parseSectionDirectiveTData(StringRef
, SMLoc
) {
112 return parseSectionSwitch(".tdata", ELF::SHT_PROGBITS
,
114 ELF::SHF_TLS
| ELF::SHF_WRITE
,
115 SectionKind::getThreadData());
117 bool parseSectionDirectiveTBSS(StringRef
, SMLoc
) {
118 return parseSectionSwitch(".tbss", ELF::SHT_NOBITS
,
120 ELF::SHF_TLS
| ELF::SHF_WRITE
,
121 SectionKind::getThreadBSS());
123 bool parseSectionDirectiveDataRel(StringRef
, SMLoc
) {
124 return parseSectionSwitch(".data.rel", ELF::SHT_PROGBITS
,
125 ELF::SHF_ALLOC
| ELF::SHF_WRITE
,
126 SectionKind::getData());
128 bool parseSectionDirectiveDataRelRo(StringRef
, SMLoc
) {
129 return parseSectionSwitch(".data.rel.ro", ELF::SHT_PROGBITS
,
132 SectionKind::getReadOnlyWithRel());
134 bool parseSectionDirectiveEhFrame(StringRef
, SMLoc
) {
135 return parseSectionSwitch(".eh_frame", ELF::SHT_PROGBITS
,
136 ELF::SHF_ALLOC
| ELF::SHF_WRITE
,
137 SectionKind::getData());
139 bool parseDirectivePushSection(StringRef
, SMLoc
);
140 bool parseDirectivePopSection(StringRef
, SMLoc
);
141 bool parseDirectiveSection(StringRef
, SMLoc
);
142 bool parseDirectiveSize(StringRef
, SMLoc
);
143 bool parseDirectivePrevious(StringRef
, SMLoc
);
144 bool parseDirectiveType(StringRef
, SMLoc
);
145 bool parseDirectiveIdent(StringRef
, SMLoc
);
146 bool parseDirectiveSymver(StringRef
, SMLoc
);
147 bool parseDirectiveVersion(StringRef
, SMLoc
);
148 bool parseDirectiveWeakref(StringRef
, SMLoc
);
149 bool parseDirectiveSymbolAttribute(StringRef
, SMLoc
);
150 bool parseDirectiveSubsection(StringRef
, SMLoc
);
151 bool parseDirectiveCGProfile(StringRef
, SMLoc
);
154 bool parseSectionName(StringRef
&SectionName
);
155 bool parseSectionArguments(bool IsPush
, SMLoc loc
);
156 unsigned parseSunStyleSectionFlags();
157 bool maybeParseSectionType(StringRef
&TypeName
);
158 bool parseMergeSize(int64_t &Size
);
159 bool parseGroup(StringRef
&GroupName
, bool &IsComdat
);
160 bool parseLinkedToSym(MCSymbolELF
*&LinkedToSym
);
161 bool maybeParseUniqueID(int64_t &UniqueID
);
164 } // end anonymous namespace
166 /// parseDirectiveSymbolAttribute
167 /// ::= { ".local", ".weak", ... } [ identifier ( , identifier )* ]
168 bool ELFAsmParser::parseDirectiveSymbolAttribute(StringRef Directive
, SMLoc
) {
169 MCSymbolAttr Attr
= StringSwitch
<MCSymbolAttr
>(Directive
)
170 .Case(".weak", MCSA_Weak
)
171 .Case(".local", MCSA_Local
)
172 .Case(".hidden", MCSA_Hidden
)
173 .Case(".internal", MCSA_Internal
)
174 .Case(".protected", MCSA_Protected
)
175 .Default(MCSA_Invalid
);
176 assert(Attr
!= MCSA_Invalid
&& "unexpected symbol attribute directive!");
177 if (getLexer().isNot(AsmToken::EndOfStatement
)) {
181 if (getParser().parseIdentifier(Name
))
182 return TokError("expected identifier");
184 if (getParser().discardLTOSymbol(Name
)) {
185 if (getLexer().is(AsmToken::EndOfStatement
))
190 MCSymbol
*Sym
= getContext().getOrCreateSymbol(Name
);
192 getStreamer().emitSymbolAttribute(Sym
, Attr
);
194 if (getLexer().is(AsmToken::EndOfStatement
))
197 if (getLexer().isNot(AsmToken::Comma
))
198 return TokError("expected comma");
207 bool ELFAsmParser::parseSectionSwitch(StringRef Section
, unsigned Type
,
208 unsigned Flags
, SectionKind Kind
) {
209 const MCExpr
*Subsection
= nullptr;
210 if (getLexer().isNot(AsmToken::EndOfStatement
)) {
211 if (getParser().parseExpression(Subsection
))
216 getStreamer().switchSection(getContext().getELFSection(Section
, Type
, Flags
),
222 bool ELFAsmParser::parseDirectiveSize(StringRef
, SMLoc
) {
224 if (getParser().parseIdentifier(Name
))
225 return TokError("expected identifier");
226 MCSymbolELF
*Sym
= cast
<MCSymbolELF
>(getContext().getOrCreateSymbol(Name
));
228 if (getLexer().isNot(AsmToken::Comma
))
229 return TokError("expected comma");
233 if (getParser().parseExpression(Expr
))
236 if (getLexer().isNot(AsmToken::EndOfStatement
))
237 return TokError("unexpected token");
240 getStreamer().emitELFSize(Sym
, Expr
);
244 bool ELFAsmParser::parseSectionName(StringRef
&SectionName
) {
245 // A section name can contain -, so we cannot just use
247 SMLoc FirstLoc
= getLexer().getLoc();
250 if (getLexer().is(AsmToken::String
)) {
251 SectionName
= getTok().getIdentifier();
256 while (!getParser().hasPendingError()) {
257 SMLoc PrevLoc
= getLexer().getLoc();
258 if (getLexer().is(AsmToken::Comma
) ||
259 getLexer().is(AsmToken::EndOfStatement
))
263 if (getLexer().is(AsmToken::String
)) {
264 CurSize
= getTok().getIdentifier().size() + 2;
266 } else if (getLexer().is(AsmToken::Identifier
)) {
267 CurSize
= getTok().getIdentifier().size();
270 CurSize
= getTok().getString().size();
274 SectionName
= StringRef(FirstLoc
.getPointer(), Size
);
276 // Make sure the following token is adjacent.
277 if (PrevLoc
.getPointer() + CurSize
!= getTok().getLoc().getPointer())
286 static unsigned parseSectionFlags(const Triple
&TT
, StringRef flagsStr
,
287 bool *UseLastGroup
) {
290 // If a valid numerical value is set for the section flag, use it verbatim
291 if (!flagsStr
.getAsInteger(0, flags
))
294 for (char i
: flagsStr
) {
297 flags
|= ELF::SHF_ALLOC
;
300 flags
|= ELF::SHF_EXCLUDE
;
303 flags
|= ELF::SHF_EXECINSTR
;
306 flags
|= ELF::SHF_WRITE
;
309 flags
|= ELF::SHF_LINK_ORDER
;
312 flags
|= ELF::SHF_MERGE
;
315 flags
|= ELF::SHF_STRINGS
;
318 flags
|= ELF::SHF_TLS
;
321 if (TT
.getArch() != Triple::xcore
)
323 flags
|= ELF::XCORE_SHF_CP_SECTION
;
326 if (TT
.getArch() != Triple::xcore
)
328 flags
|= ELF::XCORE_SHF_DP_SECTION
;
331 if (!(TT
.isARM() || TT
.isThumb()))
333 flags
|= ELF::SHF_ARM_PURECODE
;
336 if (TT
.getArch() != Triple::hexagon
)
338 flags
|= ELF::SHF_HEX_GPREL
;
341 flags
|= ELF::SHF_GROUP
;
344 if (TT
.getArch() != Triple::x86_64
)
346 flags
|= ELF::SHF_X86_64_LARGE
;
349 if (TT
.isOSSolaris())
350 flags
|= ELF::SHF_SUNW_NODISCARD
;
352 flags
|= ELF::SHF_GNU_RETAIN
;
355 *UseLastGroup
= true;
365 unsigned ELFAsmParser::parseSunStyleSectionFlags() {
367 while (getLexer().is(AsmToken::Hash
)) {
370 if (!getLexer().is(AsmToken::Identifier
))
373 StringRef flagId
= getTok().getIdentifier();
374 if (flagId
== "alloc")
375 flags
|= ELF::SHF_ALLOC
;
376 else if (flagId
== "execinstr")
377 flags
|= ELF::SHF_EXECINSTR
;
378 else if (flagId
== "write")
379 flags
|= ELF::SHF_WRITE
;
380 else if (flagId
== "tls")
381 flags
|= ELF::SHF_TLS
;
385 Lex(); // Eat the flag.
387 if (!getLexer().is(AsmToken::Comma
))
389 Lex(); // Eat the comma.
395 bool ELFAsmParser::parseDirectivePushSection(StringRef s
, SMLoc loc
) {
396 getStreamer().pushSection();
398 if (parseSectionArguments(/*IsPush=*/true, loc
)) {
399 getStreamer().popSection();
406 bool ELFAsmParser::parseDirectivePopSection(StringRef
, SMLoc
) {
407 if (!getStreamer().popSection())
408 return TokError(".popsection without corresponding .pushsection");
412 bool ELFAsmParser::parseDirectiveSection(StringRef
, SMLoc loc
) {
413 return parseSectionArguments(/*IsPush=*/false, loc
);
416 bool ELFAsmParser::maybeParseSectionType(StringRef
&TypeName
) {
417 MCAsmLexer
&L
= getLexer();
418 if (L
.isNot(AsmToken::Comma
))
421 if (L
.isNot(AsmToken::At
) && L
.isNot(AsmToken::Percent
) &&
422 L
.isNot(AsmToken::String
)) {
423 if (L
.getAllowAtInIdentifier())
424 return TokError("expected '@<type>', '%<type>' or \"<type>\"");
426 return TokError("expected '%<type>' or \"<type>\"");
428 if (!L
.is(AsmToken::String
))
430 if (L
.is(AsmToken::Integer
)) {
431 TypeName
= getTok().getString();
433 } else if (getParser().parseIdentifier(TypeName
))
434 return TokError("expected identifier");
438 bool ELFAsmParser::parseMergeSize(int64_t &Size
) {
439 if (getLexer().isNot(AsmToken::Comma
))
440 return TokError("expected the entry size");
442 if (getParser().parseAbsoluteExpression(Size
))
445 return TokError("entry size must be positive");
449 bool ELFAsmParser::parseGroup(StringRef
&GroupName
, bool &IsComdat
) {
450 MCAsmLexer
&L
= getLexer();
451 if (L
.isNot(AsmToken::Comma
))
452 return TokError("expected group name");
454 if (L
.is(AsmToken::Integer
)) {
455 GroupName
= getTok().getString();
457 } else if (getParser().parseIdentifier(GroupName
)) {
458 return TokError("invalid group name");
460 if (L
.is(AsmToken::Comma
)) {
463 if (getParser().parseIdentifier(Linkage
))
464 return TokError("invalid linkage");
465 if (Linkage
!= "comdat")
466 return TokError("Linkage must be 'comdat'");
474 bool ELFAsmParser::parseLinkedToSym(MCSymbolELF
*&LinkedToSym
) {
475 MCAsmLexer
&L
= getLexer();
476 if (L
.isNot(AsmToken::Comma
))
477 return TokError("expected linked-to symbol");
480 SMLoc StartLoc
= L
.getLoc();
481 if (getParser().parseIdentifier(Name
)) {
482 if (getParser().getTok().getString() == "0") {
484 LinkedToSym
= nullptr;
487 return TokError("invalid linked-to symbol");
489 LinkedToSym
= dyn_cast_or_null
<MCSymbolELF
>(getContext().lookupSymbol(Name
));
490 if (!LinkedToSym
|| !LinkedToSym
->isInSection())
491 return Error(StartLoc
, "linked-to symbol is not in a section: " + Name
);
495 bool ELFAsmParser::maybeParseUniqueID(int64_t &UniqueID
) {
496 MCAsmLexer
&L
= getLexer();
497 if (L
.isNot(AsmToken::Comma
))
501 if (getParser().parseIdentifier(UniqueStr
))
502 return TokError("expected identifier");
503 if (UniqueStr
!= "unique")
504 return TokError("expected 'unique'");
505 if (L
.isNot(AsmToken::Comma
))
506 return TokError("expected commma");
508 if (getParser().parseAbsoluteExpression(UniqueID
))
511 return TokError("unique id must be positive");
512 if (!isUInt
<32>(UniqueID
) || UniqueID
== ~0U)
513 return TokError("unique id is too large");
517 static bool hasPrefix(StringRef SectionName
, StringRef Prefix
) {
518 return SectionName
.consume_front(Prefix
) &&
519 (SectionName
.empty() || SectionName
[0] == '.');
522 static bool allowSectionTypeMismatch(const Triple
&TT
, StringRef SectionName
,
524 if (TT
.getArch() == Triple::x86_64
) {
525 // x86-64 psABI names SHT_X86_64_UNWIND as the canonical type for .eh_frame,
526 // but GNU as emits SHT_PROGBITS .eh_frame for .cfi_* directives. Don't
527 // error for SHT_PROGBITS .eh_frame
528 return SectionName
== ".eh_frame" && Type
== ELF::SHT_PROGBITS
;
531 // MIPS .debug_* sections should have SHT_MIPS_DWARF section type to
532 // distinguish among sections contain DWARF and ECOFF debug formats,
533 // but in assembly files these sections have SHT_PROGBITS type.
534 return SectionName
.starts_with(".debug_") && Type
== ELF::SHT_PROGBITS
;
539 bool ELFAsmParser::parseSectionArguments(bool IsPush
, SMLoc loc
) {
540 StringRef SectionName
;
542 if (parseSectionName(SectionName
))
543 return TokError("expected identifier");
548 bool IsComdat
= false;
550 unsigned extraFlags
= 0;
551 const MCExpr
*Subsection
= nullptr;
552 bool UseLastGroup
= false;
553 MCSymbolELF
*LinkedToSym
= nullptr;
554 int64_t UniqueID
= ~0;
556 // Set the defaults first.
557 if (hasPrefix(SectionName
, ".rodata") || SectionName
== ".rodata1")
558 Flags
|= ELF::SHF_ALLOC
;
559 else if (SectionName
== ".fini" || SectionName
== ".init" ||
560 hasPrefix(SectionName
, ".text"))
561 Flags
|= ELF::SHF_ALLOC
| ELF::SHF_EXECINSTR
;
562 else if (hasPrefix(SectionName
, ".data") || SectionName
== ".data1" ||
563 hasPrefix(SectionName
, ".bss") ||
564 hasPrefix(SectionName
, ".init_array") ||
565 hasPrefix(SectionName
, ".fini_array") ||
566 hasPrefix(SectionName
, ".preinit_array"))
567 Flags
|= ELF::SHF_ALLOC
| ELF::SHF_WRITE
;
568 else if (hasPrefix(SectionName
, ".tdata") || hasPrefix(SectionName
, ".tbss"))
569 Flags
|= ELF::SHF_ALLOC
| ELF::SHF_WRITE
| ELF::SHF_TLS
;
571 if (getLexer().is(AsmToken::Comma
)) {
574 if (IsPush
&& getLexer().isNot(AsmToken::String
)) {
575 if (getParser().parseExpression(Subsection
))
577 if (getLexer().isNot(AsmToken::Comma
))
582 if (getLexer().isNot(AsmToken::String
)) {
583 if (getLexer().isNot(AsmToken::Hash
))
584 return TokError("expected string");
585 extraFlags
= parseSunStyleSectionFlags();
587 StringRef FlagsStr
= getTok().getStringContents();
589 extraFlags
= parseSectionFlags(getContext().getTargetTriple(), FlagsStr
,
593 if (extraFlags
== -1U)
594 return TokError("unknown flag");
597 bool Mergeable
= Flags
& ELF::SHF_MERGE
;
598 bool Group
= Flags
& ELF::SHF_GROUP
;
599 if (Group
&& UseLastGroup
)
600 return TokError("Section cannot specifiy a group name while also acting "
601 "as a member of the last group");
603 if (maybeParseSectionType(TypeName
))
606 MCAsmLexer
&L
= getLexer();
607 if (TypeName
.empty()) {
609 return TokError("Mergeable section must specify the type");
611 return TokError("Group section must specify the type");
612 if (L
.isNot(AsmToken::EndOfStatement
))
613 return TokError("expected end of directive");
617 if (parseMergeSize(Size
))
619 if (Flags
& ELF::SHF_LINK_ORDER
)
620 if (parseLinkedToSym(LinkedToSym
))
623 if (parseGroup(GroupName
, IsComdat
))
625 if (maybeParseUniqueID(UniqueID
))
630 if (getLexer().isNot(AsmToken::EndOfStatement
))
631 return TokError("expected end of directive");
634 unsigned Type
= ELF::SHT_PROGBITS
;
636 if (TypeName
.empty()) {
637 if (SectionName
.starts_with(".note"))
638 Type
= ELF::SHT_NOTE
;
639 else if (hasPrefix(SectionName
, ".init_array"))
640 Type
= ELF::SHT_INIT_ARRAY
;
641 else if (hasPrefix(SectionName
, ".bss"))
642 Type
= ELF::SHT_NOBITS
;
643 else if (hasPrefix(SectionName
, ".tbss"))
644 Type
= ELF::SHT_NOBITS
;
645 else if (hasPrefix(SectionName
, ".fini_array"))
646 Type
= ELF::SHT_FINI_ARRAY
;
647 else if (hasPrefix(SectionName
, ".preinit_array"))
648 Type
= ELF::SHT_PREINIT_ARRAY
;
650 if (TypeName
== "init_array")
651 Type
= ELF::SHT_INIT_ARRAY
;
652 else if (TypeName
== "fini_array")
653 Type
= ELF::SHT_FINI_ARRAY
;
654 else if (TypeName
== "preinit_array")
655 Type
= ELF::SHT_PREINIT_ARRAY
;
656 else if (TypeName
== "nobits")
657 Type
= ELF::SHT_NOBITS
;
658 else if (TypeName
== "progbits")
659 Type
= ELF::SHT_PROGBITS
;
660 else if (TypeName
== "note")
661 Type
= ELF::SHT_NOTE
;
662 else if (TypeName
== "unwind")
663 Type
= ELF::SHT_X86_64_UNWIND
;
664 else if (TypeName
== "llvm_odrtab")
665 Type
= ELF::SHT_LLVM_ODRTAB
;
666 else if (TypeName
== "llvm_linker_options")
667 Type
= ELF::SHT_LLVM_LINKER_OPTIONS
;
668 else if (TypeName
== "llvm_call_graph_profile")
669 Type
= ELF::SHT_LLVM_CALL_GRAPH_PROFILE
;
670 else if (TypeName
== "llvm_dependent_libraries")
671 Type
= ELF::SHT_LLVM_DEPENDENT_LIBRARIES
;
672 else if (TypeName
== "llvm_sympart")
673 Type
= ELF::SHT_LLVM_SYMPART
;
674 else if (TypeName
== "llvm_bb_addr_map")
675 Type
= ELF::SHT_LLVM_BB_ADDR_MAP
;
676 else if (TypeName
== "llvm_offloading")
677 Type
= ELF::SHT_LLVM_OFFLOADING
;
678 else if (TypeName
== "llvm_lto")
679 Type
= ELF::SHT_LLVM_LTO
;
680 else if (TypeName
== "llvm_jt_sizes")
681 Type
= ELF::SHT_LLVM_JT_SIZES
;
682 else if (TypeName
.getAsInteger(0, Type
))
683 return TokError("unknown section type");
687 if (const MCSectionELF
*Section
=
688 cast_or_null
<MCSectionELF
>(getStreamer().getCurrentSectionOnly()))
689 if (const MCSymbol
*Group
= Section
->getGroup()) {
690 GroupName
= Group
->getName();
691 IsComdat
= Section
->isComdat();
692 Flags
|= ELF::SHF_GROUP
;
696 MCSectionELF
*Section
=
697 getContext().getELFSection(SectionName
, Type
, Flags
, Size
, GroupName
,
698 IsComdat
, UniqueID
, LinkedToSym
);
699 getStreamer().switchSection(Section
, Subsection
);
700 // Check that flags are used consistently. However, the GNU assembler permits
701 // to leave out in subsequent uses of the same sections; for compatibility,
703 if (!TypeName
.empty() && Section
->getType() != Type
&&
704 !allowSectionTypeMismatch(getContext().getTargetTriple(), SectionName
,
706 Error(loc
, "changed section type for " + SectionName
+ ", expected: 0x" +
707 utohexstr(Section
->getType()));
708 if ((extraFlags
|| Size
|| !TypeName
.empty()) && Section
->getFlags() != Flags
)
709 Error(loc
, "changed section flags for " + SectionName
+ ", expected: 0x" +
710 utohexstr(Section
->getFlags()));
711 if ((extraFlags
|| Size
|| !TypeName
.empty()) &&
712 Section
->getEntrySize() != Size
)
713 Error(loc
, "changed section entsize for " + SectionName
+
714 ", expected: " + Twine(Section
->getEntrySize()));
716 if (getContext().getGenDwarfForAssembly() &&
717 (Section
->getFlags() & ELF::SHF_ALLOC
) &&
718 (Section
->getFlags() & ELF::SHF_EXECINSTR
)) {
719 bool InsertResult
= getContext().addGenDwarfSection(Section
);
720 if (InsertResult
&& getContext().getDwarfVersion() <= 2)
721 Warning(loc
, "DWARF2 only supports one section per compilation unit");
727 bool ELFAsmParser::parseDirectivePrevious(StringRef DirName
, SMLoc
) {
728 MCSectionSubPair PreviousSection
= getStreamer().getPreviousSection();
729 if (PreviousSection
.first
== nullptr)
730 return TokError(".previous without corresponding .section");
731 getStreamer().switchSection(PreviousSection
.first
, PreviousSection
.second
);
736 static MCSymbolAttr
MCAttrForString(StringRef Type
) {
737 return StringSwitch
<MCSymbolAttr
>(Type
)
738 .Cases("STT_FUNC", "function", MCSA_ELF_TypeFunction
)
739 .Cases("STT_OBJECT", "object", MCSA_ELF_TypeObject
)
740 .Cases("STT_TLS", "tls_object", MCSA_ELF_TypeTLS
)
741 .Cases("STT_COMMON", "common", MCSA_ELF_TypeCommon
)
742 .Cases("STT_NOTYPE", "notype", MCSA_ELF_TypeNoType
)
743 .Cases("STT_GNU_IFUNC", "gnu_indirect_function",
744 MCSA_ELF_TypeIndFunction
)
745 .Case("gnu_unique_object", MCSA_ELF_TypeGnuUniqueObject
)
746 .Default(MCSA_Invalid
);
749 /// parseDirectiveELFType
750 /// ::= .type identifier , STT_<TYPE_IN_UPPER_CASE>
751 /// ::= .type identifier , #attribute
752 /// ::= .type identifier , @attribute
753 /// ::= .type identifier , %attribute
754 /// ::= .type identifier , "attribute"
755 bool ELFAsmParser::parseDirectiveType(StringRef
, SMLoc
) {
757 if (getParser().parseIdentifier(Name
))
758 return TokError("expected identifier");
760 // Handle the identifier as the key symbol.
761 MCSymbol
*Sym
= getContext().getOrCreateSymbol(Name
);
763 // NOTE the comma is optional in all cases. It is only documented as being
764 // optional in the first case, however, GAS will silently treat the comma as
765 // optional in all cases. Furthermore, although the documentation states that
766 // the first form only accepts STT_<TYPE_IN_UPPER_CASE>, in reality, GAS
767 // accepts both the upper case name as well as the lower case aliases.
768 if (getLexer().is(AsmToken::Comma
))
771 if (getLexer().isNot(AsmToken::Identifier
) &&
772 getLexer().isNot(AsmToken::Hash
) &&
773 getLexer().isNot(AsmToken::Percent
) &&
774 getLexer().isNot(AsmToken::String
)) {
775 if (!getLexer().getAllowAtInIdentifier())
776 return TokError("expected STT_<TYPE_IN_UPPER_CASE>, '#<type>', "
777 "'%<type>' or \"<type>\"");
778 else if (getLexer().isNot(AsmToken::At
))
779 return TokError("expected STT_<TYPE_IN_UPPER_CASE>, '#<type>', '@<type>', "
780 "'%<type>' or \"<type>\"");
783 if (getLexer().isNot(AsmToken::String
) &&
784 getLexer().isNot(AsmToken::Identifier
))
787 SMLoc TypeLoc
= getLexer().getLoc();
790 if (getParser().parseIdentifier(Type
))
791 return TokError("expected symbol type");
793 MCSymbolAttr Attr
= MCAttrForString(Type
);
794 if (Attr
== MCSA_Invalid
)
795 return Error(TypeLoc
, "unsupported attribute");
797 if (getLexer().isNot(AsmToken::EndOfStatement
))
798 return TokError("expected end of directive");
801 getStreamer().emitSymbolAttribute(Sym
, Attr
);
806 /// parseDirectiveIdent
807 /// ::= .ident string
808 bool ELFAsmParser::parseDirectiveIdent(StringRef
, SMLoc
) {
809 if (getLexer().isNot(AsmToken::String
))
810 return TokError("expected string");
812 StringRef Data
= getTok().getIdentifier();
816 if (getLexer().isNot(AsmToken::EndOfStatement
))
817 return TokError("expected end of directive");
820 getStreamer().emitIdent(Data
);
824 /// parseDirectiveSymver
825 /// ::= .symver foo, bar2@zed
826 bool ELFAsmParser::parseDirectiveSymver(StringRef
, SMLoc
) {
827 StringRef OriginalName
, Name
, Action
;
828 if (getParser().parseIdentifier(OriginalName
))
829 return TokError("expected identifier");
831 if (getLexer().isNot(AsmToken::Comma
))
832 return TokError("expected a comma");
834 // ARM assembly uses @ for a comment...
835 // except when parsing the second parameter of the .symver directive.
836 // Force the next symbol to allow @ in the identifier, which is
837 // required for this directive and then reset it to its initial state.
838 const bool AllowAtInIdentifier
= getLexer().getAllowAtInIdentifier();
839 getLexer().setAllowAtInIdentifier(true);
841 getLexer().setAllowAtInIdentifier(AllowAtInIdentifier
);
843 if (getParser().parseIdentifier(Name
))
844 return TokError("expected identifier");
846 if (!Name
.contains('@'))
847 return TokError("expected a '@' in the name");
848 bool KeepOriginalSym
= !Name
.contains("@@@");
849 if (parseOptionalToken(AsmToken::Comma
)) {
850 if (getParser().parseIdentifier(Action
) || Action
!= "remove")
851 return TokError("expected 'remove'");
852 KeepOriginalSym
= false;
854 (void)parseOptionalToken(AsmToken::EndOfStatement
);
856 getStreamer().emitELFSymverDirective(
857 getContext().getOrCreateSymbol(OriginalName
), Name
, KeepOriginalSym
);
861 /// parseDirectiveVersion
862 /// ::= .version string
863 bool ELFAsmParser::parseDirectiveVersion(StringRef
, SMLoc
) {
864 if (getLexer().isNot(AsmToken::String
))
865 return TokError("expected string");
867 StringRef Data
= getTok().getIdentifier();
871 MCSection
*Note
= getContext().getELFSection(".note", ELF::SHT_NOTE
, 0);
873 getStreamer().pushSection();
874 getStreamer().switchSection(Note
);
875 getStreamer().emitInt32(Data
.size() + 1); // namesz
876 getStreamer().emitInt32(0); // descsz = 0 (no description).
877 getStreamer().emitInt32(1); // type = NT_VERSION
878 getStreamer().emitBytes(Data
); // name
879 getStreamer().emitInt8(0); // NUL
880 getStreamer().emitValueToAlignment(Align(4));
881 getStreamer().popSection();
885 /// parseDirectiveWeakref
886 /// ::= .weakref foo, bar
887 bool ELFAsmParser::parseDirectiveWeakref(StringRef
, SMLoc
) {
888 // FIXME: Share code with the other alias building directives.
891 if (getParser().parseIdentifier(AliasName
))
892 return TokError("expected identifier");
894 if (getLexer().isNot(AsmToken::Comma
))
895 return TokError("expected a comma");
900 if (getParser().parseIdentifier(Name
))
901 return TokError("expected identifier");
903 MCSymbol
*Alias
= getContext().getOrCreateSymbol(AliasName
);
905 MCSymbol
*Sym
= getContext().getOrCreateSymbol(Name
);
907 getStreamer().emitWeakReference(Alias
, Sym
);
911 bool ELFAsmParser::parseDirectiveSubsection(StringRef
, SMLoc
) {
912 const MCExpr
*Subsection
= MCConstantExpr::create(0, getContext());
913 if (getLexer().isNot(AsmToken::EndOfStatement
)) {
914 if (getParser().parseExpression(Subsection
))
918 if (getLexer().isNot(AsmToken::EndOfStatement
))
919 return TokError("expected end of directive");
923 return getStreamer().switchSection(getStreamer().getCurrentSectionOnly(),
927 bool ELFAsmParser::parseDirectiveCGProfile(StringRef S
, SMLoc Loc
) {
928 return MCAsmParserExtension::parseDirectiveCGProfile(S
, Loc
);
933 MCAsmParserExtension
*createELFAsmParser() {
934 return new ELFAsmParser
;
937 } // end namespace llvm