src/cpu/aarch64/vm/frame_aarch64.cpp

Print this page
rev 7701 : 8071947: AARCH64: frame::safe_for_sender() computes incorrect sender_sp value for interpreted frames
Summary: Apply the fix for 8068655 to the AArch64 sources.
Reviewed-by: roland


 106       return false;
 107     }
 108 
 109     // Entry frame checks
 110     if (is_entry_frame()) {
 111       // an entry frame must have a valid fp.
 112 
 113       if (!fp_safe) return false;
 114 
 115       // Validate the JavaCallWrapper an entry frame must have
 116 
 117       address jcw = (address)entry_frame_call_wrapper();
 118 
 119       bool jcw_safe = (jcw < thread->stack_base()) && ( jcw > fp);
 120 
 121       return jcw_safe;
 122 
 123     }
 124 
 125     intptr_t* sender_sp = NULL;

 126     address   sender_pc = NULL;

 127 
 128     if (is_interpreted_frame()) {
 129       // fp must be safe
 130       if (!fp_safe) {
 131         return false;
 132       }
 133 
 134       sender_pc = (address) this->fp()[return_addr_offset];



 135       sender_sp = (intptr_t*) addr_at(sender_sp_offset);


 136 
 137     } else {
 138       // must be some sort of compiled/runtime frame
 139       // fp does not have to be safe (although it could be check for c1?)
 140 
 141       // check for a valid frame_size, otherwise we are unlikely to get a valid sender_pc
 142       if (_cb->frame_size() <= 0) {
 143         return false;
 144       }
 145 
 146       sender_sp = _unextended_sp + _cb->frame_size();

 147       sender_pc = (address) *(sender_sp-1);


 148     }
 149 
 150 
 151     // If the potential sender is the interpreter then we can do some more checking
 152     if (Interpreter::contains(sender_pc)) {
 153 
 154       // fp is always saved in a recognizable place in any code we generate. However
 155       // only if the sender is interpreted/call_stub (c1 too?) are we certain that the saved fp
 156       // is really a frame pointer.
 157 
 158       intptr_t *saved_fp = (intptr_t*)*(sender_sp - frame::sender_sp_offset);
 159       bool saved_fp_safe = ((address)saved_fp < thread->stack_base()) && (saved_fp > sender_sp);
 160 
 161       if (!saved_fp_safe) {
 162         return false;
 163       }
 164 
 165       // construct the potential sender
 166 
 167       frame sender(sender_sp, saved_fp, sender_pc);
 168 
 169       return sender.is_interpreted_frame_valid(thread);
 170 
 171     }
 172 
 173     // We must always be able to find a recognizable pc
 174     CodeBlob* sender_blob = CodeCache::find_blob_unsafe(sender_pc);
 175     if (sender_pc == NULL ||  sender_blob == NULL) {
 176       return false;
 177     }
 178 
 179     // Could be a zombie method
 180     if (sender_blob->is_zombie() || sender_blob->is_unloaded()) {
 181       return false;
 182     }
 183 
 184     // Could just be some random pointer within the codeBlob
 185     if (!sender_blob->code_contains(sender_pc)) {
 186       return false;
 187     }
 188 
 189     // We should never be able to see an adapter if the current frame is something from code cache
 190     if (sender_blob->is_adapter_blob()) {
 191       return false;
 192     }
 193 
 194     // Could be the call_stub
 195     if (StubRoutines::returns_to_call_stub(sender_pc)) {
 196       intptr_t *saved_fp = (intptr_t*)*(sender_sp - frame::sender_sp_offset);
 197       bool saved_fp_safe = ((address)saved_fp < thread->stack_base()) && (saved_fp > sender_sp);
 198 
 199       if (!saved_fp_safe) {
 200         return false;
 201       }
 202 
 203       // construct the potential sender
 204 
 205       frame sender(sender_sp, saved_fp, sender_pc);
 206 
 207       // Validate the JavaCallWrapper an entry frame must have
 208       address jcw = (address)sender.entry_frame_call_wrapper();
 209 
 210       bool jcw_safe = (jcw < thread->stack_base()) && ( jcw > (address)sender.fp());
 211 
 212       return jcw_safe;
 213     }
 214 
 215     if (sender_blob->is_nmethod()) {
 216         nmethod* nm = sender_blob->as_nmethod_or_null();
 217         if (nm != NULL) {
 218             if (nm->is_deopt_mh_entry(sender_pc) || nm->is_deopt_entry(sender_pc)) {
 219                 return false;
 220             }
 221         }
 222     }
 223 
 224     // If the frame size is 0 something (or less) is bad because every nmethod has a non-zero frame size
 225     // because the return address counts against the callee's frame.


 552   }
 553   if (fp() + interpreter_frame_initial_sp_offset < sp()) {
 554     return false;
 555   }
 556   // These are hacks to keep us out of trouble.
 557   // The problem with these is that they mask other problems
 558   if (fp() <= sp()) {        // this attempts to deal with unsigned comparison above
 559     return false;
 560   }
 561 
 562   // do some validation of frame elements
 563 
 564   // first the method
 565 
 566   Method* m = *interpreter_frame_method_addr();
 567 
 568   // validate the method we'd find in this potential sender
 569   if (!m->is_valid_method()) return false;
 570 
 571   // stack frames shouldn't be much larger than max_stack elements
 572 
 573   if (fp() - sp() > 1024 + m->max_stack()*Interpreter::stackElementSize) {



 574     return false;
 575   }
 576 
 577   // validate bci/bcx
 578 
 579   address  bcp    = interpreter_frame_bcp();
 580   if (m->validate_bci_from_bcp(bcp) < 0) {
 581     return false;
 582   }
 583 
 584   // validate constantPoolCache*
 585   ConstantPoolCache* cp = *interpreter_frame_cache_addr();
 586   if (cp == NULL || !cp->is_metaspace_object()) return false;
 587 
 588   // validate locals
 589 
 590   address locals =  (address) *interpreter_frame_locals_addr();
 591 
 592   if (locals > thread->stack_base() || locals < (address) fp()) return false;
 593 




 106       return false;
 107     }
 108 
 109     // Entry frame checks
 110     if (is_entry_frame()) {
 111       // an entry frame must have a valid fp.
 112 
 113       if (!fp_safe) return false;
 114 
 115       // Validate the JavaCallWrapper an entry frame must have
 116 
 117       address jcw = (address)entry_frame_call_wrapper();
 118 
 119       bool jcw_safe = (jcw < thread->stack_base()) && ( jcw > fp);
 120 
 121       return jcw_safe;
 122 
 123     }
 124 
 125     intptr_t* sender_sp = NULL;
 126     intptr_t* sender_unextended_sp = NULL;
 127     address   sender_pc = NULL;
 128     intptr_t* saved_fp =  NULL;
 129 
 130     if (is_interpreted_frame()) {
 131       // fp must be safe
 132       if (!fp_safe) {
 133         return false;
 134       }
 135 
 136       sender_pc = (address) this->fp()[return_addr_offset];
 137       // for interpreted frames, the value below is the sender "raw" sp,
 138       // which can be different from the sender unextended sp (the sp seen
 139       // by the sender) because of current frame local variables
 140       sender_sp = (intptr_t*) addr_at(sender_sp_offset);
 141       sender_unextended_sp = (intptr_t*) this->fp()[interpreter_frame_sender_sp_offset];
 142       saved_fp = (intptr_t*) this->fp()[link_offset];
 143 
 144     } else {
 145       // must be some sort of compiled/runtime frame
 146       // fp does not have to be safe (although it could be check for c1?)
 147 
 148       // check for a valid frame_size, otherwise we are unlikely to get a valid sender_pc
 149       if (_cb->frame_size() <= 0) {
 150         return false;
 151       }
 152 
 153       sender_sp = _unextended_sp + _cb->frame_size();
 154       sender_unextended_sp = sender_sp;
 155       sender_pc = (address) *(sender_sp-1);
 156       // Note: frame::sender_sp_offset is only valid for compiled frame
 157       saved_fp = (intptr_t*) *(sender_sp - frame::sender_sp_offset);
 158     }
 159 
 160 
 161     // If the potential sender is the interpreter then we can do some more checking
 162     if (Interpreter::contains(sender_pc)) {
 163 
 164       // fp is always saved in a recognizable place in any code we generate. However
 165       // only if the sender is interpreted/call_stub (c1 too?) are we certain that the saved fp
 166       // is really a frame pointer.
 167 

 168       bool saved_fp_safe = ((address)saved_fp < thread->stack_base()) && (saved_fp > sender_sp);
 169 
 170       if (!saved_fp_safe) {
 171         return false;
 172       }
 173 
 174       // construct the potential sender
 175 
 176       frame sender(sender_sp, sender_unextended_sp, saved_fp, sender_pc);
 177 
 178       return sender.is_interpreted_frame_valid(thread);
 179 
 180     }
 181 
 182     // We must always be able to find a recognizable pc
 183     CodeBlob* sender_blob = CodeCache::find_blob_unsafe(sender_pc);
 184     if (sender_pc == NULL ||  sender_blob == NULL) {
 185       return false;
 186     }
 187 
 188     // Could be a zombie method
 189     if (sender_blob->is_zombie() || sender_blob->is_unloaded()) {
 190       return false;
 191     }
 192 
 193     // Could just be some random pointer within the codeBlob
 194     if (!sender_blob->code_contains(sender_pc)) {
 195       return false;
 196     }
 197 
 198     // We should never be able to see an adapter if the current frame is something from code cache
 199     if (sender_blob->is_adapter_blob()) {
 200       return false;
 201     }
 202 
 203     // Could be the call_stub
 204     if (StubRoutines::returns_to_call_stub(sender_pc)) {

 205       bool saved_fp_safe = ((address)saved_fp < thread->stack_base()) && (saved_fp > sender_sp);
 206 
 207       if (!saved_fp_safe) {
 208         return false;
 209       }
 210 
 211       // construct the potential sender
 212 
 213       frame sender(sender_sp, sender_unextended_sp, saved_fp, sender_pc);
 214 
 215       // Validate the JavaCallWrapper an entry frame must have
 216       address jcw = (address)sender.entry_frame_call_wrapper();
 217 
 218       bool jcw_safe = (jcw < thread->stack_base()) && ( jcw > (address)sender.fp());
 219 
 220       return jcw_safe;
 221     }
 222 
 223     if (sender_blob->is_nmethod()) {
 224         nmethod* nm = sender_blob->as_nmethod_or_null();
 225         if (nm != NULL) {
 226             if (nm->is_deopt_mh_entry(sender_pc) || nm->is_deopt_entry(sender_pc)) {
 227                 return false;
 228             }
 229         }
 230     }
 231 
 232     // If the frame size is 0 something (or less) is bad because every nmethod has a non-zero frame size
 233     // because the return address counts against the callee's frame.


 560   }
 561   if (fp() + interpreter_frame_initial_sp_offset < sp()) {
 562     return false;
 563   }
 564   // These are hacks to keep us out of trouble.
 565   // The problem with these is that they mask other problems
 566   if (fp() <= sp()) {        // this attempts to deal with unsigned comparison above
 567     return false;
 568   }
 569 
 570   // do some validation of frame elements
 571 
 572   // first the method
 573 
 574   Method* m = *interpreter_frame_method_addr();
 575 
 576   // validate the method we'd find in this potential sender
 577   if (!m->is_valid_method()) return false;
 578 
 579   // stack frames shouldn't be much larger than max_stack elements
 580   // this test requires the use the unextended_sp which is the sp as seen by
 581   // the current frame, and not sp which is the "raw" pc which could point
 582   // further because of local variables of the callee method inserted after
 583   // method arguments
 584   if (fp() - unextended_sp() > 1024 + m->max_stack()*Interpreter::stackElementSize) {
 585     return false;
 586   }
 587 
 588   // validate bci/bcx
 589 
 590   address  bcp    = interpreter_frame_bcp();
 591   if (m->validate_bci_from_bcp(bcp) < 0) {
 592     return false;
 593   }
 594 
 595   // validate constantPoolCache*
 596   ConstantPoolCache* cp = *interpreter_frame_cache_addr();
 597   if (cp == NULL || !cp->is_metaspace_object()) return false;
 598 
 599   // validate locals
 600 
 601   address locals =  (address) *interpreter_frame_locals_addr();
 602 
 603   if (locals > thread->stack_base() || locals < (address) fp()) return false;
 604