mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2025-01-10 05:41:40 +00:00
[MC] Properly diagnose badly scoped .cfi_ directives
Removes two report_fatal_errors. Implement this by removing EmitCFICommon, and do the checking in getCurrentDwarfFrameInfo. Have the callers check for null before dereferencing it. llvm-svn: 315264
This commit is contained in:
parent
cb7ebedc26
commit
0aa90f844e
@ -171,9 +171,6 @@ class MCStreamer {
|
||||
|
||||
std::vector<MCDwarfFrameInfo> DwarfFrameInfos;
|
||||
MCDwarfFrameInfo *getCurrentDwarfFrameInfo();
|
||||
void EnsureValidDwarfFrame();
|
||||
|
||||
MCSymbol *EmitCFICommon();
|
||||
|
||||
/// Similar to DwarfFrameInfos, but for SEH unwind info. Chained frames may
|
||||
/// refer to each other, so use std::unique_ptr to provide pointer stability.
|
||||
|
@ -206,21 +206,18 @@ MCSymbol *MCStreamer::getDwarfLineTableSymbol(unsigned CUID) {
|
||||
return Table.getLabel();
|
||||
}
|
||||
|
||||
MCDwarfFrameInfo *MCStreamer::getCurrentDwarfFrameInfo() {
|
||||
if (DwarfFrameInfos.empty())
|
||||
return nullptr;
|
||||
return &DwarfFrameInfos.back();
|
||||
}
|
||||
|
||||
bool MCStreamer::hasUnfinishedDwarfFrameInfo() {
|
||||
MCDwarfFrameInfo *CurFrame = getCurrentDwarfFrameInfo();
|
||||
return CurFrame && !CurFrame->End;
|
||||
return !DwarfFrameInfos.empty() && !DwarfFrameInfos.back().End;
|
||||
}
|
||||
|
||||
void MCStreamer::EnsureValidDwarfFrame() {
|
||||
MCDwarfFrameInfo *CurFrame = getCurrentDwarfFrameInfo();
|
||||
if (!CurFrame || CurFrame->End)
|
||||
report_fatal_error("No open frame");
|
||||
MCDwarfFrameInfo *MCStreamer::getCurrentDwarfFrameInfo() {
|
||||
if (!hasUnfinishedDwarfFrameInfo()) {
|
||||
getContext().reportError(SMLoc(), "this directive must appear between "
|
||||
".cfi_startproc and .cfi_endproc "
|
||||
"directives");
|
||||
return nullptr;
|
||||
}
|
||||
return &DwarfFrameInfos.back();
|
||||
}
|
||||
|
||||
bool MCStreamer::EmitCVFileDirective(unsigned FileNo, StringRef Filename,
|
||||
@ -324,7 +321,8 @@ void MCStreamer::EmitCFISections(bool EH, bool Debug) {
|
||||
|
||||
void MCStreamer::EmitCFIStartProc(bool IsSimple) {
|
||||
if (hasUnfinishedDwarfFrameInfo())
|
||||
report_fatal_error("Starting a frame before finishing the previous one!");
|
||||
getContext().reportError(
|
||||
SMLoc(), "starting new .cfi frame before finishing the previous one");
|
||||
|
||||
MCDwarfFrameInfo Frame;
|
||||
Frame.IsSimple = IsSimple;
|
||||
@ -347,8 +345,9 @@ void MCStreamer::EmitCFIStartProcImpl(MCDwarfFrameInfo &Frame) {
|
||||
}
|
||||
|
||||
void MCStreamer::EmitCFIEndProc() {
|
||||
EnsureValidDwarfFrame();
|
||||
MCDwarfFrameInfo *CurFrame = getCurrentDwarfFrameInfo();
|
||||
if (!CurFrame)
|
||||
return;
|
||||
EmitCFIEndProcImpl(*CurFrame);
|
||||
}
|
||||
|
||||
@ -364,155 +363,184 @@ MCSymbol *MCStreamer::EmitCFILabel() {
|
||||
return (MCSymbol *)1;
|
||||
}
|
||||
|
||||
MCSymbol *MCStreamer::EmitCFICommon() {
|
||||
EnsureValidDwarfFrame();
|
||||
return EmitCFILabel();
|
||||
}
|
||||
|
||||
void MCStreamer::EmitCFIDefCfa(int64_t Register, int64_t Offset) {
|
||||
MCSymbol *Label = EmitCFICommon();
|
||||
MCSymbol *Label = EmitCFILabel();
|
||||
MCCFIInstruction Instruction =
|
||||
MCCFIInstruction::createDefCfa(Label, Register, Offset);
|
||||
MCDwarfFrameInfo *CurFrame = getCurrentDwarfFrameInfo();
|
||||
if (!CurFrame)
|
||||
return;
|
||||
CurFrame->Instructions.push_back(Instruction);
|
||||
CurFrame->CurrentCfaRegister = static_cast<unsigned>(Register);
|
||||
}
|
||||
|
||||
void MCStreamer::EmitCFIDefCfaOffset(int64_t Offset) {
|
||||
MCSymbol *Label = EmitCFICommon();
|
||||
MCSymbol *Label = EmitCFILabel();
|
||||
MCCFIInstruction Instruction =
|
||||
MCCFIInstruction::createDefCfaOffset(Label, Offset);
|
||||
MCDwarfFrameInfo *CurFrame = getCurrentDwarfFrameInfo();
|
||||
if (!CurFrame)
|
||||
return;
|
||||
CurFrame->Instructions.push_back(Instruction);
|
||||
}
|
||||
|
||||
void MCStreamer::EmitCFIAdjustCfaOffset(int64_t Adjustment) {
|
||||
MCSymbol *Label = EmitCFICommon();
|
||||
MCSymbol *Label = EmitCFILabel();
|
||||
MCCFIInstruction Instruction =
|
||||
MCCFIInstruction::createAdjustCfaOffset(Label, Adjustment);
|
||||
MCDwarfFrameInfo *CurFrame = getCurrentDwarfFrameInfo();
|
||||
if (!CurFrame)
|
||||
return;
|
||||
CurFrame->Instructions.push_back(Instruction);
|
||||
}
|
||||
|
||||
void MCStreamer::EmitCFIDefCfaRegister(int64_t Register) {
|
||||
MCSymbol *Label = EmitCFICommon();
|
||||
MCSymbol *Label = EmitCFILabel();
|
||||
MCCFIInstruction Instruction =
|
||||
MCCFIInstruction::createDefCfaRegister(Label, Register);
|
||||
MCDwarfFrameInfo *CurFrame = getCurrentDwarfFrameInfo();
|
||||
if (!CurFrame)
|
||||
return;
|
||||
CurFrame->Instructions.push_back(Instruction);
|
||||
CurFrame->CurrentCfaRegister = static_cast<unsigned>(Register);
|
||||
}
|
||||
|
||||
void MCStreamer::EmitCFIOffset(int64_t Register, int64_t Offset) {
|
||||
MCSymbol *Label = EmitCFICommon();
|
||||
MCSymbol *Label = EmitCFILabel();
|
||||
MCCFIInstruction Instruction =
|
||||
MCCFIInstruction::createOffset(Label, Register, Offset);
|
||||
MCDwarfFrameInfo *CurFrame = getCurrentDwarfFrameInfo();
|
||||
if (!CurFrame)
|
||||
return;
|
||||
CurFrame->Instructions.push_back(Instruction);
|
||||
}
|
||||
|
||||
void MCStreamer::EmitCFIRelOffset(int64_t Register, int64_t Offset) {
|
||||
MCSymbol *Label = EmitCFICommon();
|
||||
MCSymbol *Label = EmitCFILabel();
|
||||
MCCFIInstruction Instruction =
|
||||
MCCFIInstruction::createRelOffset(Label, Register, Offset);
|
||||
MCDwarfFrameInfo *CurFrame = getCurrentDwarfFrameInfo();
|
||||
if (!CurFrame)
|
||||
return;
|
||||
CurFrame->Instructions.push_back(Instruction);
|
||||
}
|
||||
|
||||
void MCStreamer::EmitCFIPersonality(const MCSymbol *Sym,
|
||||
unsigned Encoding) {
|
||||
EnsureValidDwarfFrame();
|
||||
MCDwarfFrameInfo *CurFrame = getCurrentDwarfFrameInfo();
|
||||
if (!CurFrame)
|
||||
return;
|
||||
CurFrame->Personality = Sym;
|
||||
CurFrame->PersonalityEncoding = Encoding;
|
||||
}
|
||||
|
||||
void MCStreamer::EmitCFILsda(const MCSymbol *Sym, unsigned Encoding) {
|
||||
EnsureValidDwarfFrame();
|
||||
MCDwarfFrameInfo *CurFrame = getCurrentDwarfFrameInfo();
|
||||
if (!CurFrame)
|
||||
return;
|
||||
CurFrame->Lsda = Sym;
|
||||
CurFrame->LsdaEncoding = Encoding;
|
||||
}
|
||||
|
||||
void MCStreamer::EmitCFIRememberState() {
|
||||
MCSymbol *Label = EmitCFICommon();
|
||||
MCSymbol *Label = EmitCFILabel();
|
||||
MCCFIInstruction Instruction = MCCFIInstruction::createRememberState(Label);
|
||||
MCDwarfFrameInfo *CurFrame = getCurrentDwarfFrameInfo();
|
||||
if (!CurFrame)
|
||||
return;
|
||||
CurFrame->Instructions.push_back(Instruction);
|
||||
}
|
||||
|
||||
void MCStreamer::EmitCFIRestoreState() {
|
||||
// FIXME: Error if there is no matching cfi_remember_state.
|
||||
MCSymbol *Label = EmitCFICommon();
|
||||
MCSymbol *Label = EmitCFILabel();
|
||||
MCCFIInstruction Instruction = MCCFIInstruction::createRestoreState(Label);
|
||||
MCDwarfFrameInfo *CurFrame = getCurrentDwarfFrameInfo();
|
||||
if (!CurFrame)
|
||||
return;
|
||||
CurFrame->Instructions.push_back(Instruction);
|
||||
}
|
||||
|
||||
void MCStreamer::EmitCFISameValue(int64_t Register) {
|
||||
MCSymbol *Label = EmitCFICommon();
|
||||
MCSymbol *Label = EmitCFILabel();
|
||||
MCCFIInstruction Instruction =
|
||||
MCCFIInstruction::createSameValue(Label, Register);
|
||||
MCDwarfFrameInfo *CurFrame = getCurrentDwarfFrameInfo();
|
||||
if (!CurFrame)
|
||||
return;
|
||||
CurFrame->Instructions.push_back(Instruction);
|
||||
}
|
||||
|
||||
void MCStreamer::EmitCFIRestore(int64_t Register) {
|
||||
MCSymbol *Label = EmitCFICommon();
|
||||
MCSymbol *Label = EmitCFILabel();
|
||||
MCCFIInstruction Instruction =
|
||||
MCCFIInstruction::createRestore(Label, Register);
|
||||
MCDwarfFrameInfo *CurFrame = getCurrentDwarfFrameInfo();
|
||||
if (!CurFrame)
|
||||
return;
|
||||
CurFrame->Instructions.push_back(Instruction);
|
||||
}
|
||||
|
||||
void MCStreamer::EmitCFIEscape(StringRef Values) {
|
||||
MCSymbol *Label = EmitCFICommon();
|
||||
MCSymbol *Label = EmitCFILabel();
|
||||
MCCFIInstruction Instruction = MCCFIInstruction::createEscape(Label, Values);
|
||||
MCDwarfFrameInfo *CurFrame = getCurrentDwarfFrameInfo();
|
||||
if (!CurFrame)
|
||||
return;
|
||||
CurFrame->Instructions.push_back(Instruction);
|
||||
}
|
||||
|
||||
void MCStreamer::EmitCFIGnuArgsSize(int64_t Size) {
|
||||
MCSymbol *Label = EmitCFICommon();
|
||||
MCSymbol *Label = EmitCFILabel();
|
||||
MCCFIInstruction Instruction =
|
||||
MCCFIInstruction::createGnuArgsSize(Label, Size);
|
||||
MCDwarfFrameInfo *CurFrame = getCurrentDwarfFrameInfo();
|
||||
if (!CurFrame)
|
||||
return;
|
||||
CurFrame->Instructions.push_back(Instruction);
|
||||
}
|
||||
|
||||
void MCStreamer::EmitCFISignalFrame() {
|
||||
EnsureValidDwarfFrame();
|
||||
MCDwarfFrameInfo *CurFrame = getCurrentDwarfFrameInfo();
|
||||
if (!CurFrame)
|
||||
return;
|
||||
CurFrame->IsSignalFrame = true;
|
||||
}
|
||||
|
||||
void MCStreamer::EmitCFIUndefined(int64_t Register) {
|
||||
MCSymbol *Label = EmitCFICommon();
|
||||
MCSymbol *Label = EmitCFILabel();
|
||||
MCCFIInstruction Instruction =
|
||||
MCCFIInstruction::createUndefined(Label, Register);
|
||||
MCDwarfFrameInfo *CurFrame = getCurrentDwarfFrameInfo();
|
||||
if (!CurFrame)
|
||||
return;
|
||||
CurFrame->Instructions.push_back(Instruction);
|
||||
}
|
||||
|
||||
void MCStreamer::EmitCFIRegister(int64_t Register1, int64_t Register2) {
|
||||
MCSymbol *Label = EmitCFICommon();
|
||||
MCSymbol *Label = EmitCFILabel();
|
||||
MCCFIInstruction Instruction =
|
||||
MCCFIInstruction::createRegister(Label, Register1, Register2);
|
||||
MCDwarfFrameInfo *CurFrame = getCurrentDwarfFrameInfo();
|
||||
if (!CurFrame)
|
||||
return;
|
||||
CurFrame->Instructions.push_back(Instruction);
|
||||
}
|
||||
|
||||
void MCStreamer::EmitCFIWindowSave() {
|
||||
MCSymbol *Label = EmitCFICommon();
|
||||
MCSymbol *Label = EmitCFILabel();
|
||||
MCCFIInstruction Instruction =
|
||||
MCCFIInstruction::createWindowSave(Label);
|
||||
MCDwarfFrameInfo *CurFrame = getCurrentDwarfFrameInfo();
|
||||
if (!CurFrame)
|
||||
return;
|
||||
CurFrame->Instructions.push_back(Instruction);
|
||||
}
|
||||
|
||||
void MCStreamer::EmitCFIReturnColumn(int64_t Register) {
|
||||
EnsureValidDwarfFrame();
|
||||
MCDwarfFrameInfo *CurFrame = getCurrentDwarfFrameInfo();
|
||||
if (!CurFrame)
|
||||
return;
|
||||
CurFrame->RAReg = Register;
|
||||
}
|
||||
|
||||
|
18
test/MC/X86/cfi-scope-errors.s
Normal file
18
test/MC/X86/cfi-scope-errors.s
Normal file
@ -0,0 +1,18 @@
|
||||
# RUN: not llvm-mc %s -triple x86_64-linux -o /dev/null 2>&1 | FileCheck %s --implicit-check-not=error:
|
||||
|
||||
# FIXME: Push source locations into diagnostics.
|
||||
|
||||
.text
|
||||
.cfi_def_cfa rsp, 8
|
||||
# CHECK: error: this directive must appear between .cfi_startproc and .cfi_endproc directives
|
||||
|
||||
.cfi_startproc
|
||||
nop
|
||||
|
||||
.cfi_startproc
|
||||
# CHECK: error: starting new .cfi frame before finishing the previous one
|
||||
nop
|
||||
.cfi_endproc
|
||||
|
||||
.cfi_def_cfa rsp, 8
|
||||
# CHECK: error: this directive must appear between .cfi_startproc and .cfi_endproc directives
|
Loading…
Reference in New Issue
Block a user