def get_result_suspstack(h): # Now we are in the target, after the switch() or the new(). # Note that this whole module was carefully written in such a way as # not to invoke pushing/popping things off the shadowstack at # unexpected moments... oldsuspstack = gcrootfinder.oldsuspstack newsuspstack = gcrootfinder.newsuspstack gcrootfinder.oldsuspstack = NULL_SUSPSTACK gcrootfinder.newsuspstack = NULL_SUSPSTACK if not h: raise MemoryError # We still have the old shadowstack active at this point; save it # away, and restore the new one if oldsuspstack: ll_assert(not _c.is_empty_handle(h), "unexpected empty stacklet handle") h = llmemory.cast_ptr_to_adr(h) llop.gc_save_current_state_away(lltype.Void, oldsuspstack, h) else: ll_assert(_c.is_empty_handle(h), "unexpected non-empty stacklet handle") llop.gc_forget_current_state(lltype.Void) # llop.gc_restore_state_from(lltype.Void, newsuspstack) # # From this point on, 'newsuspstack' is consumed and done, its # shadow stack installed as the current one. It should not be # used any more. For performance, we avoid it being deallocated # by letting it be reused on the next switch. gcrootfinder.oldsuspstack = newsuspstack # Return. return oldsuspstack
def get_result_suspstack(h): # Now we are in the target, after the switch() or the new(). # Note that this whole module was carefully written in such a way as # not to invoke pushing/popping things off the shadowstack at # unexpected moments... oldsuspstack = gcrootfinder.oldsuspstack newsuspstack = gcrootfinder.newsuspstack gcrootfinder.oldsuspstack = NULL_SUSPSTACK gcrootfinder.newsuspstack = NULL_SUSPSTACK if not h: raise MemoryError # We still have the old shadowstack active at this point; save it # away, and restore the new one if oldsuspstack: ll_assert(not _c.is_empty_handle(h),"unexpected empty stacklet handle") h = llmemory.cast_ptr_to_adr(h) llop.gc_save_current_state_away(lltype.Void, oldsuspstack, h) else: ll_assert(_c.is_empty_handle(h),"unexpected non-empty stacklet handle") llop.gc_forget_current_state(lltype.Void) # llop.gc_restore_state_from(lltype.Void, newsuspstack) # # From this point on, 'newsuspstack' is consumed and done, its # shadow stack installed as the current one. It should not be # used any more. For performance, we avoid it being deallocated # by letting it be reused on the next switch. gcrootfinder.oldsuspstack = newsuspstack # Return. return oldsuspstack
def _new_callback(h, arg): # We still have the old shadowstack active at this point; save it # away, and start a fresh new one oldsuspstack = gcrootfinder.oldsuspstack h = llmemory.cast_ptr_to_adr(h) llop.gc_save_current_state_away(lltype.Void, oldsuspstack, h) llop.gc_start_fresh_new_state(lltype.Void) gcrootfinder.oldsuspstack = NULL_SUSPSTACK # newsuspstack = gcrootfinder.callback(oldsuspstack, arg) # # Finishing this stacklet. gcrootfinder.oldsuspstack = NULL_SUSPSTACK gcrootfinder.newsuspstack = newsuspstack h = llop.gc_shadowstackref_context(llmemory.Address, newsuspstack) return llmemory.cast_adr_to_ptr(h, _c.handle)