1 /*
   2  * Copyright (c) 2020, Microsoft Corporation. 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 "precompiled.hpp"
  26 #include "jvm.h"
  27 #include "asm/macroAssembler.hpp"
  28 #include "classfile/classLoader.hpp"
  29 #include "classfile/systemDictionary.hpp"
  30 #include "classfile/vmSymbols.hpp"
  31 #include "code/codeCache.hpp"
  32 #include "code/icBuffer.hpp"
  33 #include "code/vtableStubs.hpp"
  34 #include "code/nativeInst.hpp"
  35 #include "interpreter/interpreter.hpp"
  36 #include "memory/allocation.inline.hpp"
  37 #include "prims/jniFastGetField.hpp"
  38 #include "prims/jvm_misc.hpp"
  39 #include "runtime/arguments.hpp"
  40 #include "runtime/frame.inline.hpp"
  41 #include "runtime/interfaceSupport.inline.hpp"
  42 #include "runtime/java.hpp"
  43 #include "runtime/javaCalls.hpp"
  44 #include "runtime/mutexLocker.hpp"
  45 #include "runtime/osThread.hpp"
  46 #include "runtime/sharedRuntime.hpp"
  47 #include "runtime/stubRoutines.hpp"
  48 #include "runtime/thread.inline.hpp"
  49 #include "runtime/timer.hpp"
  50 #include "unwind_windows_aarch64.hpp"
  51 #include "utilities/debug.hpp"
  52 #include "utilities/events.hpp"
  53 #include "utilities/vmError.hpp"
  54 
  55 
  56 // put OS-includes here
  57 # include <sys/types.h>
  58 # include <signal.h>
  59 # include <errno.h>
  60 # include <stdlib.h>
  61 # include <stdio.h>
  62 # include <intrin.h>
  63 
  64 void os::os_exception_wrapper(java_call_t f, JavaValue* value, const methodHandle& method, JavaCallArguments* args, Thread* thread) {
  65   f(value, method, args, thread);
  66 }
  67 
  68 PRAGMA_DISABLE_MSVC_WARNING(4172)
  69 // Returns an estimate of the current stack pointer. Result must be guaranteed
  70 // to point into the calling threads stack, and be no lower than the current
  71 // stack pointer.
  72 address os::current_stack_pointer() {
  73   int dummy;
  74   address sp = (address)&dummy;
  75   return sp;
  76 }
  77 
  78 address os::fetch_frame_from_context(const void* ucVoid,
  79                     intptr_t** ret_sp, intptr_t** ret_fp) {
  80   address  epc;
  81   CONTEXT* uc = (CONTEXT*)ucVoid;
  82 
  83   if (uc != NULL) {
  84     epc = (address)uc->Pc;
  85     if (ret_sp) *ret_sp = (intptr_t*)uc->Sp;
  86     if (ret_fp) *ret_fp = (intptr_t*)uc->Fp;
  87   } else {
  88     // construct empty ExtendedPC for return value checking
  89     epc = NULL;
  90     if (ret_sp) *ret_sp = (intptr_t *)NULL;
  91     if (ret_fp) *ret_fp = (intptr_t *)NULL;
  92   }
  93   return epc;
  94 }
  95 
  96 frame os::fetch_frame_from_context(const void* ucVoid) {
  97   intptr_t* sp;
  98   intptr_t* fp;
  99   address epc = fetch_frame_from_context(ucVoid, &sp, &fp);
 100   return frame(sp, fp, epc);
 101 }
 102 
 103 bool os::win32::get_frame_at_stack_banging_point(JavaThread* thread,
 104         struct _EXCEPTION_POINTERS* exceptionInfo, address pc, frame* fr) {
 105   PEXCEPTION_RECORD exceptionRecord = exceptionInfo->ExceptionRecord;
 106   address addr = (address) exceptionRecord->ExceptionInformation[1];
 107   if (Interpreter::contains(pc)) {
 108     // interpreter performs stack banging after the fixed frame header has
 109     // been generated while the compilers perform it before. To maintain
 110     // semantic consistency between interpreted and compiled frames, the
 111     // method returns the Java sender of the current frame.
 112     *fr = os::fetch_frame_from_context((void*)exceptionInfo->ContextRecord);
 113     if (!fr->is_first_java_frame()) {
 114       assert(fr->safe_for_sender(thread), "Safety check");
 115       *fr = fr->java_sender();
 116     }
 117   } else {
 118     // more complex code with compiled code
 119     assert(!Interpreter::contains(pc), "Interpreted methods should have been handled above");
 120     CodeBlob* cb = CodeCache::find_blob(pc);
 121     if (cb == NULL || !cb->is_nmethod() || cb->is_frame_complete_at(pc)) {
 122       // Not sure where the pc points to, fallback to default
 123       // stack overflow handling
 124       return false;
 125     } else {
 126       // In compiled code, the stack banging is performed before LR
 127       // has been saved in the frame.  LR is live, and SP and FP
 128       // belong to the caller.
 129       intptr_t* fp = (intptr_t*)exceptionInfo->ContextRecord->Fp;
 130       intptr_t* sp = (intptr_t*)exceptionInfo->ContextRecord->Sp;
 131       address pc = (address)(exceptionInfo->ContextRecord->Lr
 132                          - NativeInstruction::instruction_size);
 133       *fr = frame(sp, fp, pc);
 134       if (!fr->is_java_frame()) {
 135         assert(fr->safe_for_sender(thread), "Safety check");
 136         assert(!fr->is_first_frame(), "Safety check");
 137         *fr = fr->java_sender();
 138       }
 139     }
 140   }
 141   assert(fr->is_java_frame(), "Safety check");
 142   return true;
 143 }
 144 
 145 // By default, gcc always saves frame pointer rfp on this stack. This
 146 // may get turned off by -fomit-frame-pointer.
 147 frame os::get_sender_for_C_frame(frame* fr) {
 148   return frame(fr->link(), fr->link(), fr->sender_pc());
 149 }
 150 
 151 frame os::current_frame() {
 152   typedef intptr_t*      get_fp_func           ();
 153   get_fp_func* func = CAST_TO_FN_PTR(get_fp_func*,
 154                                      StubRoutines::aarch64::get_previous_fp_entry());
 155   if (func == NULL) return frame();
 156   intptr_t* fp = (*func)();
 157   if (fp == NULL) {
 158     return frame();
 159   }
 160 
 161   frame myframe((intptr_t*)os::current_stack_pointer(),
 162                 (intptr_t*)fp,
 163                 CAST_FROM_FN_PTR(address, os::current_frame));
 164   if (os::is_first_C_frame(&myframe)) {
 165 
 166     // stack is not walkable
 167     return frame();
 168   } else {
 169     return os::get_sender_for_C_frame(&myframe);
 170   }
 171 }
 172 
 173 ////////////////////////////////////////////////////////////////////////////////
 174 // thread stack
 175 
 176 // Minimum usable stack sizes required to get to user code. Space for
 177 // HotSpot guard pages is added later.
 178 
 179 /////////////////////////////////////////////////////////////////////////////
 180 // helper functions for fatal error handler
 181 
 182 void os::print_context(outputStream *st, const void *context) {
 183   if (context == NULL) return;
 184 
 185   const CONTEXT* uc = (const CONTEXT*)context;
 186 
 187   st->print_cr("Registers:");
 188 
 189   st->print(  "X0 =" INTPTR_FORMAT, uc->X0);
 190   st->print(", X1 =" INTPTR_FORMAT, uc->X1);
 191   st->print(", X2 =" INTPTR_FORMAT, uc->X2);
 192   st->print(", X3 =" INTPTR_FORMAT, uc->X3);
 193   st->cr();
 194   st->print(  "X4 =" INTPTR_FORMAT, uc->X4);
 195   st->print(", X5 =" INTPTR_FORMAT, uc->X5);
 196   st->print(", X6 =" INTPTR_FORMAT, uc->X6);
 197   st->print(", X7 =" INTPTR_FORMAT, uc->X7);
 198   st->cr();
 199   st->print(  "X8 =" INTPTR_FORMAT, uc->X8);
 200   st->print(", X9 =" INTPTR_FORMAT, uc->X9);
 201   st->print(", X10=" INTPTR_FORMAT, uc->X10);
 202   st->print(", X11=" INTPTR_FORMAT, uc->X11);
 203   st->cr();
 204   st->print(  "X12=" INTPTR_FORMAT, uc->X12);
 205   st->print(", X13=" INTPTR_FORMAT, uc->X13);
 206   st->print(", X14=" INTPTR_FORMAT, uc->X14);
 207   st->print(", X15=" INTPTR_FORMAT, uc->X15);
 208   st->cr();
 209   st->print(  "X16=" INTPTR_FORMAT, uc->X16);
 210   st->print(", X17=" INTPTR_FORMAT, uc->X17);
 211   st->print(", X18=" INTPTR_FORMAT, uc->X18);
 212   st->print(", X19=" INTPTR_FORMAT, uc->X19);
 213   st->cr();
 214   st->print(", X20=" INTPTR_FORMAT, uc->X20);
 215   st->print(", X21=" INTPTR_FORMAT, uc->X21);
 216   st->print(", X22=" INTPTR_FORMAT, uc->X22);
 217   st->print(", X23=" INTPTR_FORMAT, uc->X23);
 218   st->cr();
 219   st->print(", X24=" INTPTR_FORMAT, uc->X24);
 220   st->print(", X25=" INTPTR_FORMAT, uc->X25);
 221   st->print(", X26=" INTPTR_FORMAT, uc->X26);
 222   st->print(", X27=" INTPTR_FORMAT, uc->X27);
 223   st->print(", X28=" INTPTR_FORMAT, uc->X28);
 224   st->cr();
 225   st->cr();
 226 
 227   intptr_t *sp = (intptr_t *)uc->Sp;
 228   st->print_cr("Top of Stack: (sp=" PTR_FORMAT ")", sp);
 229   print_hex_dump(st, (address)sp, (address)(sp + 32), sizeof(intptr_t));
 230   st->cr();
 231 
 232   // Note: it may be unsafe to inspect memory near pc. For example, pc may
 233   // point to garbage if entry point in an nmethod is corrupted. Leave
 234   // this at the end, and hope for the best.
 235   address pc = (address)uc->Pc;
 236   st->print_cr("Instructions: (pc=" PTR_FORMAT ")", pc);
 237   print_hex_dump(st, pc - 32, pc + 32, sizeof(char));
 238   st->cr();
 239 
 240 }
 241 
 242 void os::print_register_info(outputStream *st, const void *context) {
 243  if (context == NULL) return;
 244 
 245   const CONTEXT* uc = (const CONTEXT*)context;
 246 
 247   st->print_cr("Register to memory mapping:");
 248   st->cr();
 249   // this is only for the "general purpose" registers
 250   st->print(" X0="); print_location(st, uc->X0);
 251   st->print(" X1="); print_location(st, uc->X1);
 252   st->print(" X2="); print_location(st, uc->X2);
 253   st->print(" X3="); print_location(st, uc->X3);
 254   st->cr();
 255   st->print(" X4="); print_location(st, uc->X4);
 256   st->print(" X5="); print_location(st, uc->X5);
 257   st->print(" X6="); print_location(st, uc->X6);
 258   st->print(" X7="); print_location(st, uc->X7);
 259   st->cr();
 260   st->print(" X8="); print_location(st, uc->X8);
 261   st->print(" X9="); print_location(st, uc->X9);
 262   st->print("X10="); print_location(st, uc->X10);
 263   st->print("X11="); print_location(st, uc->X11);
 264   st->cr();
 265   st->print("X12="); print_location(st, uc->X12);
 266   st->print("X13="); print_location(st, uc->X13);
 267   st->print("X14="); print_location(st, uc->X14);
 268   st->print("X15="); print_location(st, uc->X15);
 269   st->cr();
 270   st->print("X16="); print_location(st, uc->X16);
 271   st->print("X17="); print_location(st, uc->X17);
 272   st->print("X18="); print_location(st, uc->X18);
 273   st->print("X19="); print_location(st, uc->X19);
 274   st->cr();
 275   st->print("X20="); print_location(st, uc->X20);
 276   st->print("X21="); print_location(st, uc->X21);
 277   st->print("X22="); print_location(st, uc->X22);
 278   st->print("X23="); print_location(st, uc->X23);
 279   st->cr();
 280   st->print("X24="); print_location(st, uc->X24);
 281   st->print("X25="); print_location(st, uc->X25);
 282   st->print("X26="); print_location(st, uc->X26);
 283   st->print("X27="); print_location(st, uc->X27);
 284   st->print("X28="); print_location(st, uc->X28);
 285 
 286   st->cr();
 287 }
 288 
 289 void os::setup_fpu() {
 290 }
 291 
 292 bool os::supports_sse() {
 293   return true;
 294 }
 295 
 296 #ifndef PRODUCT
 297 void os::verify_stack_alignment() {
 298   assert(((intptr_t)os::current_stack_pointer() & (StackAlignmentInBytes-1)) == 0, "incorrect stack alignment");
 299 }
 300 #endif
 301 
 302 int os::extra_bang_size_in_bytes() {
 303   // AArch64 does not require the additional stack bang.
 304   return 0;
 305 }
 306 
 307 extern "C" {
 308   int SpinPause() {
 309     return 0;
 310   }
 311 };