mirror of
https://github.com/RPCS3/llvm.git
synced 2024-11-28 14:10:55 +00:00
Add support for .cfi_signal_frame. Fixes pr11762.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@148733 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
e55bbfe145
commit
16d7d437e0
@ -312,7 +312,8 @@ namespace llvm {
|
||||
struct MCDwarfFrameInfo {
|
||||
MCDwarfFrameInfo() : Begin(0), End(0), Personality(0), Lsda(0),
|
||||
Function(0), Instructions(), PersonalityEncoding(),
|
||||
LsdaEncoding(0), CompactUnwindEncoding(0) {}
|
||||
LsdaEncoding(0), CompactUnwindEncoding(0),
|
||||
IsSignalFrame(false) {}
|
||||
MCSymbol *Begin;
|
||||
MCSymbol *End;
|
||||
const MCSymbol *Personality;
|
||||
@ -322,6 +323,7 @@ namespace llvm {
|
||||
unsigned PersonalityEncoding;
|
||||
unsigned LsdaEncoding;
|
||||
uint32_t CompactUnwindEncoding;
|
||||
bool IsSignalFrame;
|
||||
};
|
||||
|
||||
class MCDwarfFrameEmitter {
|
||||
|
@ -555,6 +555,7 @@ namespace llvm {
|
||||
virtual void EmitCFIRelOffset(int64_t Register, int64_t Offset);
|
||||
virtual void EmitCFIAdjustCfaOffset(int64_t Adjustment);
|
||||
virtual void EmitCFIEscape(StringRef Values);
|
||||
virtual void EmitCFISignalFrame();
|
||||
|
||||
virtual void EmitWin64EHStartProc(const MCSymbol *Symbol);
|
||||
virtual void EmitWin64EHEndProc();
|
||||
|
@ -222,6 +222,7 @@ public:
|
||||
virtual void EmitCFISameValue(int64_t Register);
|
||||
virtual void EmitCFIRelOffset(int64_t Register, int64_t Offset);
|
||||
virtual void EmitCFIAdjustCfaOffset(int64_t Adjustment);
|
||||
virtual void EmitCFISignalFrame();
|
||||
|
||||
virtual void EmitWin64EHStartProc(const MCSymbol *Symbol);
|
||||
virtual void EmitWin64EHEndProc();
|
||||
@ -993,6 +994,16 @@ void MCAsmStreamer::EmitCFIAdjustCfaOffset(int64_t Adjustment) {
|
||||
EmitEOL();
|
||||
}
|
||||
|
||||
void MCAsmStreamer::EmitCFISignalFrame() {
|
||||
MCStreamer::EmitCFISignalFrame();
|
||||
|
||||
if (!UseCFI)
|
||||
return;
|
||||
|
||||
OS << "\t.cif_signal_frame";
|
||||
EmitEOL();
|
||||
}
|
||||
|
||||
void MCAsmStreamer::EmitWin64EHStartProc(const MCSymbol *Symbol) {
|
||||
MCStreamer::EmitWin64EHStartProc(Symbol);
|
||||
|
||||
|
@ -840,6 +840,7 @@ namespace {
|
||||
const MCSymbol *personality,
|
||||
unsigned personalityEncoding,
|
||||
const MCSymbol *lsda,
|
||||
bool IsSignalFrame,
|
||||
unsigned lsdaEncoding);
|
||||
MCSymbol *EmitFDE(MCStreamer &streamer,
|
||||
const MCSymbol &cieStart,
|
||||
@ -1111,6 +1112,7 @@ const MCSymbol &FrameEmitterImpl::EmitCIE(MCStreamer &streamer,
|
||||
const MCSymbol *personality,
|
||||
unsigned personalityEncoding,
|
||||
const MCSymbol *lsda,
|
||||
bool IsSignalFrame,
|
||||
unsigned lsdaEncoding) {
|
||||
MCContext &context = streamer.getContext();
|
||||
const MCRegisterInfo &MRI = context.getRegisterInfo();
|
||||
@ -1153,6 +1155,8 @@ const MCSymbol &FrameEmitterImpl::EmitCIE(MCStreamer &streamer,
|
||||
if (lsda)
|
||||
Augmentation += "L";
|
||||
Augmentation += "R";
|
||||
if (IsSignalFrame)
|
||||
Augmentation += "S";
|
||||
streamer.EmitBytes(Augmentation.str(), 0);
|
||||
}
|
||||
streamer.EmitIntValue(0, 1);
|
||||
@ -1312,17 +1316,18 @@ MCSymbol *FrameEmitterImpl::EmitFDE(MCStreamer &streamer,
|
||||
|
||||
namespace {
|
||||
struct CIEKey {
|
||||
static const CIEKey getEmptyKey() { return CIEKey(0, 0, -1); }
|
||||
static const CIEKey getTombstoneKey() { return CIEKey(0, -1, 0); }
|
||||
static const CIEKey getEmptyKey() { return CIEKey(0, 0, -1, false); }
|
||||
static const CIEKey getTombstoneKey() { return CIEKey(0, -1, 0, false); }
|
||||
|
||||
CIEKey(const MCSymbol* Personality_, unsigned PersonalityEncoding_,
|
||||
unsigned LsdaEncoding_) : Personality(Personality_),
|
||||
PersonalityEncoding(PersonalityEncoding_),
|
||||
LsdaEncoding(LsdaEncoding_) {
|
||||
unsigned LsdaEncoding_, bool IsSignalFrame_) :
|
||||
Personality(Personality_), PersonalityEncoding(PersonalityEncoding_),
|
||||
LsdaEncoding(LsdaEncoding_), IsSignalFrame(IsSignalFrame_) {
|
||||
}
|
||||
const MCSymbol* Personality;
|
||||
unsigned PersonalityEncoding;
|
||||
unsigned LsdaEncoding;
|
||||
bool IsSignalFrame;
|
||||
};
|
||||
}
|
||||
|
||||
@ -1340,13 +1345,15 @@ namespace llvm {
|
||||
ID.AddPointer(Key.Personality);
|
||||
ID.AddInteger(Key.PersonalityEncoding);
|
||||
ID.AddInteger(Key.LsdaEncoding);
|
||||
ID.AddBoolean(Key.IsSignalFrame);
|
||||
return ID.ComputeHash();
|
||||
}
|
||||
static bool isEqual(const CIEKey &LHS,
|
||||
const CIEKey &RHS) {
|
||||
return LHS.Personality == RHS.Personality &&
|
||||
LHS.PersonalityEncoding == RHS.PersonalityEncoding &&
|
||||
LHS.LsdaEncoding == RHS.LsdaEncoding;
|
||||
LHS.LsdaEncoding == RHS.LsdaEncoding &&
|
||||
LHS.IsSignalFrame == RHS.IsSignalFrame;
|
||||
}
|
||||
};
|
||||
}
|
||||
@ -1382,11 +1389,12 @@ void MCDwarfFrameEmitter::Emit(MCStreamer &Streamer,
|
||||
for (unsigned i = 0, n = FrameArray.size(); i < n; ++i) {
|
||||
const MCDwarfFrameInfo &Frame = FrameArray[i];
|
||||
CIEKey Key(Frame.Personality, Frame.PersonalityEncoding,
|
||||
Frame.LsdaEncoding);
|
||||
Frame.LsdaEncoding, Frame.IsSignalFrame);
|
||||
const MCSymbol *&CIEStart = IsEH ? CIEStarts[Key] : DummyDebugKey;
|
||||
if (!CIEStart)
|
||||
CIEStart = &Emitter.EmitCIE(Streamer, Frame.Personality,
|
||||
Frame.PersonalityEncoding, Frame.Lsda,
|
||||
Frame.IsSignalFrame,
|
||||
Frame.LsdaEncoding);
|
||||
|
||||
FDEEnd = Emitter.EmitFDE(Streamer, *CIEStart, Frame);
|
||||
|
@ -306,6 +306,8 @@ public:
|
||||
&GenericAsmParser::ParseDirectiveCFIRestore>(".cfi_restore");
|
||||
AddDirectiveHandler<
|
||||
&GenericAsmParser::ParseDirectiveCFIEscape>(".cfi_escape");
|
||||
AddDirectiveHandler<
|
||||
&GenericAsmParser::ParseDirectiveCFISignalFrame>(".cfi_signal_frame");
|
||||
|
||||
// Macro directives.
|
||||
AddDirectiveHandler<&GenericAsmParser::ParseDirectiveMacrosOnOff>(
|
||||
@ -341,6 +343,7 @@ public:
|
||||
bool ParseDirectiveCFISameValue(StringRef, SMLoc DirectiveLoc);
|
||||
bool ParseDirectiveCFIRestore(StringRef, SMLoc DirectiveLoc);
|
||||
bool ParseDirectiveCFIEscape(StringRef, SMLoc DirectiveLoc);
|
||||
bool ParseDirectiveCFISignalFrame(StringRef, SMLoc DirectiveLoc);
|
||||
|
||||
bool ParseDirectiveMacrosOnOff(StringRef, SMLoc DirectiveLoc);
|
||||
bool ParseDirectiveMacro(StringRef, SMLoc DirectiveLoc);
|
||||
@ -2855,6 +2858,19 @@ bool GenericAsmParser::ParseDirectiveCFIEscape(StringRef IDVal,
|
||||
return false;
|
||||
}
|
||||
|
||||
/// ParseDirectiveCFISignalFrame
|
||||
/// ::= .cfi_signal_frame
|
||||
bool GenericAsmParser::ParseDirectiveCFISignalFrame(StringRef Directive,
|
||||
SMLoc DirectiveLoc) {
|
||||
if (getLexer().isNot(AsmToken::EndOfStatement))
|
||||
return Error(getLexer().getLoc(),
|
||||
"unexpected token in '" + Directive + "' directive");
|
||||
|
||||
getStreamer().EmitCFISignalFrame();
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/// ParseDirectiveMacrosOnOff
|
||||
/// ::= .macros_on
|
||||
/// ::= .macros_off
|
||||
|
@ -439,6 +439,12 @@ void MCStreamer::EmitCFIEscape(StringRef Values) {
|
||||
CurFrame->Instructions.push_back(Instruction);
|
||||
}
|
||||
|
||||
void MCStreamer::EmitCFISignalFrame() {
|
||||
EnsureValidFrame();
|
||||
MCDwarfFrameInfo *CurFrame = getCurrentFrameInfo();
|
||||
CurFrame->IsSignalFrame = true;
|
||||
}
|
||||
|
||||
void MCStreamer::setCurrentW64UnwindInfo(MCWin64EHUnwindInfo *Frame) {
|
||||
W64UnwindInfos.push_back(Frame);
|
||||
CurrentW64UnwindInfo = W64UnwindInfos.back();
|
||||
|
23
test/MC/ELF/cfi-signal-frame.s
Normal file
23
test/MC/ELF/cfi-signal-frame.s
Normal file
@ -0,0 +1,23 @@
|
||||
// RUN: llvm-mc -filetype=obj -triple x86_64-pc-linux-gnu %s -o - | elf-dump --dump-section-data | FileCheck %s
|
||||
|
||||
f:
|
||||
.cfi_startproc
|
||||
.cfi_signal_frame
|
||||
.cfi_endproc
|
||||
|
||||
g:
|
||||
.cfi_startproc
|
||||
.cfi_endproc
|
||||
|
||||
// CHECK: (('sh_name', 0x00000011) # '.eh_frame'
|
||||
// CHECK-NEXT: ('sh_type', 0x00000001)
|
||||
// CHECK-NEXT: ('sh_flags', 0x0000000000000002)
|
||||
// CHECK-NEXT: ('sh_addr', 0x0000000000000000)
|
||||
// CHECK-NEXT: ('sh_offset', 0x0000000000000040)
|
||||
// CHECK-NEXT: ('sh_size', 0x0000000000000058)
|
||||
// CHECK-NEXT: ('sh_link', 0x00000000)
|
||||
// CHECK-NEXT: ('sh_info', 0x00000000)
|
||||
// CHECK-NEXT: ('sh_addralign', 0x0000000000000008)
|
||||
// CHECK-NEXT: ('sh_entsize', 0x0000000000000000)
|
||||
// CHECK-NEXT: ('_section_data', '14000000 00000000 017a5253 00017810 011b0c07 08900100 10000000 1c000000 00000000 00000000 00000000 14000000 00000000 017a5200 01781001 1b0c0708 90010000 10000000 1c000000 00000000 00000000 00000000')
|
||||
// CHECK-NEXT: ),
|
Loading…
Reference in New Issue
Block a user