Skip to content

Commit

Permalink
[X86] Print register names in .seh_* directives
Browse files Browse the repository at this point in the history
Also improve assembler parser register validation for .seh_ directives.
This requires moving X86-specific seh directive handling into the x86
backend, which addresses some assembler FIXMEs.

Differential Revision: https://reviews.llvm.org/D66625

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@370533 91177308-0d34-0410-b5e6-96231b3b80d8
  • Loading branch information
rnk committed Aug 30, 2019
1 parent 656df77 commit b492638
Show file tree
Hide file tree
Showing 28 changed files with 408 additions and 362 deletions.
9 changes: 5 additions & 4 deletions include/llvm/MC/MCStreamer.h
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ struct MCDwarfFrameInfo;
class MCExpr;
class MCInst;
class MCInstPrinter;
class MCRegister;
class MCSection;
class MCStreamer;
class MCSymbolRefExpr;
Expand Down Expand Up @@ -943,13 +944,13 @@ class MCStreamer {
virtual void EmitWinCFIFuncletOrFuncEnd(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,
virtual void EmitWinCFIPushReg(MCRegister Register, SMLoc Loc = SMLoc());
virtual void EmitWinCFISetFrame(MCRegister Register, unsigned Offset,
SMLoc Loc = SMLoc());
virtual void EmitWinCFIAllocStack(unsigned Size, SMLoc Loc = SMLoc());
virtual void EmitWinCFISaveReg(unsigned Register, unsigned Offset,
virtual void EmitWinCFISaveReg(MCRegister Register, unsigned Offset,
SMLoc Loc = SMLoc());
virtual void EmitWinCFISaveXMM(unsigned Register, unsigned Offset,
virtual void EmitWinCFISaveXMM(MCRegister Register, unsigned Offset,
SMLoc Loc = SMLoc());
virtual void EmitWinCFIPushFrame(bool Code, SMLoc Loc = SMLoc());
virtual void EmitWinCFIEndProlog(SMLoc Loc = SMLoc());
Expand Down
32 changes: 20 additions & 12 deletions lib/MC/MCAsmStreamer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
#include "llvm/MC/MCInstPrinter.h"
#include "llvm/MC/MCObjectFileInfo.h"
#include "llvm/MC/MCObjectWriter.h"
#include "llvm/MC/MCRegister.h"
#include "llvm/MC/MCRegisterInfo.h"
#include "llvm/MC/MCSectionMachO.h"
#include "llvm/MC/MCStreamer.h"
Expand Down Expand Up @@ -310,13 +311,13 @@ class MCAsmStreamer final : public MCStreamer {
void EmitWinCFIFuncletOrFuncEnd(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,
void EmitWinCFIPushReg(MCRegister Register, SMLoc Loc) override;
void EmitWinCFISetFrame(MCRegister Register, unsigned Offset,
SMLoc Loc) override;
void EmitWinCFIAllocStack(unsigned Size, SMLoc Loc) override;
void EmitWinCFISaveReg(unsigned Register, unsigned Offset,
void EmitWinCFISaveReg(MCRegister Register, unsigned Offset,
SMLoc Loc) override;
void EmitWinCFISaveXMM(unsigned Register, unsigned Offset,
void EmitWinCFISaveXMM(MCRegister Register, unsigned Offset,
SMLoc Loc) override;
void EmitWinCFIPushFrame(bool Code, SMLoc Loc) override;
void EmitWinCFIEndProlog(SMLoc Loc) override;
Expand Down Expand Up @@ -1755,18 +1756,21 @@ void MCAsmStreamer::EmitWinEHHandlerData(SMLoc Loc) {
EmitEOL();
}

void MCAsmStreamer::EmitWinCFIPushReg(unsigned Register, SMLoc Loc) {
void MCAsmStreamer::EmitWinCFIPushReg(MCRegister Register, SMLoc Loc) {
MCStreamer::EmitWinCFIPushReg(Register, Loc);

OS << "\t.seh_pushreg " << Register;
OS << "\t.seh_pushreg ";
InstPrinter->printRegName(OS, Register);
EmitEOL();
}

void MCAsmStreamer::EmitWinCFISetFrame(unsigned Register, unsigned Offset,
void MCAsmStreamer::EmitWinCFISetFrame(MCRegister Register, unsigned Offset,
SMLoc Loc) {
MCStreamer::EmitWinCFISetFrame(Register, Offset, Loc);

OS << "\t.seh_setframe " << Register << ", " << Offset;
OS << "\t.seh_setframe ";
InstPrinter->printRegName(OS, Register);
OS << ", " << Offset;
EmitEOL();
}

Expand All @@ -1777,19 +1781,23 @@ void MCAsmStreamer::EmitWinCFIAllocStack(unsigned Size, SMLoc Loc) {
EmitEOL();
}

void MCAsmStreamer::EmitWinCFISaveReg(unsigned Register, unsigned Offset,
void MCAsmStreamer::EmitWinCFISaveReg(MCRegister Register, unsigned Offset,
SMLoc Loc) {
MCStreamer::EmitWinCFISaveReg(Register, Offset, Loc);

OS << "\t.seh_savereg " << Register << ", " << Offset;
OS << "\t.seh_savereg ";
InstPrinter->printRegName(OS, Register);
OS << ", " << Offset;
EmitEOL();
}

void MCAsmStreamer::EmitWinCFISaveXMM(unsigned Register, unsigned Offset,
void MCAsmStreamer::EmitWinCFISaveXMM(MCRegister Register, unsigned Offset,
SMLoc Loc) {
MCStreamer::EmitWinCFISaveXMM(Register, Offset, Loc);

OS << "\t.seh_savexmm " << Register << ", " << Offset;
OS << "\t.seh_savexmm ";
InstPrinter->printRegName(OS, Register);
OS << ", " << Offset;
EmitEOL();
}

Expand Down
153 changes: 0 additions & 153 deletions lib/MC/MCParser/COFFAsmParser.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -83,18 +83,8 @@ class COFFAsmParser : public MCAsmParserExtension {
".seh_handler");
addDirectiveHandler<&COFFAsmParser::ParseSEHDirectiveHandlerData>(
".seh_handlerdata");
addDirectiveHandler<&COFFAsmParser::ParseSEHDirectivePushReg>(
".seh_pushreg");
addDirectiveHandler<&COFFAsmParser::ParseSEHDirectiveSetFrame>(
".seh_setframe");
addDirectiveHandler<&COFFAsmParser::ParseSEHDirectiveAllocStack>(
".seh_stackalloc");
addDirectiveHandler<&COFFAsmParser::ParseSEHDirectiveSaveReg>(
".seh_savereg");
addDirectiveHandler<&COFFAsmParser::ParseSEHDirectiveSaveXMM>(
".seh_savexmm");
addDirectiveHandler<&COFFAsmParser::ParseSEHDirectivePushFrame>(
".seh_pushframe");
addDirectiveHandler<&COFFAsmParser::ParseSEHDirectiveEndProlog>(
".seh_endprologue");
addDirectiveHandler<&COFFAsmParser::ParseDirectiveSymbolAttribute>(".weak");
Expand Down Expand Up @@ -143,12 +133,7 @@ class COFFAsmParser : public MCAsmParserExtension {
bool ParseSEHDirectiveEndChained(StringRef, SMLoc);
bool ParseSEHDirectiveHandler(StringRef, SMLoc);
bool ParseSEHDirectiveHandlerData(StringRef, SMLoc);
bool ParseSEHDirectivePushReg(StringRef, SMLoc);
bool ParseSEHDirectiveSetFrame(StringRef, SMLoc);
bool ParseSEHDirectiveAllocStack(StringRef, SMLoc);
bool ParseSEHDirectiveSaveReg(StringRef, SMLoc);
bool ParseSEHDirectiveSaveXMM(StringRef, SMLoc);
bool ParseSEHDirectivePushFrame(StringRef, SMLoc);
bool ParseSEHDirectiveEndProlog(StringRef, SMLoc);

bool ParseAtUnwindOrAtExcept(bool &unwind, bool &except);
Expand Down Expand Up @@ -682,39 +667,6 @@ bool COFFAsmParser::ParseSEHDirectiveHandlerData(StringRef, SMLoc Loc) {
return false;
}

bool COFFAsmParser::ParseSEHDirectivePushReg(StringRef, SMLoc Loc) {
unsigned Reg = 0;
if (ParseSEHRegisterNumber(Reg))
return true;

if (getLexer().isNot(AsmToken::EndOfStatement))
return TokError("unexpected token in directive");

Lex();
getStreamer().EmitWinCFIPushReg(Reg, Loc);
return false;
}

bool COFFAsmParser::ParseSEHDirectiveSetFrame(StringRef, SMLoc Loc) {
unsigned Reg = 0;
int64_t Off;
if (ParseSEHRegisterNumber(Reg))
return true;
if (getLexer().isNot(AsmToken::Comma))
return TokError("you must specify a stack pointer offset");

Lex();
if (getParser().parseAbsoluteExpression(Off))
return true;

if (getLexer().isNot(AsmToken::EndOfStatement))
return TokError("unexpected token in directive");

Lex();
getStreamer().EmitWinCFISetFrame(Reg, Off, Loc);
return false;
}

bool COFFAsmParser::ParseSEHDirectiveAllocStack(StringRef, SMLoc Loc) {
int64_t Size;
if (getParser().parseAbsoluteExpression(Size))
Expand All @@ -728,71 +680,6 @@ bool COFFAsmParser::ParseSEHDirectiveAllocStack(StringRef, SMLoc Loc) {
return false;
}

bool COFFAsmParser::ParseSEHDirectiveSaveReg(StringRef, SMLoc Loc) {
unsigned Reg = 0;
int64_t Off;
if (ParseSEHRegisterNumber(Reg))
return true;
if (getLexer().isNot(AsmToken::Comma))
return TokError("you must specify an offset on the stack");

Lex();
if (getParser().parseAbsoluteExpression(Off))
return true;

if (getLexer().isNot(AsmToken::EndOfStatement))
return TokError("unexpected token in directive");

Lex();
// FIXME: Err on %xmm* registers
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 Loc) {
unsigned Reg = 0;
int64_t Off;
if (ParseSEHRegisterNumber(Reg))
return true;
if (getLexer().isNot(AsmToken::Comma))
return TokError("you must specify an offset on the stack");

Lex();
if (getParser().parseAbsoluteExpression(Off))
return true;

if (getLexer().isNot(AsmToken::EndOfStatement))
return TokError("unexpected token in directive");

Lex();
// FIXME: Err on non-%xmm* registers
getStreamer().EmitWinCFISaveXMM(Reg, Off, Loc);
return false;
}

bool COFFAsmParser::ParseSEHDirectivePushFrame(StringRef, SMLoc Loc) {
bool Code = false;
StringRef CodeID;
if (getLexer().is(AsmToken::At)) {
SMLoc startLoc = getLexer().getLoc();
Lex();
if (!getParser().parseIdentifier(CodeID)) {
if (CodeID != "code")
return Error(startLoc, "expected @code");
Code = true;
}
}

if (getLexer().isNot(AsmToken::EndOfStatement))
return TokError("unexpected token in directive");

Lex();
getStreamer().EmitWinCFIPushFrame(Code, Loc);
return false;
}

bool COFFAsmParser::ParseSEHDirectiveEndProlog(StringRef, SMLoc Loc) {
Lex();
getStreamer().EmitWinCFIEndProlog(Loc);
Expand All @@ -816,46 +703,6 @@ bool COFFAsmParser::ParseAtUnwindOrAtExcept(bool &unwind, bool &except) {
return false;
}

bool COFFAsmParser::ParseSEHRegisterNumber(unsigned &RegNo) {
SMLoc startLoc = getLexer().getLoc();
if (getLexer().is(AsmToken::Percent)) {
const MCRegisterInfo *MRI = getContext().getRegisterInfo();
SMLoc endLoc;
unsigned LLVMRegNo;
if (getParser().getTargetParser().ParseRegister(LLVMRegNo,startLoc,endLoc))
return true;

#if 0
// FIXME: TargetAsmInfo::getCalleeSavedRegs() commits a serious layering
// violation so this validation code is disabled.

// Check that this is a non-volatile register.
const unsigned *NVRegs = TAI.getCalleeSavedRegs();
unsigned i;
for (i = 0; NVRegs[i] != 0; ++i)
if (NVRegs[i] == LLVMRegNo)
break;
if (NVRegs[i] == 0)
return Error(startLoc, "expected non-volatile register");
#endif

int SEHRegNo = MRI->getSEHRegNum(LLVMRegNo);
if (SEHRegNo < 0)
return Error(startLoc,"register can't be represented in SEH unwind info");
RegNo = SEHRegNo;
}
else {
int64_t n;
if (getParser().parseAbsoluteExpression(n))
return true;
if (n > 15)
return Error(startLoc, "register number is too high");
RegNo = n;
}

return false;
}

namespace llvm {

MCAsmParserExtension *createCOFFAsmParser() {
Expand Down
29 changes: 18 additions & 11 deletions lib/MC/MCStreamer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,8 @@
#include "llvm/MC/MCInst.h"
#include "llvm/MC/MCInstPrinter.h"
#include "llvm/MC/MCObjectFileInfo.h"
#include "llvm/MC/MCRegister.h"
#include "llvm/MC/MCRegisterInfo.h"
#include "llvm/MC/MCSection.h"
#include "llvm/MC/MCSectionCOFF.h"
#include "llvm/MC/MCSymbol.h"
Expand Down Expand Up @@ -809,18 +811,23 @@ MCSection *MCStreamer::getAssociatedXDataSection(const MCSection *TextSec) {

void MCStreamer::EmitSyntaxDirective() {}

void MCStreamer::EmitWinCFIPushReg(unsigned Register, SMLoc Loc) {
static unsigned encodeSEHRegNum(MCContext &Ctx, MCRegister Reg) {
return Ctx.getRegisterInfo()->getSEHRegNum(Reg);
}

void MCStreamer::EmitWinCFIPushReg(MCRegister Register, SMLoc Loc) {
WinEH::FrameInfo *CurFrame = EnsureValidWinFrameInfo(Loc);
if (!CurFrame)
return;

MCSymbol *Label = EmitCFILabel();

WinEH::Instruction Inst = Win64EH::Instruction::PushNonVol(Label, Register);
WinEH::Instruction Inst = Win64EH::Instruction::PushNonVol(
Label, encodeSEHRegNum(Context, Register));
CurFrame->Instructions.push_back(Inst);
}

void MCStreamer::EmitWinCFISetFrame(unsigned Register, unsigned Offset,
void MCStreamer::EmitWinCFISetFrame(MCRegister Register, unsigned Offset,
SMLoc Loc) {
WinEH::FrameInfo *CurFrame = EnsureValidWinFrameInfo(Loc);
if (!CurFrame)
Expand All @@ -836,8 +843,8 @@ void MCStreamer::EmitWinCFISetFrame(unsigned Register, unsigned Offset,

MCSymbol *Label = EmitCFILabel();

WinEH::Instruction Inst =
Win64EH::Instruction::SetFPReg(Label, Register, Offset);
WinEH::Instruction Inst = Win64EH::Instruction::SetFPReg(
Label, encodeSEHRegNum(getContext(), Register), Offset);
CurFrame->LastFrameInst = CurFrame->Instructions.size();
CurFrame->Instructions.push_back(Inst);
}
Expand All @@ -859,7 +866,7 @@ void MCStreamer::EmitWinCFIAllocStack(unsigned Size, SMLoc Loc) {
CurFrame->Instructions.push_back(Inst);
}

void MCStreamer::EmitWinCFISaveReg(unsigned Register, unsigned Offset,
void MCStreamer::EmitWinCFISaveReg(MCRegister Register, unsigned Offset,
SMLoc Loc) {
WinEH::FrameInfo *CurFrame = EnsureValidWinFrameInfo(Loc);
if (!CurFrame)
Expand All @@ -871,12 +878,12 @@ void MCStreamer::EmitWinCFISaveReg(unsigned Register, unsigned Offset,

MCSymbol *Label = EmitCFILabel();

WinEH::Instruction Inst =
Win64EH::Instruction::SaveNonVol(Label, Register, Offset);
WinEH::Instruction Inst = Win64EH::Instruction::SaveNonVol(
Label, encodeSEHRegNum(Context, Register), Offset);
CurFrame->Instructions.push_back(Inst);
}

void MCStreamer::EmitWinCFISaveXMM(unsigned Register, unsigned Offset,
void MCStreamer::EmitWinCFISaveXMM(MCRegister Register, unsigned Offset,
SMLoc Loc) {
WinEH::FrameInfo *CurFrame = EnsureValidWinFrameInfo(Loc);
if (!CurFrame)
Expand All @@ -886,8 +893,8 @@ void MCStreamer::EmitWinCFISaveXMM(unsigned Register, unsigned Offset,

MCSymbol *Label = EmitCFILabel();

WinEH::Instruction Inst =
Win64EH::Instruction::SaveXMM(Label, Register, Offset);
WinEH::Instruction Inst = Win64EH::Instruction::SaveXMM(
Label, encodeSEHRegNum(Context, Register), Offset);
CurFrame->Instructions.push_back(Inst);
}

Expand Down
Loading

0 comments on commit b492638

Please sign in to comment.