1 /*
2 * Copyright (c) 1999, 2025, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation.
8 *
9 * This code is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
12 * version 2 for more details (a copy is included in the LICENSE file that
13 * accompanied this code).
14 *
15 * You should have received a copy of the GNU General Public License version
16 * 2 along with this work; if not, write to the Free Software Foundation,
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18 *
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20 * or visit www.oracle.com if you need additional information or have any
21 * questions.
22 *
23 */
24
25 #include "asm/macroAssembler.hpp"
26 #include "classfile/vmSymbols.hpp"
27 #include "code/vtableStubs.hpp"
28 #include "interpreter/interpreter.hpp"
29 #include "jvm.h"
30 #include "memory/allocation.inline.hpp"
31 #include "memory/resourceArea.hpp"
32 #include "nativeInst_x86.hpp"
33 #include "os_windows.hpp"
34 #include "prims/jniFastGetField.hpp"
35 #include "prims/jvm_misc.hpp"
36 #include "runtime/arguments.hpp"
37 #include "runtime/frame.inline.hpp"
38 #include "runtime/interfaceSupport.inline.hpp"
39 #include "runtime/java.hpp"
40 #include "runtime/javaCalls.hpp"
41 #include "runtime/javaThread.hpp"
42 #include "runtime/mutexLocker.hpp"
43 #include "runtime/os.inline.hpp"
44 #include "runtime/osThread.hpp"
45 #include "runtime/sharedRuntime.hpp"
46 #include "runtime/stubRoutines.hpp"
47 #include "runtime/timer.hpp"
48 #include "symbolengine.hpp"
49 #include "unwind_windows_x86.hpp"
50 #include "utilities/events.hpp"
51 #include "utilities/vmError.hpp"
52 #include "windbghelp.hpp"
53
54
55 #undef REG_SP
56 #undef REG_FP
57 #undef REG_PC
58 #define REG_SP Rsp
59 #define REG_FP Rbp
60 #define REG_PC Rip
61 #define REG_BCP R13
62
63 JNIEXPORT
64 extern LONG WINAPI topLevelExceptionFilter(_EXCEPTION_POINTERS* );
65
66 // Install a win32 structured exception handler around thread.
67 void os::os_exception_wrapper(java_call_t f, JavaValue* value, const methodHandle& method, JavaCallArguments* args, JavaThread* thread) {
68 __try {
69 f(value, method, args, thread);
70 } __except(topLevelExceptionFilter((_EXCEPTION_POINTERS*)_exception_info())) {
71 // Nothing to do.
72 }
73 }
74
75 // This is the language specific handler for exceptions
76 // originating from dynamically generated code.
77 // We call the standard structured exception handler
78 // We only expect Continued Execution since we cannot unwind
79 // from generated code.
80 LONG HandleExceptionFromCodeCache(
81 IN PEXCEPTION_RECORD ExceptionRecord,
82 IN ULONG64 EstablisherFrame,
83 IN OUT PCONTEXT ContextRecord,
84 IN OUT PDISPATCHER_CONTEXT DispatcherContext) {
85 EXCEPTION_POINTERS ep;
86 LONG result;
87
88 ep.ExceptionRecord = ExceptionRecord;
89 ep.ContextRecord = ContextRecord;
90
91 result = topLevelExceptionFilter(&ep);
92
93 // We better only get a CONTINUE_EXECUTION from our handler
94 // since we don't have unwind information registered.
95
96 guarantee( result == EXCEPTION_CONTINUE_EXECUTION,
97 "Unexpected result from topLevelExceptionFilter");
98
99 return(ExceptionContinueExecution);
100 }
101
102
103 // Structure containing the Windows Data Structures required
104 // to register our Code Cache exception handler.
105 // We put these in the CodeCache since the API requires
106 // all addresses in these structures are relative to the Code
107 // area registered with RtlAddFunctionTable.
108 typedef struct {
109 char ExceptionHandlerInstr[16]; // jmp HandleExceptionFromCodeCache
110 RUNTIME_FUNCTION rt;
111 UNWIND_INFO_EH_ONLY unw;
112 } DynamicCodeData, *pDynamicCodeData;
113
114 //
115 // Register our CodeCache area with the OS so it will dispatch exceptions
116 // to our topLevelExceptionFilter when we take an exception in our
117 // dynamically generated code.
118 //
119 // Arguments: low and high are the address of the full reserved
120 // codeCache area
121 //
122 bool os::win32::register_code_area(char *low, char *high) {
123 ResourceMark rm;
124
125 pDynamicCodeData pDCD;
126 PRUNTIME_FUNCTION prt;
127 PUNWIND_INFO_EH_ONLY punwind;
128
129 BufferBlob* blob = BufferBlob::create("CodeCache Exception Handler", sizeof(DynamicCodeData));
130 CodeBuffer cb(blob);
131 MacroAssembler* masm = new MacroAssembler(&cb);
132 pDCD = (pDynamicCodeData) masm->pc();
133
134 masm->jump(RuntimeAddress((address)&HandleExceptionFromCodeCache), rscratch1);
135 masm->flush();
136
137 // Create an Unwind Structure specifying no unwind info
138 // other than an Exception Handler
139 punwind = &pDCD->unw;
140 punwind->Version = 1;
141 punwind->Flags = UNW_FLAG_EHANDLER;
142 punwind->SizeOfProlog = 0;
143 punwind->CountOfCodes = 0;
144 punwind->FrameRegister = 0;
145 punwind->FrameOffset = 0;
146 punwind->ExceptionHandler = (char *)(&(pDCD->ExceptionHandlerInstr[0])) -
147 (char*)low;
148 punwind->ExceptionData[0] = 0;
149
150 // This structure describes the covered dynamic code area.
151 // Addresses are relative to the beginning on the code cache area
152 prt = &pDCD->rt;
153 prt->BeginAddress = 0;
154 prt->EndAddress = (ULONG)(high - low);
155 prt->UnwindData = ((char *)punwind - low);
156
157 guarantee(RtlAddFunctionTable(prt, 1, (ULONGLONG)low),
158 "Failed to register Dynamic Code Exception Handler with RtlAddFunctionTable");
159
160 return true;
161 }
162
163 #if defined(_M_AMD64)
164 //-----------------------------------------------------------------------------
165 bool handle_FLT_exception(struct _EXCEPTION_POINTERS* exceptionInfo) {
166 // handle exception caused by native method modifying control word
167 DWORD exception_code = exceptionInfo->ExceptionRecord->ExceptionCode;
168
169 switch (exception_code) {
170 case EXCEPTION_FLT_DENORMAL_OPERAND:
171 case EXCEPTION_FLT_DIVIDE_BY_ZERO:
172 case EXCEPTION_FLT_INEXACT_RESULT:
173 case EXCEPTION_FLT_INVALID_OPERATION:
174 case EXCEPTION_FLT_OVERFLOW:
175 case EXCEPTION_FLT_STACK_CHECK:
176 case EXCEPTION_FLT_UNDERFLOW: {
177 PCONTEXT ctx = exceptionInfo->ContextRecord;
178 // On Windows, the mxcsr control bits are non-volatile across calls
179 // See also CR 6192333
180 //
181 jint MxCsr = INITIAL_MXCSR; // set to 0x1f80` in winnt.h
182 if (EnableX86ECoreOpts) {
183 // On ECore restore with status bits enabled
184 MxCsr |= 0x3F;
185 }
186
187 // we can't use StubRoutines::x86::addr_mxcsr_std()
188 // because in Win64 mxcsr is not saved there
189 if (MxCsr != ctx->MxCsr) {
190 ctx->MxCsr = MxCsr;
191 return true;
192 }
193 }
194 }
195
196 return false;
197 }
198 #endif
199
200 #ifdef HAVE_PLATFORM_PRINT_NATIVE_STACK
201 /*
202 * Windows/x64 does not use stack frames the way expected by Java:
203 * [1] in most cases, there is no frame pointer. All locals are addressed via RSP
204 * [2] in rare cases, when alloca() is used, a frame pointer is used, but this may
205 * not be RBP.
206 * See http://msdn.microsoft.com/en-us/library/ew5tede7.aspx
207 *
208 * So it's not possible to print the native stack using the
209 * while (...) {... fr = os::get_sender_for_C_frame(&fr); }
210 * loop in vmError.cpp. We need to roll our own loop.
211 */
212 bool os::win32::platform_print_native_stack(outputStream* st, const void* context,
213 char *buf, int buf_size, address& lastpc)
214 {
215 CONTEXT ctx;
216 if (context != nullptr) {
217 memcpy(&ctx, context, sizeof(ctx));
218 } else {
219 RtlCaptureContext(&ctx);
220 }
221
222 st->print_cr("Native frames: (J=compiled Java code, j=interpreted, Vv=VM code, C=native code)");
223
224 STACKFRAME stk;
225 memset(&stk, 0, sizeof(stk));
226 stk.AddrStack.Offset = ctx.Rsp;
227 stk.AddrStack.Mode = AddrModeFlat;
228 stk.AddrFrame.Offset = ctx.Rbp;
229 stk.AddrFrame.Mode = AddrModeFlat;
230 stk.AddrPC.Offset = ctx.Rip;
231 stk.AddrPC.Mode = AddrModeFlat;
232
233 // Ensure we consider dynamically loaded dll's
234 SymbolEngine::refreshModuleList();
235
236 int count = 0;
237 address lastpc_internal = 0;
238 while (count++ < StackPrintLimit) {
239 intptr_t* sp = (intptr_t*)stk.AddrStack.Offset;
240 intptr_t* fp = (intptr_t*)stk.AddrFrame.Offset; // NOT necessarily the same as ctx.Rbp!
241 address pc = (address)stk.AddrPC.Offset;
242
243 if (pc != nullptr) {
244 if (count == 2 && lastpc_internal == pc) {
245 // Skip it -- StackWalk64() may return the same PC
246 // (but different SP) on the first try.
247 } else {
248 // Don't try to create a frame(sp, fp, pc) -- on WinX64, stk.AddrFrame
249 // may not contain what Java expects, and may cause the frame() constructor
250 // to crash. Let's just print out the symbolic address.
251 frame::print_C_frame(st, buf, buf_size, pc);
252 // print source file and line, if available
253 char buf[128];
254 int line_no;
255 if (SymbolEngine::get_source_info(pc, buf, sizeof(buf), &line_no)) {
256 st->print(" (%s:%d)", buf, line_no);
257 } else {
258 st->print(" (no source info available)");
259 }
260 st->cr();
261 }
262 lastpc_internal = pc;
263 }
264
265 PVOID p = WindowsDbgHelp::symFunctionTableAccess64(GetCurrentProcess(), stk.AddrPC.Offset);
266 if (!p) {
267 // StackWalk64() can't handle this PC. Calling StackWalk64 again may cause crash.
268 lastpc = lastpc_internal;
269 break;
270 }
271
272 BOOL result = WindowsDbgHelp::stackWalk64(
273 IMAGE_FILE_MACHINE_AMD64, // __in DWORD MachineType,
274 GetCurrentProcess(), // __in HANDLE hProcess,
275 GetCurrentThread(), // __in HANDLE hThread,
276 &stk, // __inout LP STACKFRAME64 StackFrame,
277 &ctx); // __inout PVOID ContextRecord,
278
279 if (!result) {
280 break;
281 }
282 }
283 if (count > StackPrintLimit) {
284 st->print_cr("...<more frames>...");
285 }
286 st->cr();
287
288 return true;
289 }
290 #endif // HAVE_PLATFORM_PRINT_NATIVE_STACK
291
292 address os::fetch_frame_from_context(const void* ucVoid,
293 intptr_t** ret_sp, intptr_t** ret_fp) {
294
295 address epc;
296 CONTEXT* uc = (CONTEXT*)ucVoid;
297
298 if (uc != nullptr) {
299 epc = (address)uc->REG_PC;
300 if (ret_sp) *ret_sp = (intptr_t*)uc->REG_SP;
301 if (ret_fp) *ret_fp = (intptr_t*)uc->REG_FP;
302 } else {
303 epc = nullptr;
304 if (ret_sp) *ret_sp = (intptr_t *)nullptr;
305 if (ret_fp) *ret_fp = (intptr_t *)nullptr;
306 }
307
308 return epc;
309 }
310
311 frame os::fetch_frame_from_context(const void* ucVoid) {
312 intptr_t* sp;
313 intptr_t* fp;
314 address epc = fetch_frame_from_context(ucVoid, &sp, &fp);
315 if (!is_readable_pointer(epc)) {
316 // Try to recover from calling into bad memory
317 // Assume new frame has not been set up, the same as
318 // compiled frame stack bang
319 return frame(sp + 1, fp, (address)*sp);
320 }
321 return frame(sp, fp, epc);
322 }
323
324 #ifdef ASSERT
325 static bool is_interpreter(const CONTEXT* uc) {
326 assert(uc != nullptr, "invariant");
327 address pc = reinterpret_cast<address>(uc->REG_PC);
328 assert(pc != nullptr, "invariant");
329 return Interpreter::contains(pc);
330 }
331 #endif
332
333 intptr_t* os::fetch_bcp_from_context(const void* ucVoid) {
334 assert(ucVoid != nullptr, "invariant");
335 const CONTEXT* const uc = (CONTEXT*)ucVoid;
336 assert(is_interpreter(uc), "invariant");
337 return reinterpret_cast<intptr_t*>(uc->REG_BCP);
338 }
339
340 // Returns the current stack pointer. Accurate value needed for
341 // os::verify_stack_alignment().
342 address os::current_stack_pointer() {
343 typedef address get_sp_func();
344 get_sp_func* func = CAST_TO_FN_PTR(get_sp_func*,
345 StubRoutines::x86::get_previous_sp_entry());
346 return (*func)();
347 }
348
349 bool os::win32::get_frame_at_stack_banging_point(JavaThread* thread,
350 struct _EXCEPTION_POINTERS* exceptionInfo, address pc, frame* fr) {
351 PEXCEPTION_RECORD exceptionRecord = exceptionInfo->ExceptionRecord;
352 address addr = (address) exceptionRecord->ExceptionInformation[1];
353 if (Interpreter::contains(pc)) {
354 *fr = os::fetch_frame_from_context((void*)exceptionInfo->ContextRecord);
355 if (!fr->is_first_java_frame()) {
356 // get_frame_at_stack_banging_point() is only called when we
357 // have well defined stacks so java_sender() calls do not need
358 // to assert safe_for_sender() first.
359 *fr = fr->java_sender();
360 }
361 } else {
362 // more complex code with compiled code
363 assert(!Interpreter::contains(pc), "Interpreted methods should have been handled above");
364 CodeBlob* cb = CodeCache::find_blob(pc);
365 if (cb == nullptr || !cb->is_nmethod() || cb->is_frame_complete_at(pc)) {
366 // Not sure where the pc points to, fallback to default
367 // stack overflow handling
368 return false;
369 } else {
370 // in compiled code, the stack banging is performed just after the return pc
371 // has been pushed on the stack
372 intptr_t* fp = (intptr_t*)exceptionInfo->ContextRecord->REG_FP;
373 intptr_t* sp = (intptr_t*)exceptionInfo->ContextRecord->REG_SP;
374 *fr = frame(sp + 1, fp, (address)*sp);
375 if (!fr->is_java_frame()) {
376 // See java_sender() comment above.
377 *fr = fr->java_sender();
378 }
379 }
380 }
381 assert(fr->is_java_frame(), "Safety check");
382 return true;
383 }
384
385
386 // VC++ does not save frame pointer on stack in optimized build. It
387 // can be turned off by /Oy-. If we really want to walk C frames,
388 // we can use the StackWalk() API.
389 frame os::get_sender_for_C_frame(frame* fr) {
390 ShouldNotReachHere();
391 return frame();
392 }
393
394 frame os::current_frame() {
395 return frame(); // cannot walk Windows frames this way. See os::get_native_stack
396 // and os::platform_print_native_stack
397 }
398
399 void os::print_context(outputStream *st, const void *context) {
400 if (context == nullptr) return;
401
402 const CONTEXT* uc = (const CONTEXT*)context;
403
404 st->print_cr("Registers:");
405 st->print( "RAX=" INTPTR_FORMAT, uc->Rax);
406 st->print(", RBX=" INTPTR_FORMAT, uc->Rbx);
407 st->print(", RCX=" INTPTR_FORMAT, uc->Rcx);
408 st->print(", RDX=" INTPTR_FORMAT, uc->Rdx);
409 st->cr();
410 st->print( "RSP=" INTPTR_FORMAT, uc->Rsp);
411 st->print(", RBP=" INTPTR_FORMAT, uc->Rbp);
412 st->print(", RSI=" INTPTR_FORMAT, uc->Rsi);
413 st->print(", RDI=" INTPTR_FORMAT, uc->Rdi);
414 st->cr();
415 st->print( "R8 =" INTPTR_FORMAT, uc->R8);
416 st->print(", R9 =" INTPTR_FORMAT, uc->R9);
417 st->print(", R10=" INTPTR_FORMAT, uc->R10);
418 st->print(", R11=" INTPTR_FORMAT, uc->R11);
419 st->cr();
420 st->print( "R12=" INTPTR_FORMAT, uc->R12);
421 st->print(", R13=" INTPTR_FORMAT, uc->R13);
422 st->print(", R14=" INTPTR_FORMAT, uc->R14);
423 st->print(", R15=" INTPTR_FORMAT, uc->R15);
424 st->cr();
425 st->print( "RIP=" INTPTR_FORMAT, uc->Rip);
426 st->print(", EFLAGS=" INTPTR_FORMAT, uc->EFlags);
427 // Add XMM registers + MXCSR. Note that C2 uses XMM to spill GPR values including pointers.
428 st->cr();
429 st->cr();
430 for (int i = 0; i < 16; ++i) {
431 const uint64_t *xmm = ((const uint64_t*)&(uc->Xmm0)) + 2 * i;
432 st->print_cr("XMM[%d]=" INTPTR_FORMAT " " INTPTR_FORMAT,
433 i, xmm[1], xmm[0]);
434 }
435 st->print(" MXCSR=" UINT32_FORMAT_X_0, uc->MxCsr);
436 st->cr();
437 st->cr();
438 }
439
440 void os::print_register_info(outputStream *st, const void *context, int& continuation) {
441 const int register_count = 16;
442 int n = continuation;
443 assert(n >= 0 && n <= register_count, "Invalid continuation value");
444 if (context == nullptr || n == register_count) {
445 return;
446 }
447
448 const CONTEXT* uc = (const CONTEXT*)context;
449 while (n < register_count) {
450 // Update continuation with next index before printing location
451 continuation = n + 1;
452 # define CASE_PRINT_REG(n, str, id) case n: st->print(str); print_location(st, uc->id);
453 switch (n) {
454 CASE_PRINT_REG( 0, "RAX=", Rax); break;
455 CASE_PRINT_REG( 1, "RBX=", Rbx); break;
456 CASE_PRINT_REG( 2, "RCX=", Rcx); break;
457 CASE_PRINT_REG( 3, "RDX=", Rdx); break;
458 CASE_PRINT_REG( 4, "RSP=", Rsp); break;
459 CASE_PRINT_REG( 5, "RBP=", Rbp); break;
460 CASE_PRINT_REG( 6, "RSI=", Rsi); break;
461 CASE_PRINT_REG( 7, "RDI=", Rdi); break;
462 CASE_PRINT_REG( 8, "R8 =", R8); break;
463 CASE_PRINT_REG( 9, "R9 =", R9); break;
464 CASE_PRINT_REG(10, "R10=", R10); break;
465 CASE_PRINT_REG(11, "R11=", R11); break;
466 CASE_PRINT_REG(12, "R12=", R12); break;
467 CASE_PRINT_REG(13, "R13=", R13); break;
468 CASE_PRINT_REG(14, "R14=", R14); break;
469 CASE_PRINT_REG(15, "R15=", R15); break;
470 }
471 # undef CASE_PRINT_REG
472 ++n;
473 }
474 }
475
476 extern "C" int SpinPause () {
477 return 0 ;
478 }
479
480 juint os::cpu_microcode_revision() {
481 juint result = 0;
482 BYTE data[8] = {0};
483 HKEY key;
484 DWORD status = RegOpenKey(HKEY_LOCAL_MACHINE,
485 "HARDWARE\\DESCRIPTION\\System\\CentralProcessor\\0", &key);
486 if (status == ERROR_SUCCESS) {
487 DWORD size = sizeof(data);
488 status = RegQueryValueEx(key, "Update Revision", nullptr, nullptr, data, &size);
489 if (status == ERROR_SUCCESS) {
490 if (size == 4) result = *((juint*)data);
491 if (size == 8) result = *((juint*)data + 1); // upper 32-bits
492 }
493 RegCloseKey(key);
494 }
495 return result;
496 }
497
498 void os::setup_fpu() {
499 }
500
501 #ifndef PRODUCT
502 void os::verify_stack_alignment() {
503 // The current_stack_pointer() calls generated get_previous_sp stub routine.
504 // Only enable the assert after the routine becomes available.
505 if (StubRoutines::initial_stubs_code() != nullptr) {
506 assert(((intptr_t)os::current_stack_pointer() & (StackAlignmentInBytes-1)) == 0, "incorrect stack alignment");
507 }
508 }
509 #endif
510
511 int os::extra_bang_size_in_bytes() {
512 // JDK-8050147 requires the full cache line bang for x86.
513 return VM_Version::L1_line_size();
514 }