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

*** 121,140 **** --- 121,147 ---- return jcw_safe; } intptr_t* sender_sp = NULL; + intptr_t* sender_unextended_sp = NULL; address sender_pc = NULL; + intptr_t* saved_fp = NULL; if (is_interpreted_frame()) { // fp must be safe if (!fp_safe) { return false; } sender_pc = (address) this->fp()[return_addr_offset]; + // for interpreted frames, the value below is the sender "raw" sp, + // which can be different from the sender unextended sp (the sp seen + // by the sender) because of current frame local variables sender_sp = (intptr_t*) addr_at(sender_sp_offset); + sender_unextended_sp = (intptr_t*) this->fp()[interpreter_frame_sender_sp_offset]; + saved_fp = (intptr_t*) this->fp()[link_offset]; } else { // must be some sort of compiled/runtime frame // fp does not have to be safe (although it could be check for c1?)
*** 142,172 **** if (_cb->frame_size() <= 0) { return false; } sender_sp = _unextended_sp + _cb->frame_size(); sender_pc = (address) *(sender_sp-1); } // If the potential sender is the interpreter then we can do some more checking if (Interpreter::contains(sender_pc)) { // fp is always saved in a recognizable place in any code we generate. However // only if the sender is interpreted/call_stub (c1 too?) are we certain that the saved fp // is really a frame pointer. - intptr_t *saved_fp = (intptr_t*)*(sender_sp - frame::sender_sp_offset); bool saved_fp_safe = ((address)saved_fp < thread->stack_base()) && (saved_fp > sender_sp); if (!saved_fp_safe) { return false; } // construct the potential sender ! frame sender(sender_sp, saved_fp, sender_pc); return sender.is_interpreted_frame_valid(thread); } --- 149,181 ---- if (_cb->frame_size() <= 0) { return false; } sender_sp = _unextended_sp + _cb->frame_size(); + sender_unextended_sp = sender_sp; sender_pc = (address) *(sender_sp-1); + // Note: frame::sender_sp_offset is only valid for compiled frame + saved_fp = (intptr_t*) *(sender_sp - frame::sender_sp_offset); } // If the potential sender is the interpreter then we can do some more checking if (Interpreter::contains(sender_pc)) { // fp is always saved in a recognizable place in any code we generate. However // only if the sender is interpreted/call_stub (c1 too?) are we certain that the saved fp // is really a frame pointer. bool saved_fp_safe = ((address)saved_fp < thread->stack_base()) && (saved_fp > sender_sp); if (!saved_fp_safe) { return false; } // construct the potential sender ! frame sender(sender_sp, sender_unextended_sp, saved_fp, sender_pc); return sender.is_interpreted_frame_valid(thread); }
*** 191,210 **** return false; } // Could be the call_stub if (StubRoutines::returns_to_call_stub(sender_pc)) { - intptr_t *saved_fp = (intptr_t*)*(sender_sp - frame::sender_sp_offset); bool saved_fp_safe = ((address)saved_fp < thread->stack_base()) && (saved_fp > sender_sp); if (!saved_fp_safe) { return false; } // construct the potential sender ! frame sender(sender_sp, saved_fp, sender_pc); // Validate the JavaCallWrapper an entry frame must have address jcw = (address)sender.entry_frame_call_wrapper(); bool jcw_safe = (jcw < thread->stack_base()) && ( jcw > (address)sender.fp()); --- 200,218 ---- return false; } // Could be the call_stub if (StubRoutines::returns_to_call_stub(sender_pc)) { bool saved_fp_safe = ((address)saved_fp < thread->stack_base()) && (saved_fp > sender_sp); if (!saved_fp_safe) { return false; } // construct the potential sender ! frame sender(sender_sp, sender_unextended_sp, saved_fp, sender_pc); // Validate the JavaCallWrapper an entry frame must have address jcw = (address)sender.entry_frame_call_wrapper(); bool jcw_safe = (jcw < thread->stack_base()) && ( jcw > (address)sender.fp());
*** 567,578 **** // validate the method we'd find in this potential sender if (!m->is_valid_method()) return false; // stack frames shouldn't be much larger than max_stack elements ! ! if (fp() - sp() > 1024 + m->max_stack()*Interpreter::stackElementSize) { return false; } // validate bci/bcx --- 575,589 ---- // validate the method we'd find in this potential sender if (!m->is_valid_method()) return false; // stack frames shouldn't be much larger than max_stack elements ! // this test requires the use the unextended_sp which is the sp as seen by ! // the current frame, and not sp which is the "raw" pc which could point ! // further because of local variables of the callee method inserted after ! // method arguments ! if (fp() - unextended_sp() > 1024 + m->max_stack()*Interpreter::stackElementSize) { return false; } // validate bci/bcx