mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2024-10-19 02:52:53 +02:00
MC: add support for cfi_return_column
This adds support for the CFI pseudo-op return_column. This specifies the frame table column which contains the return address. Addresses PR33953! llvm-svn: 309360
This commit is contained in:
parent
65da223d2f
commit
e5f08e5254
@ -509,6 +509,7 @@ struct MCDwarfFrameInfo {
|
|||||||
uint32_t CompactUnwindEncoding = 0;
|
uint32_t CompactUnwindEncoding = 0;
|
||||||
bool IsSignalFrame = false;
|
bool IsSignalFrame = false;
|
||||||
bool IsSimple = false;
|
bool IsSimple = false;
|
||||||
|
unsigned RAReg = static_cast<unsigned>(INT_MAX);
|
||||||
};
|
};
|
||||||
|
|
||||||
class MCDwarfFrameEmitter {
|
class MCDwarfFrameEmitter {
|
||||||
|
@ -797,6 +797,7 @@ public:
|
|||||||
virtual void EmitCFIRelOffset(int64_t Register, int64_t Offset);
|
virtual void EmitCFIRelOffset(int64_t Register, int64_t Offset);
|
||||||
virtual void EmitCFIAdjustCfaOffset(int64_t Adjustment);
|
virtual void EmitCFIAdjustCfaOffset(int64_t Adjustment);
|
||||||
virtual void EmitCFIEscape(StringRef Values);
|
virtual void EmitCFIEscape(StringRef Values);
|
||||||
|
virtual void EmitCFIReturnColumn(int64_t Register);
|
||||||
virtual void EmitCFIGnuArgsSize(int64_t Size);
|
virtual void EmitCFIGnuArgsSize(int64_t Size);
|
||||||
virtual void EmitCFISignalFrame();
|
virtual void EmitCFISignalFrame();
|
||||||
virtual void EmitCFIUndefined(int64_t Register);
|
virtual void EmitCFIUndefined(int64_t Register);
|
||||||
|
@ -265,6 +265,7 @@ public:
|
|||||||
void EmitCFIUndefined(int64_t Register) override;
|
void EmitCFIUndefined(int64_t Register) override;
|
||||||
void EmitCFIRegister(int64_t Register1, int64_t Register2) override;
|
void EmitCFIRegister(int64_t Register1, int64_t Register2) override;
|
||||||
void EmitCFIWindowSave() override;
|
void EmitCFIWindowSave() override;
|
||||||
|
void EmitCFIReturnColumn(int64_t Register) override;
|
||||||
|
|
||||||
void EmitWinCFIStartProc(const MCSymbol *Symbol) override;
|
void EmitWinCFIStartProc(const MCSymbol *Symbol) override;
|
||||||
void EmitWinCFIEndProc() override;
|
void EmitWinCFIEndProc() override;
|
||||||
@ -1398,6 +1399,12 @@ void MCAsmStreamer::EmitCFIWindowSave() {
|
|||||||
EmitEOL();
|
EmitEOL();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void MCAsmStreamer::EmitCFIReturnColumn(int64_t Register) {
|
||||||
|
MCStreamer::EmitCFIReturnColumn(Register);
|
||||||
|
OS << "\t.cfi_return_column " << Register;
|
||||||
|
EmitEOL();
|
||||||
|
}
|
||||||
|
|
||||||
void MCAsmStreamer::EmitWinCFIStartProc(const MCSymbol *Symbol) {
|
void MCAsmStreamer::EmitWinCFIStartProc(const MCSymbol *Symbol) {
|
||||||
MCStreamer::EmitWinCFIStartProc(Symbol);
|
MCStreamer::EmitWinCFIStartProc(Symbol);
|
||||||
|
|
||||||
|
@ -1037,7 +1037,7 @@ public:
|
|||||||
const MCSymbol &EmitCIE(const MCSymbol *personality,
|
const MCSymbol &EmitCIE(const MCSymbol *personality,
|
||||||
unsigned personalityEncoding, const MCSymbol *lsda,
|
unsigned personalityEncoding, const MCSymbol *lsda,
|
||||||
bool IsSignalFrame, unsigned lsdaEncoding,
|
bool IsSignalFrame, unsigned lsdaEncoding,
|
||||||
bool IsSimple);
|
bool IsSimple, unsigned RAReg);
|
||||||
void EmitFDE(const MCSymbol &cieStart, const MCDwarfFrameInfo &frame,
|
void EmitFDE(const MCSymbol &cieStart, const MCDwarfFrameInfo &frame,
|
||||||
bool LastInSection, const MCSymbol &SectionStart);
|
bool LastInSection, const MCSymbol &SectionStart);
|
||||||
void EmitCFIInstructions(ArrayRef<MCCFIInstruction> Instrs,
|
void EmitCFIInstructions(ArrayRef<MCCFIInstruction> Instrs,
|
||||||
@ -1277,8 +1277,8 @@ const MCSymbol &FrameEmitterImpl::EmitCIE(const MCSymbol *personality,
|
|||||||
unsigned personalityEncoding,
|
unsigned personalityEncoding,
|
||||||
const MCSymbol *lsda,
|
const MCSymbol *lsda,
|
||||||
bool IsSignalFrame,
|
bool IsSignalFrame,
|
||||||
unsigned lsdaEncoding,
|
unsigned lsdaEncoding, bool IsSimple,
|
||||||
bool IsSimple) {
|
unsigned RAReg) {
|
||||||
MCContext &context = Streamer.getContext();
|
MCContext &context = Streamer.getContext();
|
||||||
const MCRegisterInfo *MRI = context.getRegisterInfo();
|
const MCRegisterInfo *MRI = context.getRegisterInfo();
|
||||||
const MCObjectFileInfo *MOFI = context.getObjectFileInfo();
|
const MCObjectFileInfo *MOFI = context.getObjectFileInfo();
|
||||||
@ -1331,13 +1331,15 @@ const MCSymbol &FrameEmitterImpl::EmitCIE(const MCSymbol *personality,
|
|||||||
Streamer.EmitSLEB128IntValue(getDataAlignmentFactor(Streamer));
|
Streamer.EmitSLEB128IntValue(getDataAlignmentFactor(Streamer));
|
||||||
|
|
||||||
// Return Address Register
|
// Return Address Register
|
||||||
|
if (RAReg == static_cast<unsigned>(INT_MAX))
|
||||||
|
RAReg = MRI->getDwarfRegNum(MRI->getRARegister(), IsEH);
|
||||||
|
|
||||||
if (CIEVersion == 1) {
|
if (CIEVersion == 1) {
|
||||||
assert(MRI->getRARegister() <= 255 &&
|
assert(RAReg <= 255 &&
|
||||||
"DWARF 2 encodes return_address_register in one byte");
|
"DWARF 2 encodes return_address_register in one byte");
|
||||||
Streamer.EmitIntValue(MRI->getDwarfRegNum(MRI->getRARegister(), IsEH), 1);
|
Streamer.EmitIntValue(RAReg, 1);
|
||||||
} else {
|
} else {
|
||||||
Streamer.EmitULEB128IntValue(
|
Streamer.EmitULEB128IntValue(RAReg);
|
||||||
MRI->getDwarfRegNum(MRI->getRARegister(), IsEH));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Augmentation Data Length (optional)
|
// Augmentation Data Length (optional)
|
||||||
@ -1563,9 +1565,9 @@ void MCDwarfFrameEmitter::Emit(MCObjectStreamer &Streamer, MCAsmBackend *MAB,
|
|||||||
Frame.LsdaEncoding, Frame.IsSignalFrame, Frame.IsSimple);
|
Frame.LsdaEncoding, Frame.IsSignalFrame, Frame.IsSimple);
|
||||||
const MCSymbol *&CIEStart = IsEH ? CIEStarts[Key] : DummyDebugKey;
|
const MCSymbol *&CIEStart = IsEH ? CIEStarts[Key] : DummyDebugKey;
|
||||||
if (!CIEStart)
|
if (!CIEStart)
|
||||||
CIEStart = &Emitter.EmitCIE(Frame.Personality, Frame.PersonalityEncoding,
|
CIEStart = &Emitter.EmitCIE(
|
||||||
Frame.Lsda, Frame.IsSignalFrame,
|
Frame.Personality, Frame.PersonalityEncoding, Frame.Lsda,
|
||||||
Frame.LsdaEncoding, Frame.IsSimple);
|
Frame.IsSignalFrame, Frame.LsdaEncoding, Frame.IsSimple, Frame.RAReg);
|
||||||
|
|
||||||
Emitter.EmitFDE(*CIEStart, Frame, I == E, *SectionStart);
|
Emitter.EmitFDE(*CIEStart, Frame, I == E, *SectionStart);
|
||||||
}
|
}
|
||||||
|
@ -517,6 +517,7 @@ private:
|
|||||||
DK_CFI_SAME_VALUE,
|
DK_CFI_SAME_VALUE,
|
||||||
DK_CFI_RESTORE,
|
DK_CFI_RESTORE,
|
||||||
DK_CFI_ESCAPE,
|
DK_CFI_ESCAPE,
|
||||||
|
DK_CFI_RETURN_COLUMN,
|
||||||
DK_CFI_SIGNAL_FRAME,
|
DK_CFI_SIGNAL_FRAME,
|
||||||
DK_CFI_UNDEFINED,
|
DK_CFI_UNDEFINED,
|
||||||
DK_CFI_REGISTER,
|
DK_CFI_REGISTER,
|
||||||
@ -594,6 +595,7 @@ private:
|
|||||||
bool parseDirectiveCFISameValue(SMLoc DirectiveLoc);
|
bool parseDirectiveCFISameValue(SMLoc DirectiveLoc);
|
||||||
bool parseDirectiveCFIRestore(SMLoc DirectiveLoc);
|
bool parseDirectiveCFIRestore(SMLoc DirectiveLoc);
|
||||||
bool parseDirectiveCFIEscape();
|
bool parseDirectiveCFIEscape();
|
||||||
|
bool parseDirectiveCFIReturnColumn(SMLoc DirectiveLoc);
|
||||||
bool parseDirectiveCFISignalFrame();
|
bool parseDirectiveCFISignalFrame();
|
||||||
bool parseDirectiveCFIUndefined(SMLoc DirectiveLoc);
|
bool parseDirectiveCFIUndefined(SMLoc DirectiveLoc);
|
||||||
|
|
||||||
@ -2065,6 +2067,8 @@ bool AsmParser::parseStatement(ParseStatementInfo &Info,
|
|||||||
return parseDirectiveCFIRestore(IDLoc);
|
return parseDirectiveCFIRestore(IDLoc);
|
||||||
case DK_CFI_ESCAPE:
|
case DK_CFI_ESCAPE:
|
||||||
return parseDirectiveCFIEscape();
|
return parseDirectiveCFIEscape();
|
||||||
|
case DK_CFI_RETURN_COLUMN:
|
||||||
|
return parseDirectiveCFIReturnColumn(IDLoc);
|
||||||
case DK_CFI_SIGNAL_FRAME:
|
case DK_CFI_SIGNAL_FRAME:
|
||||||
return parseDirectiveCFISignalFrame();
|
return parseDirectiveCFISignalFrame();
|
||||||
case DK_CFI_UNDEFINED:
|
case DK_CFI_UNDEFINED:
|
||||||
@ -4019,6 +4023,16 @@ bool AsmParser::parseDirectiveCFIEscape() {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// parseDirectiveCFIReturnColumn
|
||||||
|
/// ::= .cfi_return_column register
|
||||||
|
bool AsmParser::parseDirectiveCFIReturnColumn(SMLoc DirectiveLoc) {
|
||||||
|
int64_t Register = 0;
|
||||||
|
if (parseRegisterOrRegisterNumber(Register, DirectiveLoc))
|
||||||
|
return true;
|
||||||
|
getStreamer().EmitCFIReturnColumn(Register);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
/// parseDirectiveCFISignalFrame
|
/// parseDirectiveCFISignalFrame
|
||||||
/// ::= .cfi_signal_frame
|
/// ::= .cfi_signal_frame
|
||||||
bool AsmParser::parseDirectiveCFISignalFrame() {
|
bool AsmParser::parseDirectiveCFISignalFrame() {
|
||||||
@ -5138,6 +5152,7 @@ void AsmParser::initializeDirectiveKindMap() {
|
|||||||
DirectiveKindMap[".cfi_same_value"] = DK_CFI_SAME_VALUE;
|
DirectiveKindMap[".cfi_same_value"] = DK_CFI_SAME_VALUE;
|
||||||
DirectiveKindMap[".cfi_restore"] = DK_CFI_RESTORE;
|
DirectiveKindMap[".cfi_restore"] = DK_CFI_RESTORE;
|
||||||
DirectiveKindMap[".cfi_escape"] = DK_CFI_ESCAPE;
|
DirectiveKindMap[".cfi_escape"] = DK_CFI_ESCAPE;
|
||||||
|
DirectiveKindMap[".cfi_return_column"] = DK_CFI_RETURN_COLUMN;
|
||||||
DirectiveKindMap[".cfi_signal_frame"] = DK_CFI_SIGNAL_FRAME;
|
DirectiveKindMap[".cfi_signal_frame"] = DK_CFI_SIGNAL_FRAME;
|
||||||
DirectiveKindMap[".cfi_undefined"] = DK_CFI_UNDEFINED;
|
DirectiveKindMap[".cfi_undefined"] = DK_CFI_UNDEFINED;
|
||||||
DirectiveKindMap[".cfi_register"] = DK_CFI_REGISTER;
|
DirectiveKindMap[".cfi_register"] = DK_CFI_REGISTER;
|
||||||
|
@ -508,6 +508,12 @@ void MCStreamer::EmitCFIWindowSave() {
|
|||||||
CurFrame->Instructions.push_back(Instruction);
|
CurFrame->Instructions.push_back(Instruction);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void MCStreamer::EmitCFIReturnColumn(int64_t Register) {
|
||||||
|
EnsureValidDwarfFrame();
|
||||||
|
MCDwarfFrameInfo *CurFrame = getCurrentDwarfFrameInfo();
|
||||||
|
CurFrame->RAReg = Register;
|
||||||
|
}
|
||||||
|
|
||||||
void MCStreamer::EnsureValidWinFrameInfo() {
|
void MCStreamer::EnsureValidWinFrameInfo() {
|
||||||
const MCAsmInfo *MAI = Context.getAsmInfo();
|
const MCAsmInfo *MAI = Context.getAsmInfo();
|
||||||
if (!MAI->usesWindowsCFI())
|
if (!MAI->usesWindowsCFI())
|
||||||
|
17
test/Assembler/return-column.s
Normal file
17
test/Assembler/return-column.s
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
// RUN: llvm-mc -triple i686-unknown-linux-gnu -filetype asm -o - %s | FileCheck %s -check-prefix CHECK-ASM-ROUNDTRIP
|
||||||
|
// RUN: llvm-mc -triple i686-unknown-linux-gnu -filetype obj -o - %s | llvm-objdump -s -j .eh_frame - | FileCheck %s -check-prefix CHECK-EH_FRAME
|
||||||
|
|
||||||
|
.text
|
||||||
|
|
||||||
|
proc:
|
||||||
|
.cfi_startproc
|
||||||
|
.cfi_return_column 0
|
||||||
|
.cfi_endproc
|
||||||
|
|
||||||
|
// CHECK-ASM-ROUNDTRIP: .cfi_startproc
|
||||||
|
// CHECK-ASM-ROUNDTRIP-NEXT: .cfi_return_column 0
|
||||||
|
// CHECK-ASM-ROUNDTRIP: .cfi_endproc
|
||||||
|
|
||||||
|
// CHECK-EH_FRAME: Contents of section .eh_frame:
|
||||||
|
// CHECK-EH_FRAME: 0000 14000000 00000000 017a5200 017c0001 .........zR..|..
|
||||||
|
|
Loading…
Reference in New Issue
Block a user