Author: Armin Rigo <ar...@tunes.org> 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 pypy-commit@python.org https://mail.python.org/mailman/listinfo/pypy-commit