8387792: Enable PAC-RET for VM code on Windows/ARM64
Reviewed-by: haosun, erikj
This commit is contained in:
+7
-5
@@ -366,11 +366,13 @@ free disk space is required.</p>
|
||||
also possible to use <a href="#cross-compiling">cross-compiling</a>.</p>
|
||||
<h4 id="branch-protection">Branch Protection</h4>
|
||||
<p>In order to use Branch Protection features in the VM,
|
||||
<code>--enable-branch-protection</code> must be used. This option
|
||||
requires C++ compiler support (GCC 9.1.0+ or Clang 10+). The resulting
|
||||
build can be run on both machines with and without support for branch
|
||||
protection in hardware. Branch Protection is only supported for Linux
|
||||
targets.</p>
|
||||
<code>--enable-branch-protection</code> must be used. This option requires C++
|
||||
compiler support for <code>-mbranch-protection=standard</code> in GCC 9.1.0+ or
|
||||
Clang 10+ on Linux/AArch64 or for <code>/guard:signret</code> in Visual Studio
|
||||
2019+ on Windows/ARM64. The resulting build can be run on both machines with and
|
||||
without support for branch protection in hardware. Branch Protection is fully
|
||||
supported for the Linux/AArch64 target and only partially supported for the
|
||||
Windows/ARM64 targets.</p>
|
||||
<h3 id="building-on-32-bit-arm">Building on 32-bit ARM</h3>
|
||||
<p>This is not recommended. Instead, see the section on <a
|
||||
href="#cross-compiling">Cross-compiling</a>.</p>
|
||||
|
||||
+5
-3
@@ -171,9 +171,11 @@ possible to use [cross-compiling](#cross-compiling).
|
||||
|
||||
In order to use Branch Protection features in the VM,
|
||||
`--enable-branch-protection` must be used. This option requires C++ compiler
|
||||
support (GCC 9.1.0+ or Clang 10+). The resulting build can be run on both
|
||||
machines with and without support for branch protection in hardware. Branch
|
||||
Protection is only supported for Linux targets.
|
||||
support for `-mbranch-protection=standard` in GCC 9.1.0+ or Clang 10+ on
|
||||
Linux/AArch64 or for `/guard:signret` in Visual Studio 2019+ on Windows/ARM64.
|
||||
The resulting build can be run on both machines with and without support for
|
||||
branch protection in hardware. Branch Protection is fully supported for the
|
||||
Linux/AArch64 target and only partially supported for the Windows/ARM64 target.
|
||||
|
||||
### Building on 32-bit ARM
|
||||
|
||||
|
||||
@@ -945,11 +945,21 @@ AC_DEFUN_ONCE([FLAGS_SETUP_BRANCH_PROTECTION],
|
||||
[
|
||||
# Is branch protection available?
|
||||
BRANCH_PROTECTION_AVAILABLE=false
|
||||
BRANCH_PROTECTION_FLAG="-mbranch-protection=standard"
|
||||
BRANCH_PROTECTION_CFLAG=""
|
||||
BRANCH_PROTECTION_ASFLAG=""
|
||||
|
||||
if test "x$OPENJDK_TARGET_CPU" = xaarch64; then
|
||||
if test "x$TOOLCHAIN_TYPE" = xgcc || test "x$TOOLCHAIN_TYPE" = xclang; then
|
||||
FLAGS_COMPILER_CHECK_ARGUMENTS(ARGUMENT: [$BRANCH_PROTECTION_FLAG],
|
||||
BRANCH_PROTECTION_CFLAG="-mbranch-protection=standard"
|
||||
# The GCC/Clang assembler accepts the same flag as the compiler.
|
||||
BRANCH_PROTECTION_ASFLAG="$BRANCH_PROTECTION_CFLAG"
|
||||
FLAGS_COMPILER_CHECK_ARGUMENTS(ARGUMENT: [$BRANCH_PROTECTION_CFLAG],
|
||||
IF_TRUE: [BRANCH_PROTECTION_AVAILABLE=true])
|
||||
elif test "x$TOOLCHAIN_TYPE" = xmicrosoft; then
|
||||
BRANCH_PROTECTION_CFLAG="/guard:signret"
|
||||
# MSVC's assembler does not support branch protection flags, so
|
||||
# BRANCH_PROTECTION_ASFLAG is intentionally left empty.
|
||||
FLAGS_COMPILER_CHECK_ARGUMENTS(ARGUMENT: [$BRANCH_PROTECTION_CFLAG],
|
||||
IF_TRUE: [BRANCH_PROTECTION_AVAILABLE=true])
|
||||
fi
|
||||
fi
|
||||
@@ -957,5 +967,5 @@ AC_DEFUN_ONCE([FLAGS_SETUP_BRANCH_PROTECTION],
|
||||
UTIL_ARG_ENABLE(NAME: branch-protection, DEFAULT: false,
|
||||
RESULT: BRANCH_PROTECTION_ENABLED, AVAILABLE: $BRANCH_PROTECTION_AVAILABLE,
|
||||
DESC: [enable branch protection when compiling C/C++],
|
||||
IF_ENABLED: [BRANCH_PROTECTION_CFLAGS=$BRANCH_PROTECTION_FLAG])
|
||||
IF_ENABLED: [BRANCH_PROTECTION_CFLAGS=$BRANCH_PROTECTION_CFLAG])
|
||||
])
|
||||
|
||||
@@ -211,7 +211,7 @@ AC_DEFUN([FLAGS_SETUP_ASFLAGS_CPU_DEP],
|
||||
fi
|
||||
|
||||
if test "x$BRANCH_PROTECTION_ENABLED" = "xtrue"; then
|
||||
$2JVM_ASFLAGS="${$2JVM_ASFLAGS} $BRANCH_PROTECTION_FLAG"
|
||||
$2JVM_ASFLAGS="${$2JVM_ASFLAGS} $BRANCH_PROTECTION_ASFLAG"
|
||||
fi
|
||||
|
||||
AC_SUBST($2JVM_ASFLAGS)
|
||||
|
||||
@@ -79,6 +79,9 @@
|
||||
#include "utilities/population_count.hpp"
|
||||
#include "utilities/vmError.hpp"
|
||||
#include "windbghelp.hpp"
|
||||
#if defined(_M_ARM64)
|
||||
#include CPU_HEADER(pauth)
|
||||
#endif
|
||||
#if INCLUDE_JFR
|
||||
#include "jfr/jfrEvents.hpp"
|
||||
#include "jfr/support/jfrNativeLibraryLoadEvent.hpp"
|
||||
@@ -6637,6 +6640,19 @@ bool os::win32::platform_print_native_stack(outputStream* st, const void* contex
|
||||
int count = 0;
|
||||
address lastpc_internal = 0;
|
||||
while (count++ < StackPrintLimit) {
|
||||
#if defined(_M_ARM64)
|
||||
// On Windows/ARM64, when the CPU is using authenticated pointers, return
|
||||
// addresses are signed. Unfortunately, `StackWalk64()` does not strip the
|
||||
// pointer signature, so we need to do this ourself. Since stripping the
|
||||
// signature is an idempotent operation, we don't need to guard this call
|
||||
// based on whether pointer authentication is enabled.
|
||||
address original = (address)stk.AddrPC.Offset;
|
||||
address stripped = pauth_strip_pointer(original);
|
||||
stk.AddrPC.Offset = (DWORD64)(uintptr_t)stripped;
|
||||
|
||||
// We updated the stack frame's PC, so keep the context's PC in sync.
|
||||
ctx.Pc = stk.AddrPC.Offset;
|
||||
#endif
|
||||
intptr_t* sp = (intptr_t*)stk.AddrStack.Offset;
|
||||
intptr_t* fp = (intptr_t*)stk.AddrFrame.Offset; // NOT necessarily the same as ctx.Rbp!
|
||||
address pc = (address)stk.AddrPC.Offset;
|
||||
|
||||
@@ -0,0 +1,47 @@
|
||||
;
|
||||
; Copyright (c) 2026, Microsoft and/or its affiliates. All rights reserved.
|
||||
; DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
;
|
||||
; This code is free software; you can redistribute it and/or modify it
|
||||
; under the terms of the GNU General Public License version 2 only, as
|
||||
; published by the Free Software Foundation.
|
||||
;
|
||||
; This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
; ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
; FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
; version 2 for more details (a copy is included in the LICENSE file that
|
||||
; accompanied this code).
|
||||
;
|
||||
; You should have received a copy of the GNU General Public License version
|
||||
; 2 along with this work; if not, write to the Free Software Foundation,
|
||||
; Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
;
|
||||
; Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
; or visit www.oracle.com if you need additional information or have any
|
||||
; questions.
|
||||
;
|
||||
|
||||
; Remove the AArch64 pointer signature from the pointer argument
|
||||
;
|
||||
; Both XPACI and XPACLRI can get the job done, with XPACI being more
|
||||
; convenient since it can work with any general purpose register. However,
|
||||
; unlike XPACI, XPACLRI can be encoded using hint instructions, thus letting
|
||||
; us compile this function using older compilers.
|
||||
;
|
||||
; Since XPACLRI implicitly uses the link register (x30) and we instead want
|
||||
; to remove the signature from the function argument (in x0), we temporarily
|
||||
; save x30 before restoring it at the end.
|
||||
|
||||
ALIGN 4
|
||||
EXPORT pauth_drop_signature_win_arm64
|
||||
AREA pauth_text, CODE
|
||||
|
||||
pauth_drop_signature_win_arm64
|
||||
mov x9, x30
|
||||
mov x30, x0
|
||||
hint #7
|
||||
mov x0, x30
|
||||
mov x30, x9
|
||||
ret
|
||||
|
||||
END
|
||||
@@ -28,9 +28,10 @@
|
||||
// OS specific Support for ROP Protection in VM code.
|
||||
// For more details on PAC see pauth_aarch64.hpp.
|
||||
|
||||
extern "C" address pauth_drop_signature_win_arm64(address p);
|
||||
|
||||
inline address pauth_strip_pointer(address ptr) {
|
||||
// No PAC support in windows as of yet.
|
||||
return ptr;
|
||||
return pauth_drop_signature_win_arm64(ptr);
|
||||
}
|
||||
|
||||
inline address pauth_sign_return_address(address ret_addr) {
|
||||
|
||||
Reference in New Issue
Block a user