diff options
author | Oliver Stannard <oliver.stannard@arm.com> | 2015-11-17 10:00:43 +0000 |
---|---|---|
committer | Oliver Stannard <oliver.stannard@arm.com> | 2015-11-17 10:00:43 +0000 |
commit | 9be59af3abe0b3bbee54e46720a75c96723da6cb (patch) | |
tree | d7b87d3a7144c56e73294288efcbd24109e3426e /llvm/lib/MC | |
parent | 07b43d39a8ef5be442210c5ca21c780c19db0683 (diff) | |
download | bcm5719-llvm-9be59af3abe0b3bbee54e46720a75c96723da6cb.tar.gz bcm5719-llvm-9be59af3abe0b3bbee54e46720a75c96723da6cb.zip |
[Assembler] Make fatal assembler errors non-fatal
Currently, if the assembler encounters an error after parsing (such as an
out-of-range fixup), it reports this as a fatal error, and so stops after the
first error. However, for most of these there is an obvious way to recover
after emitting the error, such as emitting the fixup with a value of zero. This
means that we can report on all of the errors in a file, not just the first
one. MCContext::reportError records the fact that an error was encountered, so
we won't actually emit an object file with the incorrect contents.
Differential Revision: http://reviews.llvm.org/D14717
llvm-svn: 253328
Diffstat (limited to 'llvm/lib/MC')
-rw-r--r-- | llvm/lib/MC/ELFObjectWriter.cpp | 30 | ||||
-rw-r--r-- | llvm/lib/MC/MCAssembler.cpp | 29 | ||||
-rw-r--r-- | llvm/lib/MC/WinCOFFObjectWriter.cpp | 21 | ||||
-rw-r--r-- | llvm/lib/MC/WinCOFFStreamer.cpp | 35 |
4 files changed, 75 insertions, 40 deletions
diff --git a/llvm/lib/MC/ELFObjectWriter.cpp b/llvm/lib/MC/ELFObjectWriter.cpp index 230d3d775b1..df7a606a717 100644 --- a/llvm/lib/MC/ELFObjectWriter.cpp +++ b/llvm/lib/MC/ELFObjectWriter.cpp @@ -630,28 +630,36 @@ void ELFObjectWriter::recordRelocation(MCAssembler &Asm, // In general, ELF has no relocations for -B. It can only represent (A + C) // or (A + C - R). If B = R + K and the relocation is not pcrel, we can // replace B to implement it: (A - R - K + C) - if (IsPCRel) - Asm.getContext().reportFatalError( + if (IsPCRel) { + Asm.getContext().reportError( Fixup.getLoc(), "No relocation available to represent this relative expression"); + return; + } const auto &SymB = cast<MCSymbolELF>(RefB->getSymbol()); - if (SymB.isUndefined()) - Asm.getContext().reportFatalError( + if (SymB.isUndefined()) { + Asm.getContext().reportError( Fixup.getLoc(), Twine("symbol '") + SymB.getName() + "' can not be undefined in a subtraction expression"); + return; + } assert(!SymB.isAbsolute() && "Should have been folded"); const MCSection &SecB = SymB.getSection(); - if (&SecB != &FixupSection) - Asm.getContext().reportFatalError( + if (&SecB != &FixupSection) { + Asm.getContext().reportError( Fixup.getLoc(), "Cannot represent a difference across sections"); + return; + } - if (::isWeak(SymB)) - Asm.getContext().reportFatalError( + if (::isWeak(SymB)) { + Asm.getContext().reportError( Fixup.getLoc(), "Cannot represent a subtraction with a weak symbol"); + return; + } uint64_t SymBOffset = Layout.getSymbolOffset(SymB); uint64_t K = SymBOffset - FixupOffset; @@ -784,8 +792,10 @@ void ELFObjectWriter::computeSymbolTable( Renames.count(&Symbol))) continue; - if (Symbol.isTemporary() && Symbol.isUndefined()) - Ctx.reportFatalError(SMLoc(), "Undefined temporary"); + if (Symbol.isTemporary() && Symbol.isUndefined()) { + Ctx.reportError(SMLoc(), "Undefined temporary symbol"); + continue; + } ELFSymbolData MSD; MSD.Symbol = cast<MCSymbolELF>(&Symbol); diff --git a/llvm/lib/MC/MCAssembler.cpp b/llvm/lib/MC/MCAssembler.cpp index 06f65fcb49a..9f3ab18a40b 100644 --- a/llvm/lib/MC/MCAssembler.cpp +++ b/llvm/lib/MC/MCAssembler.cpp @@ -179,14 +179,19 @@ const MCSymbol *MCAsmLayout::getBaseSymbol(const MCSymbol &Symbol) const { const MCExpr *Expr = Symbol.getVariableValue(); MCValue Value; - if (!Expr->evaluateAsValue(Value, *this)) - llvm_unreachable("Invalid Expression"); + if (!Expr->evaluateAsValue(Value, *this)) { + Assembler.getContext().reportError( + SMLoc(), "expression could not be evaluated"); + return nullptr; + } const MCSymbolRefExpr *RefB = Value.getSymB(); - if (RefB) - Assembler.getContext().reportFatalError( + if (RefB) { + Assembler.getContext().reportError( SMLoc(), Twine("symbol '") + RefB->getSymbol().getName() + "' could not be evaluated in a subtraction expression"); + return nullptr; + } const MCSymbolRefExpr *A = Value.getSymA(); if (!A) @@ -196,9 +201,10 @@ const MCSymbol *MCAsmLayout::getBaseSymbol(const MCSymbol &Symbol) const { const MCAssembler &Asm = getAssembler(); if (ASym.isCommon()) { // FIXME: we should probably add a SMLoc to MCExpr. - Asm.getContext().reportFatalError(SMLoc(), - "Common symbol " + ASym.getName() + - " cannot be used in assignment expr"); + Asm.getContext().reportError(SMLoc(), + "Common symbol '" + ASym.getName() + + "' cannot be used in assignment expr"); + return nullptr; } return &ASym; @@ -436,8 +442,13 @@ bool MCAssembler::evaluateFixup(const MCAsmLayout &Layout, // probably merge the two into a single callback that tries to evaluate a // fixup and records a relocation if one is needed. const MCExpr *Expr = Fixup.getValue(); - if (!Expr->evaluateAsRelocatable(Target, &Layout, &Fixup)) - getContext().reportFatalError(Fixup.getLoc(), "expected relocatable expression"); + if (!Expr->evaluateAsRelocatable(Target, &Layout, &Fixup)) { + getContext().reportError(Fixup.getLoc(), "expected relocatable expression"); + // Claim to have completely evaluated the fixup, to prevent any further + // processing from being done. + Value = 0; + return true; + } bool IsPCRel = Backend.getFixupKindInfo( Fixup.getKind()).Flags & MCFixupKindInfo::FKF_IsPCRel; diff --git a/llvm/lib/MC/WinCOFFObjectWriter.cpp b/llvm/lib/MC/WinCOFFObjectWriter.cpp index 8d4d3df21ab..7eb470353b7 100644 --- a/llvm/lib/MC/WinCOFFObjectWriter.cpp +++ b/llvm/lib/MC/WinCOFFObjectWriter.cpp @@ -706,14 +706,17 @@ void WinCOFFObjectWriter::recordRelocation( const MCSymbol &Symbol = Target.getSymA()->getSymbol(); const MCSymbol &A = Symbol; - if (!A.isRegistered()) - Asm.getContext().reportFatalError(Fixup.getLoc(), + if (!A.isRegistered()) { + Asm.getContext().reportError(Fixup.getLoc(), Twine("symbol '") + A.getName() + "' can not be undefined"); + return; + } if (A.isTemporary() && A.isUndefined()) { - Asm.getContext().reportFatalError(Fixup.getLoc(), + Asm.getContext().reportError(Fixup.getLoc(), Twine("assembler label '") + A.getName() + "' can not be undefined"); + return; } MCSection *Section = Fragment->getParent(); @@ -731,17 +734,21 @@ void WinCOFFObjectWriter::recordRelocation( if (SymB) { const MCSymbol *B = &SymB->getSymbol(); - if (!B->getFragment()) - Asm.getContext().reportFatalError( + if (!B->getFragment()) { + Asm.getContext().reportError( Fixup.getLoc(), Twine("symbol '") + B->getName() + "' can not be undefined in a subtraction expression"); + return; + } - if (!A.getFragment()) - Asm.getContext().reportFatalError( + if (!A.getFragment()) { + Asm.getContext().reportError( Fixup.getLoc(), Twine("symbol '") + Symbol.getName() + "' can not be undefined in a subtraction expression"); + return; + } CrossSection = &Symbol.getSection() != &B->getSection(); diff --git a/llvm/lib/MC/WinCOFFStreamer.cpp b/llvm/lib/MC/WinCOFFStreamer.cpp index 02814fa7d28..a38b1a41a9b 100644 --- a/llvm/lib/MC/WinCOFFStreamer.cpp +++ b/llvm/lib/MC/WinCOFFStreamer.cpp @@ -122,29 +122,37 @@ void MCWinCOFFStreamer::BeginCOFFSymbolDef(MCSymbol const *Symbol) { "Got non-COFF section in the COFF backend!"); if (CurSymbol) - FatalError("starting a new symbol definition without completing the " - "previous one"); + Error("starting a new symbol definition without completing the " + "previous one"); CurSymbol = Symbol; } void MCWinCOFFStreamer::EmitCOFFSymbolStorageClass(int StorageClass) { - if (!CurSymbol) - FatalError("storage class specified outside of symbol definition"); + if (!CurSymbol) { + Error("storage class specified outside of symbol definition"); + return; + } - if (StorageClass & ~COFF::SSC_Invalid) - FatalError("storage class value '" + Twine(StorageClass) + + if (StorageClass & ~COFF::SSC_Invalid) { + Error("storage class value '" + Twine(StorageClass) + "' out of range"); + return; + } getAssembler().registerSymbol(*CurSymbol); cast<MCSymbolCOFF>(CurSymbol)->setClass((uint16_t)StorageClass); } void MCWinCOFFStreamer::EmitCOFFSymbolType(int Type) { - if (!CurSymbol) - FatalError("symbol type specified outside of a symbol definition"); + if (!CurSymbol) { + Error("symbol type specified outside of a symbol definition"); + return; + } - if (Type & ~0xffff) - FatalError("type value '" + Twine(Type) + "' out of range"); + if (Type & ~0xffff) { + Error("type value '" + Twine(Type) + "' out of range"); + return; + } getAssembler().registerSymbol(*CurSymbol); cast<MCSymbolCOFF>(CurSymbol)->setType((uint16_t)Type); @@ -152,7 +160,7 @@ void MCWinCOFFStreamer::EmitCOFFSymbolType(int Type) { void MCWinCOFFStreamer::EndCOFFSymbolDef() { if (!CurSymbol) - FatalError("ending symbol definition without starting one"); + Error("ending symbol definition without starting one"); CurSymbol = nullptr; } @@ -281,9 +289,8 @@ void MCWinCOFFStreamer::FinishImpl() { MCObjectStreamer::FinishImpl(); } -LLVM_ATTRIBUTE_NORETURN -void MCWinCOFFStreamer::FatalError(const Twine &Msg) const { - getContext().reportFatalError(SMLoc(), Msg); +void MCWinCOFFStreamer::Error(const Twine &Msg) const { + getContext().reportError(SMLoc(), Msg); } } |