~pali/+junk/llvm-toolchain-3.7

« back to all changes in this revision

Viewing changes to lib/MC/MCParser/ELFAsmParser.cpp

  • Committer: Package Import Robot
  • Author(s): Sylvestre Ledru
  • Date: 2015-07-15 17:51:08 UTC
  • Revision ID: package-import@ubuntu.com-20150715175108-l8mynwovkx4zx697
Tags: upstream-3.7~+rc2
ImportĀ upstreamĀ versionĀ 3.7~+rc2

Show diffs side-by-side

added added

removed removed

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