summaryrefslogtreecommitdiff
path: root/lib/MC/MCParser
diff options
context:
space:
mode:
authorKevin Enderby <enderby@apple.com>2013-08-28 17:50:59 +0000
committerKevin Enderby <enderby@apple.com>2013-08-28 17:50:59 +0000
commit4f066b6db8a7a95b206725aecf99a64fd6e9415c (patch)
tree76d28f54ec99c6c9b5e2bd3bc95b2d154e26bf76 /lib/MC/MCParser
parent980879e618d32f7516aa3bbf1ee084b06e52d0ef (diff)
downloadllvm-4f066b6db8a7a95b206725aecf99a64fd6e9415c.tar.gz
llvm-4f066b6db8a7a95b206725aecf99a64fd6e9415c.tar.bz2
llvm-4f066b6db8a7a95b206725aecf99a64fd6e9415c.tar.xz
The integrated darwin assembler can hang in an infinite loop (or get an assert
with a debug build) with this buggy .indirect_symbol directive usage: % cat test.s x: .indirect_symbol _y The assertion is because it is trying to get the symbol index for the symbol _y when it is writing out the indirect symbol table. This line of code in MachObjectWriter::WriteObject() : Write32(Asm.getSymbolData(*it->Symbol).getIndex()); And while there is a symbol _y it does not have any getSymbolData set which is only done in MachObjectWriter::BindIndirectSymbols() for pointer sections or stub sections. I added a check and an error in there to catch this in case something slips through. But to get a better error the parser should detect when a .indirect_symbol directive is used and it is not in a pointer section or stub section. To make that work I moved the handling of the indirect symbol out of the target independent AsmParser code into the DarwinAsmParser code that can check for the proper Mach-O section types. rdar://14825505 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@189497 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/MC/MCParser')
-rw-r--r--lib/MC/MCParser/AsmParser.cpp5
-rw-r--r--lib/MC/MCParser/DarwinAsmParser.cpp36
2 files changed, 37 insertions, 4 deletions
diff --git a/lib/MC/MCParser/AsmParser.cpp b/lib/MC/MCParser/AsmParser.cpp
index 0255c227bd..31a09a967c 100644
--- a/lib/MC/MCParser/AsmParser.cpp
+++ b/lib/MC/MCParser/AsmParser.cpp
@@ -342,7 +342,7 @@ private:
DK_FLOAT, DK_DOUBLE, DK_ALIGN, DK_ALIGN32, DK_BALIGN, DK_BALIGNW,
DK_BALIGNL, DK_P2ALIGN, DK_P2ALIGNW, DK_P2ALIGNL, DK_ORG, DK_FILL, DK_ENDR,
DK_BUNDLE_ALIGN_MODE, DK_BUNDLE_LOCK, DK_BUNDLE_UNLOCK,
- DK_ZERO, DK_EXTERN, DK_GLOBL, DK_GLOBAL, DK_INDIRECT_SYMBOL,
+ DK_ZERO, DK_EXTERN, DK_GLOBL, DK_GLOBAL,
DK_LAZY_REFERENCE, DK_NO_DEAD_STRIP, DK_SYMBOL_RESOLVER, DK_PRIVATE_EXTERN,
DK_REFERENCE, DK_WEAK_DEFINITION, DK_WEAK_REFERENCE,
DK_WEAK_DEF_CAN_BE_HIDDEN, DK_COMM, DK_COMMON, DK_LCOMM, DK_ABORT,
@@ -1365,8 +1365,6 @@ bool AsmParser::ParseStatement(ParseStatementInfo &Info) {
case DK_GLOBL:
case DK_GLOBAL:
return ParseDirectiveSymbolAttribute(MCSA_Global);
- case DK_INDIRECT_SYMBOL:
- return ParseDirectiveSymbolAttribute(MCSA_IndirectSymbol);
case DK_LAZY_REFERENCE:
return ParseDirectiveSymbolAttribute(MCSA_LazyReference);
case DK_NO_DEAD_STRIP:
@@ -3755,7 +3753,6 @@ void AsmParser::initializeDirectiveKindMap() {
DirectiveKindMap[".extern"] = DK_EXTERN;
DirectiveKindMap[".globl"] = DK_GLOBL;
DirectiveKindMap[".global"] = DK_GLOBAL;
- DirectiveKindMap[".indirect_symbol"] = DK_INDIRECT_SYMBOL;
DirectiveKindMap[".lazy_reference"] = DK_LAZY_REFERENCE;
DirectiveKindMap[".no_dead_strip"] = DK_NO_DEAD_STRIP;
DirectiveKindMap[".symbol_resolver"] = DK_SYMBOL_RESOLVER;
diff --git a/lib/MC/MCParser/DarwinAsmParser.cpp b/lib/MC/MCParser/DarwinAsmParser.cpp
index 0aeeaf6cfa..f08270c152 100644
--- a/lib/MC/MCParser/DarwinAsmParser.cpp
+++ b/lib/MC/MCParser/DarwinAsmParser.cpp
@@ -45,6 +45,8 @@ public:
this->MCAsmParserExtension::Initialize(Parser);
addDirectiveHandler<&DarwinAsmParser::ParseDirectiveDesc>(".desc");
+ addDirectiveHandler<&DarwinAsmParser::ParseDirectiveIndirectSymbol>(
+ ".indirect_symbol");
addDirectiveHandler<&DarwinAsmParser::ParseDirectiveLsym>(".lsym");
addDirectiveHandler<&DarwinAsmParser::ParseDirectiveSubsectionsViaSymbols>(
".subsections_via_symbols");
@@ -163,6 +165,7 @@ public:
}
bool ParseDirectiveDesc(StringRef, SMLoc);
+ bool ParseDirectiveIndirectSymbol(StringRef, SMLoc);
bool ParseDirectiveDumpOrLoad(StringRef, SMLoc);
bool ParseDirectiveLsym(StringRef, SMLoc);
bool ParseDirectiveLinkerOption(StringRef, SMLoc);
@@ -415,6 +418,39 @@ bool DarwinAsmParser::ParseDirectiveDesc(StringRef, SMLoc) {
return false;
}
+/// ParseDirectiveIndirectSymbol
+/// ::= .indirect_symbol identifier
+bool DarwinAsmParser::ParseDirectiveIndirectSymbol(StringRef, SMLoc Loc) {
+ const MCSectionMachO *Current = static_cast<const MCSectionMachO*>(
+ getStreamer().getCurrentSection().first);
+ unsigned SectionType = Current->getType();
+ if (SectionType != MCSectionMachO::S_NON_LAZY_SYMBOL_POINTERS &&
+ SectionType != MCSectionMachO::S_LAZY_SYMBOL_POINTERS &&
+ SectionType != MCSectionMachO::S_SYMBOL_STUBS)
+ return Error(Loc, "indirect symbol not in a symbol pointer or stub "
+ "section");
+
+ StringRef Name;
+ if (getParser().parseIdentifier(Name))
+ return TokError("expected identifier in .indirect_symbol directive");
+
+ MCSymbol *Sym = getContext().GetOrCreateSymbol(Name);
+
+ // Assembler local symbols don't make any sense here. Complain loudly.
+ if (Sym->isTemporary())
+ return TokError("non-local symbol required in directive");
+
+ if (!getStreamer().EmitSymbolAttribute(Sym, MCSA_IndirectSymbol))
+ return TokError("unable to emit indirect symbol attribute for: " + Name);
+
+ if (getLexer().isNot(AsmToken::EndOfStatement))
+ return TokError("unexpected token in '.indirect_symbol' directive");
+
+ Lex();
+
+ return false;
+}
+
/// ParseDirectiveDumpOrLoad
/// ::= ( .dump | .load ) "filename"
bool DarwinAsmParser::ParseDirectiveDumpOrLoad(StringRef Directive,