From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: Andrew Kaster Date: Sun, 12 Jun 2022 15:51:39 -0600 Subject: [PATCH] hotspot: Add workarounds for BSD differences from serenity 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 serenity-specific ifdefs due to the lack of sysctl in serenity. Co-Authored-By: Timur Sultanov --- 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(SERENITY) + 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(SERENITY) _thread_id = 0; #else _thread_id = NULL; #endif _unique_thread_id = 0; +#if defined(SERENITY) + _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 # include # include +#ifndef SERENITY # include # include +#endif # include # include # include @@ -99,6 +101,12 @@ #include #endif +#if defined(SERENITY) +#include "utilities/decoder_elf.hpp" +#include "utilities/elfFile.hpp" +#include +#endif + #ifdef __APPLE__ #include #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 SERENITY + 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 (SERENITY) + 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 // SERENITY } #ifdef __APPLE__ @@ -363,12 +380,18 @@ void os::init_system_properties_values() { if (pslash != NULL) { pslash = strrchr(buf, '/'); if (pslash != NULL) { +#ifdef SERENITY + // no dir on serenity + *pslash = '\0'; // Get rid of /lib. + } +#else *pslash = '\0'; // Get rid of /. 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 SERENITY + 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 SERENITY +// 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 // SERENITY + 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(SERENITY) 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__ || !SERENITY 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 SERENITY // 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[] = "SerenityOS"; + 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 SERENITY 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 SERENITY 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(SERENITY) + // 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(SERENITY) && !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 SERENITY + 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 SERENITY + 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 +#elif defined(SERENITY) +# include #else # include #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(SERENITY) #include # include /* For pthread_attr_get_np */ #endif +#if defined(SERENITY) +# include +#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(SERENITY) + 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);