riscv64 SCS support.
Bug: https://github.com/google/android-riscv64/issues/55
Test: treehugger
Change-Id: I05d48a07a302305126942d38529ffa280640c7b7
diff --git a/libc/arch-riscv64/bionic/setjmp.S b/libc/arch-riscv64/bionic/setjmp.S
index eea2978..ba3cacf 100644
--- a/libc/arch-riscv64/bionic/setjmp.S
+++ b/libc/arch-riscv64/bionic/setjmp.S
@@ -79,7 +79,7 @@
.macro m_mangle_registers reg, sp_reg
xor s0, s0, \reg
xor s1, s1, \reg
- xor s2, s2, \reg
+ xor a4, a4, \reg // a4 is the masked s2 (x18) for SCS.
xor s3, s3, \reg
xor s4, s4, \reg
xor s5, s5, \reg
@@ -151,13 +151,20 @@
ld a1, _JB_SIGFLAG(a0)
andi a1, a1, -2
+ // Mask off the high bits of the shadow call stack pointer.
+ // We only store the low bits of x18 to avoid leaking the
+ // shadow call stack address into memory.
+ // See the SCS commentary in pthread_internal.h for more detail.
+ li a4, SCS_MASK
+ and a4, a4, x18
+
// Save core registers.
mv a2, sp
m_mangle_registers a1, sp_reg=a2
sd ra, _JB_RA(a0)
sd s0, _JB_S0(a0)
sd s1, _JB_S1(a0)
- sd s2, _JB_S2(a0)
+ sd a4, _JB_S2(a0) // a4 is the masked s2 (x18) for SCS.
sd s3, _JB_S3(a0)
sd s4, _JB_S4(a0)
sd s5, _JB_S5(a0)
@@ -231,7 +238,7 @@
ld ra, _JB_RA(a0)
ld s0, _JB_S0(a0)
ld s1, _JB_S1(a0)
- ld s2, _JB_S2(a0)
+ ld a4, _JB_S2(a0) // Don't clobber s2 (x18) used for SCS yet.
ld s3, _JB_S3(a0)
ld s4, _JB_S4(a0)
ld s5, _JB_S5(a0)
@@ -245,6 +252,11 @@
m_unmangle_registers a2, sp_reg=a3
mv sp, a3
+ // Restore the low bits of the shadow call stack pointer.
+ li a5, ~SCS_MASK
+ and x18, x18, a5
+ or x18, a4, x18
+
addi sp, sp, -24
sd ra, 0(sp)
sd a0, 8(sp)