Skip to content
Draft
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -163,7 +163,17 @@ static void write_stack_trace(int fd, void* instruction_pointer, void* frame_poi
// address points to the instruction to be executed after this function returns
// (immediately following the call that created this frame). Symbolication tools
// will adjust to resolve the actual call site.
#ifdef __aarch64__
// Strip pointer authentication codes from the return address: on AArch64, return
// addresses stored on the stack have a PAC signature encoded in their upper 16
// bits, so we need to mask to 48-bit virtual address space to end up with the
// actual address within the relevant module.
uint64_t raw_ret = reinterpret_cast<uint64_t>(ret_addr);
raw_ret &= 0x0000ffffffffffff;

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Preserve VA bits when stripping PAC

On AArch64 Linux processes that opt in to 52-bit user VAs (for example, executable mappings above 0x0000ffffffffffff), this hard-coded 48-bit mask truncates legitimate address bits before crash processing. write_modules() records full uintptr_t ranges from /proc/self/maps, so the truncated frame address will no longer fall inside the module range and symbolication will report the frame as unknown; use an architecture PAC-strip instruction/kernel PAC mask or derive the active VA width instead of assuming 48 bits.

Useful? React with 👍 / 👎.

WriteCrashReportStackFrame(fd, raw_ret);
#else
WriteCrashReportStackFrame(fd, reinterpret_cast<uint64_t>(ret_addr));
#endif

// Reading frame[0] into fp (effectively dereferencing fp) moves to the next frame
fp = frame[0];
Expand Down