forked from OSchip/llvm-project
[SEH] Use reportError instead of report_fatal_error for bad directives
This makes the .seh_ directives slightly more usable from standalone assembly files. This removes a large number of report_fatal_errors and recovers from the error by ignoring the directive. llvm-svn: 315262
This commit is contained in:
parent
cc7171abbf
commit
e52d1e6787
|
@ -180,7 +180,10 @@ class MCStreamer {
|
|||
std::vector<std::unique_ptr<WinEH::FrameInfo>> WinFrameInfos;
|
||||
|
||||
WinEH::FrameInfo *CurrentWinFrameInfo;
|
||||
void EnsureValidWinFrameInfo();
|
||||
|
||||
/// Retreive the current frame info if one is available and it is not yet
|
||||
/// closed. Otherwise, issue an error and return null.
|
||||
WinEH::FrameInfo *EnsureValidWinFrameInfo(SMLoc Loc);
|
||||
|
||||
/// \brief Tracks an index to represent the order a symbol was emitted in.
|
||||
/// Zero means we did not emit that symbol.
|
||||
|
@ -820,20 +823,23 @@ public:
|
|||
virtual void EmitCFIRegister(int64_t Register1, int64_t Register2);
|
||||
virtual void EmitCFIWindowSave();
|
||||
|
||||
virtual void EmitWinCFIStartProc(const MCSymbol *Symbol);
|
||||
virtual void EmitWinCFIEndProc();
|
||||
virtual void EmitWinCFIStartChained();
|
||||
virtual void EmitWinCFIEndChained();
|
||||
virtual void EmitWinCFIPushReg(unsigned Register);
|
||||
virtual void EmitWinCFISetFrame(unsigned Register, unsigned Offset);
|
||||
virtual void EmitWinCFIAllocStack(unsigned Size);
|
||||
virtual void EmitWinCFISaveReg(unsigned Register, unsigned Offset);
|
||||
virtual void EmitWinCFISaveXMM(unsigned Register, unsigned Offset);
|
||||
virtual void EmitWinCFIPushFrame(bool Code);
|
||||
virtual void EmitWinCFIEndProlog();
|
||||
|
||||
virtual void EmitWinEHHandler(const MCSymbol *Sym, bool Unwind, bool Except);
|
||||
virtual void EmitWinEHHandlerData();
|
||||
virtual void EmitWinCFIStartProc(const MCSymbol *Symbol, SMLoc Loc = SMLoc());
|
||||
virtual void EmitWinCFIEndProc(SMLoc Loc = SMLoc());
|
||||
virtual void EmitWinCFIStartChained(SMLoc Loc = SMLoc());
|
||||
virtual void EmitWinCFIEndChained(SMLoc Loc = SMLoc());
|
||||
virtual void EmitWinCFIPushReg(unsigned Register, SMLoc Loc = SMLoc());
|
||||
virtual void EmitWinCFISetFrame(unsigned Register, unsigned Offset,
|
||||
SMLoc Loc = SMLoc());
|
||||
virtual void EmitWinCFIAllocStack(unsigned Size, SMLoc Loc = SMLoc());
|
||||
virtual void EmitWinCFISaveReg(unsigned Register, unsigned Offset,
|
||||
SMLoc Loc = SMLoc());
|
||||
virtual void EmitWinCFISaveXMM(unsigned Register, unsigned Offset,
|
||||
SMLoc Loc = SMLoc());
|
||||
virtual void EmitWinCFIPushFrame(bool Code, SMLoc Loc = SMLoc());
|
||||
virtual void EmitWinCFIEndProlog(SMLoc Loc = SMLoc());
|
||||
virtual void EmitWinEHHandler(const MCSymbol *Sym, bool Unwind, bool Except,
|
||||
SMLoc Loc = SMLoc());
|
||||
virtual void EmitWinEHHandlerData(SMLoc Loc = SMLoc());
|
||||
|
||||
/// Get the .pdata section used for the given section. Typically the given
|
||||
/// section is either the main .text section or some other COMDAT .text
|
||||
|
|
|
@ -61,7 +61,7 @@ public:
|
|||
void EmitTBSSSymbol(MCSection *Section, MCSymbol *Symbol, uint64_t Size,
|
||||
unsigned ByteAlignment) override;
|
||||
void EmitIdent(StringRef IdentString) override;
|
||||
void EmitWinEHHandlerData() override;
|
||||
void EmitWinEHHandlerData(SMLoc Loc) override;
|
||||
void FinishImpl() override;
|
||||
|
||||
/// \}
|
||||
|
|
|
@ -270,20 +270,24 @@ public:
|
|||
void EmitCFIWindowSave() override;
|
||||
void EmitCFIReturnColumn(int64_t Register) override;
|
||||
|
||||
void EmitWinCFIStartProc(const MCSymbol *Symbol) override;
|
||||
void EmitWinCFIEndProc() override;
|
||||
void EmitWinCFIStartChained() override;
|
||||
void EmitWinCFIEndChained() override;
|
||||
void EmitWinCFIPushReg(unsigned Register) override;
|
||||
void EmitWinCFISetFrame(unsigned Register, unsigned Offset) override;
|
||||
void EmitWinCFIAllocStack(unsigned Size) override;
|
||||
void EmitWinCFISaveReg(unsigned Register, unsigned Offset) override;
|
||||
void EmitWinCFISaveXMM(unsigned Register, unsigned Offset) override;
|
||||
void EmitWinCFIPushFrame(bool Code) override;
|
||||
void EmitWinCFIEndProlog() override;
|
||||
void EmitWinCFIStartProc(const MCSymbol *Symbol, SMLoc Loc) override;
|
||||
void EmitWinCFIEndProc(SMLoc Loc) override;
|
||||
void EmitWinCFIStartChained(SMLoc Loc) override;
|
||||
void EmitWinCFIEndChained(SMLoc Loc) override;
|
||||
void EmitWinCFIPushReg(unsigned Register, SMLoc Loc) override;
|
||||
void EmitWinCFISetFrame(unsigned Register, unsigned Offset,
|
||||
SMLoc Loc) override;
|
||||
void EmitWinCFIAllocStack(unsigned Size, SMLoc Loc) override;
|
||||
void EmitWinCFISaveReg(unsigned Register, unsigned Offset,
|
||||
SMLoc Loc) override;
|
||||
void EmitWinCFISaveXMM(unsigned Register, unsigned Offset,
|
||||
SMLoc Loc) override;
|
||||
void EmitWinCFIPushFrame(bool Code, SMLoc Loc) override;
|
||||
void EmitWinCFIEndProlog(SMLoc Loc) override;
|
||||
|
||||
void EmitWinEHHandler(const MCSymbol *Sym, bool Unwind, bool Except) override;
|
||||
void EmitWinEHHandlerData() override;
|
||||
void EmitWinEHHandler(const MCSymbol *Sym, bool Unwind, bool Except,
|
||||
SMLoc Loc) override;
|
||||
void EmitWinEHHandlerData(SMLoc Loc) override;
|
||||
|
||||
void EmitInstruction(const MCInst &Inst, const MCSubtargetInfo &STI,
|
||||
bool PrintSchedInfo) override;
|
||||
|
@ -1425,38 +1429,38 @@ void MCAsmStreamer::EmitCFIReturnColumn(int64_t Register) {
|
|||
EmitEOL();
|
||||
}
|
||||
|
||||
void MCAsmStreamer::EmitWinCFIStartProc(const MCSymbol *Symbol) {
|
||||
MCStreamer::EmitWinCFIStartProc(Symbol);
|
||||
void MCAsmStreamer::EmitWinCFIStartProc(const MCSymbol *Symbol, SMLoc Loc) {
|
||||
MCStreamer::EmitWinCFIStartProc(Symbol, Loc);
|
||||
|
||||
OS << ".seh_proc ";
|
||||
Symbol->print(OS, MAI);
|
||||
EmitEOL();
|
||||
}
|
||||
|
||||
void MCAsmStreamer::EmitWinCFIEndProc() {
|
||||
MCStreamer::EmitWinCFIEndProc();
|
||||
void MCAsmStreamer::EmitWinCFIEndProc(SMLoc Loc) {
|
||||
MCStreamer::EmitWinCFIEndProc(Loc);
|
||||
|
||||
OS << "\t.seh_endproc";
|
||||
EmitEOL();
|
||||
}
|
||||
|
||||
void MCAsmStreamer::EmitWinCFIStartChained() {
|
||||
MCStreamer::EmitWinCFIStartChained();
|
||||
void MCAsmStreamer::EmitWinCFIStartChained(SMLoc Loc) {
|
||||
MCStreamer::EmitWinCFIStartChained(Loc);
|
||||
|
||||
OS << "\t.seh_startchained";
|
||||
EmitEOL();
|
||||
}
|
||||
|
||||
void MCAsmStreamer::EmitWinCFIEndChained() {
|
||||
MCStreamer::EmitWinCFIEndChained();
|
||||
void MCAsmStreamer::EmitWinCFIEndChained(SMLoc Loc) {
|
||||
MCStreamer::EmitWinCFIEndChained(Loc);
|
||||
|
||||
OS << "\t.seh_endchained";
|
||||
EmitEOL();
|
||||
}
|
||||
|
||||
void MCAsmStreamer::EmitWinEHHandler(const MCSymbol *Sym, bool Unwind,
|
||||
bool Except) {
|
||||
MCStreamer::EmitWinEHHandler(Sym, Unwind, Except);
|
||||
bool Except, SMLoc Loc) {
|
||||
MCStreamer::EmitWinEHHandler(Sym, Unwind, Except, Loc);
|
||||
|
||||
OS << "\t.seh_handler ";
|
||||
Sym->print(OS, MAI);
|
||||
|
@ -1467,8 +1471,8 @@ void MCAsmStreamer::EmitWinEHHandler(const MCSymbol *Sym, bool Unwind,
|
|||
EmitEOL();
|
||||
}
|
||||
|
||||
void MCAsmStreamer::EmitWinEHHandlerData() {
|
||||
MCStreamer::EmitWinEHHandlerData();
|
||||
void MCAsmStreamer::EmitWinEHHandlerData(SMLoc Loc) {
|
||||
MCStreamer::EmitWinEHHandlerData(Loc);
|
||||
|
||||
// Switch sections. Don't call SwitchSection directly, because that will
|
||||
// cause the section switch to be visible in the emitted assembly.
|
||||
|
@ -1483,43 +1487,46 @@ void MCAsmStreamer::EmitWinEHHandlerData() {
|
|||
EmitEOL();
|
||||
}
|
||||
|
||||
void MCAsmStreamer::EmitWinCFIPushReg(unsigned Register) {
|
||||
MCStreamer::EmitWinCFIPushReg(Register);
|
||||
void MCAsmStreamer::EmitWinCFIPushReg(unsigned Register, SMLoc Loc) {
|
||||
MCStreamer::EmitWinCFIPushReg(Register, Loc);
|
||||
|
||||
OS << "\t.seh_pushreg " << Register;
|
||||
EmitEOL();
|
||||
}
|
||||
|
||||
void MCAsmStreamer::EmitWinCFISetFrame(unsigned Register, unsigned Offset) {
|
||||
MCStreamer::EmitWinCFISetFrame(Register, Offset);
|
||||
void MCAsmStreamer::EmitWinCFISetFrame(unsigned Register, unsigned Offset,
|
||||
SMLoc Loc) {
|
||||
MCStreamer::EmitWinCFISetFrame(Register, Offset, Loc);
|
||||
|
||||
OS << "\t.seh_setframe " << Register << ", " << Offset;
|
||||
EmitEOL();
|
||||
}
|
||||
|
||||
void MCAsmStreamer::EmitWinCFIAllocStack(unsigned Size) {
|
||||
MCStreamer::EmitWinCFIAllocStack(Size);
|
||||
void MCAsmStreamer::EmitWinCFIAllocStack(unsigned Size, SMLoc Loc) {
|
||||
MCStreamer::EmitWinCFIAllocStack(Size, Loc);
|
||||
|
||||
OS << "\t.seh_stackalloc " << Size;
|
||||
EmitEOL();
|
||||
}
|
||||
|
||||
void MCAsmStreamer::EmitWinCFISaveReg(unsigned Register, unsigned Offset) {
|
||||
MCStreamer::EmitWinCFISaveReg(Register, Offset);
|
||||
void MCAsmStreamer::EmitWinCFISaveReg(unsigned Register, unsigned Offset,
|
||||
SMLoc Loc) {
|
||||
MCStreamer::EmitWinCFISaveReg(Register, Offset, Loc);
|
||||
|
||||
OS << "\t.seh_savereg " << Register << ", " << Offset;
|
||||
EmitEOL();
|
||||
}
|
||||
|
||||
void MCAsmStreamer::EmitWinCFISaveXMM(unsigned Register, unsigned Offset) {
|
||||
MCStreamer::EmitWinCFISaveXMM(Register, Offset);
|
||||
void MCAsmStreamer::EmitWinCFISaveXMM(unsigned Register, unsigned Offset,
|
||||
SMLoc Loc) {
|
||||
MCStreamer::EmitWinCFISaveXMM(Register, Offset, Loc);
|
||||
|
||||
OS << "\t.seh_savexmm " << Register << ", " << Offset;
|
||||
EmitEOL();
|
||||
}
|
||||
|
||||
void MCAsmStreamer::EmitWinCFIPushFrame(bool Code) {
|
||||
MCStreamer::EmitWinCFIPushFrame(Code);
|
||||
void MCAsmStreamer::EmitWinCFIPushFrame(bool Code, SMLoc Loc) {
|
||||
MCStreamer::EmitWinCFIPushFrame(Code, Loc);
|
||||
|
||||
OS << "\t.seh_pushframe";
|
||||
if (Code)
|
||||
|
@ -1527,8 +1534,8 @@ void MCAsmStreamer::EmitWinCFIPushFrame(bool Code) {
|
|||
EmitEOL();
|
||||
}
|
||||
|
||||
void MCAsmStreamer::EmitWinCFIEndProlog() {
|
||||
MCStreamer::EmitWinCFIEndProlog();
|
||||
void MCAsmStreamer::EmitWinCFIEndProlog(SMLoc Loc) {
|
||||
MCStreamer::EmitWinCFIEndProlog(Loc);
|
||||
|
||||
OS << "\t.seh_endprologue";
|
||||
EmitEOL();
|
||||
|
|
|
@ -568,7 +568,7 @@ bool COFFAsmParser::ParseDirectiveLinkOnce(StringRef, SMLoc Loc) {
|
|||
return false;
|
||||
}
|
||||
|
||||
bool COFFAsmParser::ParseSEHDirectiveStartProc(StringRef, SMLoc) {
|
||||
bool COFFAsmParser::ParseSEHDirectiveStartProc(StringRef, SMLoc Loc) {
|
||||
StringRef SymbolID;
|
||||
if (getParser().parseIdentifier(SymbolID))
|
||||
return true;
|
||||
|
@ -579,29 +579,29 @@ bool COFFAsmParser::ParseSEHDirectiveStartProc(StringRef, SMLoc) {
|
|||
MCSymbol *Symbol = getContext().getOrCreateSymbol(SymbolID);
|
||||
|
||||
Lex();
|
||||
getStreamer().EmitWinCFIStartProc(Symbol);
|
||||
getStreamer().EmitWinCFIStartProc(Symbol, Loc);
|
||||
return false;
|
||||
}
|
||||
|
||||
bool COFFAsmParser::ParseSEHDirectiveEndProc(StringRef, SMLoc) {
|
||||
bool COFFAsmParser::ParseSEHDirectiveEndProc(StringRef, SMLoc Loc) {
|
||||
Lex();
|
||||
getStreamer().EmitWinCFIEndProc();
|
||||
getStreamer().EmitWinCFIEndProc(Loc);
|
||||
return false;
|
||||
}
|
||||
|
||||
bool COFFAsmParser::ParseSEHDirectiveStartChained(StringRef, SMLoc) {
|
||||
bool COFFAsmParser::ParseSEHDirectiveStartChained(StringRef, SMLoc Loc) {
|
||||
Lex();
|
||||
getStreamer().EmitWinCFIStartChained();
|
||||
getStreamer().EmitWinCFIStartChained(Loc);
|
||||
return false;
|
||||
}
|
||||
|
||||
bool COFFAsmParser::ParseSEHDirectiveEndChained(StringRef, SMLoc) {
|
||||
bool COFFAsmParser::ParseSEHDirectiveEndChained(StringRef, SMLoc Loc) {
|
||||
Lex();
|
||||
getStreamer().EmitWinCFIEndChained();
|
||||
getStreamer().EmitWinCFIEndChained(Loc);
|
||||
return false;
|
||||
}
|
||||
|
||||
bool COFFAsmParser::ParseSEHDirectiveHandler(StringRef, SMLoc) {
|
||||
bool COFFAsmParser::ParseSEHDirectiveHandler(StringRef, SMLoc Loc) {
|
||||
StringRef SymbolID;
|
||||
if (getParser().parseIdentifier(SymbolID))
|
||||
return true;
|
||||
|
@ -623,17 +623,17 @@ bool COFFAsmParser::ParseSEHDirectiveHandler(StringRef, SMLoc) {
|
|||
MCSymbol *handler = getContext().getOrCreateSymbol(SymbolID);
|
||||
|
||||
Lex();
|
||||
getStreamer().EmitWinEHHandler(handler, unwind, except);
|
||||
getStreamer().EmitWinEHHandler(handler, unwind, except, Loc);
|
||||
return false;
|
||||
}
|
||||
|
||||
bool COFFAsmParser::ParseSEHDirectiveHandlerData(StringRef, SMLoc) {
|
||||
bool COFFAsmParser::ParseSEHDirectiveHandlerData(StringRef, SMLoc Loc) {
|
||||
Lex();
|
||||
getStreamer().EmitWinEHHandlerData();
|
||||
return false;
|
||||
}
|
||||
|
||||
bool COFFAsmParser::ParseSEHDirectivePushReg(StringRef, SMLoc L) {
|
||||
bool COFFAsmParser::ParseSEHDirectivePushReg(StringRef, SMLoc Loc) {
|
||||
unsigned Reg = 0;
|
||||
if (ParseSEHRegisterNumber(Reg))
|
||||
return true;
|
||||
|
@ -642,11 +642,11 @@ bool COFFAsmParser::ParseSEHDirectivePushReg(StringRef, SMLoc L) {
|
|||
return TokError("unexpected token in directive");
|
||||
|
||||
Lex();
|
||||
getStreamer().EmitWinCFIPushReg(Reg);
|
||||
getStreamer().EmitWinCFIPushReg(Reg, Loc);
|
||||
return false;
|
||||
}
|
||||
|
||||
bool COFFAsmParser::ParseSEHDirectiveSetFrame(StringRef, SMLoc L) {
|
||||
bool COFFAsmParser::ParseSEHDirectiveSetFrame(StringRef, SMLoc Loc) {
|
||||
unsigned Reg = 0;
|
||||
int64_t Off;
|
||||
if (ParseSEHRegisterNumber(Reg))
|
||||
|
@ -655,39 +655,31 @@ bool COFFAsmParser::ParseSEHDirectiveSetFrame(StringRef, SMLoc L) {
|
|||
return TokError("you must specify a stack pointer offset");
|
||||
|
||||
Lex();
|
||||
SMLoc startLoc = getLexer().getLoc();
|
||||
if (getParser().parseAbsoluteExpression(Off))
|
||||
return true;
|
||||
|
||||
if (Off & 0x0F)
|
||||
return Error(startLoc, "offset is not a multiple of 16");
|
||||
|
||||
if (getLexer().isNot(AsmToken::EndOfStatement))
|
||||
return TokError("unexpected token in directive");
|
||||
|
||||
Lex();
|
||||
getStreamer().EmitWinCFISetFrame(Reg, Off);
|
||||
getStreamer().EmitWinCFISetFrame(Reg, Off, Loc);
|
||||
return false;
|
||||
}
|
||||
|
||||
bool COFFAsmParser::ParseSEHDirectiveAllocStack(StringRef, SMLoc) {
|
||||
bool COFFAsmParser::ParseSEHDirectiveAllocStack(StringRef, SMLoc Loc) {
|
||||
int64_t Size;
|
||||
SMLoc startLoc = getLexer().getLoc();
|
||||
if (getParser().parseAbsoluteExpression(Size))
|
||||
return true;
|
||||
|
||||
if (Size & 7)
|
||||
return Error(startLoc, "size is not a multiple of 8");
|
||||
|
||||
if (getLexer().isNot(AsmToken::EndOfStatement))
|
||||
return TokError("unexpected token in directive");
|
||||
|
||||
Lex();
|
||||
getStreamer().EmitWinCFIAllocStack(Size);
|
||||
getStreamer().EmitWinCFIAllocStack(Size, Loc);
|
||||
return false;
|
||||
}
|
||||
|
||||
bool COFFAsmParser::ParseSEHDirectiveSaveReg(StringRef, SMLoc L) {
|
||||
bool COFFAsmParser::ParseSEHDirectiveSaveReg(StringRef, SMLoc Loc) {
|
||||
unsigned Reg = 0;
|
||||
int64_t Off;
|
||||
if (ParseSEHRegisterNumber(Reg))
|
||||
|
@ -696,25 +688,21 @@ bool COFFAsmParser::ParseSEHDirectiveSaveReg(StringRef, SMLoc L) {
|
|||
return TokError("you must specify an offset on the stack");
|
||||
|
||||
Lex();
|
||||
SMLoc startLoc = getLexer().getLoc();
|
||||
if (getParser().parseAbsoluteExpression(Off))
|
||||
return true;
|
||||
|
||||
if (Off & 7)
|
||||
return Error(startLoc, "size is not a multiple of 8");
|
||||
|
||||
if (getLexer().isNot(AsmToken::EndOfStatement))
|
||||
return TokError("unexpected token in directive");
|
||||
|
||||
Lex();
|
||||
// FIXME: Err on %xmm* registers
|
||||
getStreamer().EmitWinCFISaveReg(Reg, Off);
|
||||
getStreamer().EmitWinCFISaveReg(Reg, Off, Loc);
|
||||
return false;
|
||||
}
|
||||
|
||||
// FIXME: This method is inherently x86-specific. It should really be in the
|
||||
// x86 backend.
|
||||
bool COFFAsmParser::ParseSEHDirectiveSaveXMM(StringRef, SMLoc L) {
|
||||
bool COFFAsmParser::ParseSEHDirectiveSaveXMM(StringRef, SMLoc Loc) {
|
||||
unsigned Reg = 0;
|
||||
int64_t Off;
|
||||
if (ParseSEHRegisterNumber(Reg))
|
||||
|
@ -723,23 +711,19 @@ bool COFFAsmParser::ParseSEHDirectiveSaveXMM(StringRef, SMLoc L) {
|
|||
return TokError("you must specify an offset on the stack");
|
||||
|
||||
Lex();
|
||||
SMLoc startLoc = getLexer().getLoc();
|
||||
if (getParser().parseAbsoluteExpression(Off))
|
||||
return true;
|
||||
|
||||
if (getLexer().isNot(AsmToken::EndOfStatement))
|
||||
return TokError("unexpected token in directive");
|
||||
|
||||
if (Off & 0x0F)
|
||||
return Error(startLoc, "offset is not a multiple of 16");
|
||||
|
||||
Lex();
|
||||
// FIXME: Err on non-%xmm* registers
|
||||
getStreamer().EmitWinCFISaveXMM(Reg, Off);
|
||||
getStreamer().EmitWinCFISaveXMM(Reg, Off, Loc);
|
||||
return false;
|
||||
}
|
||||
|
||||
bool COFFAsmParser::ParseSEHDirectivePushFrame(StringRef, SMLoc) {
|
||||
bool COFFAsmParser::ParseSEHDirectivePushFrame(StringRef, SMLoc Loc) {
|
||||
bool Code = false;
|
||||
StringRef CodeID;
|
||||
if (getLexer().is(AsmToken::At)) {
|
||||
|
@ -756,13 +740,13 @@ bool COFFAsmParser::ParseSEHDirectivePushFrame(StringRef, SMLoc) {
|
|||
return TokError("unexpected token in directive");
|
||||
|
||||
Lex();
|
||||
getStreamer().EmitWinCFIPushFrame(Code);
|
||||
getStreamer().EmitWinCFIPushFrame(Code, Loc);
|
||||
return false;
|
||||
}
|
||||
|
||||
bool COFFAsmParser::ParseSEHDirectiveEndProlog(StringRef, SMLoc) {
|
||||
bool COFFAsmParser::ParseSEHDirectiveEndProlog(StringRef, SMLoc Loc) {
|
||||
Lex();
|
||||
getStreamer().EmitWinCFIEndProlog();
|
||||
getStreamer().EmitWinCFIEndProlog(Loc);
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
|
@ -516,20 +516,29 @@ void MCStreamer::EmitCFIReturnColumn(int64_t Register) {
|
|||
CurFrame->RAReg = Register;
|
||||
}
|
||||
|
||||
void MCStreamer::EnsureValidWinFrameInfo() {
|
||||
WinEH::FrameInfo *MCStreamer::EnsureValidWinFrameInfo(SMLoc Loc) {
|
||||
const MCAsmInfo *MAI = Context.getAsmInfo();
|
||||
if (!MAI->usesWindowsCFI())
|
||||
report_fatal_error(".seh_* directives are not supported on this target");
|
||||
if (!CurrentWinFrameInfo || CurrentWinFrameInfo->End)
|
||||
report_fatal_error("No open Win64 EH frame function!");
|
||||
if (!MAI->usesWindowsCFI()) {
|
||||
getContext().reportError(
|
||||
Loc, ".seh_* directives are not supported on this target");
|
||||
return nullptr;
|
||||
}
|
||||
if (!CurrentWinFrameInfo || CurrentWinFrameInfo->End) {
|
||||
getContext().reportError(
|
||||
Loc, ".seh_ directive must appear within an active frame");
|
||||
return nullptr;
|
||||
}
|
||||
return CurrentWinFrameInfo;
|
||||
}
|
||||
|
||||
void MCStreamer::EmitWinCFIStartProc(const MCSymbol *Symbol) {
|
||||
void MCStreamer::EmitWinCFIStartProc(const MCSymbol *Symbol, SMLoc Loc) {
|
||||
const MCAsmInfo *MAI = Context.getAsmInfo();
|
||||
if (!MAI->usesWindowsCFI())
|
||||
report_fatal_error(".seh_* directives are not supported on this target");
|
||||
return getContext().reportError(
|
||||
Loc, ".seh_* directives are not supported on this target");
|
||||
if (CurrentWinFrameInfo && !CurrentWinFrameInfo->End)
|
||||
report_fatal_error("Starting a function before ending the previous one!");
|
||||
getContext().reportError(
|
||||
Loc, "Starting a function before ending the previous one!");
|
||||
|
||||
MCSymbol *StartProc = EmitCFILabel();
|
||||
|
||||
|
@ -539,56 +548,67 @@ void MCStreamer::EmitWinCFIStartProc(const MCSymbol *Symbol) {
|
|||
CurrentWinFrameInfo->TextSection = getCurrentSectionOnly();
|
||||
}
|
||||
|
||||
void MCStreamer::EmitWinCFIEndProc() {
|
||||
EnsureValidWinFrameInfo();
|
||||
if (CurrentWinFrameInfo->ChainedParent)
|
||||
report_fatal_error("Not all chained regions terminated!");
|
||||
void MCStreamer::EmitWinCFIEndProc(SMLoc Loc) {
|
||||
WinEH::FrameInfo *CurFrame = EnsureValidWinFrameInfo(Loc);
|
||||
if (!CurFrame)
|
||||
return;
|
||||
if (CurFrame->ChainedParent)
|
||||
getContext().reportError(Loc, "Not all chained regions terminated!");
|
||||
|
||||
MCSymbol *Label = EmitCFILabel();
|
||||
CurrentWinFrameInfo->End = Label;
|
||||
CurFrame->End = Label;
|
||||
}
|
||||
|
||||
void MCStreamer::EmitWinCFIStartChained() {
|
||||
EnsureValidWinFrameInfo();
|
||||
void MCStreamer::EmitWinCFIStartChained(SMLoc Loc) {
|
||||
WinEH::FrameInfo *CurFrame = EnsureValidWinFrameInfo(Loc);
|
||||
if (!CurFrame)
|
||||
return;
|
||||
|
||||
MCSymbol *StartProc = EmitCFILabel();
|
||||
|
||||
WinFrameInfos.emplace_back(llvm::make_unique<WinEH::FrameInfo>(
|
||||
CurrentWinFrameInfo->Function, StartProc, CurrentWinFrameInfo));
|
||||
CurFrame->Function, StartProc, CurFrame));
|
||||
CurrentWinFrameInfo = WinFrameInfos.back().get();
|
||||
CurrentWinFrameInfo->TextSection = getCurrentSectionOnly();
|
||||
}
|
||||
|
||||
void MCStreamer::EmitWinCFIEndChained() {
|
||||
EnsureValidWinFrameInfo();
|
||||
if (!CurrentWinFrameInfo->ChainedParent)
|
||||
report_fatal_error("End of a chained region outside a chained region!");
|
||||
void MCStreamer::EmitWinCFIEndChained(SMLoc Loc) {
|
||||
WinEH::FrameInfo *CurFrame = EnsureValidWinFrameInfo(Loc);
|
||||
if (!CurFrame)
|
||||
return;
|
||||
if (!CurFrame->ChainedParent)
|
||||
return getContext().reportError(
|
||||
Loc, "End of a chained region outside a chained region!");
|
||||
|
||||
MCSymbol *Label = EmitCFILabel();
|
||||
|
||||
CurrentWinFrameInfo->End = Label;
|
||||
CurrentWinFrameInfo =
|
||||
const_cast<WinEH::FrameInfo *>(CurrentWinFrameInfo->ChainedParent);
|
||||
CurFrame->End = Label;
|
||||
CurrentWinFrameInfo = const_cast<WinEH::FrameInfo *>(CurFrame->ChainedParent);
|
||||
}
|
||||
|
||||
void MCStreamer::EmitWinEHHandler(const MCSymbol *Sym, bool Unwind,
|
||||
bool Except) {
|
||||
EnsureValidWinFrameInfo();
|
||||
if (CurrentWinFrameInfo->ChainedParent)
|
||||
report_fatal_error("Chained unwind areas can't have handlers!");
|
||||
CurrentWinFrameInfo->ExceptionHandler = Sym;
|
||||
void MCStreamer::EmitWinEHHandler(const MCSymbol *Sym, bool Unwind, bool Except,
|
||||
SMLoc Loc) {
|
||||
WinEH::FrameInfo *CurFrame = EnsureValidWinFrameInfo(Loc);
|
||||
if (!CurFrame)
|
||||
return;
|
||||
if (CurFrame->ChainedParent)
|
||||
return getContext().reportError(
|
||||
Loc, "Chained unwind areas can't have handlers!");
|
||||
CurFrame->ExceptionHandler = Sym;
|
||||
if (!Except && !Unwind)
|
||||
report_fatal_error("Don't know what kind of handler this is!");
|
||||
getContext().reportError(Loc, "Don't know what kind of handler this is!");
|
||||
if (Unwind)
|
||||
CurrentWinFrameInfo->HandlesUnwind = true;
|
||||
CurFrame->HandlesUnwind = true;
|
||||
if (Except)
|
||||
CurrentWinFrameInfo->HandlesExceptions = true;
|
||||
CurFrame->HandlesExceptions = true;
|
||||
}
|
||||
|
||||
void MCStreamer::EmitWinEHHandlerData() {
|
||||
EnsureValidWinFrameInfo();
|
||||
if (CurrentWinFrameInfo->ChainedParent)
|
||||
report_fatal_error("Chained unwind areas can't have handlers!");
|
||||
void MCStreamer::EmitWinEHHandlerData(SMLoc Loc) {
|
||||
WinEH::FrameInfo *CurFrame = EnsureValidWinFrameInfo(Loc);
|
||||
if (!CurFrame)
|
||||
return;
|
||||
if (CurFrame->ChainedParent)
|
||||
getContext().reportError(Loc, "Chained unwind areas can't have handlers!");
|
||||
}
|
||||
|
||||
static MCSection *getWinCFISection(MCContext &Context, unsigned *NextWinCFIID,
|
||||
|
@ -625,86 +645,110 @@ MCSection *MCStreamer::getAssociatedXDataSection(const MCSection *TextSec) {
|
|||
|
||||
void MCStreamer::EmitSyntaxDirective() {}
|
||||
|
||||
void MCStreamer::EmitWinCFIPushReg(unsigned Register) {
|
||||
EnsureValidWinFrameInfo();
|
||||
void MCStreamer::EmitWinCFIPushReg(unsigned Register, SMLoc Loc) {
|
||||
WinEH::FrameInfo *CurFrame = EnsureValidWinFrameInfo(Loc);
|
||||
if (!CurFrame)
|
||||
return;
|
||||
|
||||
MCSymbol *Label = EmitCFILabel();
|
||||
|
||||
WinEH::Instruction Inst = Win64EH::Instruction::PushNonVol(Label, Register);
|
||||
CurrentWinFrameInfo->Instructions.push_back(Inst);
|
||||
CurFrame->Instructions.push_back(Inst);
|
||||
}
|
||||
|
||||
void MCStreamer::EmitWinCFISetFrame(unsigned Register, unsigned Offset) {
|
||||
EnsureValidWinFrameInfo();
|
||||
if (CurrentWinFrameInfo->LastFrameInst >= 0)
|
||||
report_fatal_error("Frame register and offset already specified!");
|
||||
void MCStreamer::EmitWinCFISetFrame(unsigned Register, unsigned Offset,
|
||||
SMLoc Loc) {
|
||||
WinEH::FrameInfo *CurFrame = EnsureValidWinFrameInfo(Loc);
|
||||
if (!CurFrame)
|
||||
return;
|
||||
if (CurFrame->LastFrameInst >= 0)
|
||||
return getContext().reportError(
|
||||
Loc, "frame register and offset can be set at most once");
|
||||
if (Offset & 0x0F)
|
||||
report_fatal_error("Misaligned frame pointer offset!");
|
||||
return getContext().reportError(Loc, "offset is not a multiple of 16");
|
||||
if (Offset > 240)
|
||||
report_fatal_error("Frame offset must be less than or equal to 240!");
|
||||
return getContext().reportError(
|
||||
Loc, "frame offset must be less than or equal to 240");
|
||||
|
||||
MCSymbol *Label = EmitCFILabel();
|
||||
|
||||
WinEH::Instruction Inst =
|
||||
Win64EH::Instruction::SetFPReg(Label, Register, Offset);
|
||||
CurrentWinFrameInfo->LastFrameInst = CurrentWinFrameInfo->Instructions.size();
|
||||
CurrentWinFrameInfo->Instructions.push_back(Inst);
|
||||
CurFrame->LastFrameInst = CurFrame->Instructions.size();
|
||||
CurFrame->Instructions.push_back(Inst);
|
||||
}
|
||||
|
||||
void MCStreamer::EmitWinCFIAllocStack(unsigned Size) {
|
||||
EnsureValidWinFrameInfo();
|
||||
void MCStreamer::EmitWinCFIAllocStack(unsigned Size, SMLoc Loc) {
|
||||
WinEH::FrameInfo *CurFrame = EnsureValidWinFrameInfo(Loc);
|
||||
if (!CurFrame)
|
||||
return;
|
||||
if (Size == 0)
|
||||
report_fatal_error("Allocation size must be non-zero!");
|
||||
return getContext().reportError(Loc,
|
||||
"stack allocation size must be non-zero");
|
||||
if (Size & 7)
|
||||
report_fatal_error("Misaligned stack allocation!");
|
||||
return getContext().reportError(
|
||||
Loc, "stack allocation size is not a multiple of 8");
|
||||
|
||||
MCSymbol *Label = EmitCFILabel();
|
||||
|
||||
WinEH::Instruction Inst = Win64EH::Instruction::Alloc(Label, Size);
|
||||
CurrentWinFrameInfo->Instructions.push_back(Inst);
|
||||
CurFrame->Instructions.push_back(Inst);
|
||||
}
|
||||
|
||||
void MCStreamer::EmitWinCFISaveReg(unsigned Register, unsigned Offset) {
|
||||
EnsureValidWinFrameInfo();
|
||||
void MCStreamer::EmitWinCFISaveReg(unsigned Register, unsigned Offset,
|
||||
SMLoc Loc) {
|
||||
WinEH::FrameInfo *CurFrame = EnsureValidWinFrameInfo(Loc);
|
||||
if (!CurFrame)
|
||||
return;
|
||||
|
||||
if (Offset & 7)
|
||||
report_fatal_error("Misaligned saved register offset!");
|
||||
return getContext().reportError(
|
||||
Loc, "register save offset is not 8 byte aligned");
|
||||
|
||||
MCSymbol *Label = EmitCFILabel();
|
||||
|
||||
WinEH::Instruction Inst =
|
||||
Win64EH::Instruction::SaveNonVol(Label, Register, Offset);
|
||||
CurrentWinFrameInfo->Instructions.push_back(Inst);
|
||||
CurFrame->Instructions.push_back(Inst);
|
||||
}
|
||||
|
||||
void MCStreamer::EmitWinCFISaveXMM(unsigned Register, unsigned Offset) {
|
||||
EnsureValidWinFrameInfo();
|
||||
void MCStreamer::EmitWinCFISaveXMM(unsigned Register, unsigned Offset,
|
||||
SMLoc Loc) {
|
||||
WinEH::FrameInfo *CurFrame = EnsureValidWinFrameInfo(Loc);
|
||||
if (!CurFrame)
|
||||
return;
|
||||
if (Offset & 0x0F)
|
||||
report_fatal_error("Misaligned saved vector register offset!");
|
||||
return getContext().reportError(Loc, "offset is not a multiple of 16");
|
||||
|
||||
MCSymbol *Label = EmitCFILabel();
|
||||
|
||||
WinEH::Instruction Inst =
|
||||
Win64EH::Instruction::SaveXMM(Label, Register, Offset);
|
||||
CurrentWinFrameInfo->Instructions.push_back(Inst);
|
||||
CurFrame->Instructions.push_back(Inst);
|
||||
}
|
||||
|
||||
void MCStreamer::EmitWinCFIPushFrame(bool Code) {
|
||||
EnsureValidWinFrameInfo();
|
||||
if (!CurrentWinFrameInfo->Instructions.empty())
|
||||
report_fatal_error("If present, PushMachFrame must be the first UOP");
|
||||
void MCStreamer::EmitWinCFIPushFrame(bool Code, SMLoc Loc) {
|
||||
WinEH::FrameInfo *CurFrame = EnsureValidWinFrameInfo(Loc);
|
||||
if (!CurFrame)
|
||||
return;
|
||||
if (!CurFrame->Instructions.empty())
|
||||
return getContext().reportError(
|
||||
Loc, "If present, PushMachFrame must be the first UOP");
|
||||
|
||||
MCSymbol *Label = EmitCFILabel();
|
||||
|
||||
WinEH::Instruction Inst = Win64EH::Instruction::PushMachFrame(Label, Code);
|
||||
CurrentWinFrameInfo->Instructions.push_back(Inst);
|
||||
CurFrame->Instructions.push_back(Inst);
|
||||
}
|
||||
|
||||
void MCStreamer::EmitWinCFIEndProlog() {
|
||||
EnsureValidWinFrameInfo();
|
||||
void MCStreamer::EmitWinCFIEndProlog(SMLoc Loc) {
|
||||
WinEH::FrameInfo *CurFrame = EnsureValidWinFrameInfo(Loc);
|
||||
if (!CurFrame)
|
||||
return;
|
||||
|
||||
MCSymbol *Label = EmitCFILabel();
|
||||
|
||||
CurrentWinFrameInfo->PrologEnd = Label;
|
||||
CurFrame->PrologEnd = Label;
|
||||
}
|
||||
|
||||
void MCStreamer::EmitCOFFSafeSEH(MCSymbol const *Symbol) {
|
||||
|
@ -734,9 +778,9 @@ void MCStreamer::EmitWindowsUnwindTables() {
|
|||
|
||||
void MCStreamer::Finish() {
|
||||
if (!DwarfFrameInfos.empty() && !DwarfFrameInfos.back().End)
|
||||
report_fatal_error("Unfinished frame!");
|
||||
getContext().reportError(SMLoc(), "Unfinished frame!");
|
||||
if (!WinFrameInfos.empty() && !WinFrameInfos.back()->End)
|
||||
report_fatal_error("Unfinished frame!");
|
||||
getContext().reportError(SMLoc(), "Unfinished frame!");
|
||||
|
||||
MCTargetStreamer *TS = getTargetStreamer();
|
||||
if (TS)
|
||||
|
|
|
@ -285,7 +285,7 @@ void MCWinCOFFStreamer::EmitIdent(StringRef IdentString) {
|
|||
llvm_unreachable("not implemented");
|
||||
}
|
||||
|
||||
void MCWinCOFFStreamer::EmitWinEHHandlerData() {
|
||||
void MCWinCOFFStreamer::EmitWinEHHandlerData(SMLoc Loc) {
|
||||
llvm_unreachable("not implemented");
|
||||
}
|
||||
|
||||
|
|
|
@ -21,13 +21,13 @@ public:
|
|||
raw_pwrite_stream &OS)
|
||||
: MCWinCOFFStreamer(C, AB, *CE, OS) {}
|
||||
|
||||
void EmitWinEHHandlerData() override;
|
||||
void EmitWinEHHandlerData(SMLoc Loc) override;
|
||||
void EmitWindowsUnwindTables() override;
|
||||
void FinishImpl() override;
|
||||
};
|
||||
|
||||
void X86WinCOFFStreamer::EmitWinEHHandlerData() {
|
||||
MCStreamer::EmitWinEHHandlerData();
|
||||
void X86WinCOFFStreamer::EmitWinEHHandlerData(SMLoc Loc) {
|
||||
MCStreamer::EmitWinEHHandlerData(Loc);
|
||||
|
||||
// We have to emit the unwind info now, because this directive
|
||||
// actually switches to the .xdata section!
|
||||
|
|
|
@ -0,0 +1,96 @@
|
|||
# RUN: not llvm-mc %s -filetype=obj -o /dev/null 2>&1 | FileCheck %s --implicit-check-not=error:
|
||||
.text
|
||||
|
||||
.seh_pushreg 6
|
||||
# CHECK: :[[@LINE-1]]:{{[0-9]+}}: error: .seh_ directive must appear within an active frame
|
||||
|
||||
.seh_stackalloc 32
|
||||
# CHECK: :[[@LINE-1]]:{{[0-9]+}}: error: .seh_ directive must appear within an active frame
|
||||
|
||||
.def f;
|
||||
.scl 2;
|
||||
.type 32;
|
||||
.endef
|
||||
.globl f # -- Begin function f
|
||||
.p2align 4, 0x90
|
||||
f: # @f
|
||||
.seh_proc f
|
||||
pushq %rsi
|
||||
.seh_pushreg 6
|
||||
pushq %rdi
|
||||
.seh_pushreg 7
|
||||
pushq %rbx
|
||||
.seh_pushreg 3
|
||||
subq $32, %rsp
|
||||
.seh_stackalloc 0
|
||||
# CHECK: :[[@LINE-1]]:{{[0-9]+}}: error: stack allocation size must be non-zero
|
||||
.seh_stackalloc 7
|
||||
# CHECK: :[[@LINE-1]]:{{[0-9]+}}: error: stack allocation size is not a multiple of 8
|
||||
.seh_stackalloc 32
|
||||
.seh_endprologue
|
||||
nop
|
||||
addq $32, %rsp
|
||||
popq %rbx
|
||||
popq %rdi
|
||||
popq %rsi
|
||||
retq
|
||||
.seh_handlerdata
|
||||
.text
|
||||
.seh_endproc
|
||||
|
||||
|
||||
.seh_pushreg 6
|
||||
# CHECK: :[[@LINE-1]]:{{[0-9]+}}: error: .seh_ directive must appear within an active frame
|
||||
|
||||
g:
|
||||
.seh_proc g
|
||||
pushq %rbp
|
||||
.seh_pushreg 3
|
||||
pushq %rsi
|
||||
.seh_pushreg 6
|
||||
.seh_endprologue
|
||||
.seh_setframe 3 255
|
||||
# CHECK: :[[@LINE-1]]:{{[0-9]+}}: error: you must specify a stack pointer offset
|
||||
.seh_setframe 3, 255
|
||||
# CHECK: :[[@LINE-1]]:{{[0-9]+}}: error: offset is not a multiple of 16
|
||||
.seh_setframe 3, 256
|
||||
# CHECK: :[[@LINE-1]]:{{[0-9]+}}: error: frame offset must be less than or equal to 240
|
||||
.seh_setframe 3, 128
|
||||
.seh_setframe 3, 128
|
||||
# CHECK: :[[@LINE-1]]:{{[0-9]+}}: error: frame register and offset can be set at most once
|
||||
nop
|
||||
popq %rsi
|
||||
popq %rbp
|
||||
retq
|
||||
.seh_endproc
|
||||
|
||||
.globl h # -- Begin function h
|
||||
.p2align 4, 0x90
|
||||
h: # @h
|
||||
.seh_proc h
|
||||
# BB#0: # %entry
|
||||
subq $72, %rsp
|
||||
.seh_stackalloc 72
|
||||
movaps %xmm7, 48(%rsp) # 16-byte Spill
|
||||
.seh_savexmm 7 44
|
||||
# CHECK: :[[@LINE-1]]:{{[0-9]+}}: error: you must specify an offset on the stack
|
||||
.seh_savexmm 7, 44
|
||||
# CHECK: :[[@LINE-1]]:{{[0-9]+}}: error: offset is not a multiple of 16
|
||||
.seh_savexmm 7, 48
|
||||
movaps %xmm6, 32(%rsp) # 16-byte Spill
|
||||
.seh_savexmm 6, 32
|
||||
.seh_endprologue
|
||||
movapd %xmm0, %xmm6
|
||||
callq getdbl
|
||||
movapd %xmm0, %xmm7
|
||||
addsd %xmm6, %xmm7
|
||||
callq getdbl
|
||||
addsd %xmm7, %xmm0
|
||||
movaps 32(%rsp), %xmm6 # 16-byte Reload
|
||||
movaps 48(%rsp), %xmm7 # 16-byte Reload
|
||||
addq $72, %rsp
|
||||
retq
|
||||
.seh_handlerdata
|
||||
.text
|
||||
.seh_endproc
|
||||
# -- End function
|
|
@ -1,11 +1,10 @@
|
|||
// RUN: not llvm-mc -triple x86_64-pc-win32 -filetype=obj %s -o %t.o 2>&1 | FileCheck %s
|
||||
|
||||
// CHECK: Allocation size must be non-zero!
|
||||
|
||||
.globl smallFunc
|
||||
.def smallFunc; .scl 2; .type 32; .endef
|
||||
.seh_proc smallFunc
|
||||
.seh_stackalloc 0
|
||||
// CHECK: :[[@LINE-1]]:{{[0-9]+}}: error: stack allocation size must be non-zero
|
||||
smallFunc:
|
||||
ret
|
||||
.seh_endproc
|
||||
|
|
Loading…
Reference in New Issue