Skip to content

Commit

Permalink
MC: add support for cfi_return_column
Browse files Browse the repository at this point in the history
This adds support for the CFI pseudo-op return_column.  This specifies
the frame table column which contains the return address.

Addresses PR33953!

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@309360 91177308-0d34-0410-b5e6-96231b3b80d8
  • Loading branch information
compnerd committed Jul 28, 2017
1 parent b9aeabb commit 86b02f9
Show file tree
Hide file tree
Showing 7 changed files with 59 additions and 10 deletions.
1 change: 1 addition & 0 deletions include/llvm/MC/MCDwarf.h
Original file line number Diff line number Diff line change
Expand Up @@ -509,6 +509,7 @@ struct MCDwarfFrameInfo {
uint32_t CompactUnwindEncoding = 0;
bool IsSignalFrame = false;
bool IsSimple = false;
unsigned RAReg = static_cast<unsigned>(INT_MAX);
};

class MCDwarfFrameEmitter {
Expand Down
1 change: 1 addition & 0 deletions include/llvm/MC/MCStreamer.h
Original file line number Diff line number Diff line change
Expand Up @@ -797,6 +797,7 @@ class MCStreamer {
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);
Expand Down
7 changes: 7 additions & 0 deletions lib/MC/MCAsmStreamer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -265,6 +265,7 @@ class MCAsmStreamer final : public MCStreamer {
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;
Expand Down Expand Up @@ -1398,6 +1399,12 @@ void MCAsmStreamer::EmitCFIWindowSave() {
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);

Expand Down
22 changes: 12 additions & 10 deletions lib/MC/MCDwarf.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1037,7 +1037,7 @@ class FrameEmitterImpl {
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,
Expand Down Expand Up @@ -1277,8 +1277,8 @@ const MCSymbol &FrameEmitterImpl::EmitCIE(const MCSymbol *personality,
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();
Expand Down Expand Up @@ -1331,13 +1331,15 @@ const MCSymbol &FrameEmitterImpl::EmitCIE(const MCSymbol *personality,
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)
Expand Down Expand Up @@ -1563,9 +1565,9 @@ void MCDwarfFrameEmitter::Emit(MCObjectStreamer &Streamer, MCAsmBackend *MAB,
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);
}
Expand Down
15 changes: 15 additions & 0 deletions lib/MC/MCParser/AsmParser.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -517,6 +517,7 @@ class AsmParser : public MCAsmParser {
DK_CFI_SAME_VALUE,
DK_CFI_RESTORE,
DK_CFI_ESCAPE,
DK_CFI_RETURN_COLUMN,
DK_CFI_SIGNAL_FRAME,
DK_CFI_UNDEFINED,
DK_CFI_REGISTER,
Expand Down Expand Up @@ -594,6 +595,7 @@ class AsmParser : public MCAsmParser {
bool parseDirectiveCFISameValue(SMLoc DirectiveLoc);
bool parseDirectiveCFIRestore(SMLoc DirectiveLoc);
bool parseDirectiveCFIEscape();
bool parseDirectiveCFIReturnColumn(SMLoc DirectiveLoc);
bool parseDirectiveCFISignalFrame();
bool parseDirectiveCFIUndefined(SMLoc DirectiveLoc);

Expand Down Expand Up @@ -2065,6 +2067,8 @@ bool AsmParser::parseStatement(ParseStatementInfo &Info,
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:
Expand Down Expand Up @@ -4019,6 +4023,16 @@ bool AsmParser::parseDirectiveCFIEscape() {
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() {
Expand Down Expand Up @@ -5138,6 +5152,7 @@ void AsmParser::initializeDirectiveKindMap() {
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;
Expand Down
6 changes: 6 additions & 0 deletions lib/MC/MCStreamer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -508,6 +508,12 @@ void MCStreamer::EmitCFIWindowSave() {
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())
Expand Down
17 changes: 17 additions & 0 deletions test/Assembler/return-column.s
Original file line number Diff line number Diff line change
@@ -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..|..

0 comments on commit 86b02f9

Please sign in to comment.