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