Coverage Report

Created: 2017-10-03 07:32

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