diff options
author | Dimitry Andric <dim@FreeBSD.org> | 2017-04-16 16:25:46 +0000 |
---|---|---|
committer | Dimitry Andric <dim@FreeBSD.org> | 2017-04-16 16:25:46 +0000 |
commit | 7a7e6055035bfd93ab507051819373a6f171258b (patch) | |
tree | dc9ac22b4fea4f445748feaf7232a146623f0dfa /contrib/llvm/lib/MC/MCParser/ELFAsmParser.cpp | |
parent | b96a714f453e7f5aeeb3c2df2c3e1e8ad749f96f (diff) | |
parent | 71d5a2540a98c81f5bcaeb48805e0e2881f530ef (diff) |
Merge llvm trunk r300422 and resolve conflicts.
Notes
Notes:
svn path=/projects/clang500-import/; revision=317029
Diffstat (limited to 'contrib/llvm/lib/MC/MCParser/ELFAsmParser.cpp')
-rw-r--r-- | contrib/llvm/lib/MC/MCParser/ELFAsmParser.cpp | 233 |
1 files changed, 162 insertions, 71 deletions
diff --git a/contrib/llvm/lib/MC/MCParser/ELFAsmParser.cpp b/contrib/llvm/lib/MC/MCParser/ELFAsmParser.cpp index 8d7ba0d03362..401011a027f4 100644 --- a/contrib/llvm/lib/MC/MCParser/ELFAsmParser.cpp +++ b/contrib/llvm/lib/MC/MCParser/ELFAsmParser.cpp @@ -7,17 +7,29 @@ // //===----------------------------------------------------------------------===// -#include "llvm/MC/MCParser/MCAsmParserExtension.h" #include "llvm/ADT/StringSwitch.h" -#include "llvm/ADT/Twine.h" +#include "llvm/ADT/StringRef.h" #include "llvm/MC/MCAsmInfo.h" #include "llvm/MC/MCContext.h" +#include "llvm/MC/MCDirectives.h" #include "llvm/MC/MCExpr.h" #include "llvm/MC/MCParser/MCAsmLexer.h" +#include "llvm/MC/MCParser/MCAsmParser.h" +#include "llvm/MC/MCParser/MCAsmParserExtension.h" +#include "llvm/MC/MCSection.h" #include "llvm/MC/MCSectionELF.h" #include "llvm/MC/MCStreamer.h" +#include "llvm/MC/MCSymbol.h" #include "llvm/MC/MCSymbolELF.h" +#include "llvm/MC/SectionKind.h" +#include "llvm/Support/Casting.h" #include "llvm/Support/ELF.h" +#include "llvm/Support/MathExtras.h" +#include "llvm/Support/SMLoc.h" +#include <cassert> +#include <cstdint> +#include <utility> + using namespace llvm; namespace { @@ -142,9 +154,14 @@ private: bool ParseSectionName(StringRef &SectionName); bool ParseSectionArguments(bool IsPush, SMLoc loc); unsigned parseSunStyleSectionFlags(); + bool maybeParseSectionType(StringRef &TypeName); + bool parseMergeSize(int64_t &Size); + bool parseGroup(StringRef &GroupName); + bool parseMetadataSym(MCSymbolELF *&Associated); + bool maybeParseUniqueID(int64_t &UniqueID); }; -} +} // end anonymous namespace /// ParseDirectiveSymbolAttribute /// ::= { ".local", ".weak", ... } [ identifier ( , identifier )* ] @@ -158,7 +175,7 @@ bool ELFAsmParser::ParseDirectiveSymbolAttribute(StringRef Directive, SMLoc) { .Default(MCSA_Invalid); assert(Attr != MCSA_Invalid && "unexpected symbol attribute directive!"); if (getLexer().isNot(AsmToken::EndOfStatement)) { - for (;;) { + while (true) { StringRef Name; if (getParser().parseIdentifier(Name)) @@ -230,8 +247,7 @@ bool ELFAsmParser::ParseSectionName(StringRef &SectionName) { return false; } - for (;;) { - + while (true) { SMLoc PrevLoc = getLexer().getLoc(); if (getLexer().is(AsmToken::Comma) || getLexer().is(AsmToken::EndOfStatement)) @@ -282,6 +298,9 @@ static unsigned parseSectionFlags(StringRef flagsStr, bool *UseLastGroup) { case 'w': flags |= ELF::SHF_WRITE; break; + case 'o': + flags |= ELF::SHF_LINK_ORDER; + break; case 'M': flags |= ELF::SHF_MERGE; break; @@ -366,6 +385,97 @@ bool ELFAsmParser::ParseDirectiveSection(StringRef, SMLoc loc) { return ParseSectionArguments(/*IsPush=*/false, loc); } +bool ELFAsmParser::maybeParseSectionType(StringRef &TypeName) { + MCAsmLexer &L = getLexer(); + if (L.isNot(AsmToken::Comma)) + return false; + Lex(); + if (L.isNot(AsmToken::At) && L.isNot(AsmToken::Percent) && + L.isNot(AsmToken::String)) { + if (L.getAllowAtInIdentifier()) + return TokError("expected '@<type>', '%<type>' or \"<type>\""); + else + return TokError("expected '%<type>' or \"<type>\""); + } + if (!L.is(AsmToken::String)) + Lex(); + if (L.is(AsmToken::Integer)) { + TypeName = getTok().getString(); + Lex(); + } else if (getParser().parseIdentifier(TypeName)) + return TokError("expected identifier in directive"); + return false; +} + +bool ELFAsmParser::parseMergeSize(int64_t &Size) { + if (getLexer().isNot(AsmToken::Comma)) + return TokError("expected the entry size"); + Lex(); + if (getParser().parseAbsoluteExpression(Size)) + return true; + if (Size <= 0) + return TokError("entry size must be positive"); + return false; +} + +bool ELFAsmParser::parseGroup(StringRef &GroupName) { + MCAsmLexer &L = getLexer(); + if (L.isNot(AsmToken::Comma)) + return TokError("expected group name"); + Lex(); + if (getParser().parseIdentifier(GroupName)) + return true; + if (L.is(AsmToken::Comma)) { + Lex(); + StringRef Linkage; + if (getParser().parseIdentifier(Linkage)) + return true; + if (Linkage != "comdat") + return TokError("Linkage must be 'comdat'"); + } + return false; +} + +bool ELFAsmParser::parseMetadataSym(MCSymbolELF *&Associated) { + MCAsmLexer &L = getLexer(); + if (L.isNot(AsmToken::Comma)) + return TokError("expected metadata symbol"); + Lex(); + StringRef Name; + if (getParser().parseIdentifier(Name)) + return true; + Associated = dyn_cast_or_null<MCSymbolELF>(getContext().lookupSymbol(Name)); + if (!Associated || !Associated->isInSection()) + return TokError("symbol is not in a section: " + Name); + return false; +} + +bool ELFAsmParser::maybeParseUniqueID(int64_t &UniqueID) { + MCAsmLexer &L = getLexer(); + if (L.isNot(AsmToken::Comma)) + return false; + Lex(); + StringRef UniqueStr; + if (getParser().parseIdentifier(UniqueStr)) + return TokError("expected identifier in directive"); + if (UniqueStr != "unique") + return TokError("expected 'unique'"); + if (L.isNot(AsmToken::Comma)) + return TokError("expected commma"); + Lex(); + if (getParser().parseAbsoluteExpression(UniqueID)) + return true; + if (UniqueID < 0) + return TokError("unique id must be positive"); + if (!isUInt<32>(UniqueID) || UniqueID == ~0U) + return TokError("unique id is too large"); + return false; +} + +static bool hasPrefix(StringRef SectionName, StringRef Prefix) { + return SectionName.startswith(Prefix) || SectionName == Prefix.drop_back(); +} + bool ELFAsmParser::ParseSectionArguments(bool IsPush, SMLoc loc) { StringRef SectionName; @@ -379,14 +489,24 @@ bool ELFAsmParser::ParseSectionArguments(bool IsPush, SMLoc loc) { const MCExpr *Subsection = nullptr; bool UseLastGroup = false; StringRef UniqueStr; + MCSymbolELF *Associated = nullptr; int64_t UniqueID = ~0; // Set the defaults first. - if (SectionName == ".fini" || SectionName == ".init" || - SectionName == ".rodata") + if (hasPrefix(SectionName, ".rodata.") || SectionName == ".rodata1") Flags |= ELF::SHF_ALLOC; - if (SectionName == ".fini" || SectionName == ".init") - Flags |= ELF::SHF_EXECINSTR; + if (SectionName == ".fini" || SectionName == ".init" || + hasPrefix(SectionName, ".text.")) + Flags |= ELF::SHF_ALLOC | ELF::SHF_EXECINSTR; + if (hasPrefix(SectionName, ".data.") || SectionName == ".data1" || + hasPrefix(SectionName, ".bss.") || + hasPrefix(SectionName, ".init_array.") || + hasPrefix(SectionName, ".fini_array.") || + hasPrefix(SectionName, ".preinit_array.")) + Flags |= ELF::SHF_ALLOC | ELF::SHF_WRITE; + if (hasPrefix(SectionName, ".tdata.") || + hasPrefix(SectionName, ".tbss.")) + Flags |= ELF::SHF_ALLOC | ELF::SHF_WRITE | ELF::SHF_TLS; if (getLexer().is(AsmToken::Comma)) { Lex(); @@ -422,65 +542,30 @@ bool ELFAsmParser::ParseSectionArguments(bool IsPush, SMLoc loc) { return TokError("Section cannot specifiy a group name while also acting " "as a member of the last group"); - if (getLexer().isNot(AsmToken::Comma)) { + if (maybeParseSectionType(TypeName)) + return true; + + MCAsmLexer &L = getLexer(); + if (TypeName.empty()) { if (Mergeable) return TokError("Mergeable section must specify the type"); if (Group) return TokError("Group section must specify the type"); - } else { - Lex(); - if (getLexer().is(AsmToken::At) || getLexer().is(AsmToken::Percent) || - getLexer().is(AsmToken::String)) { - if (!getLexer().is(AsmToken::String)) - Lex(); - } else - return TokError("expected '@<type>', '%<type>' or \"<type>\""); - - if (getParser().parseIdentifier(TypeName)) - return TokError("expected identifier in directive"); - - if (Mergeable) { - if (getLexer().isNot(AsmToken::Comma)) - return TokError("expected the entry size"); - Lex(); - if (getParser().parseAbsoluteExpression(Size)) - return true; - if (Size <= 0) - return TokError("entry size must be positive"); - } - - if (Group) { - if (getLexer().isNot(AsmToken::Comma)) - return TokError("expected group name"); - Lex(); - if (getParser().parseIdentifier(GroupName)) - return true; - if (getLexer().is(AsmToken::Comma)) { - Lex(); - StringRef Linkage; - if (getParser().parseIdentifier(Linkage)) - return true; - if (Linkage != "comdat") - return TokError("Linkage must be 'comdat'"); - } - } - if (getLexer().is(AsmToken::Comma)) { - Lex(); - if (getParser().parseIdentifier(UniqueStr)) - return TokError("expected identifier in directive"); - if (UniqueStr != "unique") - return TokError("expected 'unique'"); - if (getLexer().isNot(AsmToken::Comma)) - return TokError("expected commma"); - Lex(); - if (getParser().parseAbsoluteExpression(UniqueID)) - return true; - if (UniqueID < 0) - return TokError("unique id must be positive"); - if (!isUInt<32>(UniqueID) || UniqueID == ~0U) - return TokError("unique id is too large"); - } + if (L.isNot(AsmToken::EndOfStatement)) + return TokError("unexpected token in directive"); } + + if (Mergeable) + if (parseMergeSize(Size)) + return true; + if (Group) + if (parseGroup(GroupName)) + return true; + if (Flags & ELF::SHF_LINK_ORDER) + if (parseMetadataSym(Associated)) + return true; + if (maybeParseUniqueID(UniqueID)) + return true; } EndStmt: @@ -493,11 +578,15 @@ EndStmt: if (TypeName.empty()) { if (SectionName.startswith(".note")) Type = ELF::SHT_NOTE; - else if (SectionName == ".init_array") + else if (hasPrefix(SectionName, ".init_array.")) Type = ELF::SHT_INIT_ARRAY; - else if (SectionName == ".fini_array") + else if (hasPrefix(SectionName, ".bss.")) + Type = ELF::SHT_NOBITS; + else if (hasPrefix(SectionName, ".tbss.")) + Type = ELF::SHT_NOBITS; + else if (hasPrefix(SectionName, ".fini_array.")) Type = ELF::SHT_FINI_ARRAY; - else if (SectionName == ".preinit_array") + else if (hasPrefix(SectionName, ".preinit_array.")) Type = ELF::SHT_PREINIT_ARRAY; } else { if (TypeName == "init_array") @@ -514,7 +603,7 @@ EndStmt: Type = ELF::SHT_NOTE; else if (TypeName == "unwind") Type = ELF::SHT_X86_64_UNWIND; - else + else if (TypeName.getAsInteger(0, Type)) return TokError("unknown section type"); } @@ -528,8 +617,9 @@ EndStmt: } } - MCSection *ELFSection = getContext().getELFSection(SectionName, Type, Flags, - Size, GroupName, UniqueID); + MCSection *ELFSection = + getContext().getELFSection(SectionName, Type, Flags, Size, GroupName, + UniqueID, Associated); getStreamer().SwitchSection(ELFSection, Subsection); if (getContext().getGenDwarfForAssembly()) { @@ -677,6 +767,7 @@ bool ELFAsmParser::ParseDirectiveSymver(StringRef, SMLoc) { const MCExpr *Value = MCSymbolRefExpr::create(Sym, getContext()); getStreamer().EmitAssignment(Alias, Value); + getStreamer().emitELFSymverDirective(Alias, Sym); return false; } @@ -752,4 +843,4 @@ MCAsmParserExtension *createELFAsmParser() { return new ELFAsmParser; } -} +} // end namespace llvm |