Skip to content

Commit 99ab112

Browse files
committed
[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 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@253328 91177308-0d34-0410-b5e6-96231b3b80d8
1 parent 43f1dd7 commit 99ab112

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

41 files changed

+419
-215
lines changed

include/llvm/MC/MCWinCOFFStreamer.h

+1-1
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,7 @@ class MCWinCOFFStreamer : public MCObjectStreamer {
7373
void EmitInstToData(const MCInst &Inst, const MCSubtargetInfo &STI) override;
7474

7575
private:
76-
LLVM_ATTRIBUTE_NORETURN void FatalError(const Twine &Msg) const;
76+
void Error(const Twine &Msg) const;
7777
};
7878
}
7979

lib/MC/ELFObjectWriter.cpp

+20-10
Original file line numberDiff line numberDiff line change
@@ -630,28 +630,36 @@ void ELFObjectWriter::recordRelocation(MCAssembler &Asm,
630630
// In general, ELF has no relocations for -B. It can only represent (A + C)
631631
// or (A + C - R). If B = R + K and the relocation is not pcrel, we can
632632
// replace B to implement it: (A - R - K + C)
633-
if (IsPCRel)
634-
Asm.getContext().reportFatalError(
633+
if (IsPCRel) {
634+
Asm.getContext().reportError(
635635
Fixup.getLoc(),
636636
"No relocation available to represent this relative expression");
637+
return;
638+
}
637639

638640
const auto &SymB = cast<MCSymbolELF>(RefB->getSymbol());
639641

640-
if (SymB.isUndefined())
641-
Asm.getContext().reportFatalError(
642+
if (SymB.isUndefined()) {
643+
Asm.getContext().reportError(
642644
Fixup.getLoc(),
643645
Twine("symbol '") + SymB.getName() +
644646
"' can not be undefined in a subtraction expression");
647+
return;
648+
}
645649

646650
assert(!SymB.isAbsolute() && "Should have been folded");
647651
const MCSection &SecB = SymB.getSection();
648-
if (&SecB != &FixupSection)
649-
Asm.getContext().reportFatalError(
652+
if (&SecB != &FixupSection) {
653+
Asm.getContext().reportError(
650654
Fixup.getLoc(), "Cannot represent a difference across sections");
655+
return;
656+
}
651657

652-
if (::isWeak(SymB))
653-
Asm.getContext().reportFatalError(
658+
if (::isWeak(SymB)) {
659+
Asm.getContext().reportError(
654660
Fixup.getLoc(), "Cannot represent a subtraction with a weak symbol");
661+
return;
662+
}
655663

656664
uint64_t SymBOffset = Layout.getSymbolOffset(SymB);
657665
uint64_t K = SymBOffset - FixupOffset;
@@ -784,8 +792,10 @@ void ELFObjectWriter::computeSymbolTable(
784792
Renames.count(&Symbol)))
785793
continue;
786794

787-
if (Symbol.isTemporary() && Symbol.isUndefined())
788-
Ctx.reportFatalError(SMLoc(), "Undefined temporary");
795+
if (Symbol.isTemporary() && Symbol.isUndefined()) {
796+
Ctx.reportError(SMLoc(), "Undefined temporary symbol");
797+
continue;
798+
}
789799

790800
ELFSymbolData MSD;
791801
MSD.Symbol = cast<MCSymbolELF>(&Symbol);

lib/MC/MCAssembler.cpp

+20-9
Original file line numberDiff line numberDiff line change
@@ -179,14 +179,19 @@ const MCSymbol *MCAsmLayout::getBaseSymbol(const MCSymbol &Symbol) const {
179179

180180
const MCExpr *Expr = Symbol.getVariableValue();
181181
MCValue Value;
182-
if (!Expr->evaluateAsValue(Value, *this))
183-
llvm_unreachable("Invalid Expression");
182+
if (!Expr->evaluateAsValue(Value, *this)) {
183+
Assembler.getContext().reportError(
184+
SMLoc(), "expression could not be evaluated");
185+
return nullptr;
186+
}
184187

185188
const MCSymbolRefExpr *RefB = Value.getSymB();
186-
if (RefB)
187-
Assembler.getContext().reportFatalError(
189+
if (RefB) {
190+
Assembler.getContext().reportError(
188191
SMLoc(), Twine("symbol '") + RefB->getSymbol().getName() +
189192
"' could not be evaluated in a subtraction expression");
193+
return nullptr;
194+
}
190195

191196
const MCSymbolRefExpr *A = Value.getSymA();
192197
if (!A)
@@ -196,9 +201,10 @@ const MCSymbol *MCAsmLayout::getBaseSymbol(const MCSymbol &Symbol) const {
196201
const MCAssembler &Asm = getAssembler();
197202
if (ASym.isCommon()) {
198203
// FIXME: we should probably add a SMLoc to MCExpr.
199-
Asm.getContext().reportFatalError(SMLoc(),
200-
"Common symbol " + ASym.getName() +
201-
" cannot be used in assignment expr");
204+
Asm.getContext().reportError(SMLoc(),
205+
"Common symbol '" + ASym.getName() +
206+
"' cannot be used in assignment expr");
207+
return nullptr;
202208
}
203209

204210
return &ASym;
@@ -436,8 +442,13 @@ bool MCAssembler::evaluateFixup(const MCAsmLayout &Layout,
436442
// probably merge the two into a single callback that tries to evaluate a
437443
// fixup and records a relocation if one is needed.
438444
const MCExpr *Expr = Fixup.getValue();
439-
if (!Expr->evaluateAsRelocatable(Target, &Layout, &Fixup))
440-
getContext().reportFatalError(Fixup.getLoc(), "expected relocatable expression");
445+
if (!Expr->evaluateAsRelocatable(Target, &Layout, &Fixup)) {
446+
getContext().reportError(Fixup.getLoc(), "expected relocatable expression");
447+
// Claim to have completely evaluated the fixup, to prevent any further
448+
// processing from being done.
449+
Value = 0;
450+
return true;
451+
}
441452

442453
bool IsPCRel = Backend.getFixupKindInfo(
443454
Fixup.getKind()).Flags & MCFixupKindInfo::FKF_IsPCRel;

lib/MC/WinCOFFObjectWriter.cpp

+14-7
Original file line numberDiff line numberDiff line change
@@ -706,14 +706,17 @@ void WinCOFFObjectWriter::recordRelocation(
706706

707707
const MCSymbol &Symbol = Target.getSymA()->getSymbol();
708708
const MCSymbol &A = Symbol;
709-
if (!A.isRegistered())
710-
Asm.getContext().reportFatalError(Fixup.getLoc(),
709+
if (!A.isRegistered()) {
710+
Asm.getContext().reportError(Fixup.getLoc(),
711711
Twine("symbol '") + A.getName() +
712712
"' can not be undefined");
713+
return;
714+
}
713715
if (A.isTemporary() && A.isUndefined()) {
714-
Asm.getContext().reportFatalError(Fixup.getLoc(),
716+
Asm.getContext().reportError(Fixup.getLoc(),
715717
Twine("assembler label '") + A.getName() +
716718
"' can not be undefined");
719+
return;
717720
}
718721

719722
MCSection *Section = Fragment->getParent();
@@ -731,17 +734,21 @@ void WinCOFFObjectWriter::recordRelocation(
731734

732735
if (SymB) {
733736
const MCSymbol *B = &SymB->getSymbol();
734-
if (!B->getFragment())
735-
Asm.getContext().reportFatalError(
737+
if (!B->getFragment()) {
738+
Asm.getContext().reportError(
736739
Fixup.getLoc(),
737740
Twine("symbol '") + B->getName() +
738741
"' can not be undefined in a subtraction expression");
742+
return;
743+
}
739744

740-
if (!A.getFragment())
741-
Asm.getContext().reportFatalError(
745+
if (!A.getFragment()) {
746+
Asm.getContext().reportError(
742747
Fixup.getLoc(),
743748
Twine("symbol '") + Symbol.getName() +
744749
"' can not be undefined in a subtraction expression");
750+
return;
751+
}
745752

746753
CrossSection = &Symbol.getSection() != &B->getSection();
747754

lib/MC/WinCOFFStreamer.cpp

+21-14
Original file line numberDiff line numberDiff line change
@@ -122,37 +122,45 @@ void MCWinCOFFStreamer::BeginCOFFSymbolDef(MCSymbol const *Symbol) {
122122
"Got non-COFF section in the COFF backend!");
123123

124124
if (CurSymbol)
125-
FatalError("starting a new symbol definition without completing the "
126-
"previous one");
125+
Error("starting a new symbol definition without completing the "
126+
"previous one");
127127
CurSymbol = Symbol;
128128
}
129129

130130
void MCWinCOFFStreamer::EmitCOFFSymbolStorageClass(int StorageClass) {
131-
if (!CurSymbol)
132-
FatalError("storage class specified outside of symbol definition");
131+
if (!CurSymbol) {
132+
Error("storage class specified outside of symbol definition");
133+
return;
134+
}
133135

134-
if (StorageClass & ~COFF::SSC_Invalid)
135-
FatalError("storage class value '" + Twine(StorageClass) +
136+
if (StorageClass & ~COFF::SSC_Invalid) {
137+
Error("storage class value '" + Twine(StorageClass) +
136138
"' out of range");
139+
return;
140+
}
137141

138142
getAssembler().registerSymbol(*CurSymbol);
139143
cast<MCSymbolCOFF>(CurSymbol)->setClass((uint16_t)StorageClass);
140144
}
141145

142146
void MCWinCOFFStreamer::EmitCOFFSymbolType(int Type) {
143-
if (!CurSymbol)
144-
FatalError("symbol type specified outside of a symbol definition");
147+
if (!CurSymbol) {
148+
Error("symbol type specified outside of a symbol definition");
149+
return;
150+
}
145151

146-
if (Type & ~0xffff)
147-
FatalError("type value '" + Twine(Type) + "' out of range");
152+
if (Type & ~0xffff) {
153+
Error("type value '" + Twine(Type) + "' out of range");
154+
return;
155+
}
148156

149157
getAssembler().registerSymbol(*CurSymbol);
150158
cast<MCSymbolCOFF>(CurSymbol)->setType((uint16_t)Type);
151159
}
152160

153161
void MCWinCOFFStreamer::EndCOFFSymbolDef() {
154162
if (!CurSymbol)
155-
FatalError("ending symbol definition without starting one");
163+
Error("ending symbol definition without starting one");
156164
CurSymbol = nullptr;
157165
}
158166

@@ -281,9 +289,8 @@ void MCWinCOFFStreamer::FinishImpl() {
281289
MCObjectStreamer::FinishImpl();
282290
}
283291

284-
LLVM_ATTRIBUTE_NORETURN
285-
void MCWinCOFFStreamer::FatalError(const Twine &Msg) const {
286-
getContext().reportFatalError(SMLoc(), Msg);
292+
void MCWinCOFFStreamer::Error(const Twine &Msg) const {
293+
getContext().reportError(SMLoc(), Msg);
287294
}
288295
}
289296

0 commit comments

Comments
 (0)