Commit bf383a87 authored by Georgia Kouveli's avatar Georgia Kouveli Committed by Commit Bot

[arm64][cfi] Skip authenticating return addresses in the profiler

The SafeStackFrameIterator, used in the profiler, sometimes uses the
link register instead of a return address stored on the stack, to get
more accurate results. This happens in particular for bytecode handlers
that do not create a stack frame. Authentication of PC for those frames
would fail in the SafeStackFrameIterator, as the "PC address" would not
point to a stack location with a signed return address, but instead to
a member of the SafeStackFrameIterator class where the value of the link
register was stored. We address this by skipping authentication of PCs
in the profiler.

Bug: v8:10026
Change-Id: I331c6c68e703db766be1891efffa69c2f9794e8a
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/2242954Reviewed-by: 's avatarRoss McIlroy <rmcilroy@chromium.org>
Commit-Queue: Georgia Kouveli <georgia.kouveli@arm.com>
Cr-Commit-Position: refs/heads/master@{#68388}
parent 40cef10f
......@@ -77,6 +77,10 @@ inline Address StackFrame::callee_pc() const {
inline Address StackFrame::pc() const { return ReadPC(pc_address()); }
inline Address StackFrame::unauthenticated_pc() const {
return PointerAuthentication::StripPAC(*pc_address());
}
inline Address StackFrame::ReadPC(Address* pc_address) {
return PointerAuthentication::AuthenticatePC(pc_address, kSystemPointerSize);
}
......
......@@ -315,6 +315,7 @@ SafeStackFrameIterator::SafeStackFrameIterator(Isolate* isolate, Address pc,
// return address into the interpreter entry trampoline, then we are likely
// in a bytecode handler with elided frame. In that case, set the PC
// properly and make sure we do not drop the frame.
bool is_no_frame_bytecode_handler = false;
if (IsNoFrameBytecodeHandlerPc(isolate, pc, fp)) {
Address* tos_location = nullptr;
if (top_link_register_) {
......@@ -326,6 +327,7 @@ SafeStackFrameIterator::SafeStackFrameIterator(Isolate* isolate, Address pc,
if (IsInterpreterFramePc(isolate, *tos_location, &state)) {
state.pc_address = tos_location;
is_no_frame_bytecode_handler = true;
advance_frame = false;
}
}
......@@ -338,12 +340,12 @@ SafeStackFrameIterator::SafeStackFrameIterator(Isolate* isolate, Address pc,
StandardFrameConstants::kContextOffset);
Address frame_marker = fp + StandardFrameConstants::kFunctionOffset;
if (IsValidStackAddress(frame_marker)) {
type = StackFrame::ComputeType(this, &state);
top_frame_type_ = type;
// We only keep the top frame if we believe it to be interpreted frame.
if (type != StackFrame::INTERPRETED) {
advance_frame = true;
if (is_no_frame_bytecode_handler) {
type = StackFrame::INTERPRETED;
} else {
type = StackFrame::ComputeType(this, &state);
}
top_frame_type_ = type;
MSAN_MEMORY_IS_INITIALIZED(
fp + CommonFrameConstants::kContextOrFrameTypeOffset,
kSystemPointerSize);
......
......@@ -220,6 +220,11 @@ class StackFrame {
inline Address pc() const;
// Skip authentication of the PC, when using CFI. Used in the profiler, where
// in certain corner-cases we do not use an address on the stack, which would
// be signed, as the PC of the frame.
inline Address unauthenticated_pc() const;
Address constant_pool() const { return *constant_pool_address(); }
void set_constant_pool(Address constant_pool) {
*constant_pool_address() = constant_pool;
......
......@@ -337,7 +337,10 @@ bool TickSample::GetStackSample(Isolate* v8_isolate, RegisterState* regs,
continue;
}
}
frames[i++] = reinterpret_cast<void*>(it.frame()->pc());
// For arm64, the PC for the frame sometimes doesn't come from the stack,
// but from the link register instead. For this reason, we skip
// authenticating it.
frames[i++] = reinterpret_cast<void*>(it.frame()->unauthenticated_pc());
}
sample_info->frames_count = i;
return true;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment