[pypy-commit] pypy shadowstack-again: Try with the shadowstack inlined into the regular stack
arigo
noreply at buildbot.pypy.org
Fri May 23 11:25:31 CEST 2014
Author: Armin Rigo <arigo at tunes.org>
Branch: shadowstack-again
Changeset: r71684:27baaf212590
Date: 2014-05-23 11:15 +0200
http://bitbucket.org/pypy/pypy/changeset/27baaf212590/
Log: Try with the shadowstack inlined into the regular stack
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,4 @@
-from rpython.flowspace.model import Block, Link, SpaceOperation
+from rpython.flowspace.model import Block, Link, Constant, SpaceOperation
from rpython.annotator import model as annmodel
from rpython.translator.unsimplify import varoftype, copyvar
from rpython.translator.backendopt.ssa import SSA_to_SSI
@@ -26,39 +26,42 @@
def transform_graph(self, graph):
self._transforming_graph = graph
- self._ss_graph_marker = None
+ self._ss_graph_marker_op = None
super(ShadowStackFrameworkGCTransformer, self).transform_graph(graph)
- del self._ss_graph_marker
+ del self._ss_graph_marker_op
del self._transforming_graph
def sanitize_graph(self, graph):
SSA_to_SSI(graph, self.translator.annotator)
- def ensure_ss_graph_marker(self):
- if self._ss_graph_marker is None:
+ def ensure_ss_graph_marker(self, count):
+ c_count = Constant(count, lltype.Signed)
+ if self._ss_graph_marker_op is None:
graph = self._transforming_graph
inputargs = [copyvar(self.translator.annotator, v)
for v in graph.startblock.inputargs]
hblock = Block(inputargs)
v_marker = varoftype(self.RPY_SHADOWSTACK_PTR)
- hblock.operations.append(SpaceOperation('gc_ss_graph_marker',
- [], v_marker))
+ op = SpaceOperation('gc_ss_graph_marker', [c_count], v_marker)
+ hblock.operations.append(op)
hblock.closeblock(Link(inputargs, graph.startblock))
graph.startblock = hblock
- self._ss_graph_marker = v_marker
- return self._ss_graph_marker
+ self._ss_graph_marker_op = op
+ elif self._ss_graph_marker_op.args[0].value < count:
+ self._ss_graph_marker_op.args[0] = c_count
+ return self._ss_graph_marker_op.result
def push_roots(self, hop, keep_current_args=False):
livevars = self.get_livevars_for_roots(hop, keep_current_args)
self.num_pushs += len(livevars)
- v_marker = self.ensure_ss_graph_marker()
+ v_marker = self.ensure_ss_graph_marker(len(livevars))
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:
- v_marker = self.ensure_ss_graph_marker()
+ v_marker = self.ensure_ss_graph_marker(len(livevars))
hop.genop("gc_ss_reload", [v_marker] + livevars)
@@ -69,15 +72,20 @@
gcdata = self.gcdata
root_iterator = get_root_iterator(gctransformer)
- def walk_stack_root(callback, start, end):
- root_iterator.setcontext(NonConstant(llmemory.NULL))
+ def walk_stack_root(callback, addr):
+ #root_iterator.setcontext(NonConstant(llmemory.NULL))
gc = self.gc
- addr = end
while True:
- addr = root_iterator.nextleft(gc, start, addr)
+ addr += 2
+ ll_assert(not (llmemory.cast_adr_to_int(addr) & (sizeofaddr-1)),
+ "in shadowstack: misaligned")
if addr == llmemory.NULL:
- return
- callback(gc, addr)
+ break
+ while (addr.signed[0] & 2) == 0:
+ if gc.points_to_valid_gc_object(addr):
+ callback(gc, addr)
+ addr -= sizeofaddr
+ addr = addr.address[0]
self.rootstackhook = walk_stack_root
self.shadow_stack_pool = ShadowStackPool(gcdata)
@@ -100,8 +108,7 @@
def walk_stack_roots(self, collect_stack_root):
llop.gc_stack_top(lltype.Void)
gcdata = self.gcdata
- self.rootstackhook(collect_stack_root,
- gcdata.root_stack_base, gcdata.root_stack_top)
+ self.rootstackhook(collect_stack_root, gcdata.root_stack_top)
def need_thread_support(self, gctransformer, getfn):
from rpython.rlib import rthread # xxx fish
@@ -276,11 +283,11 @@
#MAX = 20 not implemented yet
def __init__(self, gcdata):
- self.unused_full_stack = llmemory.NULL
+ #self.unused_full_stack = llmemory.NULL
self.gcdata = gcdata
def initial_setup(self):
- self._prepare_unused_stack()
+ #self._prepare_unused_stack()
self.start_fresh_new_state()
def allocate(self, SHADOWSTACKREF):
@@ -294,7 +301,8 @@
forget_current_state(), and then call restore_state_from()
or start_fresh_new_state().
"""
- self._prepare_unused_stack()
+ raise MemoryError
+ #self._prepare_unused_stack()
shadowstackref.base = self.gcdata.root_stack_base
shadowstackref.top = self.gcdata.root_stack_top
shadowstackref.context = ncontext
@@ -312,14 +320,15 @@
self.gcdata.root_stack_top = llmemory.NULL # to detect missing restore
def forget_current_state(self):
- ll_assert(self.gcdata.root_stack_base == self.gcdata.root_stack_top,
- "forget_current_state: shadowstack not empty!")
- if self.unused_full_stack:
- llmemory.raw_free(self.unused_full_stack)
- self.unused_full_stack = self.gcdata.root_stack_base
+ #ll_assert(self.gcdata.root_stack_base == self.gcdata.root_stack_top,
+ # "forget_current_state: shadowstack not empty!")
+ #if self.unused_full_stack:
+ # llmemory.raw_free(self.unused_full_stack)
+ #self.unused_full_stack = self.gcdata.root_stack_base
self.gcdata.root_stack_top = llmemory.NULL # to detect missing restore
def restore_state_from(self, shadowstackref):
+ raise MemoryError
ll_assert(bool(shadowstackref.base), "empty shadowstackref!")
ll_assert(shadowstackref.base <= shadowstackref.top,
"restore_state_from: broken shadowstack")
@@ -328,9 +337,11 @@
self._cleanup(shadowstackref)
def start_fresh_new_state(self):
- self.gcdata.root_stack_base = self.unused_full_stack
- self.gcdata.root_stack_top = self.unused_full_stack
- self.unused_full_stack = llmemory.NULL
+ #self.gcdata.root_stack_base = self.unused_full_stack
+ #self.gcdata.root_stack_top = self.unused_full_stack
+ #self.unused_full_stack = llmemory.NULL
+ self.gcdata.root_stack_top = llmemory.NULL
+ self.gcdata.root_stack_top -= 2
llop.gc_stack_bottom(lltype.Void)
def _cleanup(self, shadowstackref):
@@ -338,12 +349,12 @@
shadowstackref.top = llmemory.NULL
shadowstackref.context = llmemory.NULL
- def _prepare_unused_stack(self):
- if self.unused_full_stack == llmemory.NULL:
- root_stack_size = sizeofaddr * self.root_stack_depth
- self.unused_full_stack = llmemory.raw_malloc(root_stack_size)
- if self.unused_full_stack == llmemory.NULL:
- raise MemoryError
+ ## def _prepare_unused_stack(self):
+ ## if self.unused_full_stack == llmemory.NULL:
+ ## root_stack_size = sizeofaddr * self.root_stack_depth
+ ## self.unused_full_stack = llmemory.raw_malloc(root_stack_size)
+ ## if self.unused_full_stack == llmemory.NULL:
+ ## raise MemoryError
def get_root_iterator(gctransformer):
@@ -354,8 +365,10 @@
return True
def setcontext(self, context):
pass
- def nextleft(self, gc, start, addr):
- while addr != start:
+ def nextleft(self, gc, addr):
+ assert llmemory.cast_adr_to_int(addr) & (WORD-1) == (WORD-2)
+ xxxxxxx
+ while addr != ROOT_STACK_STOP:
addr -= sizeofaddr
if gc.points_to_valid_gc_object(addr):
return addr
@@ -366,6 +379,7 @@
def get_shadowstackref(root_walker, gctransformer):
+ raise Exception("XXX")
if hasattr(gctransformer, '_SHADOWSTACKREF'):
return gctransformer._SHADOWSTACKREF
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,14 +444,16 @@
return shadowstack.ShadowStackFrameworkGCTransformer(self.db.translator)
def OP_GC_SS_GRAPH_MARKER(self, funcgen, op):
- return '%s = rpy_shadowstack;' % funcgen.expr(op.result)
+ marker = funcgen.expr(op.result)
+ count = op.args[0].value
+ return 'RPY_SS_GRAPH_MARKER(%s, %d);' % (marker, count)
def OP_GC_SS_STORE(self, funcgen, op):
marker = funcgen.expr(op.args[0])
lines = []
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) - 1))
+ lines.append('%s[%d].s = %s;' % (marker, i + 1, funcgen.expr(v)))
+ lines.append('RPY_SS_STORED(%s, %d);' % (marker, len(op.args) - 1))
return '\n'.join(lines)
def OP_GC_SS_RELOAD(self, funcgen, op):
@@ -463,7 +465,7 @@
funcgen.expr(v),
cdecl(typename, ''),
marker,
- i))
+ i + 1))
if isinstance(v, Constant):
lines[-1] = '/* %s */' % lines[-1]
lines.reverse()
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
@@ -207,15 +207,25 @@
struct rpy_shadowstack_s { void *s; };
#ifdef RPY_SHADOWSTACK_REG
-register struct rpy_shadowstack_s *rpy_shadowstack asm(RPY_SHADOWSTACK_REG);
+register void *rpy_shadowstack asm(RPY_SHADOWSTACK_REG);
#else
-extern struct rpy_shadowstack_s *rpy_shadowstack;
+extern void *rpy_shadowstack;
#endif
+#define RPY_SS_GRAPH_MARKER(marker, count) \
+ ; \
+ struct rpy_shadowstack_s a##marker[count + 1]; \
+ a##marker[0].s = rpy_shadowstack; \
+ marker = a##marker
+
+#define RPY_SS_STORED(marker, count) \
+ rpy_shadowstack = count > 0 ? (char *)(marker + count) - 2 \
+ : marker[0].s
+
static inline void pypy_asm_stack_bottom(void)
{
void *s = pypy_g_rpython_memory_gctypelayout_GCData.gcd_inst_root_stack_top;
- rpy_shadowstack = (struct rpy_shadowstack_s *)s;
+ rpy_shadowstack = s;
}
static inline void pypy_asm_stack_top(void)
@@ -232,10 +242,8 @@
else { \
r = NULL; \
}
-#define OP_SETFIELD_EXC_TYPE(x, r) \
- rpy_shadowstack = (x) ? \
- (struct rpy_shadowstack_s *)(((char *)x) + 1) \
- : NULL
+#define OP_SETFIELD_EXC_TYPE(x, r) \
+ rpy_shadowstack = (x) ? ((char *)(x)) + 1 : NULL
#endif
More information about the pypy-commit
mailing list