1 /* 2 * Copyright (c) 1999, 2025, Oracle and/or its affiliates. All rights reserved. 3 * Copyright (c) 2014, Red Hat Inc. All rights reserved. 4 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 5 * 6 * This code is free software; you can redistribute it and/or modify it 7 * under the terms of the GNU General Public License version 2 only, as 8 * published by the Free Software Foundation. 9 * 10 * This code is distributed in the hope that it will be useful, but WITHOUT 11 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 12 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 13 * version 2 for more details (a copy is included in the LICENSE file that 14 * accompanied this code). 15 * 16 * You should have received a copy of the GNU General Public License version 17 * 2 along with this work; if not, write to the Free Software Foundation, 18 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 19 * 20 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 21 * or visit www.oracle.com if you need additional information or have any 22 * questions. 23 * 24 */ 25 26 #include "asm/macroAssembler.hpp" 27 #include "classfile/vmSymbols.hpp" 28 #include "code/codeCache.hpp" 29 #include "code/vtableStubs.hpp" 30 #include "code/nativeInst.hpp" 31 #include "interpreter/interpreter.hpp" 32 #include "jvm.h" 33 #include "memory/allocation.inline.hpp" 34 #include "os_linux.hpp" 35 #include "os_posix.hpp" 36 #include "prims/jniFastGetField.hpp" 37 #include "prims/jvm_misc.hpp" 38 #include "runtime/arguments.hpp" 39 #include "runtime/frame.inline.hpp" 40 #include "runtime/interfaceSupport.inline.hpp" 41 #include "runtime/java.hpp" 42 #include "runtime/javaCalls.hpp" 43 #include "runtime/mutexLocker.hpp" 44 #include "runtime/osThread.hpp" 45 #include "runtime/safepointMechanism.hpp" 46 #include "runtime/sharedRuntime.hpp" 47 #include "runtime/stubRoutines.hpp" 48 #include "runtime/javaThread.hpp" 49 #include "runtime/timer.hpp" 50 #include "signals_posix.hpp" 51 #include "utilities/debug.hpp" 52 #include "utilities/events.hpp" 53 #include "utilities/vmError.hpp" 54 55 // put OS-includes here 56 # include <sys/types.h> 57 # include <sys/mman.h> 58 # include <pthread.h> 59 # include <signal.h> 60 # include <errno.h> 61 # include <dlfcn.h> 62 # include <stdlib.h> 63 # include <stdio.h> 64 # include <unistd.h> 65 # include <sys/resource.h> 66 # include <pthread.h> 67 # include <sys/stat.h> 68 # include <sys/time.h> 69 # include <sys/utsname.h> 70 # include <sys/socket.h> 71 # include <sys/wait.h> 72 # include <pwd.h> 73 # include <poll.h> 74 # include <ucontext.h> 75 76 #define REG_FP 29 77 #define REG_LR 30 78 79 NOINLINE address os::current_stack_pointer() { 80 return (address)__builtin_frame_address(0); 81 } 82 83 char* os::non_memory_address_word() { 84 // Must never look like an address returned by reserve_memory, 85 // even in its subfields (as defined by the CPU immediate fields, 86 // if the CPU splits constants across multiple instructions). 87 88 return (char*) 0xffffffffffff; 89 } 90 91 address os::Posix::ucontext_get_pc(const ucontext_t * uc) { 92 return (address)uc->uc_mcontext.pc; 93 } 94 95 void os::Posix::ucontext_set_pc(ucontext_t * uc, address pc) { 96 uc->uc_mcontext.pc = (intptr_t)pc; 97 } 98 99 intptr_t* os::Linux::ucontext_get_sp(const ucontext_t * uc) { 100 return (intptr_t*)uc->uc_mcontext.sp; 101 } 102 103 intptr_t* os::Linux::ucontext_get_fp(const ucontext_t * uc) { 104 return (intptr_t*)uc->uc_mcontext.regs[REG_FP]; 105 } 106 107 address os::fetch_frame_from_context(const void* ucVoid, 108 intptr_t** ret_sp, intptr_t** ret_fp) { 109 110 address epc; 111 const ucontext_t* uc = (const ucontext_t*)ucVoid; 112 113 if (uc != nullptr) { 114 epc = os::Posix::ucontext_get_pc(uc); 115 if (ret_sp) *ret_sp = os::Linux::ucontext_get_sp(uc); 116 if (ret_fp) *ret_fp = os::Linux::ucontext_get_fp(uc); 117 } else { 118 epc = nullptr; 119 if (ret_sp) *ret_sp = (intptr_t *)nullptr; 120 if (ret_fp) *ret_fp = (intptr_t *)nullptr; 121 } 122 123 return epc; 124 } 125 126 frame os::fetch_frame_from_context(const void* ucVoid) { 127 intptr_t* sp; 128 intptr_t* fp; 129 address epc = fetch_frame_from_context(ucVoid, &sp, &fp); 130 if (!is_readable_pointer(epc)) { 131 // Try to recover from calling into bad memory 132 // Assume new frame has not been set up, the same as 133 // compiled frame stack bang 134 return fetch_compiled_frame_from_context(ucVoid); 135 } 136 return frame(sp, fp, epc); 137 } 138 139 frame os::fetch_compiled_frame_from_context(const void* ucVoid) { 140 const ucontext_t* uc = (const ucontext_t*)ucVoid; 141 // In compiled code, the stack banging is performed before LR 142 // has been saved in the frame. LR is live, and SP and FP 143 // belong to the caller. 144 intptr_t* fp = os::Linux::ucontext_get_fp(uc); 145 intptr_t* sp = os::Linux::ucontext_get_sp(uc); 146 address pc = (address)(uc->uc_mcontext.regs[REG_LR] 147 - NativeInstruction::instruction_size); 148 return frame(sp, fp, pc); 149 } 150 151 // By default, gcc always saves frame pointer rfp on this stack. This 152 // may get turned off by -fomit-frame-pointer. 153 // The "Procedure Call Standard for the Arm 64-bit Architecture" doesn't 154 // specify a location for the frame record within a stack frame (6.4.6). 155 // GCC currently chooses to save it at the top of the frame (lowest address). 156 // This means that using fr->sender_sp() to set the caller's frame _unextended_sp, 157 // as we do in x86, is wrong. Using fr->link() instead only makes sense for 158 // native frames. Setting a correct value for _unextended_sp is important 159 // if this value is later used to get that frame's caller. This will happen 160 // if we end up calling frame::sender_for_compiled_frame(), which will be the 161 // case if the _pc is associated with a CodeBlob that has a _frame_size > 0 162 // (nmethod, runtime stub, safepoint stub, etc). 163 frame os::get_sender_for_C_frame(frame* fr) { 164 address pc = fr->sender_pc(); 165 CodeBlob* cb = CodeCache::find_blob(pc); 166 bool use_codeblob = cb != nullptr && cb->frame_size() > 0; 167 assert(!use_codeblob || !Interpreter::contains(pc), "should not be an interpreter frame"); 168 intptr_t* sender_sp = use_codeblob ? (fr->link() + frame::metadata_words - cb->frame_size()) : fr->link(); 169 return frame(sender_sp, sender_sp, fr->link(), pc, cb, true /* allow_cb_null */); 170 } 171 172 NOINLINE frame os::current_frame() { 173 intptr_t *fp = *(intptr_t **)__builtin_frame_address(0); 174 frame myframe((intptr_t*)os::current_stack_pointer(), 175 (intptr_t*)fp, 176 CAST_FROM_FN_PTR(address, os::current_frame)); 177 if (os::is_first_C_frame(&myframe)) { 178 // stack is not walkable 179 return frame(); 180 } else { 181 return os::get_sender_for_C_frame(&myframe); 182 } 183 } 184 185 bool PosixSignals::pd_hotspot_signal_handler(int sig, siginfo_t* info, 186 ucontext_t* uc, JavaThread* thread) { 187 188 /* 189 NOTE: does not seem to work on linux. 190 if (info == nullptr || info->si_code <= 0 || info->si_code == SI_NOINFO) { 191 // can't decode this kind of signal 192 info = nullptr; 193 } else { 194 assert(sig == info->si_signo, "bad siginfo"); 195 } 196 */ 197 // decide if this trap can be handled by a stub 198 address stub = nullptr; 199 200 address pc = nullptr; 201 202 //%note os_trap_1 203 if (info != nullptr && uc != nullptr && thread != nullptr) { 204 pc = (address) os::Posix::ucontext_get_pc(uc); 205 206 address addr = (address) info->si_addr; 207 208 // Make sure the high order byte is sign extended, as it may be masked away by the hardware. 209 if ((uintptr_t(addr) & (uintptr_t(1) << 55)) != 0) { 210 addr = address(uintptr_t(addr) | (uintptr_t(0xFF) << 56)); 211 } 212 213 // Handle ALL stack overflow variations here 214 if (sig == SIGSEGV) { 215 // check if fault address is within thread stack 216 if (thread->is_in_full_stack(addr)) { 217 if (os::Posix::handle_stack_overflow(thread, addr, pc, uc, &stub)) { 218 return true; // continue 219 } 220 } 221 } 222 223 if (thread->thread_state() == _thread_in_Java) { 224 // Java thread running in Java code => find exception handler if any 225 // a fault inside compiled code, the interpreter, or a stub 226 227 // Handle signal from NativeJump::patch_verified_entry(). 228 if ((sig == SIGILL || sig == SIGTRAP) 229 && nativeInstruction_at(pc)->is_sigill_not_entrant()) { 230 if (TraceTraps) { 231 tty->print_cr("trap: not_entrant (%s)", (sig == SIGTRAP) ? "SIGTRAP" : "SIGILL"); 232 } 233 stub = SharedRuntime::get_handle_wrong_method_stub(); 234 } else if (sig == SIGSEGV && SafepointMechanism::is_poll_address((address)info->si_addr)) { 235 stub = SharedRuntime::get_poll_stub(pc); 236 } else if (sig == SIGBUS /* && info->si_code == BUS_OBJERR */) { 237 // BugId 4454115: A read from a MappedByteBuffer can fault 238 // here if the underlying file has been truncated. 239 // Do not crash the VM in such a case. 240 CodeBlob* cb = CodeCache::find_blob(pc); 241 nmethod* nm = (cb != nullptr) ? cb->as_nmethod_or_null() : nullptr; 242 bool is_unsafe_memory_access = (thread->doing_unsafe_access() && UnsafeMemoryAccess::contains_pc(pc)); 243 if ((nm != nullptr && nm->has_unsafe_access()) || is_unsafe_memory_access) { 244 address next_pc = pc + NativeCall::instruction_size; 245 if (is_unsafe_memory_access) { 246 next_pc = UnsafeMemoryAccess::page_error_continue_pc(pc); 247 } 248 stub = SharedRuntime::handle_unsafe_access(thread, next_pc); 249 } 250 } else if (sig == SIGILL && nativeInstruction_at(pc)->is_stop()) { 251 // A pointer to the message will have been placed in r0 252 const char *detail_msg = (const char *)(uc->uc_mcontext.regs[0]); 253 const char *msg = "stop"; 254 if (TraceTraps) { 255 tty->print_cr("trap: %s: (SIGILL)", msg); 256 } 257 258 // End life with a fatal error, message and detail message and the context. 259 // Note: no need to do any post-processing here (e.g. signal chaining) 260 VMError::report_and_die(thread, uc, nullptr, 0, msg, "%s", detail_msg); 261 262 ShouldNotReachHere(); 263 264 } 265 else 266 267 if (sig == SIGFPE && 268 (info->si_code == FPE_INTDIV || info->si_code == FPE_FLTDIV)) { 269 stub = 270 SharedRuntime:: 271 continuation_for_implicit_exception(thread, 272 pc, 273 SharedRuntime:: 274 IMPLICIT_DIVIDE_BY_ZERO); 275 } else if (sig == SIGSEGV && 276 MacroAssembler::uses_implicit_null_check((void*)addr)) { 277 // Determination of interpreter/vtable stub/compiled code null exception 278 stub = SharedRuntime::continuation_for_implicit_exception(thread, pc, SharedRuntime::IMPLICIT_NULL); 279 } 280 } else if ((thread->thread_state() == _thread_in_vm || 281 thread->thread_state() == _thread_in_native) && 282 sig == SIGBUS && /* info->si_code == BUS_OBJERR && */ 283 thread->doing_unsafe_access()) { 284 address next_pc = pc + NativeCall::instruction_size; 285 if (UnsafeMemoryAccess::contains_pc(pc)) { 286 next_pc = UnsafeMemoryAccess::page_error_continue_pc(pc); 287 } 288 stub = SharedRuntime::handle_unsafe_access(thread, next_pc); 289 } 290 291 // jni_fast_Get<Primitive>Field can trap at certain pc's if a GC kicks in 292 // and the heap gets shrunk before the field access. 293 if ((sig == SIGSEGV) || (sig == SIGBUS)) { 294 address addr = JNI_FastGetField::find_slowcase_pc(pc); 295 if (addr != (address)-1) { 296 stub = addr; 297 } 298 } 299 } 300 301 if (stub != nullptr) { 302 // save all thread context in case we need to restore it 303 if (thread != nullptr) thread->set_saved_exception_pc(pc); 304 305 os::Posix::ucontext_set_pc(uc, stub); 306 return true; 307 } 308 309 return false; // Mute compiler 310 } 311 312 void os::Linux::init_thread_fpu_state(void) { 313 } 314 315 int os::Linux::get_fpu_control_word(void) { 316 return 0; 317 } 318 319 void os::Linux::set_fpu_control_word(int fpu_control) { 320 } 321 322 //////////////////////////////////////////////////////////////////////////////// 323 // thread stack 324 325 // Minimum usable stack sizes required to get to user code. Space for 326 // HotSpot guard pages is added later. 327 size_t os::_compiler_thread_min_stack_allowed = 72 * K; 328 size_t os::_java_thread_min_stack_allowed = 72 * K; 329 size_t os::_vm_internal_thread_min_stack_allowed = 72 * K; 330 331 // return default stack size for thr_type 332 size_t os::Posix::default_stack_size(os::ThreadType thr_type) { 333 // default stack size (compiler thread needs larger stack) 334 size_t s = (thr_type == os::compiler_thread ? 4 * M : 1 * M); 335 return s; 336 } 337 338 ///////////////////////////////////////////////////////////////////////////// 339 // helper functions for fatal error handler 340 341 void os::print_context(outputStream *st, const void *context) { 342 if (context == nullptr) return; 343 344 const ucontext_t *uc = (const ucontext_t*)context; 345 346 st->print_cr("Registers:"); 347 for (int r = 0; r < 31; r++) { 348 st->print_cr( "R%d=" INTPTR_FORMAT, r, (uintptr_t)uc->uc_mcontext.regs[r]); 349 } 350 st->cr(); 351 } 352 353 void os::print_register_info(outputStream *st, const void *context, int& continuation) { 354 const int register_count = 31 /* r0-r30 */; 355 int n = continuation; 356 assert(n >= 0 && n <= register_count, "Invalid continuation value"); 357 if (context == nullptr || n == register_count) { 358 return; 359 } 360 361 const ucontext_t *uc = (const ucontext_t*)context; 362 while (n < register_count) { 363 // Update continuation with next index before printing location 364 continuation = n + 1; 365 st->print("R%-2d=", n); 366 print_location(st, uc->uc_mcontext.regs[n]); 367 ++n; 368 } 369 } 370 371 void os::setup_fpu() { 372 } 373 374 #ifndef PRODUCT 375 void os::verify_stack_alignment() { 376 assert(((intptr_t)os::current_stack_pointer() & (StackAlignmentInBytes-1)) == 0, "incorrect stack alignment"); 377 } 378 #endif 379 380 int os::extra_bang_size_in_bytes() { 381 // AArch64 does not require the additional stack bang. 382 return 0; 383 } 384 385 static inline void atomic_copy64(const volatile void *src, volatile void *dst) { 386 *(jlong *) dst = *(const jlong *) src; 387 } 388 389 extern "C" { 390 int SpinPause() { 391 using spin_wait_func_ptr_t = void (*)(); 392 spin_wait_func_ptr_t func = CAST_TO_FN_PTR(spin_wait_func_ptr_t, StubRoutines::aarch64::spin_wait()); 393 assert(func != nullptr, "StubRoutines::aarch64::spin_wait must not be null."); 394 (*func)(); 395 // If StubRoutines::aarch64::spin_wait consists of only a RET, 396 // SpinPause can be considered as implemented. There will be a sequence 397 // of instructions for: 398 // - call of SpinPause 399 // - load of StubRoutines::aarch64::spin_wait stub pointer 400 // - indirect call of the stub 401 // - return from the stub 402 // - return from SpinPause 403 // So '1' always is returned. 404 return 1; 405 } 406 407 void _Copy_conjoint_jshorts_atomic(const jshort* from, jshort* to, size_t count) { 408 if (from > to) { 409 const jshort *end = from + count; 410 while (from < end) 411 *(to++) = *(from++); 412 } 413 else if (from < to) { 414 const jshort *end = from; 415 from += count - 1; 416 to += count - 1; 417 while (from >= end) 418 *(to--) = *(from--); 419 } 420 } 421 void _Copy_conjoint_jints_atomic(const jint* from, jint* to, size_t count) { 422 if (from > to) { 423 const jint *end = from + count; 424 while (from < end) 425 *(to++) = *(from++); 426 } 427 else if (from < to) { 428 const jint *end = from; 429 from += count - 1; 430 to += count - 1; 431 while (from >= end) 432 *(to--) = *(from--); 433 } 434 } 435 436 void _Copy_conjoint_jlongs_atomic(const jlong* from, jlong* to, size_t count) { 437 if (from > to) { 438 const jlong *end = from + count; 439 while (from < end) 440 atomic_copy64(from++, to++); 441 } 442 else if (from < to) { 443 const jlong *end = from; 444 from += count - 1; 445 to += count - 1; 446 while (from >= end) 447 atomic_copy64(from--, to--); 448 } 449 } 450 451 void _Copy_arrayof_conjoint_bytes(const HeapWord* from, 452 HeapWord* to, 453 size_t count) { 454 memmove(to, from, count); 455 } 456 void _Copy_arrayof_conjoint_jshorts(const HeapWord* from, 457 HeapWord* to, 458 size_t count) { 459 memmove(to, from, count * 2); 460 } 461 void _Copy_arrayof_conjoint_jints(const HeapWord* from, 462 HeapWord* to, 463 size_t count) { 464 memmove(to, from, count * 4); 465 } 466 void _Copy_arrayof_conjoint_jlongs(const HeapWord* from, 467 HeapWord* to, 468 size_t count) { 469 memmove(to, from, count * 8); 470 } 471 };