diff options
author | Kevin Enderby <enderby@apple.com> | 2013-08-28 17:50:59 +0000 |
---|---|---|
committer | Kevin Enderby <enderby@apple.com> | 2013-08-28 17:50:59 +0000 |
commit | 4f066b6db8a7a95b206725aecf99a64fd6e9415c (patch) | |
tree | 76d28f54ec99c6c9b5e2bd3bc95b2d154e26bf76 /lib/MC | |
parent | 980879e618d32f7516aa3bbf1ee084b06e52d0ef (diff) | |
download | llvm-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')
-rw-r--r-- | lib/MC/MCParser/AsmParser.cpp | 5 | ||||
-rw-r--r-- | lib/MC/MCParser/DarwinAsmParser.cpp | 36 | ||||
-rw-r--r-- | lib/MC/MachObjectWriter.cpp | 16 |
3 files changed, 53 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, diff --git a/lib/MC/MachObjectWriter.cpp b/lib/MC/MachObjectWriter.cpp index a5ba3c3653..3c1888c153 100644 --- a/lib/MC/MachObjectWriter.cpp +++ b/lib/MC/MachObjectWriter.cpp @@ -428,6 +428,22 @@ void MachObjectWriter::BindIndirectSymbols(MCAssembler &Asm) { // // FIXME: Revisit this when the dust settles. + // Report errors for use of .indirect_symbol not in a symbol pointer section + // or stub section. + for (MCAssembler::indirect_symbol_iterator it = Asm.indirect_symbol_begin(), + ie = Asm.indirect_symbol_end(); it != ie; ++it) { + const MCSectionMachO &Section = + cast<MCSectionMachO>(it->SectionData->getSection()); + + if (Section.getType() != MCSectionMachO::S_NON_LAZY_SYMBOL_POINTERS && + Section.getType() != MCSectionMachO::S_LAZY_SYMBOL_POINTERS && + Section.getType() != MCSectionMachO::S_SYMBOL_STUBS) { + MCSymbol &Symbol = *it->Symbol; + report_fatal_error("indirect symbol '" + Symbol.getName() + + "' not in a symbol pointer or stub section"); + } + } + // Bind non lazy symbol pointers first. unsigned IndirectIndex = 0; for (MCAssembler::indirect_symbol_iterator it = Asm.indirect_symbol_begin(), |