Author: Armin Rigo <[email protected]>
Branch: shadowstack-again
Changeset: r71600:77dafb290569
Date: 2014-05-20 15:21 +0200
http://bitbucket.org/pypy/pypy/changeset/77dafb290569/
Log: Starting
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,4 +1,6 @@
+from rpython.flowspace.model import Block, Link, SpaceOperation
from rpython.annotator import model as annmodel
+from rpython.translator.unsimplify import varoftype, copyvar
from rpython.rtyper.llannotation import SomePtr
from rpython.rlib.debug import ll_assert
from rpython.rlib.nonconst import NonConstant
@@ -13,46 +15,38 @@
class ShadowStackFrameworkGCTransformer(BaseFrameworkGCTransformer):
- def annotate_walker_functions(self, getfn):
- self.incr_stack_ptr = getfn(self.root_walker.incr_stack,
- [annmodel.SomeInteger()],
- SomeAddress(),
- inline = True)
- self.decr_stack_ptr = getfn(self.root_walker.decr_stack,
- [annmodel.SomeInteger()],
- SomeAddress(),
- inline = True)
-
def build_root_walker(self):
return ShadowStackRootWalker(self)
+ def transform_graph(self, graph):
+ self._transforming_graph = graph
+ super(ShadowStackFrameworkGCTransformer, self).transform_graph(graph)
+ del self._transforming_graph
+
+ 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':
+ 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
+
def push_roots(self, hop, keep_current_args=False):
livevars = self.get_livevars_for_roots(hop, keep_current_args)
self.num_pushs += len(livevars)
- if not livevars:
- return []
- c_len = rmodel.inputconst(lltype.Signed, len(livevars) )
- base_addr = hop.genop("direct_call", [self.incr_stack_ptr, c_len ],
- resulttype=llmemory.Address)
- for k,var in enumerate(livevars):
- c_k = rmodel.inputconst(lltype.Signed, k * sizeofaddr)
- v_adr = gen_cast(hop.llops, llmemory.Address, var)
- hop.genop("raw_store", [base_addr, c_k, v_adr])
+ self.ensure_ss_graph_marker()
+ hop.genop("gc_ss_store", livevars)
return livevars
def pop_roots(self, hop, livevars):
- if not livevars:
- return
- c_len = rmodel.inputconst(lltype.Signed, len(livevars) )
- base_addr = hop.genop("direct_call", [self.decr_stack_ptr, c_len ],
- resulttype=llmemory.Address)
- if self.gcdata.gc.moving_gc:
- # for moving collectors, reload the roots into the local variables
- for k,var in enumerate(livevars):
- c_k = rmodel.inputconst(lltype.Signed, k * sizeofaddr)
- v_newaddr = hop.genop("raw_load", [base_addr, c_k],
- resulttype=llmemory.Address)
- hop.genop("gc_reload_possibly_moved", [v_newaddr, var])
+ # for moving collectors, reload the roots into the local variables
+ if self.gcdata.gc.moving_gc and livevars:
+ hop.genop("gc_ss_reload", livevars)
class ShadowStackRootWalker(BaseRootWalker):
@@ -61,18 +55,6 @@
# NB. 'self' is frozen, but we can use self.gcdata to store state
gcdata = self.gcdata
- def incr_stack(n):
- top = gcdata.root_stack_top
- gcdata.root_stack_top = top + n*sizeofaddr
- return top
- self.incr_stack = incr_stack
-
- def decr_stack(n):
- top = gcdata.root_stack_top - n*sizeofaddr
- gcdata.root_stack_top = top
- return top
- self.decr_stack = decr_stack
-
root_iterator = get_root_iterator(gctransformer)
def walk_stack_root(callback, start, end):
root_iterator.setcontext(NonConstant(llmemory.NULL))
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
@@ -465,7 +465,9 @@
'gc_restore_exception': LLOp(),
'gc_call_rtti_destructor': LLOp(),
'gc_deallocate': LLOp(),
- 'gc_reload_possibly_moved': LLOp(),
+ 'gc_ss_graph_marker': LLOp(),
+ 'gc_ss_store': LLOp(),
+ 'gc_ss_reload': LLOp(),
# see rlib/objectmodel for gc_identityhash and gc_id
'gc_identityhash': LLOp(sideeffects=False, canmallocgc=True),
'gc_id': LLOp(sideeffects=False, canmallocgc=True),
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
@@ -437,6 +437,29 @@
from rpython.memory.gctransform import shadowstack
return
shadowstack.ShadowStackFrameworkGCTransformer(self.db.translator)
+ def OP_GC_SS_GRAPH_MARKER(self, funcgen, op):
+ return '; struct rpy_shadowstack_s *rpy_ss = rpy_shadowstack;'
+
+ def OP_GC_SS_STORE(self, funcgen, op):
+ 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))
+ return '\n'.join(lines)
+
+ def OP_GC_SS_RELOAD(self, funcgen, op):
+ lines = []
+ for i, v in enumerate(op.args):
+ typename = funcgen.db.gettype(v.concretetype)
+ lines.append('%s = (%s)rpy_ss[%d].s;' % (
+ funcgen.expr(v),
+ cdecl(typename, ''),
+ i))
+ if isinstance(v, Constant):
+ lines[-1] = '/* %s */' % lines[-1]
+ lines.reverse()
+ return '\n'.join(lines)
+
class AsmGcRootFrameworkGcPolicy(BasicFrameworkGcPolicy):
def gettransformer(self):
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
@@ -35,7 +35,6 @@
#ifdef PYPY_USE_ASMGCC
pypy_g_rpython_rtyper_lltypesystem_rffi_StackCounter.sc_inst_stacks_counter++;
#endif
- pypy_asm_stack_bottom();
instrument_setup();
#ifndef MS_WINDOWS
@@ -50,6 +49,7 @@
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++) {
diff --git a/rpython/translator/c/src/mem.c b/rpython/translator/c/src/mem.c
--- a/rpython/translator/c/src/mem.c
+++ b/rpython/translator/c/src/mem.c
@@ -95,7 +95,14 @@
GC_finalize_on_demand = 1;
GC_set_warn_proc(mem_boehm_ignore);
}
-#endif /* BOEHM GC */
+
+#elif !defined(PYPY_USE_ASMGCC) /* shadowstack */
+
+#ifndef RPY_SHADOWSTACK_REG
+struct rpy_shadowstack_s *rpy_shadowstack;
+#endif
+
+#endif /* BOEHM_GC / PYPY_USE_ASMGCC */
#ifdef RPY_ASSERT
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
@@ -136,12 +136,13 @@
#define OP_GC_DUMP_RPY_HEAP(fd, r) r = 0
#define OP_GC_SET_EXTRA_THRESHOLD(x, r) /* nothing */
+
+#ifdef PYPY_USE_ASMGCC
/****************************/
/* The "asmgcc" root finder */
/****************************/
-#ifndef _MSC_VER
-/* Implementation for Linux */
+/* Implementation of asmgcc, for Linux only */
extern char __gcmapstart;
extern char __gcmapend;
extern char __gccallshapes;
@@ -194,44 +195,27 @@
i == 2 ? (void*)&__gccallshapes : \
NULL
+
#else
-/* implementation of asmgcroot for Windows */
-extern void* __gcmapstart;
-extern void* __gcmapend;
-extern char* __gccallshapes;
-extern Signed pypy_asm_stackwalk(void*, void*);
+/*********************************/
+/* The "shadowstack" root finder */
+/*********************************/
-/* With the msvc Microsoft Compiler, the optimizer seems free to move
- any code (even asm) that involves local memory (registers and stack).
- The _ReadWriteBarrier function has an effect only where the content
- of a global variable is *really* used. trackgcroot.py will remove
- the extra instructions: the access to _constant_always_one_ is
- removed, and the multiplication is replaced with a simple move. */
+#if defined(__GNUC__) && defined(__amd64__)
+# define RPY_SHADOWSTACK_REG "r15"
+#endif
-static __forceinline void*
-pypy_asm_gcroot(void* _r1)
+struct rpy_shadowstack_s { void *s; };
+#ifdef RPY_SHADOWSTACK_REG
+register struct rpy_shadowstack_s *rpy_shadowstack asm(RPY_SHADOWSTACK_REG);
+#else
+extern struct rpy_shadowstack_s *rpy_shadowstack;
+#endif
+
+static inline void pypy_asm_stack_bottom(void)
{
- static volatile int _constant_always_one_ = 1;
- (Signed)_r1 *= _constant_always_one_;
- _ReadWriteBarrier();
- return _r1;
+ abort();
}
-#define pypy_asm_gc_nocollect(f) "/* GC_NOCOLLECT " #f " */"
-
-#ifndef _WIN64
-# define pypy_asm_keepalive(v) __asm { }
-#else
- /* is there something cheaper? */
-# define pypy_asm_keepalive(v) _ReadWriteBarrier();
-#endif
-
-static __declspec(noinline) void pypy_asm_stack_bottom() { }
-
-#define OP_GC_ASMGCROOT_STATIC(i, r) \
- r = i == 0 ? (void*)__gcmapstart : \
- i == 1 ? (void*)__gcmapend : \
- i == 2 ? (void*)&__gccallshapes : \
- NULL
#endif
_______________________________________________
pypy-commit mailing list
[email protected]
https://mail.python.org/mailman/listinfo/pypy-commit