blob: f87031860e629fa59f174d2e620c25fd3faf87ad [file] [log] [blame]
Daniel Dunbar5146a092010-07-12 21:23:32 +00001//===- 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/MC/MCSectionELF.h"
12#include "llvm/MC/MCContext.h"
13#include "llvm/MC/MCStreamer.h"
14#include "llvm/MC/MCParser/MCAsmLexer.h"
15using namespace llvm;
16
17namespace {
18
19class ELFAsmParser : public MCAsmParserExtension {
20 bool ParseSectionSwitch(StringRef Section, unsigned Type,
21 unsigned Flags, SectionKind Kind);
22
23public:
24 ELFAsmParser() {}
25
26 virtual void Initialize(MCAsmParser &Parser) {
27 // Call the base implementation.
28 this->MCAsmParserExtension::Initialize(Parser);
29
30 Parser.AddDirectiveHandler(this, ".data", MCAsmParser::DirectiveHandler(
31 &ELFAsmParser::ParseSectionDirectiveData));
32 Parser.AddDirectiveHandler(this, ".text", MCAsmParser::DirectiveHandler(
33 &ELFAsmParser::ParseSectionDirectiveText));
Eli Friedmanf82ccf52010-07-17 03:09:18 +000034 Parser.AddDirectiveHandler(this, ".size", MCAsmParser::DirectiveHandler(
35 &ELFAsmParser::ParseSizeDirective));
Daniel Dunbar5146a092010-07-12 21:23:32 +000036 }
37
38 bool ParseSectionDirectiveData(StringRef, SMLoc) {
39 return ParseSectionSwitch(".data", MCSectionELF::SHT_PROGBITS,
40 MCSectionELF::SHF_WRITE |MCSectionELF::SHF_ALLOC,
41 SectionKind::getDataRel());
42 }
43 bool ParseSectionDirectiveText(StringRef, SMLoc) {
44 return ParseSectionSwitch(".text", MCSectionELF::SHT_PROGBITS,
45 MCSectionELF::SHF_EXECINSTR |
46 MCSectionELF::SHF_ALLOC, SectionKind::getText());
47 }
Eli Friedmanf82ccf52010-07-17 03:09:18 +000048 bool ParseSizeDirective(StringRef, SMLoc);
Daniel Dunbar5146a092010-07-12 21:23:32 +000049};
50
51}
52
53bool ELFAsmParser::ParseSectionSwitch(StringRef Section, unsigned Type,
54 unsigned Flags, SectionKind Kind) {
55 if (getLexer().isNot(AsmToken::EndOfStatement))
56 return TokError("unexpected token in section switching directive");
57 Lex();
58
59 getStreamer().SwitchSection(getContext().getELFSection(
60 Section, Type, Flags, Kind));
61
62 return false;
63}
64
Eli Friedmanf82ccf52010-07-17 03:09:18 +000065bool ELFAsmParser::ParseSizeDirective(StringRef, SMLoc) {
66 StringRef Name;
67 if (getParser().ParseIdentifier(Name))
68 return TokError("expected identifier in directive");
69 MCSymbol *Sym = getContext().GetOrCreateSymbol(Name);;
70
71 if (getLexer().isNot(AsmToken::Comma))
72 return TokError("unexpected token in directive");
73 Lex();
74
75 const MCExpr *Expr;
76 if (getParser().ParseExpression(Expr))
77 return true;
78
79 if (getLexer().isNot(AsmToken::EndOfStatement))
80 return TokError("unexpected token in directive");
81
82 getStreamer().EmitELFSize(Sym, Expr);
83 return false;
84}
85
Daniel Dunbar5146a092010-07-12 21:23:32 +000086namespace llvm {
87
88MCAsmParserExtension *createELFAsmParser() {
89 return new ELFAsmParser;
90}
91
92}