[llvm] r349895 - [Dwarf/AArch64] Return address signing B key dwarf support
Luke Cheeseman via llvm-commits
llvm-commits at lists.llvm.org
Fri Dec 21 02:45:08 PST 2018
Author: lukecheeseman
Date: Fri Dec 21 02:45:08 2018
New Revision: 349895
URL: http://llvm.org/viewvc/llvm-project?rev=349895&view=rev
Log:
[Dwarf/AArch64] Return address signing B key dwarf support
- When signing return addresses with -msign-return-address=<scope>{+<key>},
either the A key instructions or the B key instructions can be used. To
correctly authenticate the return address, the unwinder/debugger must know
which key was used to sign the return address.
- When and exception is thrown or a break point reached, it may be necessary to
unwind the stack. To accomplish this, the unwinder/debugger must be able to
first authenticate an the return address if it has been signed.
- To enable this, the augmentation string of CIEs has been extended to allow
inclusion of a 'B' character. Functions that are signed using the B key
variant of the instructions should have and FDE whose associated CIE has a 'B'
in the augmentation string.
- One must also be able to preserve these semantics when first stepping from a
high level language into assembly and then, as a second step, into an object
file. To achieve this, I have introduced a new assembly directive
'.cfi_b_key_frame ', that tells the assembler the current frame uses return
address signing with the B key.
- This ensures that the FDE is associated with a CIE that has 'B' in the
augmentation string.
Differential Revision: https://reviews.llvm.org/D51798
Added:
llvm/trunk/test/CodeGen/MIR/AArch64/return-address-signing.mir
llvm/trunk/test/DebugInfo/AArch64/return-address-signing.ll
llvm/trunk/test/MC/ELF/cfi-b-key-frame.s
Modified:
llvm/trunk/include/llvm/MC/MCDwarf.h
llvm/trunk/include/llvm/MC/MCStreamer.h
llvm/trunk/lib/DebugInfo/DWARF/DWARFDebugFrame.cpp
llvm/trunk/lib/MC/MCAsmStreamer.cpp
llvm/trunk/lib/MC/MCDwarf.cpp
llvm/trunk/lib/MC/MCParser/AsmParser.cpp
llvm/trunk/lib/MC/MCStreamer.cpp
llvm/trunk/lib/Target/AArch64/AArch64AsmPrinter.cpp
llvm/trunk/lib/Target/AArch64/AArch64FrameLowering.cpp
llvm/trunk/lib/Target/AArch64/AArch64InstrInfo.td
llvm/trunk/lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp
Modified: llvm/trunk/include/llvm/MC/MCDwarf.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/MC/MCDwarf.h?rev=349895&r1=349894&r2=349895&view=diff
==============================================================================
--- llvm/trunk/include/llvm/MC/MCDwarf.h (original)
+++ llvm/trunk/include/llvm/MC/MCDwarf.h Fri Dec 21 02:45:08 2018
@@ -599,6 +599,7 @@ struct MCDwarfFrameInfo {
bool IsSignalFrame = false;
bool IsSimple = false;
unsigned RAReg = static_cast<unsigned>(INT_MAX);
+ bool IsBKeyFrame = false;
};
class MCDwarfFrameEmitter {
Modified: llvm/trunk/include/llvm/MC/MCStreamer.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/MC/MCStreamer.h?rev=349895&r1=349894&r2=349895&view=diff
==============================================================================
--- llvm/trunk/include/llvm/MC/MCStreamer.h (original)
+++ llvm/trunk/include/llvm/MC/MCStreamer.h Fri Dec 21 02:45:08 2018
@@ -806,6 +806,8 @@ public:
Optional<StringRef> Source,
unsigned CUID = 0);
+ virtual void EmitCFIBKeyFrame();
+
/// This implements the DWARF2 '.loc fileno lineno ...' assembler
/// directive.
virtual void EmitDwarfLocDirective(unsigned FileNo, unsigned Line,
Modified: llvm/trunk/lib/DebugInfo/DWARF/DWARFDebugFrame.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/DebugInfo/DWARF/DWARFDebugFrame.cpp?rev=349895&r1=349894&r2=349895&view=diff
==============================================================================
--- llvm/trunk/lib/DebugInfo/DWARF/DWARFDebugFrame.cpp (original)
+++ llvm/trunk/lib/DebugInfo/DWARF/DWARFDebugFrame.cpp Fri Dec 21 02:45:08 2018
@@ -446,6 +446,11 @@ void DWARFDebugFrame::parse(DWARFDataExt
StartAugmentationOffset = Offset;
EndAugmentationOffset = Offset +
static_cast<uint32_t>(*AugmentationLength);
+ break;
+ case 'B':
+ // B-Key is used for signing functions associated with this
+ // augmentation string
+ break;
}
}
Modified: llvm/trunk/lib/MC/MCAsmStreamer.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/MC/MCAsmStreamer.cpp?rev=349895&r1=349894&r2=349895&view=diff
==============================================================================
--- llvm/trunk/lib/MC/MCAsmStreamer.cpp (original)
+++ llvm/trunk/lib/MC/MCAsmStreamer.cpp Fri Dec 21 02:45:08 2018
@@ -266,6 +266,7 @@ public:
void EmitCVFPOData(const MCSymbol *ProcSym, SMLoc L) override;
void EmitIdent(StringRef IdentString) override;
+ void EmitCFIBKeyFrame() override;
void EmitCFISections(bool EH, bool Debug) override;
void EmitCFIDefCfa(int64_t Register, int64_t Offset) override;
void EmitCFIDefCfaOffset(int64_t Offset) override;
@@ -1602,6 +1603,12 @@ void MCAsmStreamer::EmitCFIReturnColumn(
EmitEOL();
}
+void MCAsmStreamer::EmitCFIBKeyFrame() {
+ MCStreamer::EmitCFIBKeyFrame();
+ OS << "\t.cfi_b_key_frame";
+ EmitEOL();
+}
+
void MCAsmStreamer::EmitWinCFIStartProc(const MCSymbol *Symbol, SMLoc Loc) {
MCStreamer::EmitWinCFIStartProc(Symbol, Loc);
Modified: llvm/trunk/lib/MC/MCDwarf.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/MC/MCDwarf.cpp?rev=349895&r1=349894&r2=349895&view=diff
==============================================================================
--- llvm/trunk/lib/MC/MCDwarf.cpp (original)
+++ llvm/trunk/lib/MC/MCDwarf.cpp Fri Dec 21 02:45:08 2018
@@ -1565,9 +1565,8 @@ const MCSymbol &FrameEmitterImpl::EmitCI
uint8_t CIEVersion = getCIEVersion(IsEH, context.getDwarfVersion());
Streamer.EmitIntValue(CIEVersion, 1);
- // Augmentation String
- SmallString<8> Augmentation;
if (IsEH) {
+ SmallString<8> Augmentation;
Augmentation += "z";
if (Frame.Personality)
Augmentation += "P";
@@ -1576,6 +1575,8 @@ const MCSymbol &FrameEmitterImpl::EmitCI
Augmentation += "R";
if (Frame.IsSignalFrame)
Augmentation += "S";
+ if (Frame.IsBKeyFrame)
+ Augmentation += "B";
Streamer.EmitBytes(Augmentation);
}
Streamer.EmitIntValue(0, 1);
@@ -1730,25 +1731,28 @@ namespace {
struct CIEKey {
static const CIEKey getEmptyKey() {
- return CIEKey(nullptr, 0, -1, false, false, static_cast<unsigned>(INT_MAX));
+ return CIEKey(nullptr, 0, -1, false, false, static_cast<unsigned>(INT_MAX),
+ false);
}
static const CIEKey getTombstoneKey() {
- return CIEKey(nullptr, -1, 0, false, false, static_cast<unsigned>(INT_MAX));
+ return CIEKey(nullptr, -1, 0, false, false, static_cast<unsigned>(INT_MAX),
+ false);
}
CIEKey(const MCSymbol *Personality, unsigned PersonalityEncoding,
unsigned LSDAEncoding, bool IsSignalFrame, bool IsSimple,
- unsigned RAReg)
+ unsigned RAReg, bool IsBKeyFrame)
: Personality(Personality), PersonalityEncoding(PersonalityEncoding),
LsdaEncoding(LSDAEncoding), IsSignalFrame(IsSignalFrame),
- IsSimple(IsSimple), RAReg(RAReg) {}
+ IsSimple(IsSimple), RAReg(RAReg), IsBKeyFrame(IsBKeyFrame) {}
explicit CIEKey(const MCDwarfFrameInfo &Frame)
: Personality(Frame.Personality),
PersonalityEncoding(Frame.PersonalityEncoding),
LsdaEncoding(Frame.LsdaEncoding), IsSignalFrame(Frame.IsSignalFrame),
- IsSimple(Frame.IsSimple), RAReg(Frame.RAReg) {}
+ IsSimple(Frame.IsSimple), RAReg(Frame.RAReg),
+ IsBKeyFrame(Frame.IsBKeyFrame) {}
const MCSymbol *Personality;
unsigned PersonalityEncoding;
@@ -1756,6 +1760,7 @@ struct CIEKey {
bool IsSignalFrame;
bool IsSimple;
unsigned RAReg;
+ bool IsBKeyFrame;
};
} // end anonymous namespace
@@ -1767,9 +1772,9 @@ template <> struct DenseMapInfo<CIEKey>
static CIEKey getTombstoneKey() { return CIEKey::getTombstoneKey(); }
static unsigned getHashValue(const CIEKey &Key) {
- return static_cast<unsigned>(
- hash_combine(Key.Personality, Key.PersonalityEncoding, Key.LsdaEncoding,
- Key.IsSignalFrame, Key.IsSimple, Key.RAReg));
+ return static_cast<unsigned>(hash_combine(
+ Key.Personality, Key.PersonalityEncoding, Key.LsdaEncoding,
+ Key.IsSignalFrame, Key.IsSimple, Key.RAReg, Key.IsBKeyFrame));
}
static bool isEqual(const CIEKey &LHS, const CIEKey &RHS) {
@@ -1777,8 +1782,8 @@ template <> struct DenseMapInfo<CIEKey>
LHS.PersonalityEncoding == RHS.PersonalityEncoding &&
LHS.LsdaEncoding == RHS.LsdaEncoding &&
LHS.IsSignalFrame == RHS.IsSignalFrame &&
- LHS.IsSimple == RHS.IsSimple &&
- LHS.RAReg == RHS.RAReg;
+ LHS.IsSimple == RHS.IsSimple && LHS.RAReg == RHS.RAReg &&
+ LHS.IsBKeyFrame == RHS.IsBKeyFrame;
}
};
Modified: llvm/trunk/lib/MC/MCParser/AsmParser.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/MC/MCParser/AsmParser.cpp?rev=349895&r1=349894&r2=349895&view=diff
==============================================================================
--- llvm/trunk/lib/MC/MCParser/AsmParser.cpp (original)
+++ llvm/trunk/lib/MC/MCParser/AsmParser.cpp Fri Dec 21 02:45:08 2018
@@ -495,6 +495,7 @@ private:
DK_CFI_UNDEFINED,
DK_CFI_REGISTER,
DK_CFI_WINDOW_SAVE,
+ DK_CFI_B_KEY_FRAME,
DK_MACROS_ON,
DK_MACROS_OFF,
DK_ALTMACRO,
@@ -5293,6 +5294,7 @@ void AsmParser::initializeDirectiveKindM
DirectiveKindMap[".cfi_undefined"] = DK_CFI_UNDEFINED;
DirectiveKindMap[".cfi_register"] = DK_CFI_REGISTER;
DirectiveKindMap[".cfi_window_save"] = DK_CFI_WINDOW_SAVE;
+ DirectiveKindMap[".cfi_b_key_frame"] = DK_CFI_B_KEY_FRAME;
DirectiveKindMap[".macros_on"] = DK_MACROS_ON;
DirectiveKindMap[".macros_off"] = DK_MACROS_OFF;
DirectiveKindMap[".macro"] = DK_MACRO;
Modified: llvm/trunk/lib/MC/MCStreamer.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/MC/MCStreamer.cpp?rev=349895&r1=349894&r2=349895&view=diff
==============================================================================
--- llvm/trunk/lib/MC/MCStreamer.cpp (original)
+++ llvm/trunk/lib/MC/MCStreamer.cpp Fri Dec 21 02:45:08 2018
@@ -221,6 +221,13 @@ void MCStreamer::emitDwarfFile0Directive
Source);
}
+void MCStreamer::EmitCFIBKeyFrame() {
+ MCDwarfFrameInfo *CurFrame = getCurrentDwarfFrameInfo();
+ if (!CurFrame)
+ return;
+ CurFrame->IsBKeyFrame = true;
+}
+
void MCStreamer::EmitDwarfLocDirective(unsigned FileNo, unsigned Line,
unsigned Column, unsigned Flags,
unsigned Isa,
Modified: llvm/trunk/lib/Target/AArch64/AArch64AsmPrinter.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/AArch64/AArch64AsmPrinter.cpp?rev=349895&r1=349894&r2=349895&view=diff
==============================================================================
--- llvm/trunk/lib/Target/AArch64/AArch64AsmPrinter.cpp (original)
+++ llvm/trunk/lib/Target/AArch64/AArch64AsmPrinter.cpp Fri Dec 21 02:45:08 2018
@@ -716,6 +716,19 @@ void AArch64AsmPrinter::EmitInstruction(
OutStreamer->EmitRawText(StringRef(OS.str()));
}
return;
+
+ case AArch64::EMITBKEY: {
+ ExceptionHandling ExceptionHandlingType = MAI->getExceptionHandlingType();
+ if (ExceptionHandlingType != ExceptionHandling::DwarfCFI &&
+ ExceptionHandlingType != ExceptionHandling::ARM)
+ return;
+
+ if (needsCFIMoves() == CFI_M_None)
+ return;
+
+ OutStreamer->EmitCFIBKeyFrame();
+ return;
+ }
}
// Tail calls use pseudo instructions so they have the proper code-gen
Modified: llvm/trunk/lib/Target/AArch64/AArch64FrameLowering.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/AArch64/AArch64FrameLowering.cpp?rev=349895&r1=349894&r2=349895&view=diff
==============================================================================
--- llvm/trunk/lib/Target/AArch64/AArch64FrameLowering.cpp (original)
+++ llvm/trunk/lib/Target/AArch64/AArch64FrameLowering.cpp Fri Dec 21 02:45:08 2018
@@ -816,10 +816,15 @@ void AArch64FrameLowering::emitPrologue(
DebugLoc DL;
if (ShouldSignReturnAddress(MF)) {
- BuildMI(
- MBB, MBBI, DL,
- TII->get(ShouldSignWithAKey(MF) ? AArch64::PACIASP : AArch64::PACIBSP))
- .setMIFlag(MachineInstr::FrameSetup);
+ if (ShouldSignWithAKey(MF))
+ BuildMI(MBB, MBBI, DL, TII->get(AArch64::PACIASP))
+ .setMIFlag(MachineInstr::FrameSetup);
+ else {
+ BuildMI(MBB, MBBI, DL, TII->get(AArch64::EMITBKEY))
+ .setMIFlag(MachineInstr::FrameSetup);
+ BuildMI(MBB, MBBI, DL, TII->get(AArch64::PACIBSP))
+ .setMIFlag(MachineInstr::FrameSetup);
+ }
unsigned CFIIndex =
MF.addFrameInst(MCCFIInstruction::createNegateRAState(nullptr));
Modified: llvm/trunk/lib/Target/AArch64/AArch64InstrInfo.td
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/AArch64/AArch64InstrInfo.td?rev=349895&r1=349894&r2=349895&view=diff
==============================================================================
--- llvm/trunk/lib/Target/AArch64/AArch64InstrInfo.td (original)
+++ llvm/trunk/lib/Target/AArch64/AArch64InstrInfo.td Fri Dec 21 02:45:08 2018
@@ -1619,6 +1619,10 @@ def TLSDESCCALL : Pseudo<(outs), (ins i6
let AsmString = ".tlsdesccall $sym";
}
+// Pseudo instruction to tell the streamer to emit a 'B' character into the
+// augmentation string.
+def EMITBKEY : Pseudo<(outs), (ins), []>, Sched<[]> {}
+
// FIXME: maybe the scratch register used shouldn't be fixed to X1?
// FIXME: can "hasSideEffects be dropped?
let isCall = 1, Defs = [LR, X0, X1], hasSideEffects = 1,
Modified: llvm/trunk/lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp?rev=349895&r1=349894&r2=349895&view=diff
==============================================================================
--- llvm/trunk/lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp (original)
+++ llvm/trunk/lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp Fri Dec 21 02:45:08 2018
@@ -176,6 +176,7 @@ private:
bool parseDirectiveReq(StringRef Name, SMLoc L);
bool parseDirectiveUnreq(SMLoc L);
bool parseDirectiveCFINegateRAState();
+ bool parseDirectiveCFIBKeyFrame();
bool validateInstruction(MCInst &Inst, SMLoc &IDLoc,
SmallVectorImpl<SMLoc> &Loc);
@@ -5030,6 +5031,8 @@ bool AArch64AsmParser::ParseDirective(As
parseDirectiveInst(Loc);
else if (IDVal == ".cfi_negate_ra_state")
parseDirectiveCFINegateRAState();
+ else if (IDVal == ".cfi_b_key_frame")
+ parseDirectiveCFIBKeyFrame();
else if (IsMachO) {
if (IDVal == MCLOHDirectiveName())
parseDirectiveLOH(IDVal, Loc);
@@ -5410,6 +5413,16 @@ bool AArch64AsmParser::parseDirectiveCFI
return false;
}
+/// parseDirectiveCFIBKeyFrame
+/// ::= .cfi_b_key
+bool AArch64AsmParser::parseDirectiveCFIBKeyFrame() {
+ if (parseToken(AsmToken::EndOfStatement,
+ "unexpected token in '.cfi_b_key_frame'"))
+ return true;
+ getStreamer().EmitCFIBKeyFrame();
+ return false;
+}
+
bool
AArch64AsmParser::classifySymbolRef(const MCExpr *Expr,
AArch64MCExpr::VariantKind &ELFRefKind,
Added: llvm/trunk/test/CodeGen/MIR/AArch64/return-address-signing.mir
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/MIR/AArch64/return-address-signing.mir?rev=349895&view=auto
==============================================================================
--- llvm/trunk/test/CodeGen/MIR/AArch64/return-address-signing.mir (added)
+++ llvm/trunk/test/CodeGen/MIR/AArch64/return-address-signing.mir Fri Dec 21 02:45:08 2018
@@ -0,0 +1,48 @@
+# RUN: llc -mtriple=aarch64-arm-none-eabi -run-pass=prologepilog -o - %s 2>&1 | FileCheck %s
+--- |
+ target datalayout = "e-m:e-i8:8:32-i16:16:32-i64:64-i128:128-n32:64-S128"
+ target triple = "aarch64-arm-none-eabi"
+
+ define dso_local i32 @foo() "sign-return-address"="all" "sign-return-address-key"="a_key" {
+ entry:
+ ret i32 2
+ }
+
+ define dso_local i32 @bar() "sign-return-address"="all" "sign-return-address-key"="b_key" {
+ entry:
+ ret i32 2
+ }
+...
+---
+#CHECK: foo
+name: foo
+alignment: 2
+tracksRegLiveness: true
+frameInfo:
+ maxCallFrameSize: 0
+#CHECK: frame-setup PACIASP implicit-def $lr, implicit $lr, implicit $sp
+#CHECK: frame-setup CFI_INSTRUCTION negate_ra_sign_state
+#CHECK: frame-destroy AUTIASP implicit-def $lr, implicit $lr, implicit $sp
+body: |
+ bb.0.entry:
+ $w0 = MOVi32imm 2
+ RET_ReallyLR implicit killed $w0
+
+...
+---
+#CHECK: bar
+name: bar
+alignment: 2
+tracksRegLiveness: true
+frameInfo:
+ maxCallFrameSize: 0
+#CHECK: frame-setup EMITBKEY
+#CHECK: frame-setup PACIBSP implicit-def $lr, implicit $lr, implicit $sp
+#CHECK: frame-setup CFI_INSTRUCTION negate_ra_sign_state
+#CHECK: frame-destroy AUTIBSP implicit-def $lr, implicit $lr, implicit $sp
+body: |
+ bb.0.entry:
+ $w0 = MOVi32imm 2
+ RET_ReallyLR implicit killed $w0
+
+...
Added: llvm/trunk/test/DebugInfo/AArch64/return-address-signing.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/DebugInfo/AArch64/return-address-signing.ll?rev=349895&view=auto
==============================================================================
--- llvm/trunk/test/DebugInfo/AArch64/return-address-signing.ll (added)
+++ llvm/trunk/test/DebugInfo/AArch64/return-address-signing.ll Fri Dec 21 02:45:08 2018
@@ -0,0 +1,27 @@
+; RUN: llc -mtriple=aarch64-arm-none-eabi < %s -filetype=obj -o - \
+; RUN: | llvm-dwarfdump -v - | FileCheck -check-prefix=CHECK %s
+
+;CHECK: CIE
+;CHECK: Augmentation: "zR"
+define i32 @foo() "sign-return-address"="all" {
+ ret i32 0
+}
+
+;CHECK: CIE
+;CHECK: Augmentation: "zRB"
+
+define i32 @bar() "sign-return-address"="all" "sign-return-address-key"="b_key" {
+ ret i32 0
+}
+
+;CHECK-NOT: CIE
+
+define i32 @baz() "sign-return-address"="all" nounwind {
+ ret i32 0
+}
+
+;CHECK-NOT: CIE
+
+define i32 @qux() "sign-return-address"="all" "sign-return-address-key"="b_key" nounwind {
+ ret i32 0
+}
Added: llvm/trunk/test/MC/ELF/cfi-b-key-frame.s
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/MC/ELF/cfi-b-key-frame.s?rev=349895&view=auto
==============================================================================
--- llvm/trunk/test/MC/ELF/cfi-b-key-frame.s (added)
+++ llvm/trunk/test/MC/ELF/cfi-b-key-frame.s Fri Dec 21 02:45:08 2018
@@ -0,0 +1,6 @@
+// RUN: llvm-mc -filetype=obj -triple aarch64-arm-none-eabi %s -o - | llvm-dwarfdump - -v | FileCheck %s
+#CHECK: Augmentation: "zRB"
+f1:
+ .cfi_startproc
+ .cfi_b_key_frame
+ .cfi_endproc
More information about the llvm-commits
mailing list