]> CyberLeo.Net >> Repos - FreeBSD/releng/9.2.git/blob - contrib/llvm/lib/MC/MCParser/ELFAsmParser.cpp
- Copy stable/9 to releng/9.2 as part of the 9.2-RELEASE cycle.
[FreeBSD/releng/9.2.git] / contrib / llvm / lib / MC / MCParser / ELFAsmParser.cpp
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/Support/ELF.h"
20 using namespace llvm;
21
22 namespace {
23
24 class ELFAsmParser : public MCAsmParserExtension {
25   template<bool (ELFAsmParser::*HandlerMethod)(StringRef, SMLoc)>
26   void addDirectiveHandler(StringRef Directive) {
27     MCAsmParser::ExtensionDirectiveHandler Handler = std::make_pair(
28         this, HandleDirective<ELFAsmParser, HandlerMethod>);
29
30     getParser().addDirectiveHandler(Directive, Handler);
31   }
32
33   bool ParseSectionSwitch(StringRef Section, unsigned Type,
34                           unsigned Flags, SectionKind Kind);
35   bool SeenIdent;
36
37 public:
38   ELFAsmParser() : SeenIdent(false) {
39     BracketExpressionsSupported = true;
40   }
41
42   virtual void Initialize(MCAsmParser &Parser) {
43     // Call the base implementation.
44     this->MCAsmParserExtension::Initialize(Parser);
45
46     addDirectiveHandler<&ELFAsmParser::ParseSectionDirectiveData>(".data");
47     addDirectiveHandler<&ELFAsmParser::ParseSectionDirectiveText>(".text");
48     addDirectiveHandler<&ELFAsmParser::ParseSectionDirectiveBSS>(".bss");
49     addDirectiveHandler<&ELFAsmParser::ParseSectionDirectiveRoData>(".rodata");
50     addDirectiveHandler<&ELFAsmParser::ParseSectionDirectiveTData>(".tdata");
51     addDirectiveHandler<&ELFAsmParser::ParseSectionDirectiveTBSS>(".tbss");
52     addDirectiveHandler<
53       &ELFAsmParser::ParseSectionDirectiveDataRel>(".data.rel");
54     addDirectiveHandler<
55       &ELFAsmParser::ParseSectionDirectiveDataRelRo>(".data.rel.ro");
56     addDirectiveHandler<
57       &ELFAsmParser::ParseSectionDirectiveDataRelRoLocal>(".data.rel.ro.local");
58     addDirectiveHandler<
59       &ELFAsmParser::ParseSectionDirectiveEhFrame>(".eh_frame");
60     addDirectiveHandler<&ELFAsmParser::ParseDirectiveSection>(".section");
61     addDirectiveHandler<
62       &ELFAsmParser::ParseDirectivePushSection>(".pushsection");
63     addDirectiveHandler<&ELFAsmParser::ParseDirectivePopSection>(".popsection");
64     addDirectiveHandler<&ELFAsmParser::ParseDirectiveSize>(".size");
65     addDirectiveHandler<&ELFAsmParser::ParseDirectivePrevious>(".previous");
66     addDirectiveHandler<&ELFAsmParser::ParseDirectiveType>(".type");
67     addDirectiveHandler<&ELFAsmParser::ParseDirectiveIdent>(".ident");
68     addDirectiveHandler<&ELFAsmParser::ParseDirectiveSymver>(".symver");
69     addDirectiveHandler<&ELFAsmParser::ParseDirectiveVersion>(".version");
70     addDirectiveHandler<&ELFAsmParser::ParseDirectiveWeakref>(".weakref");
71     addDirectiveHandler<&ELFAsmParser::ParseDirectiveSymbolAttribute>(".weak");
72     addDirectiveHandler<&ELFAsmParser::ParseDirectiveSymbolAttribute>(".local");
73     addDirectiveHandler<
74       &ELFAsmParser::ParseDirectiveSymbolAttribute>(".protected");
75     addDirectiveHandler<
76       &ELFAsmParser::ParseDirectiveSymbolAttribute>(".internal");
77     addDirectiveHandler<
78       &ELFAsmParser::ParseDirectiveSymbolAttribute>(".hidden");
79     addDirectiveHandler<&ELFAsmParser::ParseDirectiveSubsection>(".subsection");
80   }
81
82   // FIXME: Part of this logic is duplicated in the MCELFStreamer. What is
83   // the best way for us to get access to it?
84   bool ParseSectionDirectiveData(StringRef, SMLoc) {
85     return ParseSectionSwitch(".data", ELF::SHT_PROGBITS,
86                               ELF::SHF_WRITE |ELF::SHF_ALLOC,
87                               SectionKind::getDataRel());
88   }
89   bool ParseSectionDirectiveText(StringRef, SMLoc) {
90     return ParseSectionSwitch(".text", ELF::SHT_PROGBITS,
91                               ELF::SHF_EXECINSTR |
92                               ELF::SHF_ALLOC, SectionKind::getText());
93   }
94   bool ParseSectionDirectiveBSS(StringRef, SMLoc) {
95     return ParseSectionSwitch(".bss", ELF::SHT_NOBITS,
96                               ELF::SHF_WRITE |
97                               ELF::SHF_ALLOC, SectionKind::getBSS());
98   }
99   bool ParseSectionDirectiveRoData(StringRef, SMLoc) {
100     return ParseSectionSwitch(".rodata", ELF::SHT_PROGBITS,
101                               ELF::SHF_ALLOC,
102                               SectionKind::getReadOnly());
103   }
104   bool ParseSectionDirectiveTData(StringRef, SMLoc) {
105     return ParseSectionSwitch(".tdata", ELF::SHT_PROGBITS,
106                               ELF::SHF_ALLOC |
107                               ELF::SHF_TLS | ELF::SHF_WRITE,
108                               SectionKind::getThreadData());
109   }
110   bool ParseSectionDirectiveTBSS(StringRef, SMLoc) {
111     return ParseSectionSwitch(".tbss", ELF::SHT_NOBITS,
112                               ELF::SHF_ALLOC |
113                               ELF::SHF_TLS | ELF::SHF_WRITE,
114                               SectionKind::getThreadBSS());
115   }
116   bool ParseSectionDirectiveDataRel(StringRef, SMLoc) {
117     return ParseSectionSwitch(".data.rel", ELF::SHT_PROGBITS,
118                               ELF::SHF_ALLOC |
119                               ELF::SHF_WRITE,
120                               SectionKind::getDataRel());
121   }
122   bool ParseSectionDirectiveDataRelRo(StringRef, SMLoc) {
123     return ParseSectionSwitch(".data.rel.ro", ELF::SHT_PROGBITS,
124                               ELF::SHF_ALLOC |
125                               ELF::SHF_WRITE,
126                               SectionKind::getReadOnlyWithRel());
127   }
128   bool ParseSectionDirectiveDataRelRoLocal(StringRef, SMLoc) {
129     return ParseSectionSwitch(".data.rel.ro.local", ELF::SHT_PROGBITS,
130                               ELF::SHF_ALLOC |
131                               ELF::SHF_WRITE,
132                               SectionKind::getReadOnlyWithRelLocal());
133   }
134   bool ParseSectionDirectiveEhFrame(StringRef, SMLoc) {
135     return ParseSectionSwitch(".eh_frame", ELF::SHT_PROGBITS,
136                               ELF::SHF_ALLOC |
137                               ELF::SHF_WRITE,
138                               SectionKind::getDataRel());
139   }
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);
156 };
157
158 }
159
160 /// ParseDirectiveSymbolAttribute
161 ///  ::= { ".local", ".weak", ... } [ identifier ( , identifier )* ]
162 bool ELFAsmParser::ParseDirectiveSymbolAttribute(StringRef Directive, SMLoc) {
163   MCSymbolAttr Attr = StringSwitch<MCSymbolAttr>(Directive)
164     .Case(".weak", MCSA_Weak)
165     .Case(".local", MCSA_Local)
166     .Case(".hidden", MCSA_Hidden)
167     .Case(".internal", MCSA_Internal)
168     .Case(".protected", MCSA_Protected)
169     .Default(MCSA_Invalid);
170   assert(Attr != MCSA_Invalid && "unexpected symbol attribute directive!");
171   if (getLexer().isNot(AsmToken::EndOfStatement)) {
172     for (;;) {
173       StringRef Name;
174
175       if (getParser().parseIdentifier(Name))
176         return TokError("expected identifier in directive");
177
178       MCSymbol *Sym = getContext().GetOrCreateSymbol(Name);
179
180       getStreamer().EmitSymbolAttribute(Sym, Attr);
181
182       if (getLexer().is(AsmToken::EndOfStatement))
183         break;
184
185       if (getLexer().isNot(AsmToken::Comma))
186         return TokError("unexpected token in directive");
187       Lex();
188     }
189   }
190
191   Lex();
192   return false;
193 }
194
195 bool ELFAsmParser::ParseSectionSwitch(StringRef Section, unsigned Type,
196                                       unsigned Flags, SectionKind Kind) {
197   const MCExpr *Subsection = 0;
198   if (getLexer().isNot(AsmToken::EndOfStatement)) {
199     if (getParser().parseExpression(Subsection))
200       return true;
201   }
202
203   getStreamer().SwitchSection(getContext().getELFSection(
204                                 Section, Type, Flags, Kind),
205                               Subsection);
206
207   return false;
208 }
209
210 bool ELFAsmParser::ParseDirectiveSize(StringRef, SMLoc) {
211   StringRef Name;
212   if (getParser().parseIdentifier(Name))
213     return TokError("expected identifier in directive");
214   MCSymbol *Sym = getContext().GetOrCreateSymbol(Name);
215
216   if (getLexer().isNot(AsmToken::Comma))
217     return TokError("unexpected token in directive");
218   Lex();
219
220   const MCExpr *Expr;
221   if (getParser().parseExpression(Expr))
222     return true;
223
224   if (getLexer().isNot(AsmToken::EndOfStatement))
225     return TokError("unexpected token in directive");
226
227   getStreamer().EmitELFSize(Sym, Expr);
228   return false;
229 }
230
231 bool ELFAsmParser::ParseSectionName(StringRef &SectionName) {
232   // A section name can contain -, so we cannot just use
233   // parseIdentifier.
234   SMLoc FirstLoc = getLexer().getLoc();
235   unsigned Size = 0;
236
237   if (getLexer().is(AsmToken::String)) {
238     SectionName = getTok().getIdentifier();
239     Lex();
240     return false;
241   }
242
243   for (;;) {
244     StringRef Tmp;
245     unsigned CurSize;
246
247     SMLoc PrevLoc = getLexer().getLoc();
248     if (getLexer().is(AsmToken::Minus)) {
249       CurSize = 1;
250       Lex(); // Consume the "-".
251     } else if (getLexer().is(AsmToken::String)) {
252       CurSize = getTok().getIdentifier().size() + 2;
253       Lex();
254     } else if (getLexer().is(AsmToken::Identifier)) {
255       CurSize = getTok().getIdentifier().size();
256       Lex();
257     } else {
258       break;
259     }
260
261     Size += CurSize;
262     SectionName = StringRef(FirstLoc.getPointer(), Size);
263
264     // Make sure the following token is adjacent.
265     if (PrevLoc.getPointer() + CurSize != getTok().getLoc().getPointer())
266       break;
267   }
268   if (Size == 0)
269     return true;
270
271   return false;
272 }
273
274 static SectionKind computeSectionKind(unsigned Flags) {
275   if (Flags & ELF::SHF_EXECINSTR)
276     return SectionKind::getText();
277   if (Flags & ELF::SHF_TLS)
278     return SectionKind::getThreadData();
279   return SectionKind::getDataRel();
280 }
281
282 static int parseSectionFlags(StringRef flagsStr) {
283   int flags = 0;
284
285   for (unsigned i = 0; i < flagsStr.size(); i++) {
286     switch (flagsStr[i]) {
287     case 'a':
288       flags |= ELF::SHF_ALLOC;
289       break;
290     case 'x':
291       flags |= ELF::SHF_EXECINSTR;
292       break;
293     case 'w':
294       flags |= ELF::SHF_WRITE;
295       break;
296     case 'M':
297       flags |= ELF::SHF_MERGE;
298       break;
299     case 'S':
300       flags |= ELF::SHF_STRINGS;
301       break;
302     case 'T':
303       flags |= ELF::SHF_TLS;
304       break;
305     case 'c':
306       flags |= ELF::XCORE_SHF_CP_SECTION;
307       break;
308     case 'd':
309       flags |= ELF::XCORE_SHF_DP_SECTION;
310       break;
311     case 'G':
312       flags |= ELF::SHF_GROUP;
313       break;
314     default:
315       return -1;
316     }
317   }
318
319   return flags;
320 }
321
322 bool ELFAsmParser::ParseDirectivePushSection(StringRef s, SMLoc loc) {
323   getStreamer().PushSection();
324
325   if (ParseSectionArguments(/*IsPush=*/true)) {
326     getStreamer().PopSection();
327     return true;
328   }
329
330   return false;
331 }
332
333 bool ELFAsmParser::ParseDirectivePopSection(StringRef, SMLoc) {
334   if (!getStreamer().PopSection())
335     return TokError(".popsection without corresponding .pushsection");
336   return false;
337 }
338
339 // FIXME: This is a work in progress.
340 bool ELFAsmParser::ParseDirectiveSection(StringRef, SMLoc) {
341   return ParseSectionArguments(/*IsPush=*/false);
342 }
343
344 bool ELFAsmParser::ParseSectionArguments(bool IsPush) {
345   StringRef SectionName;
346
347   if (ParseSectionName(SectionName))
348     return TokError("expected identifier in directive");
349
350   StringRef TypeName;
351   int64_t Size = 0;
352   StringRef GroupName;
353   unsigned Flags = 0;
354   const MCExpr *Subsection = 0;
355
356   // Set the defaults first.
357   if (SectionName == ".fini" || SectionName == ".init" ||
358       SectionName == ".rodata")
359     Flags |= ELF::SHF_ALLOC;
360   if (SectionName == ".fini" || SectionName == ".init")
361     Flags |= ELF::SHF_EXECINSTR;
362
363   if (getLexer().is(AsmToken::Comma)) {
364     Lex();
365
366     if (IsPush && getLexer().isNot(AsmToken::String)) {
367       if (getParser().parseExpression(Subsection))
368         return true;
369       if (getLexer().isNot(AsmToken::Comma))
370         goto EndStmt;
371       Lex();
372     }
373    
374     if (getLexer().isNot(AsmToken::String))
375       return TokError("expected string in directive");
376
377     StringRef FlagsStr = getTok().getStringContents();
378     Lex();
379
380     int extraFlags = parseSectionFlags(FlagsStr);
381     if (extraFlags < 0)
382       return TokError("unknown flag");
383     Flags |= extraFlags;
384
385     bool Mergeable = Flags & ELF::SHF_MERGE;
386     bool Group = Flags & ELF::SHF_GROUP;
387
388     if (getLexer().isNot(AsmToken::Comma)) {
389       if (Mergeable)
390         return TokError("Mergeable section must specify the type");
391       if (Group)
392         return TokError("Group section must specify the type");
393     } else {
394       Lex();
395       if (getLexer().isNot(AsmToken::Percent) && getLexer().isNot(AsmToken::At))
396         return TokError("expected '@' or '%' before type");
397
398       Lex();
399       if (getParser().parseIdentifier(TypeName))
400         return TokError("expected identifier in directive");
401
402       if (Mergeable) {
403         if (getLexer().isNot(AsmToken::Comma))
404           return TokError("expected the entry size");
405         Lex();
406         if (getParser().parseAbsoluteExpression(Size))
407           return true;
408         if (Size <= 0)
409           return TokError("entry size must be positive");
410       }
411
412       if (Group) {
413         if (getLexer().isNot(AsmToken::Comma))
414           return TokError("expected group name");
415         Lex();
416         if (getParser().parseIdentifier(GroupName))
417           return true;
418         if (getLexer().is(AsmToken::Comma)) {
419           Lex();
420           StringRef Linkage;
421           if (getParser().parseIdentifier(Linkage))
422             return true;
423           if (Linkage != "comdat")
424             return TokError("Linkage must be 'comdat'");
425         }
426       }
427     }
428   }
429
430 EndStmt:
431   if (getLexer().isNot(AsmToken::EndOfStatement))
432     return TokError("unexpected token in directive");
433
434   unsigned Type = ELF::SHT_PROGBITS;
435
436   if (TypeName.empty()) {
437     if (SectionName.startswith(".note"))
438       Type = ELF::SHT_NOTE;
439     else if (SectionName == ".init_array")
440       Type = ELF::SHT_INIT_ARRAY;
441     else if (SectionName == ".fini_array")
442       Type = ELF::SHT_FINI_ARRAY;
443     else if (SectionName == ".preinit_array")
444       Type = ELF::SHT_PREINIT_ARRAY;
445   } else {
446     if (TypeName == "init_array")
447       Type = ELF::SHT_INIT_ARRAY;
448     else if (TypeName == "fini_array")
449       Type = ELF::SHT_FINI_ARRAY;
450     else if (TypeName == "preinit_array")
451       Type = ELF::SHT_PREINIT_ARRAY;
452     else if (TypeName == "nobits")
453       Type = ELF::SHT_NOBITS;
454     else if (TypeName == "progbits")
455       Type = ELF::SHT_PROGBITS;
456     else if (TypeName == "note")
457       Type = ELF::SHT_NOTE;
458     else if (TypeName == "unwind")
459       Type = ELF::SHT_X86_64_UNWIND;
460     else
461       return TokError("unknown section type");
462   }
463
464   SectionKind Kind = computeSectionKind(Flags);
465   getStreamer().SwitchSection(getContext().getELFSection(SectionName, Type,
466                                                          Flags, Kind, Size,
467                                                          GroupName),
468                               Subsection);
469   return false;
470 }
471
472 bool ELFAsmParser::ParseDirectivePrevious(StringRef DirName, SMLoc) {
473   MCSectionSubPair PreviousSection = getStreamer().getPreviousSection();
474   if (PreviousSection.first == NULL)
475       return TokError(".previous without corresponding .section");
476   getStreamer().SwitchSection(PreviousSection.first, PreviousSection.second);
477
478   return false;
479 }
480
481 /// ParseDirectiveELFType
482 ///  ::= .type identifier , @attribute
483 bool ELFAsmParser::ParseDirectiveType(StringRef, SMLoc) {
484   StringRef Name;
485   if (getParser().parseIdentifier(Name))
486     return TokError("expected identifier in directive");
487
488   // Handle the identifier as the key symbol.
489   MCSymbol *Sym = getContext().GetOrCreateSymbol(Name);
490
491   if (getLexer().isNot(AsmToken::Comma))
492     return TokError("unexpected token in '.type' directive");
493   Lex();
494
495   if (getLexer().isNot(AsmToken::Percent) && getLexer().isNot(AsmToken::At))
496     return TokError("expected '@' or '%' before type");
497   Lex();
498
499   StringRef Type;
500   SMLoc TypeLoc;
501
502   TypeLoc = getLexer().getLoc();
503   if (getParser().parseIdentifier(Type))
504     return TokError("expected symbol type in directive");
505
506   MCSymbolAttr Attr = StringSwitch<MCSymbolAttr>(Type)
507     .Case("function", MCSA_ELF_TypeFunction)
508     .Case("object", MCSA_ELF_TypeObject)
509     .Case("tls_object", MCSA_ELF_TypeTLS)
510     .Case("common", MCSA_ELF_TypeCommon)
511     .Case("notype", MCSA_ELF_TypeNoType)
512     .Case("gnu_unique_object", MCSA_ELF_TypeGnuUniqueObject)
513     .Case("gnu_indirect_function", MCSA_ELF_TypeIndFunction)
514     .Default(MCSA_Invalid);
515
516   if (Attr == MCSA_Invalid)
517     return Error(TypeLoc, "unsupported attribute in '.type' directive");
518
519   if (getLexer().isNot(AsmToken::EndOfStatement))
520     return TokError("unexpected token in '.type' directive");
521
522   Lex();
523
524   getStreamer().EmitSymbolAttribute(Sym, Attr);
525
526   return false;
527 }
528
529 /// ParseDirectiveIdent
530 ///  ::= .ident string
531 bool ELFAsmParser::ParseDirectiveIdent(StringRef, SMLoc) {
532   if (getLexer().isNot(AsmToken::String))
533     return TokError("unexpected token in '.ident' directive");
534
535   StringRef Data = getTok().getIdentifier();
536
537   Lex();
538
539   const MCSection *Comment =
540     getContext().getELFSection(".comment", ELF::SHT_PROGBITS,
541                                ELF::SHF_MERGE |
542                                ELF::SHF_STRINGS,
543                                SectionKind::getReadOnly(),
544                                1, "");
545
546   getStreamer().PushSection();
547   getStreamer().SwitchSection(Comment);
548   if (!SeenIdent) {
549     getStreamer().EmitIntValue(0, 1);
550     SeenIdent = true;
551   }
552   getStreamer().EmitBytes(Data);
553   getStreamer().EmitIntValue(0, 1);
554   getStreamer().PopSection();
555   return false;
556 }
557
558 /// ParseDirectiveSymver
559 ///  ::= .symver foo, bar2@zed
560 bool ELFAsmParser::ParseDirectiveSymver(StringRef, SMLoc) {
561   StringRef Name;
562   if (getParser().parseIdentifier(Name))
563     return TokError("expected identifier in directive");
564
565   if (getLexer().isNot(AsmToken::Comma))
566     return TokError("expected a comma");
567
568   Lex();
569
570   StringRef AliasName;
571   if (getParser().parseIdentifier(AliasName))
572     return TokError("expected identifier in directive");
573
574   if (AliasName.find('@') == StringRef::npos)
575     return TokError("expected a '@' in the name");
576
577   MCSymbol *Alias = getContext().GetOrCreateSymbol(AliasName);
578   MCSymbol *Sym = getContext().GetOrCreateSymbol(Name);
579   const MCExpr *Value = MCSymbolRefExpr::Create(Sym, getContext());
580
581   getStreamer().EmitAssignment(Alias, Value);
582   return false;
583 }
584
585 /// ParseDirectiveVersion
586 ///  ::= .version string
587 bool ELFAsmParser::ParseDirectiveVersion(StringRef, SMLoc) {
588   if (getLexer().isNot(AsmToken::String))
589     return TokError("unexpected token in '.version' directive");
590
591   StringRef Data = getTok().getIdentifier();
592
593   Lex();
594
595   const MCSection *Note =
596     getContext().getELFSection(".note", ELF::SHT_NOTE, 0,
597                                SectionKind::getReadOnly());
598
599   getStreamer().PushSection();
600   getStreamer().SwitchSection(Note);
601   getStreamer().EmitIntValue(Data.size()+1, 4); // namesz.
602   getStreamer().EmitIntValue(0, 4);             // descsz = 0 (no description).
603   getStreamer().EmitIntValue(1, 4);             // type = NT_VERSION.
604   getStreamer().EmitBytes(Data);                // name.
605   getStreamer().EmitIntValue(0, 1);             // terminate the string.
606   getStreamer().EmitValueToAlignment(4);        // ensure 4 byte alignment.
607   getStreamer().PopSection();
608   return false;
609 }
610
611 /// ParseDirectiveWeakref
612 ///  ::= .weakref foo, bar
613 bool ELFAsmParser::ParseDirectiveWeakref(StringRef, SMLoc) {
614   // FIXME: Share code with the other alias building directives.
615
616   StringRef AliasName;
617   if (getParser().parseIdentifier(AliasName))
618     return TokError("expected identifier in directive");
619
620   if (getLexer().isNot(AsmToken::Comma))
621     return TokError("expected a comma");
622
623   Lex();
624
625   StringRef Name;
626   if (getParser().parseIdentifier(Name))
627     return TokError("expected identifier in directive");
628
629   MCSymbol *Alias = getContext().GetOrCreateSymbol(AliasName);
630
631   MCSymbol *Sym = getContext().GetOrCreateSymbol(Name);
632
633   getStreamer().EmitWeakReference(Alias, Sym);
634   return false;
635 }
636
637 bool ELFAsmParser::ParseDirectiveSubsection(StringRef, SMLoc) {
638   const MCExpr *Subsection = 0;
639   if (getLexer().isNot(AsmToken::EndOfStatement)) {
640     if (getParser().parseExpression(Subsection))
641      return true;
642   }
643
644   if (getLexer().isNot(AsmToken::EndOfStatement))
645     return TokError("unexpected token in directive");
646
647   getStreamer().SubSection(Subsection);
648   return false;
649 }
650
651 namespace llvm {
652
653 MCAsmParserExtension *createELFAsmParser() {
654   return new ELFAsmParser;
655 }
656
657 }