forked from OSchip/llvm-project
[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
78eb8b912f
commit
97a2d5c42f
|
@ -171,9 +171,6 @@ class MCStreamer {
|
||||||
|
|
||||||
std::vector<MCDwarfFrameInfo> DwarfFrameInfos;
|
std::vector<MCDwarfFrameInfo> DwarfFrameInfos;
|
||||||
MCDwarfFrameInfo *getCurrentDwarfFrameInfo();
|
MCDwarfFrameInfo *getCurrentDwarfFrameInfo();
|
||||||
void EnsureValidDwarfFrame();
|
|
||||||
|
|
||||||
MCSymbol *EmitCFICommon();
|
|
||||||
|
|
||||||
/// Similar to DwarfFrameInfos, but for SEH unwind info. Chained frames may
|
/// Similar to DwarfFrameInfos, but for SEH unwind info. Chained frames may
|
||||||
/// refer to each other, so use std::unique_ptr to provide pointer stability.
|
/// 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();
|
return Table.getLabel();
|
||||||
}
|
}
|
||||||
|
|
||||||
MCDwarfFrameInfo *MCStreamer::getCurrentDwarfFrameInfo() {
|
|
||||||
if (DwarfFrameInfos.empty())
|
|
||||||
return nullptr;
|
|
||||||
return &DwarfFrameInfos.back();
|
|
||||||
}
|
|
||||||
|
|
||||||
bool MCStreamer::hasUnfinishedDwarfFrameInfo() {
|
bool MCStreamer::hasUnfinishedDwarfFrameInfo() {
|
||||||
MCDwarfFrameInfo *CurFrame = getCurrentDwarfFrameInfo();
|
return !DwarfFrameInfos.empty() && !DwarfFrameInfos.back().End;
|
||||||
return CurFrame && !CurFrame->End;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void MCStreamer::EnsureValidDwarfFrame() {
|
MCDwarfFrameInfo *MCStreamer::getCurrentDwarfFrameInfo() {
|
||||||
MCDwarfFrameInfo *CurFrame = getCurrentDwarfFrameInfo();
|
if (!hasUnfinishedDwarfFrameInfo()) {
|
||||||
if (!CurFrame || CurFrame->End)
|
getContext().reportError(SMLoc(), "this directive must appear between "
|
||||||
report_fatal_error("No open frame");
|
".cfi_startproc and .cfi_endproc "
|
||||||
|
"directives");
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
return &DwarfFrameInfos.back();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool MCStreamer::EmitCVFileDirective(unsigned FileNo, StringRef Filename,
|
bool MCStreamer::EmitCVFileDirective(unsigned FileNo, StringRef Filename,
|
||||||
|
@ -324,7 +321,8 @@ void MCStreamer::EmitCFISections(bool EH, bool Debug) {
|
||||||
|
|
||||||
void MCStreamer::EmitCFIStartProc(bool IsSimple) {
|
void MCStreamer::EmitCFIStartProc(bool IsSimple) {
|
||||||
if (hasUnfinishedDwarfFrameInfo())
|
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;
|
MCDwarfFrameInfo Frame;
|
||||||
Frame.IsSimple = IsSimple;
|
Frame.IsSimple = IsSimple;
|
||||||
|
@ -347,8 +345,9 @@ void MCStreamer::EmitCFIStartProcImpl(MCDwarfFrameInfo &Frame) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void MCStreamer::EmitCFIEndProc() {
|
void MCStreamer::EmitCFIEndProc() {
|
||||||
EnsureValidDwarfFrame();
|
|
||||||
MCDwarfFrameInfo *CurFrame = getCurrentDwarfFrameInfo();
|
MCDwarfFrameInfo *CurFrame = getCurrentDwarfFrameInfo();
|
||||||
|
if (!CurFrame)
|
||||||
|
return;
|
||||||
EmitCFIEndProcImpl(*CurFrame);
|
EmitCFIEndProcImpl(*CurFrame);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -364,155 +363,184 @@ MCSymbol *MCStreamer::EmitCFILabel() {
|
||||||
return (MCSymbol *)1;
|
return (MCSymbol *)1;
|
||||||
}
|
}
|
||||||
|
|
||||||
MCSymbol *MCStreamer::EmitCFICommon() {
|
|
||||||
EnsureValidDwarfFrame();
|
|
||||||
return EmitCFILabel();
|
|
||||||
}
|
|
||||||
|
|
||||||
void MCStreamer::EmitCFIDefCfa(int64_t Register, int64_t Offset) {
|
void MCStreamer::EmitCFIDefCfa(int64_t Register, int64_t Offset) {
|
||||||
MCSymbol *Label = EmitCFICommon();
|
MCSymbol *Label = EmitCFILabel();
|
||||||
MCCFIInstruction Instruction =
|
MCCFIInstruction Instruction =
|
||||||
MCCFIInstruction::createDefCfa(Label, Register, Offset);
|
MCCFIInstruction::createDefCfa(Label, Register, Offset);
|
||||||
MCDwarfFrameInfo *CurFrame = getCurrentDwarfFrameInfo();
|
MCDwarfFrameInfo *CurFrame = getCurrentDwarfFrameInfo();
|
||||||
|
if (!CurFrame)
|
||||||
|
return;
|
||||||
CurFrame->Instructions.push_back(Instruction);
|
CurFrame->Instructions.push_back(Instruction);
|
||||||
CurFrame->CurrentCfaRegister = static_cast<unsigned>(Register);
|
CurFrame->CurrentCfaRegister = static_cast<unsigned>(Register);
|
||||||
}
|
}
|
||||||
|
|
||||||
void MCStreamer::EmitCFIDefCfaOffset(int64_t Offset) {
|
void MCStreamer::EmitCFIDefCfaOffset(int64_t Offset) {
|
||||||
MCSymbol *Label = EmitCFICommon();
|
MCSymbol *Label = EmitCFILabel();
|
||||||
MCCFIInstruction Instruction =
|
MCCFIInstruction Instruction =
|
||||||
MCCFIInstruction::createDefCfaOffset(Label, Offset);
|
MCCFIInstruction::createDefCfaOffset(Label, Offset);
|
||||||
MCDwarfFrameInfo *CurFrame = getCurrentDwarfFrameInfo();
|
MCDwarfFrameInfo *CurFrame = getCurrentDwarfFrameInfo();
|
||||||
|
if (!CurFrame)
|
||||||
|
return;
|
||||||
CurFrame->Instructions.push_back(Instruction);
|
CurFrame->Instructions.push_back(Instruction);
|
||||||
}
|
}
|
||||||
|
|
||||||
void MCStreamer::EmitCFIAdjustCfaOffset(int64_t Adjustment) {
|
void MCStreamer::EmitCFIAdjustCfaOffset(int64_t Adjustment) {
|
||||||
MCSymbol *Label = EmitCFICommon();
|
MCSymbol *Label = EmitCFILabel();
|
||||||
MCCFIInstruction Instruction =
|
MCCFIInstruction Instruction =
|
||||||
MCCFIInstruction::createAdjustCfaOffset(Label, Adjustment);
|
MCCFIInstruction::createAdjustCfaOffset(Label, Adjustment);
|
||||||
MCDwarfFrameInfo *CurFrame = getCurrentDwarfFrameInfo();
|
MCDwarfFrameInfo *CurFrame = getCurrentDwarfFrameInfo();
|
||||||
|
if (!CurFrame)
|
||||||
|
return;
|
||||||
CurFrame->Instructions.push_back(Instruction);
|
CurFrame->Instructions.push_back(Instruction);
|
||||||
}
|
}
|
||||||
|
|
||||||
void MCStreamer::EmitCFIDefCfaRegister(int64_t Register) {
|
void MCStreamer::EmitCFIDefCfaRegister(int64_t Register) {
|
||||||
MCSymbol *Label = EmitCFICommon();
|
MCSymbol *Label = EmitCFILabel();
|
||||||
MCCFIInstruction Instruction =
|
MCCFIInstruction Instruction =
|
||||||
MCCFIInstruction::createDefCfaRegister(Label, Register);
|
MCCFIInstruction::createDefCfaRegister(Label, Register);
|
||||||
MCDwarfFrameInfo *CurFrame = getCurrentDwarfFrameInfo();
|
MCDwarfFrameInfo *CurFrame = getCurrentDwarfFrameInfo();
|
||||||
|
if (!CurFrame)
|
||||||
|
return;
|
||||||
CurFrame->Instructions.push_back(Instruction);
|
CurFrame->Instructions.push_back(Instruction);
|
||||||
CurFrame->CurrentCfaRegister = static_cast<unsigned>(Register);
|
CurFrame->CurrentCfaRegister = static_cast<unsigned>(Register);
|
||||||
}
|
}
|
||||||
|
|
||||||
void MCStreamer::EmitCFIOffset(int64_t Register, int64_t Offset) {
|
void MCStreamer::EmitCFIOffset(int64_t Register, int64_t Offset) {
|
||||||
MCSymbol *Label = EmitCFICommon();
|
MCSymbol *Label = EmitCFILabel();
|
||||||
MCCFIInstruction Instruction =
|
MCCFIInstruction Instruction =
|
||||||
MCCFIInstruction::createOffset(Label, Register, Offset);
|
MCCFIInstruction::createOffset(Label, Register, Offset);
|
||||||
MCDwarfFrameInfo *CurFrame = getCurrentDwarfFrameInfo();
|
MCDwarfFrameInfo *CurFrame = getCurrentDwarfFrameInfo();
|
||||||
|
if (!CurFrame)
|
||||||
|
return;
|
||||||
CurFrame->Instructions.push_back(Instruction);
|
CurFrame->Instructions.push_back(Instruction);
|
||||||
}
|
}
|
||||||
|
|
||||||
void MCStreamer::EmitCFIRelOffset(int64_t Register, int64_t Offset) {
|
void MCStreamer::EmitCFIRelOffset(int64_t Register, int64_t Offset) {
|
||||||
MCSymbol *Label = EmitCFICommon();
|
MCSymbol *Label = EmitCFILabel();
|
||||||
MCCFIInstruction Instruction =
|
MCCFIInstruction Instruction =
|
||||||
MCCFIInstruction::createRelOffset(Label, Register, Offset);
|
MCCFIInstruction::createRelOffset(Label, Register, Offset);
|
||||||
MCDwarfFrameInfo *CurFrame = getCurrentDwarfFrameInfo();
|
MCDwarfFrameInfo *CurFrame = getCurrentDwarfFrameInfo();
|
||||||
|
if (!CurFrame)
|
||||||
|
return;
|
||||||
CurFrame->Instructions.push_back(Instruction);
|
CurFrame->Instructions.push_back(Instruction);
|
||||||
}
|
}
|
||||||
|
|
||||||
void MCStreamer::EmitCFIPersonality(const MCSymbol *Sym,
|
void MCStreamer::EmitCFIPersonality(const MCSymbol *Sym,
|
||||||
unsigned Encoding) {
|
unsigned Encoding) {
|
||||||
EnsureValidDwarfFrame();
|
|
||||||
MCDwarfFrameInfo *CurFrame = getCurrentDwarfFrameInfo();
|
MCDwarfFrameInfo *CurFrame = getCurrentDwarfFrameInfo();
|
||||||
|
if (!CurFrame)
|
||||||
|
return;
|
||||||
CurFrame->Personality = Sym;
|
CurFrame->Personality = Sym;
|
||||||
CurFrame->PersonalityEncoding = Encoding;
|
CurFrame->PersonalityEncoding = Encoding;
|
||||||
}
|
}
|
||||||
|
|
||||||
void MCStreamer::EmitCFILsda(const MCSymbol *Sym, unsigned Encoding) {
|
void MCStreamer::EmitCFILsda(const MCSymbol *Sym, unsigned Encoding) {
|
||||||
EnsureValidDwarfFrame();
|
|
||||||
MCDwarfFrameInfo *CurFrame = getCurrentDwarfFrameInfo();
|
MCDwarfFrameInfo *CurFrame = getCurrentDwarfFrameInfo();
|
||||||
|
if (!CurFrame)
|
||||||
|
return;
|
||||||
CurFrame->Lsda = Sym;
|
CurFrame->Lsda = Sym;
|
||||||
CurFrame->LsdaEncoding = Encoding;
|
CurFrame->LsdaEncoding = Encoding;
|
||||||
}
|
}
|
||||||
|
|
||||||
void MCStreamer::EmitCFIRememberState() {
|
void MCStreamer::EmitCFIRememberState() {
|
||||||
MCSymbol *Label = EmitCFICommon();
|
MCSymbol *Label = EmitCFILabel();
|
||||||
MCCFIInstruction Instruction = MCCFIInstruction::createRememberState(Label);
|
MCCFIInstruction Instruction = MCCFIInstruction::createRememberState(Label);
|
||||||
MCDwarfFrameInfo *CurFrame = getCurrentDwarfFrameInfo();
|
MCDwarfFrameInfo *CurFrame = getCurrentDwarfFrameInfo();
|
||||||
|
if (!CurFrame)
|
||||||
|
return;
|
||||||
CurFrame->Instructions.push_back(Instruction);
|
CurFrame->Instructions.push_back(Instruction);
|
||||||
}
|
}
|
||||||
|
|
||||||
void MCStreamer::EmitCFIRestoreState() {
|
void MCStreamer::EmitCFIRestoreState() {
|
||||||
// FIXME: Error if there is no matching cfi_remember_state.
|
// FIXME: Error if there is no matching cfi_remember_state.
|
||||||
MCSymbol *Label = EmitCFICommon();
|
MCSymbol *Label = EmitCFILabel();
|
||||||
MCCFIInstruction Instruction = MCCFIInstruction::createRestoreState(Label);
|
MCCFIInstruction Instruction = MCCFIInstruction::createRestoreState(Label);
|
||||||
MCDwarfFrameInfo *CurFrame = getCurrentDwarfFrameInfo();
|
MCDwarfFrameInfo *CurFrame = getCurrentDwarfFrameInfo();
|
||||||
|
if (!CurFrame)
|
||||||
|
return;
|
||||||
CurFrame->Instructions.push_back(Instruction);
|
CurFrame->Instructions.push_back(Instruction);
|
||||||
}
|
}
|
||||||
|
|
||||||
void MCStreamer::EmitCFISameValue(int64_t Register) {
|
void MCStreamer::EmitCFISameValue(int64_t Register) {
|
||||||
MCSymbol *Label = EmitCFICommon();
|
MCSymbol *Label = EmitCFILabel();
|
||||||
MCCFIInstruction Instruction =
|
MCCFIInstruction Instruction =
|
||||||
MCCFIInstruction::createSameValue(Label, Register);
|
MCCFIInstruction::createSameValue(Label, Register);
|
||||||
MCDwarfFrameInfo *CurFrame = getCurrentDwarfFrameInfo();
|
MCDwarfFrameInfo *CurFrame = getCurrentDwarfFrameInfo();
|
||||||
|
if (!CurFrame)
|
||||||
|
return;
|
||||||
CurFrame->Instructions.push_back(Instruction);
|
CurFrame->Instructions.push_back(Instruction);
|
||||||
}
|
}
|
||||||
|
|
||||||
void MCStreamer::EmitCFIRestore(int64_t Register) {
|
void MCStreamer::EmitCFIRestore(int64_t Register) {
|
||||||
MCSymbol *Label = EmitCFICommon();
|
MCSymbol *Label = EmitCFILabel();
|
||||||
MCCFIInstruction Instruction =
|
MCCFIInstruction Instruction =
|
||||||
MCCFIInstruction::createRestore(Label, Register);
|
MCCFIInstruction::createRestore(Label, Register);
|
||||||
MCDwarfFrameInfo *CurFrame = getCurrentDwarfFrameInfo();
|
MCDwarfFrameInfo *CurFrame = getCurrentDwarfFrameInfo();
|
||||||
|
if (!CurFrame)
|
||||||
|
return;
|
||||||
CurFrame->Instructions.push_back(Instruction);
|
CurFrame->Instructions.push_back(Instruction);
|
||||||
}
|
}
|
||||||
|
|
||||||
void MCStreamer::EmitCFIEscape(StringRef Values) {
|
void MCStreamer::EmitCFIEscape(StringRef Values) {
|
||||||
MCSymbol *Label = EmitCFICommon();
|
MCSymbol *Label = EmitCFILabel();
|
||||||
MCCFIInstruction Instruction = MCCFIInstruction::createEscape(Label, Values);
|
MCCFIInstruction Instruction = MCCFIInstruction::createEscape(Label, Values);
|
||||||
MCDwarfFrameInfo *CurFrame = getCurrentDwarfFrameInfo();
|
MCDwarfFrameInfo *CurFrame = getCurrentDwarfFrameInfo();
|
||||||
|
if (!CurFrame)
|
||||||
|
return;
|
||||||
CurFrame->Instructions.push_back(Instruction);
|
CurFrame->Instructions.push_back(Instruction);
|
||||||
}
|
}
|
||||||
|
|
||||||
void MCStreamer::EmitCFIGnuArgsSize(int64_t Size) {
|
void MCStreamer::EmitCFIGnuArgsSize(int64_t Size) {
|
||||||
MCSymbol *Label = EmitCFICommon();
|
MCSymbol *Label = EmitCFILabel();
|
||||||
MCCFIInstruction Instruction =
|
MCCFIInstruction Instruction =
|
||||||
MCCFIInstruction::createGnuArgsSize(Label, Size);
|
MCCFIInstruction::createGnuArgsSize(Label, Size);
|
||||||
MCDwarfFrameInfo *CurFrame = getCurrentDwarfFrameInfo();
|
MCDwarfFrameInfo *CurFrame = getCurrentDwarfFrameInfo();
|
||||||
|
if (!CurFrame)
|
||||||
|
return;
|
||||||
CurFrame->Instructions.push_back(Instruction);
|
CurFrame->Instructions.push_back(Instruction);
|
||||||
}
|
}
|
||||||
|
|
||||||
void MCStreamer::EmitCFISignalFrame() {
|
void MCStreamer::EmitCFISignalFrame() {
|
||||||
EnsureValidDwarfFrame();
|
|
||||||
MCDwarfFrameInfo *CurFrame = getCurrentDwarfFrameInfo();
|
MCDwarfFrameInfo *CurFrame = getCurrentDwarfFrameInfo();
|
||||||
|
if (!CurFrame)
|
||||||
|
return;
|
||||||
CurFrame->IsSignalFrame = true;
|
CurFrame->IsSignalFrame = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void MCStreamer::EmitCFIUndefined(int64_t Register) {
|
void MCStreamer::EmitCFIUndefined(int64_t Register) {
|
||||||
MCSymbol *Label = EmitCFICommon();
|
MCSymbol *Label = EmitCFILabel();
|
||||||
MCCFIInstruction Instruction =
|
MCCFIInstruction Instruction =
|
||||||
MCCFIInstruction::createUndefined(Label, Register);
|
MCCFIInstruction::createUndefined(Label, Register);
|
||||||
MCDwarfFrameInfo *CurFrame = getCurrentDwarfFrameInfo();
|
MCDwarfFrameInfo *CurFrame = getCurrentDwarfFrameInfo();
|
||||||
|
if (!CurFrame)
|
||||||
|
return;
|
||||||
CurFrame->Instructions.push_back(Instruction);
|
CurFrame->Instructions.push_back(Instruction);
|
||||||
}
|
}
|
||||||
|
|
||||||
void MCStreamer::EmitCFIRegister(int64_t Register1, int64_t Register2) {
|
void MCStreamer::EmitCFIRegister(int64_t Register1, int64_t Register2) {
|
||||||
MCSymbol *Label = EmitCFICommon();
|
MCSymbol *Label = EmitCFILabel();
|
||||||
MCCFIInstruction Instruction =
|
MCCFIInstruction Instruction =
|
||||||
MCCFIInstruction::createRegister(Label, Register1, Register2);
|
MCCFIInstruction::createRegister(Label, Register1, Register2);
|
||||||
MCDwarfFrameInfo *CurFrame = getCurrentDwarfFrameInfo();
|
MCDwarfFrameInfo *CurFrame = getCurrentDwarfFrameInfo();
|
||||||
|
if (!CurFrame)
|
||||||
|
return;
|
||||||
CurFrame->Instructions.push_back(Instruction);
|
CurFrame->Instructions.push_back(Instruction);
|
||||||
}
|
}
|
||||||
|
|
||||||
void MCStreamer::EmitCFIWindowSave() {
|
void MCStreamer::EmitCFIWindowSave() {
|
||||||
MCSymbol *Label = EmitCFICommon();
|
MCSymbol *Label = EmitCFILabel();
|
||||||
MCCFIInstruction Instruction =
|
MCCFIInstruction Instruction =
|
||||||
MCCFIInstruction::createWindowSave(Label);
|
MCCFIInstruction::createWindowSave(Label);
|
||||||
MCDwarfFrameInfo *CurFrame = getCurrentDwarfFrameInfo();
|
MCDwarfFrameInfo *CurFrame = getCurrentDwarfFrameInfo();
|
||||||
|
if (!CurFrame)
|
||||||
|
return;
|
||||||
CurFrame->Instructions.push_back(Instruction);
|
CurFrame->Instructions.push_back(Instruction);
|
||||||
}
|
}
|
||||||
|
|
||||||
void MCStreamer::EmitCFIReturnColumn(int64_t Register) {
|
void MCStreamer::EmitCFIReturnColumn(int64_t Register) {
|
||||||
EnsureValidDwarfFrame();
|
|
||||||
MCDwarfFrameInfo *CurFrame = getCurrentDwarfFrameInfo();
|
MCDwarfFrameInfo *CurFrame = getCurrentDwarfFrameInfo();
|
||||||
|
if (!CurFrame)
|
||||||
|
return;
|
||||||
CurFrame->RAReg = Register;
|
CurFrame->RAReg = Register;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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