diff options
author | 2024-01-06 10:51:30 -0800 | |
---|---|---|
committer | 2024-08-11 20:36:41 -0700 | |
commit | d36378fcc4640c2a376d53e393988801f118e460 (patch) | |
tree | 4454beda69f16295a0b70541dd0dcee8174e472e | |
parent | riscv: Add threadlocalref_get (diff) | |
download | pypy-d36378fcc4640c2a376d53e393988801f118e460.tar.gz pypy-d36378fcc4640c2a376d53e393988801f118e460.tar.bz2 pypy-d36378fcc4640c2a376d53e393988801f118e460.zip |
riscv: Add shadow stack to header/footer
This commit adds shadow stack header/footer to
`_call_header`/`_call_footer`.
Test: pytest.py rpython/jit/backend/riscv/test/test_zrpy_gc.py
-k test_compile_framework_2
pytest.py rpython/jit/backend/riscv/test/test_zrpy_gc.py
-k test_compile_framework_3
pytest.py rpython/jit/backend/riscv/test/test_zrpy_gc.py
-k test_compile_framework_4
-rw-r--r-- | rpython/jit/backend/riscv/assembler.py | 48 |
1 files changed, 48 insertions, 0 deletions
diff --git a/rpython/jit/backend/riscv/assembler.py b/rpython/jit/backend/riscv/assembler.py index 8808810171..455349d663 100644 --- a/rpython/jit/backend/riscv/assembler.py +++ b/rpython/jit/backend/riscv/assembler.py @@ -409,11 +409,59 @@ class AssemblerRISCV(OpAssembler): self.mc.MV(r.jfp.value, r.x10.value) + gcrootmap = self.cpu.gc_ll_descr.gcrootmap + if gcrootmap and gcrootmap.is_shadow_stack: + self.gen_shadowstack_header(gcrootmap) + def _call_footer(self, mc): + gcrootmap = self.cpu.gc_ll_descr.gcrootmap + if gcrootmap and gcrootmap.is_shadow_stack: + self.gen_shadowstack_footer(gcrootmap, mc) + mc.MV(r.x10.value, r.jfp.value) self._pop_callee_save_regs_from_stack(mc) mc.RET() + def gen_shadowstack_header(self, gcrootmap): + scratch_reg = r.x31 + scratch2_reg = r.x30 + scratch3_reg = r.x29 + + # scratch_reg = &root_stack_top_addr (address to pointer to stack top) + rst = gcrootmap.get_root_stack_top_addr() + self.mc.load_int_imm(scratch_reg.value, rst) + # scratch2_reg = root_stack_top_addr (address to stack top) + self.mc.load_int(scratch2_reg.value, scratch_reg.value, 0) + + # We push two words, like the x86 backend does: + # The '1' is to benefit from the shadowstack 'is_minor' optimization + + # scratch2_reg[0] = 1 + self.mc.load_int_imm(scratch3_reg.value, 1) + self.mc.store_int(scratch3_reg.value, scratch2_reg.value, 0) + # scratch2_reg[1] = r.jfp + self.mc.store_int(r.jfp.value, scratch2_reg.value, XLEN) + + # scratch2_reg += 2 * XLEN + self.mc.ADDI(scratch2_reg.value, scratch2_reg.value, 2 * XLEN) + # root_stack_top_addr = scratch2_reg + self.mc.store_int(scratch2_reg.value, scratch_reg.value, 0) + + def gen_shadowstack_footer(self, gcrootmap, mc): + scratch_reg = r.x31 + scratch2_reg = r.x30 + + # scratch_reg = &root_stack_top_addr + rst = gcrootmap.get_root_stack_top_addr() + mc.load_int_imm(scratch_reg.value, rst) + # scratch2_reg = root_stack_top_addr + mc.load_int(scratch2_reg.value, scratch_reg.value, 0) + + # scratch2_reg -= 2 * XLEN + mc.ADDI(scratch2_reg.value, scratch2_reg.value, -(2 * XLEN)) + # root_stack_top_addr = scratch2_reg + mc.store_int(scratch2_reg.value, scratch_reg.value, 0) + def _calculate_callee_save_area_size(self): # Extra thread local storage (see. riscv/callbuiler.py) # |