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