uint32_t CompactUnwindEncoding = 0;
bool IsSignalFrame = false;
bool IsSimple = false;
+ unsigned RAReg = static_cast<unsigned>(INT_MAX);
};
class MCDwarfFrameEmitter {
virtual void EmitCFIRelOffset(int64_t Register, int64_t Offset);
virtual void EmitCFIAdjustCfaOffset(int64_t Adjustment);
virtual void EmitCFIEscape(StringRef Values);
+ virtual void EmitCFIReturnColumn(int64_t Register);
virtual void EmitCFIGnuArgsSize(int64_t Size);
virtual void EmitCFISignalFrame();
virtual void EmitCFIUndefined(int64_t Register);
void EmitCFIUndefined(int64_t Register) override;
void EmitCFIRegister(int64_t Register1, int64_t Register2) override;
void EmitCFIWindowSave() override;
+ void EmitCFIReturnColumn(int64_t Register) override;
void EmitWinCFIStartProc(const MCSymbol *Symbol) override;
void EmitWinCFIEndProc() override;
EmitEOL();
}
+void MCAsmStreamer::EmitCFIReturnColumn(int64_t Register) {
+ MCStreamer::EmitCFIReturnColumn(Register);
+ OS << "\t.cfi_return_column " << Register;
+ EmitEOL();
+}
+
void MCAsmStreamer::EmitWinCFIStartProc(const MCSymbol *Symbol) {
MCStreamer::EmitWinCFIStartProc(Symbol);
const MCSymbol &EmitCIE(const MCSymbol *personality,
unsigned personalityEncoding, const MCSymbol *lsda,
bool IsSignalFrame, unsigned lsdaEncoding,
- bool IsSimple);
+ bool IsSimple, unsigned RAReg);
void EmitFDE(const MCSymbol &cieStart, const MCDwarfFrameInfo &frame,
bool LastInSection, const MCSymbol &SectionStart);
void EmitCFIInstructions(ArrayRef<MCCFIInstruction> Instrs,
unsigned personalityEncoding,
const MCSymbol *lsda,
bool IsSignalFrame,
- unsigned lsdaEncoding,
- bool IsSimple) {
+ unsigned lsdaEncoding, bool IsSimple,
+ unsigned RAReg) {
MCContext &context = Streamer.getContext();
const MCRegisterInfo *MRI = context.getRegisterInfo();
const MCObjectFileInfo *MOFI = context.getObjectFileInfo();
Streamer.EmitSLEB128IntValue(getDataAlignmentFactor(Streamer));
// Return Address Register
+ if (RAReg == static_cast<unsigned>(INT_MAX))
+ RAReg = MRI->getDwarfRegNum(MRI->getRARegister(), IsEH);
+
if (CIEVersion == 1) {
- assert(MRI->getRARegister() <= 255 &&
+ assert(RAReg <= 255 &&
"DWARF 2 encodes return_address_register in one byte");
- Streamer.EmitIntValue(MRI->getDwarfRegNum(MRI->getRARegister(), IsEH), 1);
+ Streamer.EmitIntValue(RAReg, 1);
} else {
- Streamer.EmitULEB128IntValue(
- MRI->getDwarfRegNum(MRI->getRARegister(), IsEH));
+ Streamer.EmitULEB128IntValue(RAReg);
}
// Augmentation Data Length (optional)
Frame.LsdaEncoding, Frame.IsSignalFrame, Frame.IsSimple);
const MCSymbol *&CIEStart = IsEH ? CIEStarts[Key] : DummyDebugKey;
if (!CIEStart)
- CIEStart = &Emitter.EmitCIE(Frame.Personality, Frame.PersonalityEncoding,
- Frame.Lsda, Frame.IsSignalFrame,
- Frame.LsdaEncoding, Frame.IsSimple);
+ CIEStart = &Emitter.EmitCIE(
+ Frame.Personality, Frame.PersonalityEncoding, Frame.Lsda,
+ Frame.IsSignalFrame, Frame.LsdaEncoding, Frame.IsSimple, Frame.RAReg);
Emitter.EmitFDE(*CIEStart, Frame, I == E, *SectionStart);
}
DK_CFI_SAME_VALUE,
DK_CFI_RESTORE,
DK_CFI_ESCAPE,
+ DK_CFI_RETURN_COLUMN,
DK_CFI_SIGNAL_FRAME,
DK_CFI_UNDEFINED,
DK_CFI_REGISTER,
bool parseDirectiveCFISameValue(SMLoc DirectiveLoc);
bool parseDirectiveCFIRestore(SMLoc DirectiveLoc);
bool parseDirectiveCFIEscape();
+ bool parseDirectiveCFIReturnColumn(SMLoc DirectiveLoc);
bool parseDirectiveCFISignalFrame();
bool parseDirectiveCFIUndefined(SMLoc DirectiveLoc);
return parseDirectiveCFIRestore(IDLoc);
case DK_CFI_ESCAPE:
return parseDirectiveCFIEscape();
+ case DK_CFI_RETURN_COLUMN:
+ return parseDirectiveCFIReturnColumn(IDLoc);
case DK_CFI_SIGNAL_FRAME:
return parseDirectiveCFISignalFrame();
case DK_CFI_UNDEFINED:
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
/// ::= .cfi_signal_frame
bool AsmParser::parseDirectiveCFISignalFrame() {
DirectiveKindMap[".cfi_same_value"] = DK_CFI_SAME_VALUE;
DirectiveKindMap[".cfi_restore"] = DK_CFI_RESTORE;
DirectiveKindMap[".cfi_escape"] = DK_CFI_ESCAPE;
+ DirectiveKindMap[".cfi_return_column"] = DK_CFI_RETURN_COLUMN;
DirectiveKindMap[".cfi_signal_frame"] = DK_CFI_SIGNAL_FRAME;
DirectiveKindMap[".cfi_undefined"] = DK_CFI_UNDEFINED;
DirectiveKindMap[".cfi_register"] = DK_CFI_REGISTER;
CurFrame->Instructions.push_back(Instruction);
}
+void MCStreamer::EmitCFIReturnColumn(int64_t Register) {
+ EnsureValidDwarfFrame();
+ MCDwarfFrameInfo *CurFrame = getCurrentDwarfFrameInfo();
+ CurFrame->RAReg = Register;
+}
+
void MCStreamer::EnsureValidWinFrameInfo() {
const MCAsmInfo *MAI = Context.getAsmInfo();
if (!MAI->usesWindowsCFI())
--- /dev/null
+// 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..|..
+