From 1c9cd021c8999d9c2c0786dff074d1e75bbd0eb2 Mon Sep 17 00:00:00 2001 From: Saleem Abdulrasool Date: Fri, 9 Aug 2013 01:52:03 +0000 Subject: [CodeGen] prevent abnormal on invalid attributes Currently, when an invalid attribute is encountered on processing a .s file, clang will abort due to llvm_unreachable. Invalid user input should not cause an abnormal termination of the compiler. Change the interface to return a boolean to indicate the failure as a first step towards improving hanlding of malformed user input to clang. Signed-off-by: Saleem Abdulrasool git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@188047 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/llvm/MC/MCELFStreamer.h | 2 +- include/llvm/MC/MCStreamer.h | 2 +- lib/MC/MCAsmStreamer.cpp | 13 ++++++++----- lib/MC/MCELFStreamer.cpp | 10 ++++++---- lib/MC/MCMachOStreamer.cpp | 10 ++++++---- lib/MC/MCNullStreamer.cpp | 4 +++- lib/MC/MCParser/AsmParser.cpp | 3 ++- lib/MC/MCPureStreamer.cpp | 3 ++- lib/MC/WinCOFFStreamer.cpp | 8 +++++--- tools/lto/LTOModule.cpp | 3 ++- 10 files changed, 36 insertions(+), 22 deletions(-) diff --git a/include/llvm/MC/MCELFStreamer.h b/include/llvm/MC/MCELFStreamer.h index 7565c153f0..bff0cbad5b 100644 --- a/include/llvm/MC/MCELFStreamer.h +++ b/include/llvm/MC/MCELFStreamer.h @@ -57,7 +57,7 @@ public: virtual void EmitAssemblerFlag(MCAssemblerFlag Flag); virtual void EmitThumbFunc(MCSymbol *Func); virtual void EmitWeakReference(MCSymbol *Alias, const MCSymbol *Symbol); - virtual void EmitSymbolAttribute(MCSymbol *Symbol, MCSymbolAttr Attribute); + virtual bool EmitSymbolAttribute(MCSymbol *Symbol, MCSymbolAttr Attribute); virtual void EmitSymbolDesc(MCSymbol *Symbol, unsigned DescValue); virtual void EmitCommonSymbol(MCSymbol *Symbol, uint64_t Size, unsigned ByteAlignment); diff --git a/include/llvm/MC/MCStreamer.h b/include/llvm/MC/MCStreamer.h index 970c4ed99c..96b32cd358 100644 --- a/include/llvm/MC/MCStreamer.h +++ b/include/llvm/MC/MCStreamer.h @@ -323,7 +323,7 @@ namespace llvm { virtual void EmitWeakReference(MCSymbol *Alias, const MCSymbol *Symbol) = 0; /// EmitSymbolAttribute - Add the given @p Attribute to @p Symbol. - virtual void EmitSymbolAttribute(MCSymbol *Symbol, + virtual bool EmitSymbolAttribute(MCSymbol *Symbol, MCSymbolAttr Attribute) = 0; /// EmitSymbolDesc - Set the @p DescValue for the @p Symbol. diff --git a/lib/MC/MCAsmStreamer.cpp b/lib/MC/MCAsmStreamer.cpp index 781e40052b..60d72abbcb 100644 --- a/lib/MC/MCAsmStreamer.cpp +++ b/lib/MC/MCAsmStreamer.cpp @@ -154,7 +154,7 @@ public: virtual void EmitDwarfAdvanceFrameAddr(const MCSymbol *LastLabel, const MCSymbol *Label); - virtual void EmitSymbolAttribute(MCSymbol *Symbol, MCSymbolAttr Attribute); + virtual bool EmitSymbolAttribute(MCSymbol *Symbol, MCSymbolAttr Attribute); virtual void EmitSymbolDesc(MCSymbol *Symbol, unsigned DescValue); virtual void BeginCOFFSymbolDef(const MCSymbol *Symbol); @@ -436,7 +436,7 @@ void MCAsmStreamer::EmitDwarfAdvanceFrameAddr(const MCSymbol *LastLabel, } -void MCAsmStreamer::EmitSymbolAttribute(MCSymbol *Symbol, +bool MCAsmStreamer::EmitSymbolAttribute(MCSymbol *Symbol, MCSymbolAttr Attribute) { switch (Attribute) { case MCSA_Invalid: llvm_unreachable("Invalid symbol attribute"); @@ -447,11 +447,12 @@ void MCAsmStreamer::EmitSymbolAttribute(MCSymbol *Symbol, case MCSA_ELF_TypeCommon: /// .type _foo, STT_COMMON # aka @common case MCSA_ELF_TypeNoType: /// .type _foo, STT_NOTYPE # aka @notype case MCSA_ELF_TypeGnuUniqueObject: /// .type _foo, @gnu_unique_object - assert(MAI->hasDotTypeDotSizeDirective() && "Symbol Attr not supported"); + if (!MAI->hasDotTypeDotSizeDirective()) + return false; // Symbol attribute not supported OS << "\t.type\t" << *Symbol << ',' << ((MAI->getCommentString()[0] != '@') ? '@' : '%'); switch (Attribute) { - default: llvm_unreachable("Unknown ELF .type"); + default: return false; case MCSA_ELF_TypeFunction: OS << "function"; break; case MCSA_ELF_TypeIndFunction: OS << "gnu_indirect_function"; break; case MCSA_ELF_TypeObject: OS << "object"; break; @@ -461,7 +462,7 @@ void MCAsmStreamer::EmitSymbolAttribute(MCSymbol *Symbol, case MCSA_ELF_TypeGnuUniqueObject: OS << "gnu_unique_object"; break; } EmitEOL(); - return; + return true; case MCSA_Global: // .globl/.global OS << MAI->getGlobalDirective(); FlagMap[Symbol] |= EHGlobal; @@ -491,6 +492,8 @@ void MCAsmStreamer::EmitSymbolAttribute(MCSymbol *Symbol, OS << *Symbol; EmitEOL(); + + return true; } void MCAsmStreamer::EmitSymbolDesc(MCSymbol *Symbol, unsigned DescValue) { diff --git a/lib/MC/MCELFStreamer.cpp b/lib/MC/MCELFStreamer.cpp index 6e5ff50e37..4661d503c3 100644 --- a/lib/MC/MCELFStreamer.cpp +++ b/lib/MC/MCELFStreamer.cpp @@ -148,8 +148,8 @@ static unsigned CombineSymbolTypes(unsigned T1, unsigned T2) { return T2; } -void MCELFStreamer::EmitSymbolAttribute(MCSymbol *Symbol, - MCSymbolAttr Attribute) { +bool MCELFStreamer::EmitSymbolAttribute(MCSymbol *Symbol, + MCSymbolAttr Attribute) { // Indirect symbols are handled differently, to match how 'as' handles // them. This makes writing matching .o files easier. if (Attribute == MCSA_IndirectSymbol) { @@ -159,7 +159,7 @@ void MCELFStreamer::EmitSymbolAttribute(MCSymbol *Symbol, ISD.Symbol = Symbol; ISD.SectionData = getCurrentSectionData(); getAssembler().getIndirectSymbols().push_back(ISD); - return; + return true; } // Adding a symbol attribute always introduces the symbol, note that an @@ -182,7 +182,7 @@ void MCELFStreamer::EmitSymbolAttribute(MCSymbol *Symbol, case MCSA_WeakDefAutoPrivate: case MCSA_Invalid: case MCSA_IndirectSymbol: - llvm_unreachable("Invalid symbol attribute for ELF!"); + return false; case MCSA_NoDeadStrip: case MCSA_ELF_TypeGnuUniqueObject: @@ -251,6 +251,8 @@ void MCELFStreamer::EmitSymbolAttribute(MCSymbol *Symbol, MCELF::SetVisibility(SD, ELF::STV_INTERNAL); break; } + + return true; } void MCELFStreamer::EmitCommonSymbol(MCSymbol *Symbol, uint64_t Size, diff --git a/lib/MC/MCMachOStreamer.cpp b/lib/MC/MCMachOStreamer.cpp index 0729b7a2f2..bf8c561ea6 100644 --- a/lib/MC/MCMachOStreamer.cpp +++ b/lib/MC/MCMachOStreamer.cpp @@ -51,7 +51,7 @@ public: virtual void EmitLinkerOptions(ArrayRef Options); virtual void EmitDataRegion(MCDataRegionType Kind); virtual void EmitThumbFunc(MCSymbol *Func); - virtual void EmitSymbolAttribute(MCSymbol *Symbol, MCSymbolAttr Attribute); + virtual bool EmitSymbolAttribute(MCSymbol *Symbol, MCSymbolAttr Attribute); virtual void EmitSymbolDesc(MCSymbol *Symbol, unsigned DescValue); virtual void EmitCommonSymbol(MCSymbol *Symbol, uint64_t Size, unsigned ByteAlignment); @@ -217,7 +217,7 @@ void MCMachOStreamer::EmitThumbFunc(MCSymbol *Symbol) { SD.setFlags(SD.getFlags() | SF_ThumbFunc); } -void MCMachOStreamer::EmitSymbolAttribute(MCSymbol *Symbol, +bool MCMachOStreamer::EmitSymbolAttribute(MCSymbol *Symbol, MCSymbolAttr Attribute) { // Indirect symbols are handled differently, to match how 'as' handles // them. This makes writing matching .o files easier. @@ -228,7 +228,7 @@ void MCMachOStreamer::EmitSymbolAttribute(MCSymbol *Symbol, ISD.Symbol = Symbol; ISD.SectionData = getCurrentSectionData(); getAssembler().getIndirectSymbols().push_back(ISD); - return; + return true; } // Adding a symbol attribute always introduces the symbol, note that an @@ -257,7 +257,7 @@ void MCMachOStreamer::EmitSymbolAttribute(MCSymbol *Symbol, case MCSA_Protected: case MCSA_Weak: case MCSA_Local: - llvm_unreachable("Invalid symbol attribute for Mach-O!"); + return false; case MCSA_Global: SD.setExternal(true); @@ -309,6 +309,8 @@ void MCMachOStreamer::EmitSymbolAttribute(MCSymbol *Symbol, SD.setFlags(SD.getFlags() | SF_WeakDefinition | SF_WeakReference); break; } + + return true; } void MCMachOStreamer::EmitSymbolDesc(MCSymbol *Symbol, unsigned DescValue) { diff --git a/lib/MC/MCNullStreamer.cpp b/lib/MC/MCNullStreamer.cpp index 530c6469e0..87a7db69cd 100644 --- a/lib/MC/MCNullStreamer.cpp +++ b/lib/MC/MCNullStreamer.cpp @@ -52,7 +52,9 @@ namespace { const MCSymbol *Label, unsigned PointerSize) {} - virtual void EmitSymbolAttribute(MCSymbol *Symbol, MCSymbolAttr Attribute){} + virtual bool EmitSymbolAttribute(MCSymbol *Symbol, MCSymbolAttr Attribute){ + return true; + } virtual void EmitSymbolDesc(MCSymbol *Symbol, unsigned DescValue) {} diff --git a/lib/MC/MCParser/AsmParser.cpp b/lib/MC/MCParser/AsmParser.cpp index dd0d181b6f..07796dd6b0 100644 --- a/lib/MC/MCParser/AsmParser.cpp +++ b/lib/MC/MCParser/AsmParser.cpp @@ -3375,7 +3375,8 @@ bool AsmParser::ParseDirectiveSymbolAttribute(MCSymbolAttr Attr) { if (Sym->isTemporary()) return Error(Loc, "non-local symbol required in directive"); - getStreamer().EmitSymbolAttribute(Sym, Attr); + if (!getStreamer().EmitSymbolAttribute(Sym, Attr)) + return Error(Loc, "unable to emit symbol attribute"); if (getLexer().is(AsmToken::EndOfStatement)) break; diff --git a/lib/MC/MCPureStreamer.cpp b/lib/MC/MCPureStreamer.cpp index c5c3bb7055..c6c772c6e2 100644 --- a/lib/MC/MCPureStreamer.cpp +++ b/lib/MC/MCPureStreamer.cpp @@ -51,8 +51,9 @@ public: virtual void FinishImpl(); - virtual void EmitSymbolAttribute(MCSymbol *Symbol, MCSymbolAttr Attribute) { + virtual bool EmitSymbolAttribute(MCSymbol *Symbol, MCSymbolAttr Attribute) { report_fatal_error("unsupported directive in pure streamer"); + return false; } virtual void EmitAssemblerFlag(MCAssemblerFlag Flag) { report_fatal_error("unsupported directive in pure streamer"); diff --git a/lib/MC/WinCOFFStreamer.cpp b/lib/MC/WinCOFFStreamer.cpp index 04bfeb4c2b..3f0449dc46 100644 --- a/lib/MC/WinCOFFStreamer.cpp +++ b/lib/MC/WinCOFFStreamer.cpp @@ -55,7 +55,7 @@ public: virtual void EmitDebugLabel(MCSymbol *Symbol); virtual void EmitAssemblerFlag(MCAssemblerFlag Flag); virtual void EmitThumbFunc(MCSymbol *Func); - virtual void EmitSymbolAttribute(MCSymbol *Symbol, MCSymbolAttr Attribute); + virtual bool EmitSymbolAttribute(MCSymbol *Symbol, MCSymbolAttr Attribute); virtual void EmitSymbolDesc(MCSymbol *Symbol, unsigned DescValue); virtual void BeginCOFFSymbolDef(MCSymbol const *Symbol); virtual void EmitCOFFSymbolStorageClass(int StorageClass); @@ -201,7 +201,7 @@ void WinCOFFStreamer::EmitThumbFunc(MCSymbol *Func) { llvm_unreachable("not implemented"); } -void WinCOFFStreamer::EmitSymbolAttribute(MCSymbol *Symbol, +bool WinCOFFStreamer::EmitSymbolAttribute(MCSymbol *Symbol, MCSymbolAttr Attribute) { assert(Symbol && "Symbol must be non-null!"); assert((Symbol->isInSection() @@ -221,8 +221,10 @@ void WinCOFFStreamer::EmitSymbolAttribute(MCSymbol *Symbol, break; default: - llvm_unreachable("unsupported attribute"); + return false; } + + return true; } void WinCOFFStreamer::EmitSymbolDesc(MCSymbol *Symbol, unsigned DescValue) { diff --git a/tools/lto/LTOModule.cpp b/tools/lto/LTOModule.cpp index e89733f587..1812346077 100644 --- a/tools/lto/LTOModule.cpp +++ b/tools/lto/LTOModule.cpp @@ -738,9 +738,10 @@ namespace { // FIXME: should we handle aliases? markDefined(*Symbol); } - virtual void EmitSymbolAttribute(MCSymbol *Symbol, MCSymbolAttr Attribute) { + virtual bool EmitSymbolAttribute(MCSymbol *Symbol, MCSymbolAttr Attribute) { if (Attribute == MCSA_Global) markGlobal(*Symbol); + return true; } virtual void EmitZerofill(const MCSection *Section, MCSymbol *Symbol, uint64_t Size , unsigned ByteAlignment) { -- cgit v1.2.3