v8
V8 is Google’s open source high-performance JavaScript and WebAssembly engine, written in C++.
Loading...
Searching...
No Matches
pointer-authentication-arm64.h
Go to the documentation of this file.
1// Copyright 2019 the V8 project authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#ifndef V8_EXECUTION_ARM64_POINTER_AUTHENTICATION_ARM64_H_
6#define V8_EXECUTION_ARM64_POINTER_AUTHENTICATION_ARM64_H_
7
12
13namespace v8 {
14namespace internal {
15
16// The following functions execute on the host and therefore need a different
17// path based on whether we are simulating arm64 or not.
18
19namespace impl {
21#ifdef USE_SIMULATOR
22 pc = Simulator::AddPAC(pc, sp, Simulator::kPACKeyIB,
23 Simulator::kInstructionPointer);
24#else
25 asm volatile(
26 " mov x17, %[pc]\n"
27 " mov x16, %[sp]\n"
28 " pacib1716\n"
29 " mov %[pc], x17\n"
30 : [pc] "+r"(pc)
31 : [sp] "r"(sp)
32 : "x16", "x17");
33#endif
34 return pc;
35}
36
38#ifdef USE_SIMULATOR
39 pc = Simulator::AuthPAC(pc, sp, Simulator::kPACKeyIB,
40 Simulator::kInstructionPointer);
41#else
42 asm volatile(
43 " mov x17, %[pc]\n"
44 " mov x16, %[stack_ptr]\n"
45 " autib1716\n"
46 " mov %[pc], x17\n"
47 // Save LR.
48 " mov x16, x30\n"
49 // Check if authentication was successful, otherwise crash.
50 " mov x30, x17\n"
51 " xpaclri\n"
52 " cmp x30, x17\n"
53 // Restore LR, to help with unwinding in case `brk #0` is hit below.
54 " mov x30, x16\n"
55 " b.eq 1f\n"
56 " brk #0\n"
57 "1:\n"
58 : [pc] "+r"(pc)
59 : [stack_ptr] "r"(sp)
60 : "x16", "x17", "x30", "cc");
61#endif
62 return pc;
63}
64} // namespace impl
65
66// Authenticate the address stored in {pc_address}. {offset_from_sp} is the
67// offset between {pc_address} and the pointer used as a context for signing.
69 Address* pc_address, unsigned offset_from_sp) {
70 uint64_t sp = reinterpret_cast<uint64_t>(pc_address) + offset_from_sp;
71 uint64_t pc = static_cast<uint64_t>(*pc_address);
72 return impl::AuthPAC(pc, sp);
73}
74
75// Strip Pointer Authentication Code (PAC) from {pc} and return the raw value.
77#ifdef USE_SIMULATOR
78 return Simulator::StripPAC(pc, Simulator::kInstructionPointer);
79#else
80 // x30 == lr, but use 'x30' instead of 'lr' below, as GCC does not accept
81 // 'lr' in the clobbers list.
82 asm volatile(
83 " mov x16, x30\n"
84 " mov x30, %[pc]\n"
85 " xpaclri\n"
86 " mov %[pc], x30\n"
87 " mov x30, x16\n"
88 : [pc] "+r"(pc)
89 :
90 : "x16", "x30");
91 return pc;
92#endif
93}
94
95// Authenticate the address stored in {pc_address} and replace it with
96// {new_pc}, after signing it. {offset_from_sp} is the offset between
97// {pc_address} and the pointer used as a context for signing.
99 Address new_pc,
100 int offset_from_sp) {
101 uint64_t sp = reinterpret_cast<uint64_t>(pc_address) + offset_from_sp;
102 uint64_t old_pc = static_cast<uint64_t>(*pc_address);
103#ifdef USE_SIMULATOR
104 uint64_t auth_old_pc = Simulator::AuthPAC(old_pc, sp, Simulator::kPACKeyIB,
105 Simulator::kInstructionPointer);
106 uint64_t raw_old_pc =
107 Simulator::StripPAC(old_pc, Simulator::kInstructionPointer);
108 // Verify that the old address is authenticated.
109 CHECK_EQ(auth_old_pc, raw_old_pc);
110 new_pc = Simulator::AddPAC(new_pc, sp, Simulator::kPACKeyIB,
111 Simulator::kInstructionPointer);
112#else
113 // Only store newly signed address after we have verified that the old
114 // address is authenticated.
115 asm volatile(
116 " mov x17, %[new_pc]\n"
117 " mov x16, %[sp]\n"
118 " pacib1716\n"
119 " mov %[new_pc], x17\n"
120 " mov x17, %[old_pc]\n"
121 " autib1716\n"
122 // Save LR.
123 " mov x16, x30\n"
124 // Check if authentication was successful, otherwise crash.
125 " mov x30, x17\n"
126 " xpaclri\n"
127 " cmp x30, x17\n"
128 // Restore LR, to help with unwinding in case `brk #0` is hit below.
129 " mov x30, x16\n"
130 " b.eq 1f\n"
131 " brk #0\n"
132 "1:\n"
133 : [new_pc] "+&r"(new_pc)
134 : [sp] "r"(sp), [old_pc] "r"(old_pc)
135 : "x16", "x17", "x30", "cc");
136#endif
137 *pc_address = new_pc;
138}
139
140// Sign {pc} using {sp}.
149
150// Sign {pc} using {new_sp}.
152 Address pc,
153 Address new_sp,
154 Address old_sp) {
155#if V8_ENABLE_WEBASSEMBLY
156 // Only used by wasm deoptimizations and growable stacks.
157 CHECK(v8_flags.wasm_deopt || v8_flags.experimental_wasm_growable_stacks);
158 // Verify the old pc and sign it for the new sp.
159 return impl::SignPC(impl::AuthPAC(pc, old_sp), new_sp);
160#else
161 UNREACHABLE();
162#endif
163}
164
165} // namespace internal
166} // namespace v8
167#endif // V8_EXECUTION_ARM64_POINTER_AUTHENTICATION_ARM64_H_
static Address EnsureValidReturnAddress(Isolate *isolate, Address address)
static V8_INLINE void ReplacePC(Address *pc_address, Address new_pc, int offset_from_sp)
static V8_INLINE Address SignAndCheckPC(Isolate *isolate, Address pc, Address sp)
static V8_INLINE Address StripPAC(Address pc)
static V8_INLINE Address MoveSignedPC(Isolate *isolate, Address pc, Address new_sp, Address old_sp)
static V8_INLINE Address AuthenticatePC(Address *pc_address, unsigned offset_from_sp)
V8_INLINE Address SignPC(Address pc, Address sp)
V8_INLINE Address AuthPAC(Address pc, Address sp)
V8_EXPORT_PRIVATE FlagValues v8_flags
#define CHECK(condition)
Definition logging.h:124
#define CHECK_EQ(lhs, rhs)
#define V8_INLINE
Definition v8config.h:500