[pypy-commit] pypy shadowstack-again: in-progress: use r15 also to return exceptions

arigo noreply at buildbot.pypy.org
Tue May 20 17:40:54 CEST 2014


Author: Armin Rigo <arigo at tunes.org>
Branch: shadowstack-again
Changeset: r71602:35fc2a0ae50c
Date: 2014-05-20 17:40 +0200
http://bitbucket.org/pypy/pypy/changeset/35fc2a0ae50c/

Log:	in-progress: use r15 also to return exceptions

diff --git a/rpython/memory/gctransform/shadowstack.py b/rpython/memory/gctransform/shadowstack.py
--- a/rpython/memory/gctransform/shadowstack.py
+++ b/rpython/memory/gctransform/shadowstack.py
@@ -1,6 +1,7 @@
 from rpython.flowspace.model import Block, Link, SpaceOperation
 from rpython.annotator import model as annmodel
 from rpython.translator.unsimplify import varoftype, copyvar
+from rpython.translator.backendopt.ssa import SSA_to_SSI
 from rpython.rtyper.llannotation import SomePtr
 from rpython.rlib.debug import ll_assert
 from rpython.rlib.nonconst import NonConstant
@@ -16,38 +17,49 @@
 
 
 class ShadowStackFrameworkGCTransformer(BaseFrameworkGCTransformer):
+    RPY_SHADOWSTACK_PTR = lltype.Ptr(
+        lltype.Struct('rpy_shadowstack_s',
+                      hints={"external": "C", "c_name": "rpy_shadowstack_s"}))
+
     def build_root_walker(self):
         return ShadowStackRootWalker(self)
 
     def transform_graph(self, graph):
         self._transforming_graph = graph
+        self._ss_graph_marker = None
         super(ShadowStackFrameworkGCTransformer, self).transform_graph(graph)
+        del self._ss_graph_marker
         del self._transforming_graph
 
+    def sanitize_graph(self, graph):
+        SSA_to_SSI(graph, self.translator.annotator)
+
     def ensure_ss_graph_marker(self):
-        graph = self._transforming_graph
-        ops = graph.startblock.operations
-        if not ops or ops[0].opname != 'gc_ss_graph_marker':
+        if self._ss_graph_marker is None:
+            graph = self._transforming_graph
             inputargs = [copyvar(self.translator.annotator, v)
                          for v in graph.startblock.inputargs]
-            block = Block(inputargs)
-            v_void = varoftype(lltype.Void)
-            block.operations.append(SpaceOperation('gc_ss_graph_marker',
-                                                   [], v_void))
-            block.closeblock(Link(inputargs, graph.startblock))
-            graph.startblock = block
+            hblock = Block(inputargs)
+            v_marker = varoftype(self.RPY_SHADOWSTACK_PTR)
+            hblock.operations.append(SpaceOperation('gc_ss_graph_marker',
+                                                    [], v_marker))
+            hblock.closeblock(Link(inputargs, graph.startblock))
+            graph.startblock = hblock
+            self._ss_graph_marker = v_marker
+        return self._ss_graph_marker
 
     def push_roots(self, hop, keep_current_args=False):
         livevars = self.get_livevars_for_roots(hop, keep_current_args)
         self.num_pushs += len(livevars)
-        self.ensure_ss_graph_marker()
-        hop.genop("gc_ss_store", livevars)
+        v_marker = self.ensure_ss_graph_marker()
+        hop.genop("gc_ss_store", [v_marker] + livevars)
         return livevars
 
     def pop_roots(self, hop, livevars):
         # for moving collectors, reload the roots into the local variables
         if self.gcdata.gc.moving_gc and livevars:
-            hop.genop("gc_ss_reload", livevars)
+            v_marker = self.ensure_ss_graph_marker()
+            hop.genop("gc_ss_reload", [v_marker] + livevars)
 
 
 class ShadowStackRootWalker(BaseRootWalker):
diff --git a/rpython/memory/gctransform/transform.py b/rpython/memory/gctransform/transform.py
--- a/rpython/memory/gctransform/transform.py
+++ b/rpython/memory/gctransform/transform.py
@@ -247,6 +247,7 @@
             old_startblock = graph.startblock
             graph.startblock = graph.startblock.exits[0].target
 
+        self.sanitize_graph(graph)
         checkgraph(graph)
 
         self.links_to_split = None
@@ -257,6 +258,9 @@
         graph.exc_cleanup = (v, list(llops))
         return is_borrowed    # xxx for tests only
 
+    def sanitize_graph(self, graph):
+        pass
+
     def annotate_helper(self, ll_helper, ll_args, ll_result, inline=False):
         assert not self.finished_helpers
         args_s = map(lltype_to_annotation, ll_args)
diff --git a/rpython/rtyper/lltypesystem/lloperation.py b/rpython/rtyper/lltypesystem/lloperation.py
--- a/rpython/rtyper/lltypesystem/lloperation.py
+++ b/rpython/rtyper/lltypesystem/lloperation.py
@@ -438,6 +438,9 @@
     'gc_gettypeptr_group':  LLOp(canfold=True),
     'get_member_index':     LLOp(canfold=True),
 
+    'getfield_exc_type':    LLOp(sideeffects=False),
+    'setfield_exc_type':    LLOp(),
+
     # __________ used by the JIT ________
 
     'jit_marker':           LLOp(),
diff --git a/rpython/translator/c/gc.py b/rpython/translator/c/gc.py
--- a/rpython/translator/c/gc.py
+++ b/rpython/translator/c/gc.py
@@ -444,22 +444,25 @@
         return shadowstack.ShadowStackFrameworkGCTransformer(self.db.translator)
 
     def OP_GC_SS_GRAPH_MARKER(self, funcgen, op):
-        return '; struct rpy_shadowstack_s *rpy_ss = rpy_shadowstack;'
+        return '%s = rpy_shadowstack;' % funcgen.expr(op.result)
 
     def OP_GC_SS_STORE(self, funcgen, op):
+        marker = funcgen.expr(op.args[0])
         lines = []
-        for i, v in enumerate(op.args):
-            lines.append('rpy_ss[%d].s = %s;' % (i, funcgen.expr(v)))
-        lines.append('rpy_shadowstack = rpy_ss + %d;' % len(op.args))
+        for i, v in enumerate(op.args[1:]):
+            lines.append('%s[%d].s = %s;' % (marker, i, funcgen.expr(v)))
+        lines.append('rpy_shadowstack = %s + %d;' % (marker, len(op.args)))
         return '\n'.join(lines)
 
     def OP_GC_SS_RELOAD(self, funcgen, op):
+        marker = funcgen.expr(op.args[0])
         lines = []
-        for i, v in enumerate(op.args):
+        for i, v in enumerate(op.args[1:]):
             typename = funcgen.db.gettype(v.concretetype)
-            lines.append('%s = (%s)rpy_ss[%d].s;' % (
+            lines.append('%s = (%s)%s[%d].s;' % (
                 funcgen.expr(v),
                 cdecl(typename, ''),
+                marker,
                 i))
             if isinstance(v, Constant):
                 lines[-1] = '/* %s */' % lines[-1]
diff --git a/rpython/translator/c/src/entrypoint.c b/rpython/translator/c/src/entrypoint.c
--- a/rpython/translator/c/src/entrypoint.c
+++ b/rpython/translator/c/src/entrypoint.c
@@ -36,7 +36,6 @@
     pypy_g_rpython_rtyper_lltypesystem_rffi_StackCounter.sc_inst_stacks_counter++;
 #endif
     instrument_setup();
-    pypy_asm_stack_bottom();
 
 #ifndef MS_WINDOWS
     /* this message does no longer apply to win64 :-) */
@@ -50,14 +49,18 @@
     errmsg = RPython_StartupCode();
     if (errmsg) goto error;
 
+    pypy_asm_stack_bottom();
     list = _RPyListOfString_New(argc);
     if (RPyExceptionOccurred()) goto memory_out;
     for (i=0; i<argc; i++) {
+        pypy_asm_stack_bottom();
         RPyString *s = RPyString_FromString(argv[i]);
         if (RPyExceptionOccurred()) goto memory_out;
+        pypy_asm_stack_bottom();
         _RPyListOfString_SetItem(list, i, s);
     }
 
+    pypy_asm_stack_bottom();
     exitcode = STANDALONE_ENTRY_POINT(list);
 
     pypy_debug_alloc_results();
diff --git a/rpython/translator/c/src/mem.h b/rpython/translator/c/src/mem.h
--- a/rpython/translator/c/src/mem.h
+++ b/rpython/translator/c/src/mem.h
@@ -224,5 +224,18 @@
     pypy_g_rpython_memory_gctypelayout_GCData.gcd_inst_root_stack_top = s;
 }
 
+#define OP_GETFIELD_EXC_TYPE(r)                                            \
+    if (__builtin_expect(((Signed)rpy_shadowstack) & 1, 0)) {              \
+        r = (struct pypy_object_vtable0 *)(((char *)rpy_shadowstack) - 1); \
+        if (!r) __builtin_unreachable();                                   \
+    }                                                                      \
+    else {                                                                 \
+        r = NULL;                                                          \
+    }
+#define OP_SETFIELD_EXC_TYPE(x, r)                        \
+    rpy_shadowstack = (x) ?                               \
+        (struct rpy_shadowstack_s *)(((char *)x) + 1)     \
+        : NULL
+
 
 #endif
diff --git a/rpython/translator/exceptiontransform.py b/rpython/translator/exceptiontransform.py
--- a/rpython/translator/exceptiontransform.py
+++ b/rpython/translator/exceptiontransform.py
@@ -67,17 +67,19 @@
         self.c_n_i_error_ll_exc_type = constant_value(n_i_error_ll_exc_type)
 
         def rpyexc_occured():
-            exc_type = exc_data.exc_type
+            exc_type = lloperation.llop.getfield_exc_type(
+                self.lltype_of_exception_type)
             return bool(exc_type)
 
         def rpyexc_fetch_type():
-            return exc_data.exc_type
+            return lloperation.llop.getfield_exc_type(
+                self.lltype_of_exception_type)
 
         def rpyexc_fetch_value():
             return exc_data.exc_value
 
         def rpyexc_clear():
-            exc_data.exc_type = null_type
+            lloperation.llop.setfield_exc_type(lltype.Void, null_type)
             exc_data.exc_value = null_value
 
         def rpyexc_raise(etype, evalue):
@@ -90,12 +92,12 @@
             # us to see at least part of the traceback for them.
             ll_assert(etype != assertion_error_ll_exc_type, "AssertionError")
             ll_assert(etype != n_i_error_ll_exc_type, "NotImplementedError")
-            exc_data.exc_type = etype
+            lloperation.llop.setfield_exc_type(lltype.Void, etype)
             exc_data.exc_value = evalue
             lloperation.llop.debug_start_traceback(lltype.Void, etype)
 
         def rpyexc_reraise(etype, evalue):
-            exc_data.exc_type = etype
+            lloperation.llop.setfield_exc_type(lltype.Void, etype)
             exc_data.exc_value = evalue
             lloperation.llop.debug_reraise_traceback(lltype.Void, etype)
 
@@ -106,7 +108,8 @@
 
         def rpyexc_restore_exception(evalue):
             if evalue:
-                exc_data.exc_type = ll_inst_type(evalue)
+                lloperation.llop.setfield_exc_type(lltype.Void,
+                                                   ll_inst_type(evalue))
                 exc_data.exc_value = evalue
 
         self.rpyexc_occured_ptr = self.build_func(
@@ -143,15 +146,15 @@
             lltype.Void,
             jitcallkind='rpyexc_raise') # for the JIT
 
-        self.rpyexc_fetch_exception_ptr = self.build_func(
-            "RPyFetchException",
-            rpyexc_fetch_exception,
-            [], self.lltype_of_exception_value)
+        #self.rpyexc_fetch_exception_ptr = self.build_func(
+        #    "RPyFetchException",
+        #    rpyexc_fetch_exception,
+        #    [], self.lltype_of_exception_value)
 
-        self.rpyexc_restore_exception_ptr = self.build_func(
-            "RPyRestoreException",
-            self.noinline(rpyexc_restore_exception),
-            [self.lltype_of_exception_value], lltype.Void)
+        #self.rpyexc_restore_exception_ptr = self.build_func(
+        #    "RPyRestoreException",
+        #    self.noinline(rpyexc_restore_exception),
+        #    [self.lltype_of_exception_value], lltype.Void)
 
         self.build_extra_funcs()
 
@@ -461,7 +464,6 @@
 
     def setup_excdata(self):
         EXCDATA = lltype.Struct('ExcData',
-            ('exc_type',  self.lltype_of_exception_type),
             ('exc_value', self.lltype_of_exception_value))
         self.EXCDATA = EXCDATA
 
@@ -482,11 +484,17 @@
         return Constant(fn_ptr, lltype.Ptr(FUNC_TYPE))
 
     def gen_getfield(self, name, llops):
+        if name == 'exc_type':
+            return llops.genop('getfield_exc_type', [],
+                               resulttype = self.lltype_of_exception_type)
         c_name = inputconst(lltype.Void, name)
         return llops.genop('getfield', [self.cexcdata, c_name],
                            resulttype = getattr(self.EXCDATA, name))
 
     def gen_setfield(self, name, v_value, llops):
+        if name == 'exc_type':
+            llops.genop('setfield_exc_type', [v_value])
+            return
         c_name = inputconst(lltype.Void, name)
         llops.genop('setfield', [self.cexcdata, c_name, v_value])
 
@@ -515,6 +523,7 @@
         exc_data = self.exc_data_ptr
 
         def rpyexc_get_exception_addr():
+            raise NotImplementedError
             return (llmemory.cast_ptr_to_adr(exc_data) +
                     llmemory.offsetof(EXCDATA, 'exc_type'))
 


More information about the pypy-commit mailing list