aboutsummaryrefslogtreecommitdiff
path: root/lib/MC/MCParser/ELFAsmParser.cpp
diff options
context:
space:
mode:
authorEli Friedman <eli.friedman@gmail.com>2010-07-17 04:29:04 +0000
committerEli Friedman <eli.friedman@gmail.com>2010-07-17 04:29:04 +0000
commit21444efae03be297faf5bdb8f16567765307fa9d (patch)
tree287986462601674a10e189a68021c6759882ab4f /lib/MC/MCParser/ELFAsmParser.cpp
parent5423856e44a7e4b173af211b0fb0675c44945a58 (diff)
Work-in-progress parsing for ELF .section directive.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@108609 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/MC/MCParser/ELFAsmParser.cpp')
-rw-r--r--lib/MC/MCParser/ELFAsmParser.cpp118
1 files changed, 113 insertions, 5 deletions
diff --git a/lib/MC/MCParser/ELFAsmParser.cpp b/lib/MC/MCParser/ELFAsmParser.cpp
index f87031860e..340af23cf9 100644
--- a/lib/MC/MCParser/ELFAsmParser.cpp
+++ b/lib/MC/MCParser/ELFAsmParser.cpp
@@ -8,10 +8,11 @@
//===----------------------------------------------------------------------===//
#include "llvm/MC/MCParser/MCAsmParserExtension.h"
-#include "llvm/MC/MCSectionELF.h"
+#include "llvm/MC/MCAsmInfo.h"
#include "llvm/MC/MCContext.h"
-#include "llvm/MC/MCStreamer.h"
#include "llvm/MC/MCParser/MCAsmLexer.h"
+#include "llvm/MC/MCSectionELF.h"
+#include "llvm/MC/MCStreamer.h"
using namespace llvm;
namespace {
@@ -31,8 +32,10 @@ public:
&ELFAsmParser::ParseSectionDirectiveData));
Parser.AddDirectiveHandler(this, ".text", MCAsmParser::DirectiveHandler(
&ELFAsmParser::ParseSectionDirectiveText));
+ Parser.AddDirectiveHandler(this, ".section", MCAsmParser::DirectiveHandler(
+ &ELFAsmParser::ParseDirectiveSection));
Parser.AddDirectiveHandler(this, ".size", MCAsmParser::DirectiveHandler(
- &ELFAsmParser::ParseSizeDirective));
+ &ELFAsmParser::ParseDirectiveSize));
}
bool ParseSectionDirectiveData(StringRef, SMLoc) {
@@ -45,7 +48,8 @@ public:
MCSectionELF::SHF_EXECINSTR |
MCSectionELF::SHF_ALLOC, SectionKind::getText());
}
- bool ParseSizeDirective(StringRef, SMLoc);
+ bool ParseDirectiveSection(StringRef, SMLoc);
+ bool ParseDirectiveSize(StringRef, SMLoc);
};
}
@@ -62,7 +66,7 @@ bool ELFAsmParser::ParseSectionSwitch(StringRef Section, unsigned Type,
return false;
}
-bool ELFAsmParser::ParseSizeDirective(StringRef, SMLoc) {
+bool ELFAsmParser::ParseDirectiveSize(StringRef, SMLoc) {
StringRef Name;
if (getParser().ParseIdentifier(Name))
return TokError("expected identifier in directive");
@@ -83,6 +87,110 @@ bool ELFAsmParser::ParseSizeDirective(StringRef, SMLoc) {
return false;
}
+// FIXME: This is a work in progress.
+bool ELFAsmParser::ParseDirectiveSection(StringRef, SMLoc) {
+ StringRef SectionName;
+ // FIXME: This doesn't parse section names like ".note.GNU-stack" correctly.
+ if (getParser().ParseIdentifier(SectionName))
+ return TokError("expected identifier in directive");
+
+ std::string FlagsStr;
+ StringRef TypeName;
+ int64_t Size = 0;
+ if (getLexer().is(AsmToken::Comma)) {
+ Lex();
+
+ if (getLexer().isNot(AsmToken::String))
+ return TokError("expected string in directive");
+
+ FlagsStr = getTok().getStringContents();
+ Lex();
+
+ AsmToken::TokenKind TypeStartToken;
+ if (getContext().getAsmInfo().getCommentString()[0] == '@')
+ TypeStartToken = AsmToken::Percent;
+ else
+ TypeStartToken = AsmToken::At;
+
+ if (getLexer().is(AsmToken::Comma)) {
+ Lex();
+ if (getLexer().is(TypeStartToken)) {
+ Lex();
+ if (getParser().ParseIdentifier(TypeName))
+ return TokError("expected identifier in directive");
+
+ if (getLexer().is(AsmToken::Comma)) {
+ Lex();
+
+ if (getParser().ParseAbsoluteExpression(Size))
+ return true;
+
+ if (Size <= 0)
+ return TokError("section size must be positive");
+ }
+ }
+ }
+ }
+
+ if (getLexer().isNot(AsmToken::EndOfStatement))
+ return TokError("unexpected token in directive");
+
+ unsigned Flags = 0;
+ for (unsigned i = 0; i < FlagsStr.size(); i++) {
+ switch (FlagsStr[i]) {
+ case 'a':
+ Flags |= MCSectionELF::SHF_ALLOC;
+ break;
+ case 'x':
+ Flags |= MCSectionELF::SHF_EXECINSTR;
+ break;
+ case 'w':
+ Flags |= MCSectionELF::SHF_WRITE;
+ break;
+ case 'M':
+ Flags |= MCSectionELF::SHF_MERGE;
+ break;
+ case 'S':
+ Flags |= MCSectionELF::SHF_STRINGS;
+ break;
+ case 'T':
+ Flags |= MCSectionELF::SHF_TLS;
+ break;
+ case 'c':
+ Flags |= MCSectionELF::XCORE_SHF_CP_SECTION;
+ break;
+ case 'd':
+ Flags |= MCSectionELF::XCORE_SHF_DP_SECTION;
+ break;
+ default:
+ return TokError("unknown flag");
+ }
+ }
+
+ unsigned Type = MCSectionELF::SHT_NULL;
+ if (!TypeName.empty()) {
+ if (TypeName == "init_array")
+ Type = MCSectionELF::SHT_INIT_ARRAY;
+ else if (TypeName == "fini_array")
+ Type = MCSectionELF::SHT_FINI_ARRAY;
+ else if (TypeName == "preinit_array")
+ Type = MCSectionELF::SHT_PREINIT_ARRAY;
+ else if (TypeName == "nobits")
+ Type = MCSectionELF::SHT_NOBITS;
+ else if (TypeName == "progbits")
+ Type = MCSectionELF::SHT_PROGBITS;
+ else
+ return TokError("unknown section type");
+ }
+
+ SectionKind Kind = (Flags & MCSectionELF::SHF_EXECINSTR)
+ ? SectionKind::getText()
+ : SectionKind::getDataRel();
+ getStreamer().SwitchSection(getContext().getELFSection(SectionName, Type,
+ Flags, Kind, false));
+ return false;
+}
+
namespace llvm {
MCAsmParserExtension *createELFAsmParser() {