summaryrefslogtreecommitdiff
path: root/tools/llvm-mc
diff options
context:
space:
mode:
authorChris Lattner <sabre@nondot.org>2009-08-10 01:39:42 +0000
committerChris Lattner <sabre@nondot.org>2009-08-10 01:39:42 +0000
commitff4bc460c52c1f285d8a56da173641bf92d49e3f (patch)
tree7da0d5977dffaffaa4bb5da91039d0960f839f77 /tools/llvm-mc
parente36df3fd31a08a41d9ad04fcba182b616b030c9c (diff)
downloadllvm-ff4bc460c52c1f285d8a56da173641bf92d49e3f.tar.gz
llvm-ff4bc460c52c1f285d8a56da173641bf92d49e3f.tar.bz2
llvm-ff4bc460c52c1f285d8a56da173641bf92d49e3f.tar.xz
Make the big switch: Change MCSectionMachO to represent a section *semantically*
instead of syntactically as a string. This means that it keeps track of the segment, section, flags, etc directly and asmprints them in the right format. This also includes parsing and validation support for llvm-mc and "attribute(section)", so we should now start getting errors about invalid section attributes from the compiler instead of the assembler on darwin. Still todo: 1) Uniquing of darwin mcsections 2) Move all the Darwin stuff out to MCSectionMachO.[cpp|h] 3) there are a few FIXMEs, for example what is the syntax to get the S_GB_ZEROFILL segment type? git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@78547 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'tools/llvm-mc')
-rw-r--r--tools/llvm-mc/AsmLexer.cpp11
-rw-r--r--tools/llvm-mc/AsmLexer.h3
-rw-r--r--tools/llvm-mc/AsmParser.cpp188
-rw-r--r--tools/llvm-mc/AsmParser.h4
-rw-r--r--tools/llvm-mc/llvm-mc.cpp9
5 files changed, 116 insertions, 99 deletions
diff --git a/tools/llvm-mc/AsmLexer.cpp b/tools/llvm-mc/AsmLexer.cpp
index 28b0c1e3c9..5b394b6cc4 100644
--- a/tools/llvm-mc/AsmLexer.cpp
+++ b/tools/llvm-mc/AsmLexer.cpp
@@ -242,6 +242,17 @@ AsmToken AsmLexer::LexQuote() {
return AsmToken(AsmToken::String, StringRef(TokStart, CurPtr - TokStart));
}
+StringRef AsmLexer::LexUntilEndOfStatement() {
+ TokStart = CurPtr;
+
+ while (*CurPtr != '#' && // Start of line comment.
+ *CurPtr != ';' && // End of statement marker.
+ *CurPtr != '\n' &&
+ *CurPtr != '\r' &&
+ (*CurPtr != 0 || CurPtr != CurBuf->getBufferEnd()))
+ ++CurPtr;
+ return StringRef(TokStart, CurPtr-TokStart);
+}
AsmToken AsmLexer::LexToken() {
TokStart = CurPtr;
diff --git a/tools/llvm-mc/AsmLexer.h b/tools/llvm-mc/AsmLexer.h
index 4200137f64..905ff75ec9 100644
--- a/tools/llvm-mc/AsmLexer.h
+++ b/tools/llvm-mc/AsmLexer.h
@@ -50,6 +50,9 @@ public:
~AsmLexer();
SMLoc getLoc() const;
+
+ StringRef LexUntilEndOfStatement();
+
/// EnterIncludeFile - Enter the specified file. This returns true on failure.
bool EnterIncludeFile(const std::string &Filename);
diff --git a/tools/llvm-mc/AsmParser.cpp b/tools/llvm-mc/AsmParser.cpp
index 8f6583a591..153cdde779 100644
--- a/tools/llvm-mc/AsmParser.cpp
+++ b/tools/llvm-mc/AsmParser.cpp
@@ -404,95 +404,104 @@ bool AsmParser::ParseStatement() {
if (IDVal == ".text")
// FIXME: This changes behavior based on the -static flag to the
// assembler.
- return ParseDirectiveSectionSwitch("__TEXT,__text",
- "regular,pure_instructions");
+ return ParseDirectiveSectionSwitch("__TEXT", "__text",
+ MCSectionMachO::S_ATTR_PURE_INSTRUCTIONS);
if (IDVal == ".const")
- return ParseDirectiveSectionSwitch("__TEXT,__const");
+ return ParseDirectiveSectionSwitch("__TEXT", "__const", 0);
if (IDVal == ".static_const")
- return ParseDirectiveSectionSwitch("__TEXT,__static_const");
+ return ParseDirectiveSectionSwitch("__TEXT", "__static_const", 0);
if (IDVal == ".cstring")
- return ParseDirectiveSectionSwitch("__TEXT,__cstring",
- "cstring_literals");
+ return ParseDirectiveSectionSwitch("__TEXT","__cstring",
+ MCSectionMachO::S_CSTRING_LITERALS);
if (IDVal == ".literal4")
- return ParseDirectiveSectionSwitch("__TEXT,__literal4", "4byte_literals");
+ return ParseDirectiveSectionSwitch("__TEXT", "__literal4",
+ MCSectionMachO::S_4BYTE_LITERALS);
if (IDVal == ".literal8")
- return ParseDirectiveSectionSwitch("__TEXT,__literal8", "8byte_literals");
+ return ParseDirectiveSectionSwitch("__TEXT", "__literal8",
+ MCSectionMachO::S_8BYTE_LITERALS);
if (IDVal == ".literal16")
- return ParseDirectiveSectionSwitch("__TEXT,__literal16",
- "16byte_literals");
+ return ParseDirectiveSectionSwitch("__TEXT","__literal16",
+ MCSectionMachO::S_16BYTE_LITERALS);
if (IDVal == ".constructor")
- return ParseDirectiveSectionSwitch("__TEXT,__constructor");
+ return ParseDirectiveSectionSwitch("__TEXT","__constructor", 0);
if (IDVal == ".destructor")
- return ParseDirectiveSectionSwitch("__TEXT,__destructor");
+ return ParseDirectiveSectionSwitch("__TEXT","__destructor", 0);
if (IDVal == ".fvmlib_init0")
- return ParseDirectiveSectionSwitch("__TEXT,__fvmlib_init0");
+ return ParseDirectiveSectionSwitch("__TEXT","__fvmlib_init0", 0);
if (IDVal == ".fvmlib_init1")
- return ParseDirectiveSectionSwitch("__TEXT,__fvmlib_init1");
- if (IDVal == ".symbol_stub") // FIXME: Different on PPC.
- return ParseDirectiveSectionSwitch("__IMPORT,__jump_table,symbol_stubs",
- "self_modifying_code+pure_instructions,5");
+ return ParseDirectiveSectionSwitch("__TEXT","__fvmlib_init1", 0);
+ if (IDVal == ".symbol_stub")
+ return ParseDirectiveSectionSwitch("__TEXT","__symbol_stub",
+ MCSectionMachO::S_SYMBOL_STUBS |
+ MCSectionMachO::S_ATTR_SELF_MODIFYING_CODE |
+ MCSectionMachO::S_ATTR_PURE_INSTRUCTIONS,
+ // FIXME: Different on PPC and ARM.
+ 16);
// FIXME: .picsymbol_stub on PPC.
if (IDVal == ".data")
- return ParseDirectiveSectionSwitch("__DATA,__data");
+ return ParseDirectiveSectionSwitch("__DATA", "__data", 0);
if (IDVal == ".static_data")
- return ParseDirectiveSectionSwitch("__DATA,__static_data");
+ return ParseDirectiveSectionSwitch("__DATA", "__static_data", 0);
if (IDVal == ".non_lazy_symbol_pointer")
- return ParseDirectiveSectionSwitch("__DATA,__nl_symbol_pointer",
- "non_lazy_symbol_pointers");
+ return ParseDirectiveSectionSwitch("__DATA", "__nl_symbol_pointer",
+ MCSectionMachO::S_NON_LAZY_SYMBOL_POINTERS);
if (IDVal == ".lazy_symbol_pointer")
- return ParseDirectiveSectionSwitch("__DATA,__la_symbol_pointer",
- "lazy_symbol_pointers");
+ return ParseDirectiveSectionSwitch("__DATA", "__la_symbol_pointer",
+ MCSectionMachO::S_LAZY_SYMBOL_POINTERS);
if (IDVal == ".dyld")
- return ParseDirectiveSectionSwitch("__DATA,__dyld");
+ return ParseDirectiveSectionSwitch("__DATA", "__dyld", 0);
if (IDVal == ".mod_init_func")
- return ParseDirectiveSectionSwitch("__DATA,__mod_init_func",
- "mod_init_funcs");
+ return ParseDirectiveSectionSwitch("__DATA", "__mod_init_func",
+ MCSectionMachO::S_MOD_INIT_FUNC_POINTERS);
if (IDVal == ".mod_term_func")
- return ParseDirectiveSectionSwitch("__DATA,__mod_term_func",
- "mod_term_funcs");
+ return ParseDirectiveSectionSwitch("__DATA", "__mod_term_func",
+ MCSectionMachO::S_MOD_TERM_FUNC_POINTERS);
if (IDVal == ".const_data")
- return ParseDirectiveSectionSwitch("__DATA,__const", "regular");
+ return ParseDirectiveSectionSwitch("__DATA", "__const", 0);
// FIXME: Verify attributes on sections.
if (IDVal == ".objc_class")
- return ParseDirectiveSectionSwitch("__OBJC,__class");
+ return ParseDirectiveSectionSwitch("__OBJC", "__class", 0);
if (IDVal == ".objc_meta_class")
- return ParseDirectiveSectionSwitch("__OBJC,__meta_class");
+ return ParseDirectiveSectionSwitch("__OBJC", "__meta_class", 0);
if (IDVal == ".objc_cat_cls_meth")
- return ParseDirectiveSectionSwitch("__OBJC,__cat_cls_meth");
+ return ParseDirectiveSectionSwitch("__OBJC", "__cat_cls_meth", 0);
if (IDVal == ".objc_cat_inst_meth")
- return ParseDirectiveSectionSwitch("__OBJC,__cat_inst_meth");
+ return ParseDirectiveSectionSwitch("__OBJC", "__cat_inst_meth", 0);
if (IDVal == ".objc_protocol")
- return ParseDirectiveSectionSwitch("__OBJC,__protocol");
+ return ParseDirectiveSectionSwitch("__OBJC", "__protocol", 0);
if (IDVal == ".objc_string_object")
- return ParseDirectiveSectionSwitch("__OBJC,__string_object");
+ return ParseDirectiveSectionSwitch("__OBJC", "__string_object", 0);
if (IDVal == ".objc_cls_meth")
- return ParseDirectiveSectionSwitch("__OBJC,__cls_meth");
+ return ParseDirectiveSectionSwitch("__OBJC", "__cls_meth", 0);
if (IDVal == ".objc_inst_meth")
- return ParseDirectiveSectionSwitch("__OBJC,__inst_meth");
+ return ParseDirectiveSectionSwitch("__OBJC", "__inst_meth", 0);
if (IDVal == ".objc_cls_refs")
- return ParseDirectiveSectionSwitch("__OBJC,__cls_refs");
+ return ParseDirectiveSectionSwitch("__OBJC", "__cls_refs", 0);
if (IDVal == ".objc_message_refs")
- return ParseDirectiveSectionSwitch("__OBJC,__message_refs");
+ return ParseDirectiveSectionSwitch("__OBJC", "__message_refs", 0);
if (IDVal == ".objc_symbols")
- return ParseDirectiveSectionSwitch("__OBJC,__symbols");
+ return ParseDirectiveSectionSwitch("__OBJC", "__symbols", 0);
if (IDVal == ".objc_category")
- return ParseDirectiveSectionSwitch("__OBJC,__category");
+ return ParseDirectiveSectionSwitch("__OBJC", "__category", 0);
if (IDVal == ".objc_class_vars")
- return ParseDirectiveSectionSwitch("__OBJC,__class_vars");
+ return ParseDirectiveSectionSwitch("__OBJC", "__class_vars", 0);
if (IDVal == ".objc_instance_vars")
- return ParseDirectiveSectionSwitch("__OBJC,__instance_vars");
+ return ParseDirectiveSectionSwitch("__OBJC", "__instance_vars", 0);
if (IDVal == ".objc_module_info")
- return ParseDirectiveSectionSwitch("__OBJC,__module_info");
+ return ParseDirectiveSectionSwitch("__OBJC", "__module_info", 0);
if (IDVal == ".objc_class_names")
- return ParseDirectiveSectionSwitch("__TEXT,__cstring","cstring_literals");
+ return ParseDirectiveSectionSwitch("__TEXT", "__cstring",
+ MCSectionMachO::S_CSTRING_LITERALS);
if (IDVal == ".objc_meth_var_types")
- return ParseDirectiveSectionSwitch("__TEXT,__cstring","cstring_literals");
+ return ParseDirectiveSectionSwitch("__TEXT", "__cstring",
+ MCSectionMachO::S_CSTRING_LITERALS);
if (IDVal == ".objc_meth_var_names")
- return ParseDirectiveSectionSwitch("__TEXT,__cstring","cstring_literals");
+ return ParseDirectiveSectionSwitch("__TEXT", "__cstring",
+ MCSectionMachO::S_CSTRING_LITERALS);
if (IDVal == ".objc_selector_strs")
- return ParseDirectiveSectionSwitch("__OBJC,__selector_strs");
+ return ParseDirectiveSectionSwitch("__OBJC", "__selector_strs", 0);
// Assembler features
if (IDVal == ".set")
@@ -681,53 +690,52 @@ bool AsmParser::ParseDirectiveSet() {
bool AsmParser::ParseDirectiveDarwinSection() {
StringRef SectionName;
- if (ParseIdentifier(SectionName))
+ if (Lexer.isNot(AsmToken::Identifier))
return TokError("expected identifier after '.section' directive");
- std::string Section = SectionName;
-
- // FIXME: This doesn't work, we lose quoting on things
-
- // Accept a comma separated list of modifiers.
- while (Lexer.is(AsmToken::Comma)) {
- Lexer.Lex(); // Consume the comma.
-
- StringRef ModifierName;
- if (ParseIdentifier(ModifierName))
- return TokError("expected identifier in '.section' directive");
- Section += ',';
- Section += ModifierName;
- }
-
+ std::string SectionSpec = SectionName;
+ StringRef EOL = Lexer.LexUntilEndOfStatement();
+ SectionSpec.append(EOL.begin(), EOL.end());
+ Lexer.Lex();
if (Lexer.isNot(AsmToken::EndOfStatement))
return TokError("unexpected token in '.section' directive");
Lexer.Lex();
+
+ StringRef Segment, Section;
+ unsigned TAA, StubSize;
+ std::string ErrorStr =
+ MCSectionMachO::ParseSectionSpecifier(SectionSpec, Segment, Section,
+ TAA, StubSize);
+
+ if (!ErrorStr.empty())
+ return TokError(ErrorStr.c_str());
+
+ // FIXME: CACHE THESE.
+
// FIXME: Arch specific.
- MCSection *S = Ctx.GetSection(Section);
+ MCSection *S = 0; //Ctx.GetSection(Section);
if (S == 0)
- S = MCSectionMachO::Create(Section, false, SectionKind(), Ctx);
+ S = MCSectionMachO::Create(Segment, Section, TAA, StubSize,
+ SectionKind(), Ctx);
Out.SwitchSection(S);
return false;
}
-bool AsmParser::ParseDirectiveSectionSwitch(const char *Section,
- const char *Directives) {
+bool AsmParser::ParseDirectiveSectionSwitch(const char *Segment,
+ const char *Section,
+ unsigned TAA, unsigned StubSize) {
if (Lexer.isNot(AsmToken::EndOfStatement))
return TokError("unexpected token in section switching directive");
Lexer.Lex();
- std::string SectionStr = Section;
- if (Directives && Directives[0]) {
- SectionStr += ",";
- SectionStr += Directives;
- }
-
// FIXME: Arch specific.
- MCSection *S = Ctx.GetSection(Section);
+ // FIXME: Cache this!
+ MCSection *S = 0; // Ctx.GetSection(Section);
if (S == 0)
- S = MCSectionMachO::Create(Section, false, SectionKind(), Ctx);
+ S = MCSectionMachO::Create(Segment, Section, TAA, StubSize,
+ SectionKind(), Ctx);
Out.SwitchSection(S);
return false;
@@ -1090,35 +1098,28 @@ bool AsmParser::ParseDirectiveDarwinZerofill() {
if (Lexer.isNot(AsmToken::Identifier))
return TokError("expected segment name after '.zerofill' directive");
- std::string Section = Lexer.getTok().getString();
+ StringRef Segment = Lexer.getTok().getString();
Lexer.Lex();
if (Lexer.isNot(AsmToken::Comma))
return TokError("unexpected token in directive");
- Section += ',';
Lexer.Lex();
if (Lexer.isNot(AsmToken::Identifier))
return TokError("expected section name after comma in '.zerofill' "
"directive");
- Section += Lexer.getTok().getString().str();
+ StringRef Section = Lexer.getTok().getString();
Lexer.Lex();
- // FIXME: we will need to tell GetSection() that this is to be created with or
- // must have the Mach-O section type of S_ZEROFILL. Something like the code
- // below could be done but for now it is not as EmitZerofill() does not know
- // how to deal with a section type in the section name like
- // ParseDirectiveDarwinSection() allows.
- // Section += ',';
- // Section += "zerofill";
-
// If this is the end of the line all that was wanted was to create the
// the section but with no symbol.
if (Lexer.is(AsmToken::EndOfStatement)) {
- // FIXME: Arch specific.
- MCSection *S = Ctx.GetSection(Section);
+ // FIXME: CACHE THIS.
+ MCSection *S = 0; //Ctx.GetSection(Section);
if (S == 0)
- S = MCSectionMachO::Create(Section, false, SectionKind(), Ctx);
+ S = MCSectionMachO::Create(Segment, Section,
+ MCSectionMachO::S_ZEROFILL, 0,
+ SectionKind(), Ctx);
// Create the zerofill section but no symbol
Out.EmitZerofill(S);
@@ -1176,9 +1177,12 @@ bool AsmParser::ParseDirectiveDarwinZerofill() {
return Error(IDLoc, "invalid symbol redefinition");
// FIXME: Arch specific.
- MCSection *S = Ctx.GetSection(Section);
+ // FIXME: CACHE.
+ MCSection *S = 0; //Ctx.GetSection(Section);
if (S == 0)
- S = MCSectionMachO::Create(Section, false, SectionKind(), Ctx);
+ S = MCSectionMachO::Create(Segment, Section,
+ MCSectionMachO::S_ZEROFILL, 0,
+ SectionKind(), Ctx);
// Create the zerofill Symbol with Size and Pow2Alignment
Out.EmitZerofill(S, Sym, Size, Pow2Alignment);
diff --git a/tools/llvm-mc/AsmParser.h b/tools/llvm-mc/AsmParser.h
index c6f6f63e48..646001ce7a 100644
--- a/tools/llvm-mc/AsmParser.h
+++ b/tools/llvm-mc/AsmParser.h
@@ -99,8 +99,8 @@ private:
// Directive Parsing.
bool ParseDirectiveDarwinSection(); // Darwin specific ".section".
- bool ParseDirectiveSectionSwitch(const char *Section,
- const char *Directives = 0);
+ bool ParseDirectiveSectionSwitch(const char *Segment, const char *Section,
+ unsigned TAA, unsigned StubSize = 0);
bool ParseDirectiveAscii(bool ZeroTerminated); // ".ascii", ".asciiz"
bool ParseDirectiveValue(unsigned Size); // ".byte", ".long", ...
bool ParseDirectiveFill(); // ".fill"
diff --git a/tools/llvm-mc/llvm-mc.cpp b/tools/llvm-mc/llvm-mc.cpp
index 5f746f2e47..5bddea4c31 100644
--- a/tools/llvm-mc/llvm-mc.cpp
+++ b/tools/llvm-mc/llvm-mc.cpp
@@ -186,11 +186,10 @@ static int AssembleInput(const char *ProgName) {
OwningPtr<MCStreamer> Str(createAsmStreamer(Ctx, outs()));
// FIXME: Target hook & command line option for initial section.
- Str.get()->SwitchSection(MCSectionMachO::Create("__TEXT,__text,"
- "regular,pure_instructions",
- false,
- SectionKind::getText(),
- Ctx));
+ Str.get()->SwitchSection(MCSectionMachO::Create("__TEXT","__text",
+ MCSectionMachO::S_ATTR_PURE_INSTRUCTIONS,
+ 0, SectionKind::getText(),
+ Ctx));
AsmParser Parser(SrcMgr, Ctx, *Str.get());
OwningPtr<TargetAsmParser> TAP(GetTargetAsmParser(ProgName, Parser));