Skip to content

Commit faed2ea

Browse files
author
Yeting Kuo
committed
[RISCV] Implement shadow stack on shadow stack mode with Zicfiss.
There are two shadow stack implements with Zicfiss in [spec] now. In Shadow stack mode, programs still store the return address to regular address. In Control stack mode, programs only store the return address to shadow stack. This patch only supports the shadow stack mode. [spec]: https://github.com/riscv/riscv-cfi/blob/main/cfi_backward.adoc#push-to-and-pop-from-the-shadow-stack
1 parent ce94459 commit faed2ea

File tree

2 files changed

+142
-2
lines changed

2 files changed

+142
-2
lines changed

llvm/lib/Target/RISCV/RISCVFrameLowering.cpp

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -51,9 +51,14 @@ static void emitSCSPrologue(MachineFunction &MF, MachineBasicBlock &MBB,
5151
CSI, [&](CalleeSavedInfo &CSR) { return CSR.getReg() == RAReg; }))
5252
return;
5353

54+
const RISCVInstrInfo *TII = STI.getInstrInfo();
55+
if (STI.hasFeature(RISCV::FeatureStdExtZicfiss)) {
56+
BuildMI(MBB, MI, DL, TII->get(RISCV::SSPUSH)).addReg(RAReg);
57+
return;
58+
}
59+
5460
Register SCSPReg = RISCVABI::getSCSPReg();
5561

56-
const RISCVInstrInfo *TII = STI.getInstrInfo();
5762
bool IsRV64 = STI.hasFeature(RISCV::Feature64Bit);
5863
int64_t SlotSize = STI.getXLen() / 8;
5964
// Store return address to shadow call stack
@@ -106,9 +111,14 @@ static void emitSCSEpilogue(MachineFunction &MF, MachineBasicBlock &MBB,
106111
CSI, [&](CalleeSavedInfo &CSR) { return CSR.getReg() == RAReg; }))
107112
return;
108113

114+
const RISCVInstrInfo *TII = STI.getInstrInfo();
115+
if (STI.hasFeature(RISCV::FeatureStdExtZicfiss)) {
116+
BuildMI(MBB, MI, DL, TII->get(RISCV::SSPOPCHK)).addReg(RAReg);
117+
return;
118+
}
119+
109120
Register SCSPReg = RISCVABI::getSCSPReg();
110121

111-
const RISCVInstrInfo *TII = STI.getInstrInfo();
112122
bool IsRV64 = STI.hasFeature(RISCV::Feature64Bit);
113123
int64_t SlotSize = STI.getXLen() / 8;
114124
// Load return address from shadow call stack

llvm/test/CodeGen/RISCV/shadowcallstack.ll

Lines changed: 130 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,10 @@
33
; RUN: | FileCheck %s --check-prefix=RV32
44
; RUN: llc -mtriple=riscv64 -verify-machineinstrs < %s \
55
; RUN: | FileCheck %s --check-prefix=RV64
6+
; RUN: llc -mtriple=riscv32 -mattr=+experimental-zicfiss -verify-machineinstrs < %s \
7+
; RUN: | FileCheck %s --check-prefix=RV32-ZICFISS
8+
; RUN: llc -mtriple=riscv64 -mattr=+experimental-zicfiss -verify-machineinstrs < %s \
9+
; RUN: | FileCheck %s --check-prefix=RV64-ZICFISS
610

711
define void @f1() shadowcallstack {
812
; RV32-LABEL: f1:
@@ -12,6 +16,14 @@ define void @f1() shadowcallstack {
1216
; RV64-LABEL: f1:
1317
; RV64: # %bb.0:
1418
; RV64-NEXT: ret
19+
;
20+
; RV32-ZICFISS-LABEL: f1:
21+
; RV32-ZICFISS: # %bb.0:
22+
; RV32-ZICFISS-NEXT: ret
23+
;
24+
; RV64-ZICFISS-LABEL: f1:
25+
; RV64-ZICFISS: # %bb.0:
26+
; RV64-ZICFISS-NEXT: ret
1527
ret void
1628
}
1729

@@ -25,6 +37,14 @@ define void @f2() shadowcallstack {
2537
; RV64-LABEL: f2:
2638
; RV64: # %bb.0:
2739
; RV64-NEXT: tail foo
40+
;
41+
; RV32-ZICFISS-LABEL: f2:
42+
; RV32-ZICFISS: # %bb.0:
43+
; RV32-ZICFISS-NEXT: tail foo
44+
;
45+
; RV64-ZICFISS-LABEL: f2:
46+
; RV64-ZICFISS: # %bb.0:
47+
; RV64-ZICFISS-NEXT: tail foo
2848
tail call void @foo()
2949
ret void
3050
}
@@ -65,6 +85,32 @@ define i32 @f3() shadowcallstack {
6585
; RV64-NEXT: addi gp, gp, -8
6686
; RV64-NEXT: .cfi_restore gp
6787
; RV64-NEXT: ret
88+
;
89+
; RV32-ZICFISS-LABEL: f3:
90+
; RV32-ZICFISS: # %bb.0:
91+
; RV32-ZICFISS-NEXT: sspush ra
92+
; RV32-ZICFISS-NEXT: addi sp, sp, -16
93+
; RV32-ZICFISS-NEXT: .cfi_def_cfa_offset 16
94+
; RV32-ZICFISS-NEXT: sw ra, 12(sp) # 4-byte Folded Spill
95+
; RV32-ZICFISS-NEXT: .cfi_offset ra, -4
96+
; RV32-ZICFISS-NEXT: call bar
97+
; RV32-ZICFISS-NEXT: lw ra, 12(sp) # 4-byte Folded Reload
98+
; RV32-ZICFISS-NEXT: addi sp, sp, 16
99+
; RV32-ZICFISS-NEXT: sspopchk ra
100+
; RV32-ZICFISS-NEXT: ret
101+
;
102+
; RV64-ZICFISS-LABEL: f3:
103+
; RV64-ZICFISS: # %bb.0:
104+
; RV64-ZICFISS-NEXT: sspush ra
105+
; RV64-ZICFISS-NEXT: addi sp, sp, -16
106+
; RV64-ZICFISS-NEXT: .cfi_def_cfa_offset 16
107+
; RV64-ZICFISS-NEXT: sd ra, 8(sp) # 8-byte Folded Spill
108+
; RV64-ZICFISS-NEXT: .cfi_offset ra, -8
109+
; RV64-ZICFISS-NEXT: call bar
110+
; RV64-ZICFISS-NEXT: ld ra, 8(sp) # 8-byte Folded Reload
111+
; RV64-ZICFISS-NEXT: addi sp, sp, 16
112+
; RV64-ZICFISS-NEXT: sspopchk ra
113+
; RV64-ZICFISS-NEXT: ret
68114
%res = call i32 @bar()
69115
%res1 = add i32 %res, 1
70116
ret i32 %res
@@ -140,6 +186,68 @@ define i32 @f4() shadowcallstack {
140186
; RV64-NEXT: addi gp, gp, -8
141187
; RV64-NEXT: .cfi_restore gp
142188
; RV64-NEXT: ret
189+
;
190+
; RV32-ZICFISS-LABEL: f4:
191+
; RV32-ZICFISS: # %bb.0:
192+
; RV32-ZICFISS-NEXT: sspush ra
193+
; RV32-ZICFISS-NEXT: addi sp, sp, -16
194+
; RV32-ZICFISS-NEXT: .cfi_def_cfa_offset 16
195+
; RV32-ZICFISS-NEXT: sw ra, 12(sp) # 4-byte Folded Spill
196+
; RV32-ZICFISS-NEXT: sw s0, 8(sp) # 4-byte Folded Spill
197+
; RV32-ZICFISS-NEXT: sw s1, 4(sp) # 4-byte Folded Spill
198+
; RV32-ZICFISS-NEXT: sw s2, 0(sp) # 4-byte Folded Spill
199+
; RV32-ZICFISS-NEXT: .cfi_offset ra, -4
200+
; RV32-ZICFISS-NEXT: .cfi_offset s0, -8
201+
; RV32-ZICFISS-NEXT: .cfi_offset s1, -12
202+
; RV32-ZICFISS-NEXT: .cfi_offset s2, -16
203+
; RV32-ZICFISS-NEXT: call bar
204+
; RV32-ZICFISS-NEXT: mv s0, a0
205+
; RV32-ZICFISS-NEXT: call bar
206+
; RV32-ZICFISS-NEXT: mv s1, a0
207+
; RV32-ZICFISS-NEXT: call bar
208+
; RV32-ZICFISS-NEXT: mv s2, a0
209+
; RV32-ZICFISS-NEXT: call bar
210+
; RV32-ZICFISS-NEXT: add s0, s0, s1
211+
; RV32-ZICFISS-NEXT: add a0, s2, a0
212+
; RV32-ZICFISS-NEXT: add a0, s0, a0
213+
; RV32-ZICFISS-NEXT: lw ra, 12(sp) # 4-byte Folded Reload
214+
; RV32-ZICFISS-NEXT: lw s0, 8(sp) # 4-byte Folded Reload
215+
; RV32-ZICFISS-NEXT: lw s1, 4(sp) # 4-byte Folded Reload
216+
; RV32-ZICFISS-NEXT: lw s2, 0(sp) # 4-byte Folded Reload
217+
; RV32-ZICFISS-NEXT: addi sp, sp, 16
218+
; RV32-ZICFISS-NEXT: sspopchk ra
219+
; RV32-ZICFISS-NEXT: ret
220+
;
221+
; RV64-ZICFISS-LABEL: f4:
222+
; RV64-ZICFISS: # %bb.0:
223+
; RV64-ZICFISS-NEXT: sspush ra
224+
; RV64-ZICFISS-NEXT: addi sp, sp, -32
225+
; RV64-ZICFISS-NEXT: .cfi_def_cfa_offset 32
226+
; RV64-ZICFISS-NEXT: sd ra, 24(sp) # 8-byte Folded Spill
227+
; RV64-ZICFISS-NEXT: sd s0, 16(sp) # 8-byte Folded Spill
228+
; RV64-ZICFISS-NEXT: sd s1, 8(sp) # 8-byte Folded Spill
229+
; RV64-ZICFISS-NEXT: sd s2, 0(sp) # 8-byte Folded Spill
230+
; RV64-ZICFISS-NEXT: .cfi_offset ra, -8
231+
; RV64-ZICFISS-NEXT: .cfi_offset s0, -16
232+
; RV64-ZICFISS-NEXT: .cfi_offset s1, -24
233+
; RV64-ZICFISS-NEXT: .cfi_offset s2, -32
234+
; RV64-ZICFISS-NEXT: call bar
235+
; RV64-ZICFISS-NEXT: mv s0, a0
236+
; RV64-ZICFISS-NEXT: call bar
237+
; RV64-ZICFISS-NEXT: mv s1, a0
238+
; RV64-ZICFISS-NEXT: call bar
239+
; RV64-ZICFISS-NEXT: mv s2, a0
240+
; RV64-ZICFISS-NEXT: call bar
241+
; RV64-ZICFISS-NEXT: add s0, s0, s1
242+
; RV64-ZICFISS-NEXT: add a0, s2, a0
243+
; RV64-ZICFISS-NEXT: addw a0, s0, a0
244+
; RV64-ZICFISS-NEXT: ld ra, 24(sp) # 8-byte Folded Reload
245+
; RV64-ZICFISS-NEXT: ld s0, 16(sp) # 8-byte Folded Reload
246+
; RV64-ZICFISS-NEXT: ld s1, 8(sp) # 8-byte Folded Reload
247+
; RV64-ZICFISS-NEXT: ld s2, 0(sp) # 8-byte Folded Reload
248+
; RV64-ZICFISS-NEXT: addi sp, sp, 32
249+
; RV64-ZICFISS-NEXT: sspopchk ra
250+
; RV64-ZICFISS-NEXT: ret
143251
%res1 = call i32 @bar()
144252
%res2 = call i32 @bar()
145253
%res3 = call i32 @bar()
@@ -176,6 +284,28 @@ define i32 @f5() shadowcallstack nounwind {
176284
; RV64-NEXT: ld ra, -8(gp)
177285
; RV64-NEXT: addi gp, gp, -8
178286
; RV64-NEXT: ret
287+
;
288+
; RV32-ZICFISS-LABEL: f5:
289+
; RV32-ZICFISS: # %bb.0:
290+
; RV32-ZICFISS-NEXT: sspush ra
291+
; RV32-ZICFISS-NEXT: addi sp, sp, -16
292+
; RV32-ZICFISS-NEXT: sw ra, 12(sp) # 4-byte Folded Spill
293+
; RV32-ZICFISS-NEXT: call bar
294+
; RV32-ZICFISS-NEXT: lw ra, 12(sp) # 4-byte Folded Reload
295+
; RV32-ZICFISS-NEXT: addi sp, sp, 16
296+
; RV32-ZICFISS-NEXT: sspopchk ra
297+
; RV32-ZICFISS-NEXT: ret
298+
;
299+
; RV64-ZICFISS-LABEL: f5:
300+
; RV64-ZICFISS: # %bb.0:
301+
; RV64-ZICFISS-NEXT: sspush ra
302+
; RV64-ZICFISS-NEXT: addi sp, sp, -16
303+
; RV64-ZICFISS-NEXT: sd ra, 8(sp) # 8-byte Folded Spill
304+
; RV64-ZICFISS-NEXT: call bar
305+
; RV64-ZICFISS-NEXT: ld ra, 8(sp) # 8-byte Folded Reload
306+
; RV64-ZICFISS-NEXT: addi sp, sp, 16
307+
; RV64-ZICFISS-NEXT: sspopchk ra
308+
; RV64-ZICFISS-NEXT: ret
179309
%res = call i32 @bar()
180310
%res1 = add i32 %res, 1
181311
ret i32 %res

0 commit comments

Comments
 (0)