1.1 --- a/src/cpu/sparc/vm/frame_sparc.cpp Mon Apr 07 15:15:16 2008 -0700 1.2 +++ b/src/cpu/sparc/vm/frame_sparc.cpp Tue Apr 08 12:23:15 2008 -0400 1.3 @@ -157,22 +157,158 @@ 1.4 check_location_valid(); 1.5 } 1.6 1.7 +bool frame::safe_for_sender(JavaThread *thread) { 1.8 1.9 -bool frame::safe_for_sender(JavaThread *thread) { 1.10 - address sp = (address)_sp; 1.11 - if (sp != NULL && 1.12 - (sp <= thread->stack_base() && sp >= thread->stack_base() - thread->stack_size())) { 1.13 - // Unfortunately we can only check frame complete for runtime stubs and nmethod 1.14 - // other generic buffer blobs are more problematic so we just assume they are 1.15 - // ok. adapter blobs never have a frame complete and are never ok. 1.16 - if (_cb != NULL && !_cb->is_frame_complete_at(_pc)) { 1.17 - if (_cb->is_nmethod() || _cb->is_adapter_blob() || _cb->is_runtime_stub()) { 1.18 - return false; 1.19 - } 1.20 + address _SP = (address) sp(); 1.21 + address _FP = (address) fp(); 1.22 + address _UNEXTENDED_SP = (address) unextended_sp(); 1.23 + // sp must be within the stack 1.24 + bool sp_safe = (_SP <= thread->stack_base()) && 1.25 + (_SP >= thread->stack_base() - thread->stack_size()); 1.26 + 1.27 + if (!sp_safe) { 1.28 + return false; 1.29 + } 1.30 + 1.31 + // unextended sp must be within the stack and above or equal sp 1.32 + bool unextended_sp_safe = (_UNEXTENDED_SP <= thread->stack_base()) && 1.33 + (_UNEXTENDED_SP >= _SP); 1.34 + 1.35 + if (!unextended_sp_safe) return false; 1.36 + 1.37 + // an fp must be within the stack and above (but not equal) sp 1.38 + bool fp_safe = (_FP <= thread->stack_base()) && 1.39 + (_FP > _SP); 1.40 + 1.41 + // We know sp/unextended_sp are safe only fp is questionable here 1.42 + 1.43 + // If the current frame is known to the code cache then we can attempt to 1.44 + // to construct the sender and do some validation of it. This goes a long way 1.45 + // toward eliminating issues when we get in frame construction code 1.46 + 1.47 + if (_cb != NULL ) { 1.48 + 1.49 + // First check if frame is complete and tester is reliable 1.50 + // Unfortunately we can only check frame complete for runtime stubs and nmethod 1.51 + // other generic buffer blobs are more problematic so we just assume they are 1.52 + // ok. adapter blobs never have a frame complete and are never ok. 1.53 + 1.54 + if (!_cb->is_frame_complete_at(_pc)) { 1.55 + if (_cb->is_nmethod() || _cb->is_adapter_blob() || _cb->is_runtime_stub()) { 1.56 + return false; 1.57 } 1.58 - return true; 1.59 + } 1.60 + 1.61 + // Entry frame checks 1.62 + if (is_entry_frame()) { 1.63 + // an entry frame must have a valid fp. 1.64 + 1.65 + if (!fp_safe) { 1.66 + return false; 1.67 + } 1.68 + 1.69 + // Validate the JavaCallWrapper an entry frame must have 1.70 + 1.71 + address jcw = (address)entry_frame_call_wrapper(); 1.72 + 1.73 + bool jcw_safe = (jcw <= thread->stack_base()) && ( jcw > _FP); 1.74 + 1.75 + return jcw_safe; 1.76 + 1.77 + } 1.78 + 1.79 + intptr_t* younger_sp = sp(); 1.80 + intptr_t* _SENDER_SP = sender_sp(); // sender is actually just _FP 1.81 + bool adjusted_stack = is_interpreted_frame(); 1.82 + 1.83 + address sender_pc = (address)younger_sp[I7->sp_offset_in_saved_window()] + pc_return_offset; 1.84 + 1.85 + 1.86 + // We must always be able to find a recognizable pc 1.87 + CodeBlob* sender_blob = CodeCache::find_blob_unsafe(sender_pc); 1.88 + if (sender_pc == NULL || sender_blob == NULL) { 1.89 + return false; 1.90 + } 1.91 + 1.92 + // It should be safe to construct the sender though it might not be valid 1.93 + 1.94 + frame sender(_SENDER_SP, younger_sp, adjusted_stack); 1.95 + 1.96 + // Do we have a valid fp? 1.97 + address sender_fp = (address) sender.fp(); 1.98 + 1.99 + // an fp must be within the stack and above (but not equal) current frame's _FP 1.100 + 1.101 + bool sender_fp_safe = (sender_fp <= thread->stack_base()) && 1.102 + (sender_fp > _FP); 1.103 + 1.104 + if (!sender_fp_safe) { 1.105 + return false; 1.106 + } 1.107 + 1.108 + 1.109 + // If the potential sender is the interpreter then we can do some more checking 1.110 + if (Interpreter::contains(sender_pc)) { 1.111 + return sender.is_interpreted_frame_valid(thread); 1.112 + } 1.113 + 1.114 + // Could just be some random pointer within the codeBlob 1.115 + if (!sender.cb()->instructions_contains(sender_pc)) return false; 1.116 + 1.117 + // We should never be able to see an adapter if the current frame is something from code cache 1.118 + 1.119 + if ( sender_blob->is_adapter_blob()) { 1.120 + return false; 1.121 + } 1.122 + 1.123 + if( sender.is_entry_frame()) { 1.124 + // Validate the JavaCallWrapper an entry frame must have 1.125 + 1.126 + address jcw = (address)sender.entry_frame_call_wrapper(); 1.127 + 1.128 + bool jcw_safe = (jcw <= thread->stack_base()) && ( jcw > sender_fp); 1.129 + 1.130 + return jcw_safe; 1.131 + } 1.132 + 1.133 + // If the frame size is 0 something is bad because every nmethod has a non-zero frame size 1.134 + // because you must allocate window space 1.135 + 1.136 + if (sender_blob->frame_size() == 0) { 1.137 + assert(!sender_blob->is_nmethod(), "should count return address at least"); 1.138 + return false; 1.139 + } 1.140 + 1.141 + // The sender should positively be an nmethod or call_stub. On sparc we might in fact see something else. 1.142 + // The cause of this is because at a save instruction the O7 we get is a leftover from an earlier 1.143 + // window use. So if a runtime stub creates two frames (common in fastdebug/jvmg) then we see the 1.144 + // stale pc. So if the sender blob is not something we'd expect we have little choice but to declare 1.145 + // the stack unwalkable. pd_get_top_frame_for_signal_handler tries to recover from this by unwinding 1.146 + // that initial frame and retrying. 1.147 + 1.148 + if (!sender_blob->is_nmethod()) { 1.149 + return false; 1.150 + } 1.151 + 1.152 + // Could put some more validation for the potential non-interpreted sender 1.153 + // frame we'd create by calling sender if I could think of any. Wait for next crash in forte... 1.154 + 1.155 + // One idea is seeing if the sender_pc we have is one that we'd expect to call to current cb 1.156 + 1.157 + // We've validated the potential sender that would be created 1.158 + 1.159 + return true; 1.160 + 1.161 } 1.162 - return false; 1.163 + 1.164 + // Must be native-compiled frame. Since sender will try and use fp to find 1.165 + // linkages it must be safe 1.166 + 1.167 + if (!fp_safe) return false; 1.168 + 1.169 + // could try and do some more potential verification of native frame if we could think of some... 1.170 + 1.171 + return true; 1.172 } 1.173 1.174 // constructors 1.175 @@ -450,7 +586,7 @@ 1.176 } 1.177 1.178 1.179 -bool frame::is_interpreted_frame_valid() const { 1.180 +bool frame::is_interpreted_frame_valid(JavaThread* thread) const { 1.181 #ifdef CC_INTERP 1.182 // Is there anything to do? 1.183 #else 1.184 @@ -462,6 +598,7 @@ 1.185 if (sp() == 0 || (intptr_t(sp()) & (2*wordSize-1)) != 0) { 1.186 return false; 1.187 } 1.188 + 1.189 const intptr_t interpreter_frame_initial_sp_offset = interpreter_frame_vm_local_words; 1.190 if (fp() + interpreter_frame_initial_sp_offset < sp()) { 1.191 return false; 1.192 @@ -471,9 +608,43 @@ 1.193 if (fp() <= sp()) { // this attempts to deal with unsigned comparison above 1.194 return false; 1.195 } 1.196 - if (fp() - sp() > 4096) { // stack frames shouldn't be large. 1.197 + // do some validation of frame elements 1.198 + 1.199 + // first the method 1.200 + 1.201 + methodOop m = *interpreter_frame_method_addr(); 1.202 + 1.203 + // validate the method we'd find in this potential sender 1.204 + if (!Universe::heap()->is_valid_method(m)) return false; 1.205 + 1.206 + // stack frames shouldn't be much larger than max_stack elements 1.207 + 1.208 + if (fp() - sp() > 1024 + m->max_stack()*Interpreter::stackElementSize()) { 1.209 return false; 1.210 } 1.211 + 1.212 + // validate bci/bcx 1.213 + 1.214 + intptr_t bcx = interpreter_frame_bcx(); 1.215 + if (m->validate_bci_from_bcx(bcx) < 0) { 1.216 + return false; 1.217 + } 1.218 + 1.219 + // validate constantPoolCacheOop 1.220 + 1.221 + constantPoolCacheOop cp = *interpreter_frame_cache_addr(); 1.222 + 1.223 + if (cp == NULL || 1.224 + !Space::is_aligned(cp) || 1.225 + !Universe::heap()->is_permanent((void*)cp)) return false; 1.226 + 1.227 + // validate locals 1.228 + 1.229 + address locals = (address) *interpreter_frame_locals_addr(); 1.230 + 1.231 + if (locals > thread->stack_base() || locals < (address) fp()) return false; 1.232 + 1.233 + // We'd have to be pretty unlucky to be mislead at this point 1.234 #endif /* CC_INTERP */ 1.235 return true; 1.236 }