1. Pypy
  2. Untitled project
  3. pypy

Commits

David Schneider  committed 5c95268

pass test_shadowstack_call and test_shadowstack_collecting_call_float

  • Participants
  • Parent commits c1c1319
  • Branches jitframe-on-heap

Comments (0)

Files changed (4)

File rpython/jit/backend/arm/assembler.py

View file
  • Ignore whitespace
         self._exit_code_addr = 0
         self.current_clt = None
         self.malloc_slowpath = 0
-        self.wb_slowpath = [0, 0, 0, 0]
+        self.wb_slowpath = [0, 0, 0, 0, 0]
         self._regalloc = None
         self.datablockwrapper = None
         self.propagate_exception_path = 0
     def _reload_frame_if_necessary(self, mc, align_stack=False, can_collect=0):
         gcrootmap = self.cpu.gc_ll_descr.gcrootmap
         if gcrootmap and gcrootmap.is_shadow_stack:
-            import pdb; pdb.set_trace()
             rst = gcrootmap.get_root_stack_top_addr()
-            mc.MOV(ecx, heap(rst))
-            mc.MOV(ebp, mem(ecx, -WORD))
+            mc.gen_load_int(r.ip.value, rst)
+            self.load_reg(mc, r.ip, r.ip)
+            self.load_reg(mc, r.fp, r.ip, ofs=-WORD)
         wbdescr = self.cpu.gc_ll_descr.write_barrier_descr
         if gcrootmap and wbdescr:
             # frame never uses card marking, so we enforce this is not
     def gen_shadowstack_header(self, gcrootmap):
         # we need to put two words into the shadowstack: the MARKER_FRAME
         # and the address of the frame (fp, actually)
+        # lr = rst addr
+        # ip = *lr
         rst = gcrootmap.get_root_stack_top_addr()
-        self.mc.gen_load_int(r.ip.value, rst)
-        self.mc.LDR_ri(r.r4.value, r.ip.value)  # LDR r4, [rootstacktop]
+        self.mc.gen_load_int(r.lr.value, rst)
+        self.load_reg(self.mc, r.ip, r.lr)
+        # *ip = r.fp
+        self.store_reg(self.mc, r.fp, r.ip)
         #
-        MARKER = gcrootmap.MARKER_FRAME
-        self.mc.ADD_ri(r.r5.value, r.r4.value,
-                                    imm=2 * WORD)  # ADD r5, r4 [2*WORD]
-        self.mc.gen_load_int(r.r6.value, MARKER)
-        self.mc.STR_ri(r.r6.value, r.r4.value, WORD)  # STR MARKER, r4 [WORD]
-        self.mc.STR_ri(r.fp.value, r.r4.value)  # STR fp, r4
-        #
-        self.mc.STR_ri(r.r5.value, r.ip.value)  # STR r5 [rootstacktop]
+        self.mc.ADD_ri(r.ip.value, r.ip.value, WORD)
+        # *lr = ip + WORD
+        self.store_reg(self.mc, r.ip, r.lr)
 
     def gen_footer_shadowstack(self, gcrootmap, mc):
         rst = gcrootmap.get_root_stack_top_addr()
         mc.gen_load_int(r.ip.value, rst)
-        mc.LDR_ri(r.r4.value, r.ip.value)  # LDR r4, [rootstacktop]
-        mc.SUB_ri(r.r5.value, r.r4.value, imm=2 * WORD)  # ADD r5, r4 [2*WORD]
-        mc.STR_ri(r.r5.value, r.ip.value)
+        self.load_reg(mc, r.r4, r.ip)
+        mc.SUB_ri(r.r4.value, r.r4.value, WORD)
+        self.store_reg(mc, r.r4, r.ip)
 
     def _dump(self, ops, type='loop'):
         debug_start('jit-backend-ops')
 
     def _load_shadowstack_top(self, mc, reg, gcrootmap):
         rst = gcrootmap.get_root_stack_top_addr()
-        self.mc.gen_load_int(reg.value, rst)
-        self.mc.gen_load_int(reg.value, reg.value)
+        mc.gen_load_int(reg.value, rst)
+        mc.gen_load_int(reg.value, reg.value)
         return rst
 
     def fixup_target_tokens(self, rawstart):
             mc.VLDR(target.value, helper.value, cond=cond)
 
     def _load_core_reg(self, mc, target, base, ofs, cond=c.AL, helper=r.ip):
-        if check_imm_arg(ofs):
+        if check_imm_arg(abs(ofs)):
             mc.LDR_ri(target.value, base.value, imm=ofs, cond=cond)
         else:
             mc.gen_load_int(helper.value, ofs, cond=cond)
 
     def pop_gcmap(self, mc):
         ofs = self.cpu.get_ofs_of_frame_field('jf_gcmap')
-        mc.MOV_bi(ofs, 0)
+        assert check_imm_arg(ofs)
+        mc.gen_load_int(r.ip.value, 0)
+        self.store_reg(mc, r.ip, r.fp, ofs)
 
 
 

File rpython/jit/backend/arm/opassembler.py

View file
  • Ignore whitespace
         return cond
 
     def _emit_call(self, adr, arglocs, fcond=c.AL, resloc=None,
-                                            result_info=(-1, -1)):
+                                            result_info=(-1, -1),
+                                            can_collect=1):
         if self.cpu.use_hf_abi:
-            stack_args, adr = self._setup_call_hf(adr,
-                                        arglocs, fcond, resloc, result_info)
+            stack_args, adr = self._setup_call_hf(adr, arglocs, fcond,
+                                            resloc, result_info)
         else:
-            stack_args, adr = self._setup_call_sf(adr,
-                                        arglocs, fcond, resloc, result_info)
+            stack_args, adr = self._setup_call_sf(adr, arglocs, fcond,
+                                            resloc, result_info)
 
+        if can_collect:
+            noregs = self.cpu.gc_ll_descr.is_shadow_stack()
+            gcmap = self._regalloc.get_gcmap([r.r0], noregs=noregs)
+            self.push_gcmap(self.mc, gcmap, store=True)
         #the actual call
         #self.mc.BKPT()
         if adr.is_imm():
             elif resloc.is_reg() and result_info != (-1, -1):
                 self._ensure_result_bit_extension(resloc, result_info[0],
                                                           result_info[1])
+        if can_collect:
+            self._reload_frame_if_necessary(self.mc, can_collect=can_collect)
+            self.pop_gcmap(self.mc)
         return fcond
 
     def _restore_sp(self, stack_args, fcond):
         self._write_barrier_fastpath(self.mc, op.getdescr(), arglocs,
                                                         fcond, array=True)
 
-    def _write_barrier_fastpath(self, mc, descr, arglocs, fcond, array=False,
+    def _write_barrier_fastpath(self, mc, descr, arglocs, fcond=c.AL, array=False,
                                                             is_frame=False):
         # Write code equivalent to write_barrier() in the GC: it checks
         # a flag in the object at arglocs[0], and if set, it calls a
         loc_base = arglocs[0]
         if is_frame:
             assert loc_base is r.fp
-        else:
-            self.mc.LDRB_ri(r.ip.value, loc_base.value,
-                                        imm=descr.jit_wb_if_flag_byteofs)
+        mc.LDRB_ri(r.ip.value, loc_base.value,
+                                    imm=descr.jit_wb_if_flag_byteofs)
         mask &= 0xFF
-        self.mc.TST_ri(r.ip.value, imm=mask)
-        jz_location = self.mc.currpos()
-        self.mc.BKPT()
+        mc.TST_ri(r.ip.value, imm=mask)
+        jz_location = mc.currpos()
+        mc.BKPT()
 
         # for cond_call_gc_wb_array, also add another fast path:
         # if GCFLAG_CARDS_SET, then we can just set one bit and be done
         if card_marking:
             # GCFLAG_CARDS_SET is in this byte at 0x80
-            self.mc.TST_ri(r.ip.value, imm=0x80)
+            mc.TST_ri(r.ip.value, imm=0x80)
 
-            js_location = self.mc.currpos()
-            self.mc.BKPT()
+            js_location = mc.currpos()
+            mc.BKPT()
         else:
             js_location = 0
 
         # argument the address of the structure we are writing into
         # (the first argument to COND_CALL_GC_WB).
         helper_num = card_marking
-        if self._regalloc.vfprm.reg_bindings:
+        if self._regalloc is not None and self._regalloc.vfprm.reg_bindings:
             helper_num += 2
         if self.wb_slowpath[helper_num] == 0:    # tests only
             assert not we_are_translated()
                                     bool(self._regalloc.vfprm.reg_bindings))
             assert self.wb_slowpath[helper_num] != 0
         #
-        if loc_base is not r.r0:
+        if not is_frame and loc_base is not r.r0:
             # push two registers to keep stack aligned
-            self.mc.PUSH([r.r0.value, loc_base.value])
+            mc.PUSH([r.r0.value, loc_base.value])
             remap_frame_layout(self, [loc_base], [r.r0], r.ip)
-        self.mc.BL(self.wb_slowpath[helper_num])
-        if loc_base is not r.r0:
-            self.mc.POP([r.r0.value, loc_base.value])
+        mc.BL(self.wb_slowpath[helper_num])
+        if not is_frame and loc_base is not r.r0:
+            mc.POP([r.r0.value, loc_base.value])
 
         if card_marking:
             # The helper ends again with a check of the flag in the object.  So
             # here, we can simply write again a conditional jump, which will be
             # taken if GCFLAG_CARDS_SET is still not set.
-            jns_location = self.mc.currpos()
-            self.mc.BKPT()
+            jns_location = mc.currpos()
+            mc.BKPT()
             #
             # patch the JS above
-            offset = self.mc.currpos()
-            pmc = OverwritingBuilder(self.mc, js_location, WORD)
+            offset = mc.currpos()
+            pmc = OverwritingBuilder(mc, js_location, WORD)
             pmc.B_offs(offset, c.NE)  # We want to jump if the z flag isn't set
             #
             # case GCFLAG_CARDS_SET: emit a few instructions to do
             loc_index = arglocs[1]
             assert loc_index.is_reg()
             # must save the register loc_index before it is mutated
-            self.mc.PUSH([loc_index.value])
+            mc.PUSH([loc_index.value])
             tmp1 = loc_index
             tmp2 = arglocs[-1]  # the last item is a preallocated tmp
             # lr = byteofs
             s = 3 + descr.jit_wb_card_page_shift
-            self.mc.MVN_rr(r.lr.value, loc_index.value,
+            mc.MVN_rr(r.lr.value, loc_index.value,
                                        imm=s, shifttype=shift.LSR)
 
             # tmp1 = byte_index
-            self.mc.MOV_ri(r.ip.value, imm=7)
-            self.mc.AND_rr(tmp1.value, r.ip.value, loc_index.value,
+            mc.MOV_ri(r.ip.value, imm=7)
+            mc.AND_rr(tmp1.value, r.ip.value, loc_index.value,
             imm=descr.jit_wb_card_page_shift, shifttype=shift.LSR)
 
             # set the bit
-            self.mc.MOV_ri(tmp2.value, imm=1)
-            self.mc.LDRB_rr(r.ip.value, loc_base.value, r.lr.value)
-            self.mc.ORR_rr_sr(r.ip.value, r.ip.value, tmp2.value,
+            mc.MOV_ri(tmp2.value, imm=1)
+            mc.LDRB_rr(r.ip.value, loc_base.value, r.lr.value)
+            mc.ORR_rr_sr(r.ip.value, r.ip.value, tmp2.value,
                                           tmp1.value, shifttype=shift.LSL)
-            self.mc.STRB_rr(r.ip.value, loc_base.value, r.lr.value)
+            mc.STRB_rr(r.ip.value, loc_base.value, r.lr.value)
             # done
-            self.mc.POP([loc_index.value])
+            mc.POP([loc_index.value])
             #
             #
             # patch the JNS above
-            offset = self.mc.currpos()
-            pmc = OverwritingBuilder(self.mc, jns_location, WORD)
+            offset = mc.currpos()
+            pmc = OverwritingBuilder(mc, jns_location, WORD)
             pmc.B_offs(offset, c.EQ)  # We want to jump if the z flag is set
 
-        offset = self.mc.currpos()
-        pmc = OverwritingBuilder(self.mc, jz_location, WORD)
+        offset = mc.currpos()
+        pmc = OverwritingBuilder(mc, jz_location, WORD)
         pmc.B_offs(offset, c.EQ)
         return fcond
 
         # call memcpy()
         regalloc.before_call()
         self._emit_call(imm(self.memcpy_addr),
-                            [dstaddr_loc, srcaddr_loc, length_loc])
+                            [dstaddr_loc, srcaddr_loc, length_loc],
+                            can_collect=False)
 
         regalloc.possibly_free_var(length_box)
         regalloc.possibly_free_var(dstaddr_box)

File rpython/jit/backend/arm/regalloc.py

View file
  • Ignore whitespace
         for box, loc in self.fm.bindings.iteritems():
             if box.type == REF and self.rm.is_still_alive(box):
                 assert loc.is_stack()
-                val = loc.value // WORD
+                val = loc.position + JITFRAME_FIXED_SIZE
                 gcmap[val // WORD // 8] |= r_uint(1) << (val % (WORD * 8))
         return gcmap
 

File rpython/jit/backend/llsupport/test/test_gc_integration.py

View file
  • Ignore whitespace
             gcmap = unpack_gcmap(frame)
             if self.cpu.IS_64_BIT:
                 assert gcmap == [28, 29, 30]
+            elif self.cpu.backend_name.startswith('arm'):
+                assert gcmap == [44, 45, 46]
+                pass
             else:
                 assert gcmap == [22, 23, 24]
             for item, s in zip(gcmap, new_items):