Newer
Older
minerva / Ports / OpenJDK / patches / 0004-hotspot-Add-workarounds-for-BSD-differences-from-ser.patch
@minerva minerva on 13 Jul 13 KB Initial commit
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Andrew Kaster <akaster@serenityos.org>
Date: Sun, 12 Jun 2022 15:51:39 -0600
Subject: [PATCH] hotspot: Add workarounds for BSD differences from minerva

For the most part, we can pretend to be *BSD.

However, for some methods, we need to convince hotspot that we're macOS,
and others need minerva-specific ifdefs due to the lack of sysctl in
minerva.

Co-Authored-By: Timur Sultanov <sultanovts@yandex.ru>
---
 src/hotspot/os/bsd/attachListener_bsd.cpp     | 12 +++
 src/hotspot/os/bsd/osThread_bsd.cpp           |  6 +-
 src/hotspot/os/bsd/os_bsd.cpp                 | 77 ++++++++++++++++++-
 src/hotspot/os/bsd/os_perf_bsd.cpp            |  4 +
 .../os_cpu/bsd_zero/bytes_bsd_zero.hpp        |  2 +
 src/hotspot/os_cpu/bsd_zero/os_bsd_zero.cpp   | 18 ++++-
 src/hotspot/share/classfile/classLoader.cpp   |  2 +-
 7 files changed, 114 insertions(+), 7 deletions(-)

diff --git a/src/hotspot/os/bsd/attachListener_bsd.cpp b/src/hotspot/os/bsd/attachListener_bsd.cpp
index 9daad43dc7ad567dd87c9ce44b1363d18c4f5931..092b4d94ab99eb016fe8583ae9defca4922f807f 100644
--- a/src/hotspot/os/bsd/attachListener_bsd.cpp
+++ b/src/hotspot/os/bsd/attachListener_bsd.cpp
@@ -358,11 +358,23 @@ BsdAttachOperation* BsdAttachListener::dequeue() {
     // get the credentials of the peer and check the effective uid/guid
     uid_t puid;
     gid_t pgid;
+#if defined(MINERVA)
+    struct ucred creds = {};
+    socklen_t creds_size = sizeof(creds);
+    if (::getsockopt(s, SOL_SOCKET, SO_PEERCRED, &creds, &creds_size) != 0) {
+      log_debug(attach)("Failed to get peer id");
+      ::close(s);
+      continue;
+    }
+    puid = creds.uid;
+    pgid = creds.gid;
+#else
     if (::getpeereid(s, &puid, &pgid) != 0) {
       log_debug(attach)("Failed to get peer id");
       ::close(s);
       continue;
     }
+#endif
 
     if (!os::Posix::matches_effective_uid_and_gid_or_root(puid, pgid)) {
       log_debug(attach)("euid/egid check failed (%d/%d vs %d/%d)", puid, pgid,
diff --git a/src/hotspot/os/bsd/osThread_bsd.cpp b/src/hotspot/os/bsd/osThread_bsd.cpp
index 9eba7288fbe36fbe2149fb54c5709b5fd3f098ba..d7164e5d5f2151e71b535ccf998a5c9b260ad160 100644
--- a/src/hotspot/os/bsd/osThread_bsd.cpp
+++ b/src/hotspot/os/bsd/osThread_bsd.cpp
@@ -31,13 +31,17 @@
 
 void OSThread::pd_initialize() {
   assert(this != NULL, "check");
-#ifdef __APPLE__
+#if defined(__APPLE__) || defined(MINERVA)
   _thread_id        = 0;
 #else
   _thread_id        = NULL;
 #endif
   _unique_thread_id = 0;
+#if defined(MINERVA)
+  _pthread_id       = 0;
+#else
   _pthread_id       = NULL;
+#endif
   _siginfo          = NULL;
   _ucontext         = NULL;
   _expanding_stack  = 0;
diff --git a/src/hotspot/os/bsd/os_bsd.cpp b/src/hotspot/os/bsd/os_bsd.cpp
index 94649ae546d9b03217b6086ae0775a88e2a850a9..50225096a826511edacd983a5c6bf670deb8efc5 100644
--- a/src/hotspot/os/bsd/os_bsd.cpp
+++ b/src/hotspot/os/bsd/os_bsd.cpp
@@ -87,8 +87,10 @@
 # include <sys/resource.h>
 # include <sys/socket.h>
 # include <sys/stat.h>
+#ifndef MINERVA
 # include <sys/syscall.h>
 # include <sys/sysctl.h>
+#endif
 # include <sys/time.h>
 # include <sys/times.h>
 # include <sys/types.h>
@@ -99,6 +101,12 @@
   #include <elf.h>
 #endif
 
+#if defined(MINERVA)
+#include "utilities/decoder_elf.hpp"
+#include "utilities/elfFile.hpp"
+#include <cxxabi.h>
+#endif
+
 #ifdef __APPLE__
   #include <mach-o/dyld.h>
 #endif
@@ -162,6 +170,9 @@ julong os::Bsd::available_memory() {
 // for more info see :
 // https://man.openbsd.org/sysctl.2
 void os::Bsd::print_uptime_info(outputStream* st) {
+#ifdef MINERVA
+  st->print("OS uptime: unknown"); // FIXME: Grab uptime
+#else
   struct timeval boottime;
   size_t len = sizeof(boottime);
   int mib[2];
@@ -173,6 +184,7 @@ void os::Bsd::print_uptime_info(outputStream* st) {
     time_t currsec = time(NULL);
     os::print_dhm(st, "OS uptime:", (long) difftime(currsec, bootsec));
   }
+#endif
 }
 
 julong os::physical_memory() {
@@ -221,6 +233,10 @@ static char cpu_arch[] = "ppc";
 
 
 void os::Bsd::initialize_system_info() {
+#if defined (MINERVA)
+  set_processor_count(1); // FIXME
+  _physical_memory = 256 * 1024 * 1024; // FIXME
+#else
   int mib[2];
   size_t len;
   int cpu_val;
@@ -275,6 +291,7 @@ void os::Bsd::initialize_system_info() {
     _physical_memory = MIN2(_physical_memory, (julong)limits.rlim_cur);
   }
 #endif
+#endif // MINERVA
 }
 
 #ifdef __APPLE__
@@ -363,12 +380,18 @@ void os::init_system_properties_values() {
     if (pslash != NULL) {
       pslash = strrchr(buf, '/');
       if (pslash != NULL) {
+#ifdef MINERVA
+      // no <arch> dir on minerva
+      *pslash = '\0';        // Get rid of /lib.
+      }
+#else
         *pslash = '\0';          // Get rid of /<arch>.
         pslash = strrchr(buf, '/');
         if (pslash != NULL) {
           *pslash = '\0';        // Get rid of /lib.
         }
       }
+#endif
     }
     Arguments::set_java_home(buf);
     if (!set_boot_path('/', ':')) {
@@ -883,6 +906,10 @@ pid_t os::Bsd::gettid() {
     #else
       #ifdef __NetBSD__
   retval = (pid_t) syscall(SYS__lwp_self);
+      #else
+        #ifdef MINERVA
+         retval = ::gettid();
+        #endif
       #endif
     #endif
   #endif
@@ -891,6 +918,7 @@ pid_t os::Bsd::gettid() {
   if (retval == -1) {
     return getpid();
   }
+  return retval;
 }
 
 intx os::current_thread_id() {
@@ -959,6 +987,26 @@ bool os::address_is_in_vm(address addr) {
   return false;
 }
 
+#ifdef MINERVA
+// We put this here so that we don't need to add an entire file just to dup this method from the linux decoder
+bool ElfDecoder::demangle(const char* symbol, char *buf, int buflen) {
+  int   status;
+  char* result;
+  size_t size = (size_t)buflen;
+
+  // Don't pass buf to __cxa_demangle. In case of the 'buf' is too small,
+  // __cxa_demangle will call system "realloc" for additional memory, which
+  // may use different malloc/realloc mechanism that allocates 'buf'.
+  if ((result = abi::__cxa_demangle(symbol, NULL, NULL, &status)) != NULL) {
+    jio_snprintf(buf, buflen, "%s", result);
+      // call c library's free
+      ::free(result);
+      return true;
+  }
+  return false;
+}
+#endif // MINERVA
+
 bool os::dll_address_to_function_name(address addr, char *buf,
                                       int buflen, int *offset,
                                       bool demangle) {
@@ -1041,7 +1089,7 @@ bool os::dll_address_to_library_name(address addr, char* buf,
 // in case of error it checks if .dll/.so was built for the
 // same architecture as Hotspot is running on
 
-#ifdef __APPLE__
+#if defined(__APPLE__) || defined(MINERVA)
 void * os::dll_load(const char *filename, char *ebuf, int ebuflen) {
 #ifdef STATIC_BUILD
   return os::get_default_process_handle();
@@ -1254,7 +1302,7 @@ void * os::dll_load(const char *filename, char *ebuf, int ebuflen) {
   return NULL;
 #endif // STATIC_BUILD
 }
-#endif // !__APPLE__
+#endif // !__APPLE__ || !MINERVA
 
 int _print_dll_info_cb(const char * name, address base_address, address top_address, void * param) {
   outputStream * out = (outputStream *) param;
@@ -1317,6 +1365,7 @@ int os::get_loaded_modules_info(os::LoadedModulesCallbackFunc callback, void *pa
 }
 
 void os::get_summary_os_info(char* buf, size_t buflen) {
+#ifndef MINERVA
   // These buffers are small because we want this to be brief
   // and not use a lot of stack while generating the hs_err file.
   char os[100];
@@ -1354,6 +1403,10 @@ void os::get_summary_os_info(char* buf, size_t buflen) {
       snprintf(buf, buflen, "%s %s, macOS %s (%s)", os, release, osproductversion, build);
     }
   } else
+#endif
+#else
+  const char os[] = "Minerva";
+  const char release[] = "1.0-dev";
 #endif
   snprintf(buf, buflen, "%s %s", os, release);
 }
@@ -1381,6 +1434,7 @@ void os::pd_print_cpu_info(outputStream* st, char* buf, size_t buflen) {
 }
 
 void os::get_summary_cpu_info(char* buf, size_t buflen) {
+#ifndef MINERVA
   unsigned int mhz;
   size_t size = sizeof(mhz);
   int mib[] = { CTL_HW, HW_CPU_FREQ };
@@ -1415,9 +1469,13 @@ void os::get_summary_cpu_info(char* buf, size_t buflen) {
 #else
   snprintf(buf, buflen, "\"%s\" %s %d MHz", model, machine, mhz);
 #endif
+#else
+  snprintf(buf, buflen, "%s", "FIXME: Implement CPU Info");
+#endif
 }
 
 void os::print_memory_info(outputStream* st) {
+#ifndef MINERVA
   xsw_usage swap_usage;
   size_t size = sizeof(swap_usage);
 
@@ -1439,6 +1497,9 @@ void os::print_memory_info(outputStream* st) {
   }
 
   st->cr();
+#else
+  st->print("Memory: FIXME unknown");
+#endif
 }
 
 static char saved_jvm_path[MAXPATHLEN] = {0};
@@ -1600,6 +1661,10 @@ bool os::pd_commit_memory(char* addr, size_t size, bool exec) {
     }
   }
 #else
+  #if defined(MINERVA)
+  // FIXME: Mount location of java install with MS_WXALLOWED and MS_AXALLOWED
+  prot &= ~PROT_EXEC;
+  #endif
   uintptr_t res = (uintptr_t) ::mmap(addr, size, prot,
                                      MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS, -1, 0);
   if (res != (uintptr_t) MAP_FAILED) {
@@ -2003,6 +2068,10 @@ OSReturn os::get_native_priority(const Thread* const thread, int *priority_ptr)
 extern void report_error(char* file_name, int line_no, char* title,
                          char* format, ...);
 
+#if defined(MINERVA) && !defined(CLK_TCK)
+#define CLK_TCK 100
+#endif
+
 // this is called _before_ the most of global arguments have been parsed
 void os::init(void) {
   char dummy;   // used to get a guess on initial stack address
@@ -2503,7 +2572,11 @@ bool os::is_thread_cpu_time_supported() {
 // Bsd doesn't yet have a (official) notion of processor sets,
 // so just return the system wide load average.
 int os::loadavg(double loadavg[], int nelem) {
+#ifdef MINERVA
+  return -1;
+#else
   return ::getloadavg(loadavg, nelem);
+#endif
 }
 
 void os::pause() {
diff --git a/src/hotspot/os/bsd/os_perf_bsd.cpp b/src/hotspot/os/bsd/os_perf_bsd.cpp
index e69bfc79558c3fb5cebf3a8451b98f1fd0ecad80..4e67e2e4b7add0a56cf356156c6f40987db773e3 100644
--- a/src/hotspot/os/bsd/os_perf_bsd.cpp
+++ b/src/hotspot/os/bsd/os_perf_bsd.cpp
@@ -425,6 +425,9 @@ NetworkPerformanceInterface::NetworkPerformance::~NetworkPerformance() {
 }
 
 int NetworkPerformanceInterface::NetworkPerformance::network_utilization(NetworkInterface** network_interfaces) const {
+#ifdef MINERVA
+  return OS_ERR; // FIXME: Get stats from Network interface daemon
+#else
   size_t len;
   int mib[] = {CTL_NET, PF_ROUTE, /* protocol number */ 0, /* address family */ 0, NET_RT_IFLIST2, /* NET_RT_FLAGS mask*/ 0};
   if (sysctl(mib, sizeof(mib) / sizeof(mib[0]), NULL, &len, NULL, 0) != 0) {
@@ -464,6 +467,7 @@ int NetworkPerformanceInterface::NetworkPerformance::network_utilization(Network
   *network_interfaces = ret;
 
   return OS_OK;
+#endif
 }
 
 NetworkPerformanceInterface::NetworkPerformanceInterface() {
diff --git a/src/hotspot/os_cpu/bsd_zero/bytes_bsd_zero.hpp b/src/hotspot/os_cpu/bsd_zero/bytes_bsd_zero.hpp
index 0da7ecc7892dc74b21caf5c9ac831d6ab45aae2e..bd1ee9a6756e040733b30cef6823053f793d7c75 100644
--- a/src/hotspot/os_cpu/bsd_zero/bytes_bsd_zero.hpp
+++ b/src/hotspot/os_cpu/bsd_zero/bytes_bsd_zero.hpp
@@ -30,6 +30,8 @@
 
 #ifdef __APPLE__
 #  include <libkern/OSByteOrder.h>
+#elif defined(MINERVA)
+#  include <endian.h>
 #else
 #  include <sys/endian.h>
 #endif
diff --git a/src/hotspot/os_cpu/bsd_zero/os_bsd_zero.cpp b/src/hotspot/os_cpu/bsd_zero/os_bsd_zero.cpp
index d85822bdec231eeb7d686e2a8d16f893212a5584..9f7dc05986ce999efeeb52cfea45bf98c0c0a88d 100644
--- a/src/hotspot/os_cpu/bsd_zero/os_bsd_zero.cpp
+++ b/src/hotspot/os_cpu/bsd_zero/os_bsd_zero.cpp
@@ -23,11 +23,15 @@
  *
  */
 
-#if !defined(__APPLE__) && !defined(__NetBSD__)
+#if !defined(__APPLE__) && !defined(__NetBSD__) && !defined(MINERVA)
 #include <pthread.h>
 # include <pthread_np.h> /* For pthread_attr_get_np */
 #endif
 
+#if defined(MINERVA)
+#  include <minerva.h>
+#endif
+
 // no precompiled headers
 #include "jvm.h"
 #include "asm/assembler.inline.hpp"
@@ -56,8 +60,7 @@
 #include "utilities/vmError.hpp"
 
 address os::current_stack_pointer() {
-  address dummy = (address) &dummy;
-  return dummy;
+  return (address) __builtin_frame_address(0);
 }
 
 frame os::get_sender_for_C_frame(frame* fr) {
@@ -194,6 +197,15 @@ static void current_stack_region(address *bottom, size_t *size) {
   stack_top = (address) ss.ss_sp;
   stack_bytes  = ss.ss_size;
   stack_bottom = stack_top - stack_bytes;
+#elif defined(MINERVA)
+  uintptr_t real_stack_bottom = 0;
+  int rslt = get_stack_bounds(&real_stack_bottom, &stack_bytes);
+
+  if (rslt < 0)
+    fatal("get_stack_bounds failed with error = " INT32_FORMAT, rslt);
+
+  stack_bottom = (address)real_stack_bottom;
+  stack_top = stack_bottom + stack_bytes;
 #else
   pthread_attr_t attr;
 
diff --git a/src/hotspot/share/classfile/classLoader.cpp b/src/hotspot/share/classfile/classLoader.cpp
index 0287b73e50373c5634fbfa5b0ab09059b507a576..101299b2f28ae496d9de2cc32c3b52974ac1b32b 100644
--- a/src/hotspot/share/classfile/classLoader.cpp
+++ b/src/hotspot/share/classfile/classLoader.cpp
@@ -249,7 +249,7 @@ ClassFileStream* ClassPathDirEntry::open_stream(JavaThread* current, const char*
   struct stat st;
   if (os::stat(path, &st) == 0) {
     // found file, open it
-    int file_handle = os::open(path, 0, 0);
+    int file_handle = os::open(path, O_RDONLY, 0);
     if (file_handle != -1) {
       // read contents into resource array
       u1* buffer = NEW_RESOURCE_ARRAY(u1, st.st_size);