$OpenBSD: patch-hotspot_src_os_cpu_bsd_i486_vm_os_bsd_i486_cpp,v 1.3 2007/07/13 22:52:35 kurt Exp $
--- hotspot/src/os_cpu/bsd_i486/vm/os_bsd_i486.cpp.orig	Fri Jul  6 08:51:57 2007
+++ hotspot/src/os_cpu/bsd_i486/vm/os_bsd_i486.cpp	Fri Jul  6 08:51:59 2007
@@ -47,9 +47,59 @@
 # include <sys/wait.h>
 # include <pwd.h>
 # include <poll.h>
+#ifndef __OpenBSD__
 # include <ucontext.h>
+#endif
+#ifndef _ALLBSD_SOURCE
 # include <fpu_control.h>
+#endif
 
+#ifdef _ALLBSD_SOURCE
+# include <pthread_np.h>
+#endif
+
+# ifdef __FreeBSD__
+#  define context_eip uc_mcontext.mc_eip
+#  define context_esp uc_mcontext.mc_esp
+#  define context_eax uc_mcontext.mc_eax
+#  define context_ebx uc_mcontext.mc_ebx
+#  define context_ecx uc_mcontext.mc_ecx
+#  define context_edx uc_mcontext.mc_edx
+#  define context_ebp uc_mcontext.mc_ebp
+#  define context_esi uc_mcontext.mc_esi
+#  define context_edi uc_mcontext.mc_edi
+#  define context_eflags uc_mcontext.mc_eflags
+#  define context_trapno uc_mcontext.mc_trapno
+# endif
+
+# ifdef __NetBSD__
+#  define context_eip uc_mcontext.__gregs[_REG_EIP]
+#  define context_esp uc_mcontext.__gregs[_REG_UESP]
+#  define context_eax uc_mcontext.__gregs[_REG_EAX]
+#  define context_ebx uc_mcontext.__gregs[_REG_EBX]
+#  define context_ecx uc_mcontext.__gregs[_REG_ECX]
+#  define context_edx uc_mcontext.__gregs[_REG_EDX]
+#  define context_ebp uc_mcontext.__gregs[_REG_EBP]
+#  define context_esi uc_mcontext.__gregs[_REG_ESI]
+#  define context_edi uc_mcontext.__gregs[_REG_EDI]
+#  define context_eflags uc_mcontext.__gregs[_REG_EFL]
+#  define context_trapno uc_mcontext.mc_trapno
+# endif
+
+# ifdef __OpenBSD__
+#  define context_eip sc_eip
+#  define context_esp sc_esp
+#  define context_eax sc_eax
+#  define context_ebx sc_ebx
+#  define context_ecx sc_ecx
+#  define context_edx sc_edx
+#  define context_ebp sc_ebp
+#  define context_esi sc_esi
+#  define context_edi sc_edi
+#  define context_eflags sc_eflags
+#  define context_trapno sc_trapno
+# endif
+
 address os::current_stack_pointer() {
   register void *esp __asm__ ("esp");
   return (address) esp;
@@ -68,15 +118,15 @@ void os::initialize_thread() {
 }
 
 address os::Bsd::ucontext_get_pc(ucontext_t * uc) {
-  return (address)uc->uc_mcontext.gregs[REG_EIP];
+  return (address)uc->context_eip;
 }
 
 intptr_t* os::Bsd::ucontext_get_sp(ucontext_t * uc) {
-  return (intptr_t*)uc->uc_mcontext.gregs[REG_UESP];
+  return (intptr_t*)uc->context_esp;
 }
 
 intptr_t* os::Bsd::ucontext_get_fp(ucontext_t * uc) {
-  return (intptr_t*)uc->uc_mcontext.gregs[REG_EBP];
+  return (intptr_t*)uc->context_ebp;
 }
 
 // For Forte Analyzer AsyncGetCallTrace profiling support - thread
@@ -231,12 +281,12 @@ JVM_handle_bsd_signal(int sig,
     pc = (address) os::Bsd::ucontext_get_pc(uc);
 
     if (pc == (address) Fetch32PFI) { 
-       uc->uc_mcontext.gregs[REG_EIP] = intptr_t(Fetch32Resume) ; 
+       uc->context_eip = intptr_t(Fetch32Resume) ; 
        return 1 ;  
     }
 
     // Handle ALL stack overflow variations here
-    if (sig == SIGSEGV) {
+    if (sig == SIGSEGV || sig == SIGBUS) {
       address addr = (address) info->si_addr;
 
       // check if fault address is within thread stack
@@ -258,6 +308,7 @@ JVM_handle_bsd_signal(int sig,
           // to handle_unexpected_exception way down below.
           thread->disable_stack_red_zone();
           tty->print_raw_cr("An irrecoverable stack overflow has occurred.");
+#ifndef _ALLBSD_SOURCE
         } else {
           // Accessing stack address below sp may cause SEGV if current
           // thread has MAP_GROWSDOWN stack. This should only happen when
@@ -273,6 +324,7 @@ JVM_handle_bsd_signal(int sig,
           } else {
              fatal("recursive segv. expanding stack.");
           }
+#endif
         }
       }
     }
@@ -281,7 +333,7 @@ JVM_handle_bsd_signal(int sig,
       // Java thread running in Java code => find exception handler if any
       // a fault inside compiled code, the interpreter, or a stub
 
-      if (sig == SIGSEGV && os::is_poll_address((address)info->si_addr)) {
+      if ((sig == SIGSEGV || sig == SIGBUS) && os::is_poll_address((address)info->si_addr)) {
         stub = SharedRuntime::get_poll_stub(pc);
       } else if (sig == SIGBUS /* && info->si_code == BUS_OBJERR */) {
 	// BugId 4454115: A read from a MappedByteBuffer can fault
@@ -321,7 +373,7 @@ JVM_handle_bsd_signal(int sig,
           fatal("please update this code.");
         }
       }
-      else if (sig == SIGSEGV &&
+      else if ((sig == SIGSEGV || sig==SIGBUS) &&
                !MacroAssembler::needs_explicit_null_check((int)info->si_addr)) {
           // Determination of interpreter/vtable stub/compiled code null exception
           stub = SharedRuntime::continuation_for_implicit_exception(thread, pc, SharedRuntime::IMPLICIT_NULL);
@@ -345,7 +397,7 @@ JVM_handle_bsd_signal(int sig,
     // process of write protecting the memory serialization page.
     // It write enables the page immediately after protecting it
     // so we can just return to retry the write.
-    if ((sig == SIGSEGV) &&
+    if ((sig == SIGSEGV || sig == SIGBUS) &&
         os::is_memory_serialize_page(thread, (address) info->si_addr)) {
       // Block current thread until the memory serialize page permission restored.
       os::block_on_serialize_page_trap();
@@ -365,7 +417,7 @@ JVM_handle_bsd_signal(int sig,
   // Furthermore, a false-positive should be harmless.
   if (UnguardOnExecutionViolation > 0 &&
       (sig == SIGSEGV || sig == SIGBUS) &&
-      uc->uc_mcontext.gregs[REG_TRAPNO] == trap_page_fault) {
+      uc->context_trapno == trap_page_fault) {
     int page_size = os::vm_page_size();
     address addr = (address) info->si_addr;
     address pc = os::Bsd::ucontext_get_pc(uc);
@@ -433,7 +485,7 @@ JVM_handle_bsd_signal(int sig,
     // save all thread context in case we need to restore it
     if (thread != NULL) thread->set_saved_exception_pc(pc);
 
-    uc->uc_mcontext.gregs[REG_EIP] = (greg_t)stub;
+    uc->context_eip = (int)stub;
     return true;
   }
 
@@ -463,11 +515,22 @@ JVM_handle_bsd_signal(int sig,
   ShouldNotReachHere();
 }
 
+#ifdef _ALLBSD_SOURCE
+// From solaris_i486.s ported to bsd_i486.s
+extern "C" void fixcw();
+#endif
+
 void os::Bsd::init_thread_fpu_state(void) {
+#ifdef _ALLBSD_SOURCE
+  // Set fpu to 53 bit precision. This happens too early to use a stub.
+  fixcw();
+#else
   // set fpu to 53 bit precision
   set_fpu_control_word(0x27f);
+#endif
 }
 
+#ifndef _ALLBSD_SOURCE
 int os::Bsd::get_fpu_control_word(void) {
   int fpu_control;
   _FPU_GETCW(fpu_control);
@@ -475,12 +538,17 @@ int os::Bsd::get_fpu_control_word(void) {
 }
 
 void os::Bsd::set_fpu_control_word(int fpu_control) {
-  _FPU_SETCW(fpu_control);
+  _FPmU_SETCW(fpu_control);
 }
+#endif
 
 // Check that the bsd kernel version is 2.4 or higher since earlier
 // versions do not support SSE without patches.
 bool os::supports_sse() {
+#ifdef _ALLBSD_SOURCE
+  // XXXBSD: try implementing this
+  return true;
+#else
   struct utsname uts;
   if( uname(&uts) != 0 ) return false; // uname fails?
   char *minor_string;
@@ -494,6 +562,7 @@ bool os::supports_sse() {
   }
 #endif
   return result;
+#endif
 }
 
 bool os::is_allocatable(size_t bytes) {
@@ -518,6 +587,9 @@ size_t os::Bsd::min_stack_allowed  =  (48 DEBUG_ONLY(+
 
 #define GET_GS() ({int gs; __asm__ volatile("movw %%gs, %w0":"=q"(gs)); gs&0xffff;})
 
+#ifdef _ALLBSD_SOURCE
+bool os::Bsd::supports_variable_stack_size() { return true; }
+#else
 // Test if pthread library can support variable thread stack size. BsdThreads
 // in fixed stack mode allocates 2M fixed slot for each thread. BsdThreads 
 // in floating stack mode and NPTL support variable stack size.
@@ -550,6 +622,7 @@ bool os::Bsd::supports_variable_stack_size() {
     return (GET_GS() != 0);
   }
 }
+#endif
 
 // return default stack size for thr_type
 size_t os::Bsd::default_stack_size(os::ThreadType thr_type) {
@@ -598,6 +671,36 @@ size_t os::Bsd::default_guard_size(os::ThreadType thr_
 //    pthread_attr_getstack()
 
 static void current_stack_region(address * bottom, size_t * size) {
+#ifdef __OpenBSD__
+  stack_t ss;
+  int rslt = pthread_stackseg_np(pthread_self(), &ss);
+
+  if (rslt != 0)
+    fatal1("pthread_stackseg_np failed with err = %d", rslt);
+
+  *bottom = (address)((char *)ss.ss_sp - ss.ss_size);
+  *size   = ss.ss_size;
+#elif defined(_ALLBSD_SOURCE)
+  pthread_attr_t attr;
+
+  int rslt = pthread_attr_init(&attr);
+
+  // JVM needs to know exact stack location, abort if it fails
+  if (rslt != 0)
+    fatal1("pthread_attr_init failed with err = %d", rslt);
+
+  rslt = pthread_attr_get_np(pthread_self(), &attr);
+
+  if (rslt != 0)
+    fatal1("pthread_attr_get_np failed with err = %d", rslt);
+
+  if (pthread_attr_getstackaddr(&attr, (void **)bottom) != 0 || 
+      pthread_attr_getstacksize(&attr, size) != 0) {
+      fatal("Can not locate current stack attributes!");
+  }
+
+  pthread_attr_destroy(&attr);
+#else
   if (os::Bsd::is_initial_thread()) {
      // initial thread needs special handling because pthread_getattr_np()
      // may return bogus value.
@@ -624,6 +727,7 @@ static void current_stack_region(address * bottom, siz
      pthread_attr_destroy(&attr);
 
   }
+#endif
   assert(os::current_stack_pointer() >= *bottom &&
          os::current_stack_pointer() < *bottom + *size, "just checking");
 }
@@ -651,19 +755,18 @@ void os::print_context(outputStream *st, void *context
 
   ucontext_t *uc = (ucontext_t*)context;
   st->print_cr("Registers:");
-  st->print(  "EAX=" INTPTR_FORMAT, uc->uc_mcontext.gregs[REG_EAX]);
-  st->print(", EBX=" INTPTR_FORMAT, uc->uc_mcontext.gregs[REG_EBX]);
-  st->print(", ECX=" INTPTR_FORMAT, uc->uc_mcontext.gregs[REG_ECX]);
-  st->print(", EDX=" INTPTR_FORMAT, uc->uc_mcontext.gregs[REG_EDX]);
+  st->print(  "EAX=" INTPTR_FORMAT, uc->context_eax);
+  st->print(", EBX=" INTPTR_FORMAT, uc->context_ebx);
+  st->print(", ECX=" INTPTR_FORMAT, uc->context_ecx);
+  st->print(", EDX=" INTPTR_FORMAT, uc->context_edx);
   st->cr();
-  st->print(  "ESP=" INTPTR_FORMAT, uc->uc_mcontext.gregs[REG_UESP]);
-  st->print(", EBP=" INTPTR_FORMAT, uc->uc_mcontext.gregs[REG_EBP]);
-  st->print(", ESI=" INTPTR_FORMAT, uc->uc_mcontext.gregs[REG_ESI]);
-  st->print(", EDI=" INTPTR_FORMAT, uc->uc_mcontext.gregs[REG_EDI]);
+  st->print(  "ESP=" INTPTR_FORMAT, uc->context_esp);
+  st->print(", EBP=" INTPTR_FORMAT, uc->context_ebp);
+  st->print(", ESI=" INTPTR_FORMAT, uc->context_esi);
+  st->print(", EDI=" INTPTR_FORMAT, uc->context_edi);
   st->cr();
-  st->print(  "EIP=" INTPTR_FORMAT, uc->uc_mcontext.gregs[REG_EIP]);
-  st->print(", CR2=" INTPTR_FORMAT, uc->uc_mcontext.cr2);
-  st->print(", EFLAGS=" INTPTR_FORMAT, uc->uc_mcontext.gregs[REG_EFL]);
+  st->print(  "EIP=" INTPTR_FORMAT, uc->context_eip);
+  st->print(", EFLAGS=" INTPTR_FORMAT, uc->context_eflags);
   st->cr();
   st->cr();
 
