summaryrefslogtreecommitdiff
path: root/lib/MC/MCParser/ELFAsmParser.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'lib/MC/MCParser/ELFAsmParser.cpp')
-rw-r--r--lib/MC/MCParser/ELFAsmParser.cpp108
1 files changed, 85 insertions, 23 deletions
diff --git a/lib/MC/MCParser/ELFAsmParser.cpp b/lib/MC/MCParser/ELFAsmParser.cpp
index 3e2150a451e0..67e3512cc5bd 100644
--- a/lib/MC/MCParser/ELFAsmParser.cpp
+++ b/lib/MC/MCParser/ELFAsmParser.cpp
@@ -85,6 +85,7 @@ public:
addDirectiveHandler<
&ELFAsmParser::ParseDirectiveSymbolAttribute>(".hidden");
addDirectiveHandler<&ELFAsmParser::ParseDirectiveSubsection>(".subsection");
+ addDirectiveHandler<&ELFAsmParser::ParseDirectiveCGProfile>(".cg_profile");
}
// FIXME: Part of this logic is duplicated in the MCELFStreamer. What is
@@ -149,6 +150,7 @@ public:
bool ParseDirectiveWeakref(StringRef, SMLoc);
bool ParseDirectiveSymbolAttribute(StringRef, SMLoc);
bool ParseDirectiveSubsection(StringRef, SMLoc);
+ bool ParseDirectiveCGProfile(StringRef, SMLoc);
private:
bool ParseSectionName(StringRef &SectionName);
@@ -380,7 +382,6 @@ bool ELFAsmParser::ParseDirectivePopSection(StringRef, SMLoc) {
return false;
}
-// FIXME: This is a work in progress.
bool ELFAsmParser::ParseDirectiveSection(StringRef, SMLoc loc) {
return ParseSectionArguments(/*IsPush=*/false, loc);
}
@@ -447,7 +448,7 @@ bool ELFAsmParser::parseMetadataSym(MCSymbolELF *&Associated) {
Lex();
StringRef Name;
if (getParser().parseIdentifier(Name))
- return true;
+ return TokError("invalid metadata symbol");
Associated = dyn_cast_or_null<MCSymbolELF>(getContext().lookupSymbol(Name));
if (!Associated || !Associated->isInSection())
return TokError("symbol is not in a section: " + Name);
@@ -480,6 +481,34 @@ static bool hasPrefix(StringRef SectionName, StringRef Prefix) {
return SectionName.startswith(Prefix) || SectionName == Prefix.drop_back();
}
+// Return a set of section flags based on the section name that can then
+// be augmented later, otherwise return 0 if we don't have any reasonable
+// defaults.
+static unsigned defaultSectionFlags(StringRef SectionName) {
+
+ if (hasPrefix(SectionName, ".rodata.cst"))
+ return ELF::SHF_ALLOC | ELF::SHF_MERGE;
+
+ if (hasPrefix(SectionName, ".rodata.") || SectionName == ".rodata1")
+ return ELF::SHF_ALLOC;
+
+ if (SectionName == ".fini" || SectionName == ".init" ||
+ hasPrefix(SectionName, ".text."))
+ return 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."))
+ return ELF::SHF_ALLOC | ELF::SHF_WRITE;
+
+ if (hasPrefix(SectionName, ".tdata.") || hasPrefix(SectionName, ".tbss."))
+ return ELF::SHF_ALLOC | ELF::SHF_WRITE | ELF::SHF_TLS;
+
+ return 0;
+}
+
bool ELFAsmParser::ParseSectionArguments(bool IsPush, SMLoc loc) {
StringRef SectionName;
@@ -489,27 +518,13 @@ bool ELFAsmParser::ParseSectionArguments(bool IsPush, SMLoc loc) {
StringRef TypeName;
int64_t Size = 0;
StringRef GroupName;
- unsigned Flags = 0;
const MCExpr *Subsection = nullptr;
bool UseLastGroup = false;
MCSymbolELF *Associated = nullptr;
int64_t UniqueID = ~0;
- // Set the defaults first.
- if (hasPrefix(SectionName, ".rodata.") || SectionName == ".rodata1")
- Flags |= ELF::SHF_ALLOC;
- 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;
+ // Set the default section flags first in case no others are given.
+ unsigned Flags = defaultSectionFlags(SectionName);
if (getLexer().is(AsmToken::Comma)) {
Lex();
@@ -537,6 +552,12 @@ bool ELFAsmParser::ParseSectionArguments(bool IsPush, SMLoc loc) {
if (extraFlags == -1U)
return TokError("unknown flag");
+
+ // If we found additional section flags on a known section then give a
+ // warning.
+ if (Flags && Flags != extraFlags)
+ Warning(loc, "setting incorrect section attributes for " + SectionName);
+
Flags |= extraFlags;
bool Mergeable = Flags & ELF::SHF_MERGE;
@@ -608,6 +629,10 @@ EndStmt:
Type = ELF::SHT_X86_64_UNWIND;
else if (TypeName == "llvm_odrtab")
Type = ELF::SHT_LLVM_ODRTAB;
+ else if (TypeName == "llvm_linker_options")
+ Type = ELF::SHT_LLVM_LINKER_OPTIONS;
+ else if (TypeName == "llvm_call_graph_profile")
+ Type = ELF::SHT_LLVM_CALL_GRAPH_PROFILE;
else if (TypeName.getAsInteger(0, Type))
return TokError("unknown section type");
}
@@ -767,12 +792,8 @@ bool ELFAsmParser::ParseDirectiveSymver(StringRef, SMLoc) {
if (AliasName.find('@') == StringRef::npos)
return TokError("expected a '@' in the name");
- MCSymbol *Alias = getContext().getOrCreateSymbol(AliasName);
MCSymbol *Sym = getContext().getOrCreateSymbol(Name);
- const MCExpr *Value = MCSymbolRefExpr::create(Sym, getContext());
-
- getStreamer().EmitAssignment(Alias, Value);
- getStreamer().emitELFSymverDirective(Alias, Sym);
+ getStreamer().emitELFSymverDirective(AliasName, Sym);
return false;
}
@@ -842,6 +863,47 @@ bool ELFAsmParser::ParseDirectiveSubsection(StringRef, SMLoc) {
return false;
}
+/// ParseDirectiveCGProfile
+/// ::= .cg_profile identifier, identifier, <number>
+bool ELFAsmParser::ParseDirectiveCGProfile(StringRef, SMLoc) {
+ StringRef From;
+ SMLoc FromLoc = getLexer().getLoc();
+ if (getParser().parseIdentifier(From))
+ return TokError("expected identifier in directive");
+
+ if (getLexer().isNot(AsmToken::Comma))
+ return TokError("expected a comma");
+ Lex();
+
+ StringRef To;
+ SMLoc ToLoc = getLexer().getLoc();
+ if (getParser().parseIdentifier(To))
+ return TokError("expected identifier in directive");
+
+ if (getLexer().isNot(AsmToken::Comma))
+ return TokError("expected a comma");
+ Lex();
+
+ int64_t Count;
+ if (getParser().parseIntToken(
+ Count, "expected integer count in '.cg_profile' directive"))
+ return true;
+
+ if (getLexer().isNot(AsmToken::EndOfStatement))
+ return TokError("unexpected token in directive");
+
+ MCSymbol *FromSym = getContext().getOrCreateSymbol(From);
+ MCSymbol *ToSym = getContext().getOrCreateSymbol(To);
+
+ getStreamer().emitCGProfileEntry(
+ MCSymbolRefExpr::create(FromSym, MCSymbolRefExpr::VK_None, getContext(),
+ FromLoc),
+ MCSymbolRefExpr::create(ToSym, MCSymbolRefExpr::VK_None, getContext(),
+ ToLoc),
+ Count);
+ return false;
+}
+
namespace llvm {
MCAsmParserExtension *createELFAsmParser() {