diff --git a/build/meta/omnios-build-tools.p5m b/build/meta/omnios-build-tools.p5m index 648008f936..e739dabc02 100644 --- a/build/meta/omnios-build-tools.p5m +++ b/build/meta/omnios-build-tools.p5m @@ -52,6 +52,7 @@ depend fmri=pkg://$(PKGPUBLISHER)/library/security/openssl-3 type=require depend fmri=pkg://$(PKGPUBLISHER)/library/zlib type=require depend fmri=pkg://$(PKGPUBLISHER)/network/rsync type=require depend fmri=pkg://$(PKGPUBLISHER)/runtime/java/openjdk17 type=require +depend fmri=pkg://$(PKGPUBLISHER)/runtime/java/openjdk21 type=require depend fmri=pkg://$(PKGPUBLISHER)/runtime/perl type=require depend fmri=pkg://$(PKGPUBLISHER)/runtime/python-27 type=require depend fmri=pkg://$(PKGPUBLISHER)/runtime/python-311 type=require diff --git a/build/openjdk21/build.sh b/build/openjdk21/build.sh new file mode 100755 index 0000000000..520838e706 --- /dev/null +++ b/build/openjdk21/build.sh @@ -0,0 +1,142 @@ +#!/usr/bin/bash +# +# {{{ CDDL HEADER +# +# This file and its contents are supplied under the terms of the +# Common Development and Distribution License ("CDDL"), version 1.0. +# You may only use this file in accordance with the terms of version +# 1.0 of the CDDL. +# +# A full copy of the text of the CDDL should have accompanied this +# source. A copy of the CDDL is also available via the Internet at +# http://www.illumos.org/license/CDDL. +# }}} +# +# Copyright 2024 OmniOS Community Edition (OmniOSce) Association. + +. ../../lib/build.sh + +PROG=openjdk +VER=21.0.5+11 +PKG=runtime/java/openjdk21 +SUMMARY="openjdk ${VER%%.*}" +DESC="Open-source implementation of the twenty-first edition of the " +DESC+="Java SE Platform" + +# The full jdk version string is: +# feature.interim.update.patch.extra1.extra2.extra3-pre+build-opt +# We pass 'opt' explicitly to configure (see below) and currently don't parse +# the 'extra' values out of the version string. +if [[ $VER =~ ^([0-9]+)(\.([0-9]+))?(\.([0-9]+))?(\.([0-9]+))?\+([0-9]+)$ ]] +then + V_FEATURE=${BASH_REMATCH[1]} + V_INTERIM=${BASH_REMATCH[3]} + V_UPDATE=${BASH_REMATCH[5]} + V_PATCH=${BASH_REMATCH[7]} + V_BUILD=${BASH_REMATCH[8]} +else + logerr "Could not parse openjdk version $VER" +fi + +# check ooce/fonts/liberation for current version +LIBERATIONFONTSVER=2.1.5 +SKIP_LICENCES="SILv1.1" + +set_arch 64 + +set_builddir "jdk${V_FEATURE}u-jdk-${VER//+/-}" + +BMI_EXPECTED=1 +SKIP_RTIME_CHECK=1 +NO_SONAME_EXPECTED=1 + +BUILD_DEPENDS_IPS=" + system/header/header-audio + runtime/java/openjdk21 + ooce/library/fontconfig + ooce/library/freetype2 + ooce/print/cups +" + +RUN_DEPENDS_IPS="runtime/java/jexec" + +VERHUMAN="jdk${V_FEATURE}u${V_UPDATE}${V_PATCH:+.}$V_PATCH-b$V_BUILD" +IVER="$V_FEATURE.$V_INTERIM" + +IROOT=usr/jdk/instances +IFULL=$IROOT/$PROG$IVER + +OOCEPREFIX=/opt/ooce + +XFORM_ARGS=" + -DVER=$V_FEATURE + -DIVER=$IVER + -DIROOT=$IROOT + -DIFULL=$IFULL + -DLFVER=$LIBERATIONFONTSVER +" + +# The JDK build framework does not use the -j option to make. +NO_PARALLEL_MAKE=1 + +CONFIGURE_OPTS=" + --with-version-string=$VER + --with-version-opt=omnios-$RELVER + --with-toolchain-type=gcc + --with-boot-jdk=/$IFULL + --enable-deprecated-ports=yes + --enable-headless-only + --disable-ccache + --with-native-debug-symbols=none + --disable-warnings-as-errors + --enable-unlimited-crypto + --disable-dtrace + --with-cacerts-file=/etc/ssl/java/cacerts + --x-includes=$OOCEPREFIX/include + --with-cups-include=$OOCEPREFIX/include + --with-freetype=bundled + --with-fontconfig-include=$OOCEPREFIX/include + DATE=$GNUBIN/date +" +CONFIGURE_OPTS[amd64]+=" + --x-libraries=$OOCEPREFIX/lib/amd64 +" +CONFIGURE_OPTS[amd64_WS]=" + --with-extra-cflags=\"$CFLAGS ${CFLAGS[amd64]}\" + --with-extra-cxxflags=\"$CXXFLAGS ${CXXFLAGS[amd64]}\" +" + +MAKE_ARGS="all" + +make_install() { + logmsg "Installing openjdk to $DESTDIR" + + logcmd mkdir -p $DESTDIR/$IFULL || logerr "--- mkdir failed" + logcmd rsync -a $TMPDIR/$BUILDDIR/images/jdk/ $DESTDIR/$IFULL/ \ + || logerr "--- rsync failed" + + # Install liberation fonts to cover the 'core fonts' set + # See also patches/fontpath.patch + DDIR=$DESTDIR/$IFULL/lib/fonts + logcmd mkdir -p $DDIR || logerr "mkdir fonts" + logcmd cp $TMPDIR/$LFDIR/Liberation*.ttf $DDIR \ + || logerr "failed to copy fonts" +} + +init +download_source $PROG "jdk-$VER" +patch_source + +# Also download the liberation fonts archive. Fonts from here will be +# provided to satisfy the core fonts. +LFDIR=liberation-fonts-ttf-$LIBERATIONFONTSVER +BUILDDIR=$LFDIR download_source liberation-fonts $LFDIR + +prep_build autoconf-like -oot +chmod +x $CONFIGURE_CMD +build -noctf +VER=${VER%%+*} DASHREV=$V_BUILD make_package +clean_up + +# Vim hints +# vim:ts=4:sw=4:et:fdm=marker diff --git a/build/openjdk21/local.mog b/build/openjdk21/local.mog new file mode 100644 index 0000000000..e5d2f6adea --- /dev/null +++ b/build/openjdk21/local.mog @@ -0,0 +1,53 @@ +# +# This file and its contents are supplied under the terms of the +# Common Development and Distribution License ("CDDL"), version 1.0. +# You may only use this file in accordance with the terms of version +# 1.0 of the CDDL. +# +# A full copy of the text of the CDDL should have accompanied this +# source. A copy of the CDDL is also available via the Internet at +# http://www.illumos.org/license/CDDL. + +# Copyright 2024 OmniOS Community Edition (OmniOSce) Association. + + drop> + drop> + + set preserve renamenew> + set overlay allow> + + drop> +link path=$(IFULL)/jre/lib/security/cacerts target=/etc/ssl/java/cacerts +link path=$(IFULL)/lib/security/cacerts target=/etc/ssl/java/cacerts + + set pkg.depend.bypass-generate libjvm\.so> + add pkg.depend.bypass-generate libjava\.so> +# stop pulling in X11 stuff from omnios-extra + add pkg.depend.bypass-generate .*/lib[xX].*> + +# Mediated binaries + emit \ + link path=usr/bin/%<1> target=../java/bin/%<1> \ + mediator=openjdk mediator-version=$(VER)> + +# Mediated man pages + emit \ + link path=usr/share/man/man1/%<1> target=../../../java/man/man1/%<1> \ + mediator=openjdk mediator-version=$(VER)> + +# Add mediated link for /usr/java +link path=usr/java target=jdk/openjdk$(IVER) \ + mediator=openjdk mediator-version=$(VER) + +link path=usr/jdk/openjdk$(IVER) target=instances/openjdk$(IVER) + +license $(IFULL)/legal/java.base/LICENSE \ + license="GPLv2/with Classpath Exception" + +license ../liberation-fonts-ttf-$(LFVER)/LICENSE license=SILv1.1 + + set preserve renamenew> + diff --git a/build/openjdk21/patches/.tribblix-flags-ldflags2.patch.swp b/build/openjdk21/patches/.tribblix-flags-ldflags2.patch.swp new file mode 100644 index 0000000000..7c9d10b840 Binary files /dev/null and b/build/openjdk21/patches/.tribblix-flags-ldflags2.patch.swp differ diff --git a/build/openjdk21/patches/README.txt b/build/openjdk21/patches/README.txt new file mode 100644 index 0000000000..7882411606 --- /dev/null +++ b/build/openjdk21/patches/README.txt @@ -0,0 +1,274 @@ +This is originally derived from the pkgsrc-joyent set for openjdk11, +considerably modified. Cut from the jdk15 patches as of jdk15+32. + +See also README-zero.txt for note on a project zero variant. + +JDK 21 now we're in rampdown. + +21.0.4 + +Removed last remnants of extended_FILE_stdio, it's unused as 32-bit +only, and the code to enable it had already been removed. + +Remove local copies of os::dont_yield() os::naked_yield() + +Centralization of breakpoint() + +21.0.3 respin 2 + +Provide a working DefaultPoller implementation rather than the current +stub in order to get loom fully working. (Courtesy of Jasper Siepkes.) + +21.0.3 respin 1 + +Fixed the patch for src/java.base/unix/classes/java/lang/ProcessImpl.java +which fixes the startup hang in jshell and illuminate (and hopefully +the minecraft reports) + +Cleanup: missed the dropping of TIERED in 17+8, it's now +COMPILER1_AND_COMPILER2 + +21.0.3 + +The smartcardio patch failed to apply. It's been reworked, but I can't +see any evidence of this change in mainline so it's not a +backport. Fixed up, mostly it's indented one stop deeper. + +New undefined symbol os::pd_dll_unload; copy the implementation from +os_linux.cpp (backported from jdk23). + +os::prepare_native_symbols() has been added, provide a no-op implementation +(backported from jdk22) + +21.0.2 + +A bit of shuffling in ProcessHandleImpl_unix.c + +21.0.1 + +Now jdk21u. + +We need an implementation of os::can_trim_native_heap() and +trim_native_heap(); simply add a stub in os_solaris.inline.hpp to +return false like pretty much every other platform except linux does. + +21+34, 21+35 + +No changes. + +21+33 + +No changes in regular port. + +Fix zero port; see Atomic and print_register_info change in jdk 21+23 + +21+27, 21+28, 21+29, 21+30, 21+31, 21+32 + +No changes. + +21+26 + +Forked to the jdk21 stabilisation repo. + +Some patch noise. + +Add null implementation of jfr_report_memory_info() + +It appears that pipewire has been imported; see illumos-port-27.patch +for a minor tweak to make it compile + +21+25 + +Bit of patch noise + +21+24 + +It appears that jline https://github.com/jline/jline3 has been +imported +See illumos-jline.patch for implementation + +21+23 + +Extensive rework of +src/jdk.jlink/share/classes/jdk/tools/jlink/internal/Platform.java +dropped the existing patch, which no longer applies + +Atomic, fetch_and_add has been renamed to fetch_then_add + +os_solaris_x86.cpp, print_register_info has been reworked; copy the +linux_x86 changes (the function was the same as linux was before). + +Need to add static julong free_memory(); use available_memory() as I +can't see why they would be different. + +21+21 + +OperatingSystemProps has become PlatformProps, and restructured a bit. + +21+20 + +Boot jdk bumped to 20. + +21+19 + +More OperatingSystem changes +src/java.desktop/share/classes/sun/awt/FontConfiguration.java +src/java.desktop/share/classes/sun/awt/OSInfo.java +src/java.desktop/share/classes/sun/font/FontUtilities.java +src/java.desktop/unix/classes/sun/print/PrintServiceLookupProvider.java +src/java.desktop/unix/classes/sun/print/UnixPrintJob.java + +Delete the patch for src/java.desktop/share/classes/sun/font/CMap.java, +it's very specific to openwin. Ditto +src/java.desktop/share/classes/sun/font/SunFontManager.java + +Copy illumos-port-22.patch from openjdk20 to illumos-port-26.patch +here to ensure INT_MAX is defined. + +21+18 + +More OperatingSystem changes. Fixed patches to: +src/java.security.jgss/share/classes/sun/security/jgss/wrapper/SunNativeProvider.java +src/java.security.jgss/share/classes/sun/security/krb5/Config.java +src/jdk.charsets/share/classes/sun/nio/cs/ext/JISAutoDetect.java +The JISAutoDetect.java needed an extra fi as there's a whole extra method. + +Also fix +src/jdk.sctp/unix/classes/sun/nio/ch/sctp/SctpNet.java +where Solaris was actually the only consumer. +FIXME: the SctpNet fix is a non-portable hack, the code won't work on +any other platform, as I've unconditionally patched it. This ought to +use the OperatingSystem, but that would involve messing around with +src/java.base/share/classes/module-info.java and +src/java.base/share/lib/security/default.policy +which seems excessively fussy and security-dependent + +(Looking at our patches, there are many more opportunities to use the +central OperatingSystem machinery.) + +Missed the patch from 21+17 for javaThread.cpp; added illumos-port-25.patch + +21+17 + +Remove anything related to libfdlibm, as that's gone entirely + +Remove tribblix-flags-ldflags2.patch; the patched solaris behaviour is +now the default. + +src/hotspot/share/runtime/javaThread.cpp uses alloca() so needs the header + +test/jdk/java/io/File/libGetXSpace.c uses statfs() which ought to be +statvfs() for us, see illumos-port-24.patch + +21+16 + +Triggered by changes in SdpSupport.java, add SunOS support to +src/java.base/share/classes/jdk/internal/util/OperatingSystem.java +src/java.base/share/classes/jdk/internal/util/OperatingSystemProps.java.template +See illumos-port-23.patch + +The new OperatingSystem support has also been used in +src/java.base/unix/classes/java/lang/ProcessImpl.java +which needs a completely different patch + +And src/java.base/unix/classes/sun/net/PortConfig.java needs fixing. + +Cleanup: merge and remove illumos-signal-2.patch and +illumos-signal-3.patch + +Cleanup: remove TAR_CREATE_FILE_PARAM TAR_CREATE_EXTRA_PARAM + +Cleanup: remove ThreadPriorityVerbose (was Solaris-only) + +Cleanup: remove UseDetachedThreads (always true) + +21+15 + +Trivial patch noise. NULL -> nullptr changes still to do. + +21+14 + +Minor patch noise. NULL -> nullptr changes still to do. + +CodeCache::mark_all_nmethods_for_deoptimization() changed. + +21+13 + +Trivial patch noise. NULL -> nullptr changes still to do. + +Remove the deprecated platform configure option, as we'll run into +trouble if the 32-bit windows deprecation reuses it. + +21+12 + +Reinstate make/data/charsetmapping/stdcs-solaris, removal broke the build + +NULL -> nullptr changes still to do. + +21+11 + +Trivial patch noise. NULL -> nullptr changes still to do. + +os::numa_has_static_binding() has been removed. + +21+10 + +Trivial patch noise. NULL -> nullptr changes still to do. + +21+9 + +Trivial patch noise. This was also an update where NULL was being +replaced with nullptr on a large scale. The initial build did not make +those changes for the solaris port. + +21+7, 21+8 + +Trivial patch noise + +21+6 + +Remove unused os::get_page_info(). +Add a no-op for os::numa_get_group_ids_for_range(). + +21+5 + +Minor patch noise. + +The JAVA_WARNINGS_ARE_ERRORS note appears to only occur on some build +machines, which is very odd. + +21+4 + +The reorderMap in MFontConfiguration.java now needs to construct +String[] by hand rather than using FontConfiguration.split() + +Something odd has changed that's broken my build; I needed to add +JAVA_WARNINGS_ARE_ERRORS="" +to the gmake command. Otherwise -Werror turns all java warnings into +errors and fails the build. The thing is that there's nothing new here. + +21+2, 21+3 + +Trivial patch noise + +21+0 + +Starting fairly clean. + +VM_Version::page_size_count() has been removed, but it's only returning +a constant so we can easily handle that. + +Build: + +env PATH=/usr/bin:/usr/sbin:/usr/sfw/bin:/usr/gnu/bin bash ./configure \ +--enable-unlimited-crypto --with-boot-jdk=/usr/jdk/instances/jdk20 \ +--with-native-debug-symbols=none \ +--with-toolchain-type=gcc \ +--disable-dtrace \ +--disable-warnings-as-errors \ +--with-source-date=current \ +--with-jobs=3 \ +DATE=/usr/gnu/bin/date \ +STRIP=/usr/gnu/bin/strip + +env PATH=/usr/bin:/usr/sbin:/usr/sfw/bin:/usr/gnu/bin gmake all diff --git a/build/openjdk21/patches/fontpath.patch b/build/openjdk21/patches/fontpath.patch new file mode 100644 index 0000000000..3058eed600 --- /dev/null +++ b/build/openjdk21/patches/fontpath.patch @@ -0,0 +1,34 @@ +diff -wpruN '--exclude=*.orig' a~/src/java.desktop/solaris/data/fontconfig/fontconfig.properties a/src/java.desktop/solaris/data/fontconfig/fontconfig.properties +--- a~/src/java.desktop/solaris/data/fontconfig/fontconfig.properties 1970-01-01 00:00:00 ++++ a/src/java.desktop/solaris/data/fontconfig/fontconfig.properties 1970-01-01 00:00:00 +@@ -433,18 +433,18 @@ sequence.fallback=latin-1,latin-2,latin- + + # Font File Names + +-filename.-monotype-arial-medium-r-normal--*-%d-*-*-p-*-iso10646-1=/usr/share/fonts/TrueType/core/arial.ttf +-filename.-monotype-arial-medium-i-normal--*-%d-*-*-p-*-iso10646-1=/usr/share/fonts/TrueType/core/ariali.ttf +-filename.-monotype-arial-bold-r-normal--*-%d-*-*-p-*-iso10646-1=/usr/share/fonts/TrueType/core/arialbd.ttf +-filename.-monotype-arial-bold-i-normal--*-%d-*-*-p-*-iso10646-1=/usr/share/fonts/TrueType/core/arialbi.ttf +-filename.-monotype-courier_new-medium-r-normal--*-%d-*-*-p-*-iso10646-1=/usr/share/fonts/TrueType/core/cour.ttf +-filename.-monotype-courier_new-medium-i-normal--*-%d-*-*-p-*-iso10646-1=/usr/share/fonts/TrueType/core/couri.ttf +-filename.-monotype-courier_new-bold-r-normal--*-%d-*-*-p-*-iso10646-1=/usr/share/fonts/TrueType/core/courbd.ttf +-filename.-monotype-courier_new-bold-i-normal--*-%d-*-*-p-*-iso10646-1=/usr/share/fonts/TrueType/core/courbi.ttf +-filename.-monotype-times_new_roman-medium-r-normal--*-%d-*-*-p-*-iso10646-1=/usr/share/fonts/TrueType/core/times.ttf +-filename.-monotype-times_new_roman-medium-i-normal--*-%d-*-*-p-*-iso10646-1=/usr/share/fonts/TrueType/core/timesi.ttf +-filename.-monotype-times_new_roman-bold-r-normal--*-%d-*-*-p-*-iso10646-1=/usr/share/fonts/TrueType/core/timesbd.ttf +-filename.-monotype-times_new_roman-bold-i-normal--*-%d-*-*-p-*-iso10646-1=/usr/share/fonts/TrueType/core/timesbi.ttf ++filename.-monotype-arial-medium-r-normal--*-%d-*-*-p-*-iso10646-1=/usr/jdk/instances/openjdk21.0/lib/fonts/LiberationSans-Regular.ttf ++filename.-monotype-arial-medium-i-normal--*-%d-*-*-p-*-iso10646-1=/usr/jdk/instances/openjdk21.0/lib/fonts/LiberationSans-Italic.ttf ++filename.-monotype-arial-bold-r-normal--*-%d-*-*-p-*-iso10646-1=/usr/jdk/instances/openjdk21.0/lib/fonts/LiberationSans-Bold.ttf ++filename.-monotype-arial-bold-i-normal--*-%d-*-*-p-*-iso10646-1=/usr/jdk/instances/openjdk21.0/lib/fonts/LiberationSans-BoldItalic.ttf ++filename.-monotype-courier_new-medium-r-normal--*-%d-*-*-p-*-iso10646-1=/usr/jdk/instances/openjdk21.0/lib/fonts/LiberationMono-Regular.ttf ++filename.-monotype-courier_new-medium-i-normal--*-%d-*-*-p-*-iso10646-1=/usr/jdk/instances/openjdk21.0/lib/fonts/LiberationMono-Italic.ttf ++filename.-monotype-courier_new-bold-r-normal--*-%d-*-*-p-*-iso10646-1=/usr/jdk/instances/openjdk21.0/lib/fonts/LiberationMono-Bold.ttf ++filename.-monotype-courier_new-bold-i-normal--*-%d-*-*-p-*-iso10646-1=/usr/jdk/instances/openjdk21.0/lib/fonts/LiberationMono-BoldItalic.ttf ++filename.-monotype-times_new_roman-medium-r-normal--*-%d-*-*-p-*-iso10646-1=/usr/jdk/instances/openjdk21.0/lib/fonts/LiberationSerif-Regular.ttf ++filename.-monotype-times_new_roman-medium-i-normal--*-%d-*-*-p-*-iso10646-1=/usr/jdk/instances/openjdk21.0/lib/fonts/LiberationSerif-Italic.ttf ++filename.-monotype-times_new_roman-bold-r-normal--*-%d-*-*-p-*-iso10646-1=/usr/jdk/instances/openjdk21.0/lib/fonts/LiberationSerif-Bold.ttf ++filename.-monotype-times_new_roman-bold-i-normal--*-%d-*-*-p-*-iso10646-1=/usr/jdk/instances/openjdk21.0/lib/fonts/LiberationSerif-BoldItalic.ttf + + filename.-monotype-angsana_new-medium-r-normal--*-%d-*-*-p-*-iso10646-1=/usr/share/fonts/TrueType/core/angsa.ttf + filename.-monotype-angsana_new-medium-i-normal--*-%d-*-*-p-*-iso10646-1=/usr/share/fonts/TrueType/core/angsai.ttf diff --git a/build/openjdk21/patches/illumos-jline.patch b/build/openjdk21/patches/illumos-jline.patch new file mode 100644 index 0000000000..4c69f934f1 --- /dev/null +++ b/build/openjdk21/patches/illumos-jline.patch @@ -0,0 +1,828 @@ +--- /dev/null ++++ b/src/jdk.internal.le/solaris/classes/jdk/internal/org/jline/terminal/impl/jna/JDKNativePty.java 2023-06-02 10:45:50.331153527 +0100 +@@ -0,0 +1,51 @@ ++/* ++ * Copyright (c) 2023, Oracle and/or its affiliates. All rights reserved. ++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. ++ * ++ * This code is free software; you can redistribute it and/or modify it ++ * under the terms of the GNU General Public License version 2 only, as ++ * published by the Free Software Foundation. Oracle designates this ++ * particular file as subject to the "Classpath" exception as provided ++ * by Oracle in the LICENSE file that accompanied this code. ++ * ++ * This code is distributed in the hope that it will be useful, but WITHOUT ++ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or ++ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License ++ * version 2 for more details (a copy is included in the LICENSE file that ++ * accompanied this code). ++ * ++ * You should have received a copy of the GNU General Public License version ++ * 2 along with this work; if not, write to the Free Software Foundation, ++ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. ++ * ++ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA ++ * or visit www.oracle.com if you need additional information or have any ++ * questions. ++ */ ++package jdk.internal.org.jline.terminal.impl.jna; ++ ++import java.io.IOException; ++import jdk.internal.org.jline.terminal.Attributes; ++import jdk.internal.org.jline.terminal.Size; ++import jdk.internal.org.jline.terminal.impl.jna.solaris.SolarisNativePty; ++import jdk.internal.org.jline.terminal.spi.TerminalProvider; ++ ++class JDKNativePty { ++ ++ static JnaNativePty current(TerminalProvider.Stream console) throws IOException { ++ return SolarisNativePty.current(console); ++ } ++ ++ static JnaNativePty open(Attributes attr, Size size) throws IOException { ++ return SolarisNativePty.open(attr, size); ++ } ++ ++ static int isatty(int fd) { ++ return SolarisNativePty.isatty(fd); ++ } ++ ++ static String ttyname(int fd) { ++ return SolarisNativePty.ttyname(fd); ++ } ++ ++} +--- /dev/null ++++ b/src/jdk.internal.le/solaris/classes/jdk/internal/org/jline/terminal/impl/jna/solaris/CLibrary.java 2023-06-02 10:47:56.181885176 +0100 +@@ -0,0 +1,387 @@ ++/* ++ * Copyright (c) 2002-2020, the original author(s). ++ * ++ * This software is distributable under the BSD license. See the terms of the ++ * BSD license in the documentation provided with this software. ++ * ++ * https://opensource.org/licenses/BSD-3-Clause ++ */ ++package jdk.internal.org.jline.terminal.impl.jna.solaris; ++ ++import java.util.Arrays; ++import java.util.EnumMap; ++import java.util.EnumSet; ++import java.util.List; ++ ++//import com.sun.jna.LastErrorException; ++//import com.sun.jna.Structure; ++import jdk.internal.org.jline.terminal.Attributes; ++import jdk.internal.org.jline.terminal.Attributes.ControlChar; ++import jdk.internal.org.jline.terminal.Attributes.ControlFlag; ++import jdk.internal.org.jline.terminal.Attributes.InputFlag; ++import jdk.internal.org.jline.terminal.Attributes.LocalFlag; ++import jdk.internal.org.jline.terminal.Attributes.OutputFlag; ++import jdk.internal.org.jline.terminal.Size; ++import jdk.internal.org.jline.terminal.impl.jna.LastErrorException; ++ ++public interface CLibrary {//extends com.sun.jna.Library { ++ ++ void tcgetattr(int fd, termios termios) throws LastErrorException; ++ ++ void tcsetattr(int fd, int cmd, termios termios) throws LastErrorException; ++ ++ void ioctl(int fd, long cmd, winsize data) throws LastErrorException; ++ ++ int isatty(int fd); ++ ++ void ttyname_r(int fd, byte[] buf, int len) throws LastErrorException; ++ ++ void openpty(int[] master, int[] slave, byte[] name, termios t, winsize s) throws LastErrorException; ++ ++ class winsize { //extends Structure { ++ public short ws_row; ++ public short ws_col; ++ public short ws_xpixel; ++ public short ws_ypixel; ++ ++ public winsize() { ++ } ++ ++ public winsize(Size ws) { ++ ws_row = (short) ws.getRows(); ++ ws_col = (short) ws.getColumns(); ++ } ++ ++ public Size toSize() { ++ return new Size(ws_col, ws_row); ++ } ++ ++// @Override ++// protected List getFieldOrder() { ++// return Arrays.asList( // ++// "ws_row", // ++// "ws_col", // ++// "ws_xpixel", // ++// "ws_ypixel" // ++// ); ++// } ++ } ++ ++ class termios {//extends Structure { ++ ++ public int c_iflag; ++ public int c_oflag; ++ public int c_cflag; ++ public int c_lflag; ++ public byte[] c_cc = new byte[32]; ++ ++// @Override ++// protected List getFieldOrder() { ++// return Arrays.asList( // ++// "c_iflag", // ++// "c_oflag", // ++// "c_cflag", // ++// "c_lflag", // ++// "c_cc" // ++// ); ++// } ++ ++ public termios() { ++ } ++ ++ public termios(Attributes t) { ++ // Input flags ++ c_iflag = setFlag(t.getInputFlag(InputFlag.IGNBRK), IGNBRK, c_iflag); ++ c_iflag = setFlag(t.getInputFlag(InputFlag.BRKINT), BRKINT, c_iflag); ++ c_iflag = setFlag(t.getInputFlag(InputFlag.IGNPAR), IGNPAR, c_iflag); ++ c_iflag = setFlag(t.getInputFlag(InputFlag.PARMRK), PARMRK, c_iflag); ++ c_iflag = setFlag(t.getInputFlag(InputFlag.INPCK), INPCK, c_iflag); ++ c_iflag = setFlag(t.getInputFlag(InputFlag.ISTRIP), ISTRIP, c_iflag); ++ c_iflag = setFlag(t.getInputFlag(InputFlag.INLCR), INLCR, c_iflag); ++ c_iflag = setFlag(t.getInputFlag(InputFlag.IGNCR), IGNCR, c_iflag); ++ c_iflag = setFlag(t.getInputFlag(InputFlag.ICRNL), ICRNL, c_iflag); ++ c_iflag = setFlag(t.getInputFlag(InputFlag.IXON), IXON, c_iflag); ++ c_iflag = setFlag(t.getInputFlag(InputFlag.IXOFF), IXOFF, c_iflag); ++ c_iflag = setFlag(t.getInputFlag(InputFlag.IXANY), IXANY, c_iflag); ++ c_iflag = setFlag(t.getInputFlag(InputFlag.IMAXBEL), IMAXBEL, c_iflag); ++ c_iflag = setFlag(t.getInputFlag(InputFlag.IUTF8), IUTF8, c_iflag); ++ // Output flags ++ c_oflag = setFlag(t.getOutputFlag(OutputFlag.OPOST), OPOST, c_oflag); ++ c_oflag = setFlag(t.getOutputFlag(OutputFlag.ONLCR), ONLCR, c_oflag); ++ c_oflag = setFlag(t.getOutputFlag(OutputFlag.OCRNL), OCRNL, c_oflag); ++ c_oflag = setFlag(t.getOutputFlag(OutputFlag.ONOCR), ONOCR, c_oflag); ++ c_oflag = setFlag(t.getOutputFlag(OutputFlag.ONLRET), ONLRET, c_oflag); ++ c_oflag = setFlag(t.getOutputFlag(OutputFlag.OFILL), OFILL, c_oflag); ++ c_oflag = setFlag(t.getOutputFlag(OutputFlag.NLDLY), NLDLY, c_oflag); ++ c_oflag = setFlag(t.getOutputFlag(OutputFlag.TABDLY), TABDLY, c_oflag); ++ c_oflag = setFlag(t.getOutputFlag(OutputFlag.CRDLY), CRDLY, c_oflag); ++ c_oflag = setFlag(t.getOutputFlag(OutputFlag.FFDLY), FFDLY, c_oflag); ++ c_oflag = setFlag(t.getOutputFlag(OutputFlag.BSDLY), BSDLY, c_oflag); ++ c_oflag = setFlag(t.getOutputFlag(OutputFlag.VTDLY), VTDLY, c_oflag); ++ c_oflag = setFlag(t.getOutputFlag(OutputFlag.OFDEL), OFDEL, c_oflag); ++ // Control flags ++ c_cflag = setFlag(t.getControlFlag(ControlFlag.CS5), CS5, c_cflag); ++ c_cflag = setFlag(t.getControlFlag(ControlFlag.CS6), CS6, c_cflag); ++ c_cflag = setFlag(t.getControlFlag(ControlFlag.CS7), CS7, c_cflag); ++ c_cflag = setFlag(t.getControlFlag(ControlFlag.CS8), CS8, c_cflag); ++ c_cflag = setFlag(t.getControlFlag(ControlFlag.CSTOPB), CSTOPB, c_cflag); ++ c_cflag = setFlag(t.getControlFlag(ControlFlag.CREAD), CREAD, c_cflag); ++ c_cflag = setFlag(t.getControlFlag(ControlFlag.PARENB), PARENB, c_cflag); ++ c_cflag = setFlag(t.getControlFlag(ControlFlag.PARODD), PARODD, c_cflag); ++ c_cflag = setFlag(t.getControlFlag(ControlFlag.HUPCL), HUPCL, c_cflag); ++ c_cflag = setFlag(t.getControlFlag(ControlFlag.CLOCAL), CLOCAL, c_cflag); ++ // Local flags ++ c_lflag = setFlag(t.getLocalFlag(LocalFlag.ECHOKE), ECHOKE, c_lflag); ++ c_lflag = setFlag(t.getLocalFlag(LocalFlag.ECHOE), ECHOE, c_lflag); ++ c_lflag = setFlag(t.getLocalFlag(LocalFlag.ECHOK), ECHOK, c_lflag); ++ c_lflag = setFlag(t.getLocalFlag(LocalFlag.ECHO), ECHO, c_lflag); ++ c_lflag = setFlag(t.getLocalFlag(LocalFlag.ECHONL), ECHONL, c_lflag); ++ c_lflag = setFlag(t.getLocalFlag(LocalFlag.ECHOPRT), ECHOPRT, c_lflag); ++ c_lflag = setFlag(t.getLocalFlag(LocalFlag.ECHOCTL), ECHOCTL, c_lflag); ++ c_lflag = setFlag(t.getLocalFlag(LocalFlag.ISIG), ISIG, c_lflag); ++ c_lflag = setFlag(t.getLocalFlag(LocalFlag.ICANON), ICANON, c_lflag); ++ c_lflag = setFlag(t.getLocalFlag(LocalFlag.IEXTEN), IEXTEN, c_lflag); ++ c_lflag = setFlag(t.getLocalFlag(LocalFlag.EXTPROC), EXTPROC, c_lflag); ++ c_lflag = setFlag(t.getLocalFlag(LocalFlag.TOSTOP), TOSTOP, c_lflag); ++ c_lflag = setFlag(t.getLocalFlag(LocalFlag.FLUSHO), FLUSHO, c_lflag); ++ c_lflag = setFlag(t.getLocalFlag(LocalFlag.PENDIN), PENDIN, c_lflag); ++ c_lflag = setFlag(t.getLocalFlag(LocalFlag.NOFLSH), NOFLSH, c_lflag); ++ // Control chars ++ c_cc[VEOF] = (byte) t.getControlChar(ControlChar.VEOF); ++ c_cc[VEOL] = (byte) t.getControlChar(ControlChar.VEOL); ++ c_cc[VEOL2] = (byte) t.getControlChar(ControlChar.VEOL2); ++ c_cc[VERASE] = (byte) t.getControlChar(ControlChar.VERASE); ++ c_cc[VWERASE] = (byte) t.getControlChar(ControlChar.VWERASE); ++ c_cc[VKILL] = (byte) t.getControlChar(ControlChar.VKILL); ++ c_cc[VREPRINT] = (byte) t.getControlChar(ControlChar.VREPRINT); ++ c_cc[VINTR] = (byte) t.getControlChar(ControlChar.VINTR); ++ c_cc[VQUIT] = (byte) t.getControlChar(ControlChar.VQUIT); ++ c_cc[VSUSP] = (byte) t.getControlChar(ControlChar.VSUSP); ++ c_cc[VSTART] = (byte) t.getControlChar(ControlChar.VSTART); ++ c_cc[VSTOP] = (byte) t.getControlChar(ControlChar.VSTOP); ++ c_cc[VLNEXT] = (byte) t.getControlChar(ControlChar.VLNEXT); ++ c_cc[VDISCARD] = (byte) t.getControlChar(ControlChar.VDISCARD); ++ c_cc[VMIN] = (byte) t.getControlChar(ControlChar.VMIN); ++ c_cc[VTIME] = (byte) t.getControlChar(ControlChar.VTIME); ++ } ++ ++ private int setFlag(boolean flag, int value, int org) { ++ return flag ? (org | value) : org; ++ } ++ ++ public Attributes toAttributes() { ++ Attributes attr = new Attributes(); ++ // Input flags ++ EnumSet iflag = attr.getInputFlags(); ++ addFlag(c_iflag, iflag, InputFlag.IGNBRK, IGNBRK); ++ addFlag(c_iflag, iflag, InputFlag.IGNBRK, IGNBRK); ++ addFlag(c_iflag, iflag, InputFlag.BRKINT, BRKINT); ++ addFlag(c_iflag, iflag, InputFlag.IGNPAR, IGNPAR); ++ addFlag(c_iflag, iflag, InputFlag.PARMRK, PARMRK); ++ addFlag(c_iflag, iflag, InputFlag.INPCK, INPCK); ++ addFlag(c_iflag, iflag, InputFlag.ISTRIP, ISTRIP); ++ addFlag(c_iflag, iflag, InputFlag.INLCR, INLCR); ++ addFlag(c_iflag, iflag, InputFlag.IGNCR, IGNCR); ++ addFlag(c_iflag, iflag, InputFlag.ICRNL, ICRNL); ++ addFlag(c_iflag, iflag, InputFlag.IXON, IXON); ++ addFlag(c_iflag, iflag, InputFlag.IXOFF, IXOFF); ++ addFlag(c_iflag, iflag, InputFlag.IXANY, IXANY); ++ addFlag(c_iflag, iflag, InputFlag.IMAXBEL, IMAXBEL); ++ addFlag(c_iflag, iflag, InputFlag.IUTF8, IUTF8); ++ // Output flags ++ EnumSet oflag = attr.getOutputFlags(); ++ addFlag(c_oflag, oflag, OutputFlag.OPOST, OPOST); ++ addFlag(c_oflag, oflag, OutputFlag.ONLCR, ONLCR); ++ addFlag(c_oflag, oflag, OutputFlag.OCRNL, OCRNL); ++ addFlag(c_oflag, oflag, OutputFlag.ONOCR, ONOCR); ++ addFlag(c_oflag, oflag, OutputFlag.ONLRET, ONLRET); ++ addFlag(c_oflag, oflag, OutputFlag.OFILL, OFILL); ++ addFlag(c_oflag, oflag, OutputFlag.NLDLY, NLDLY); ++ addFlag(c_oflag, oflag, OutputFlag.TABDLY, TABDLY); ++ addFlag(c_oflag, oflag, OutputFlag.CRDLY, CRDLY); ++ addFlag(c_oflag, oflag, OutputFlag.FFDLY, FFDLY); ++ addFlag(c_oflag, oflag, OutputFlag.BSDLY, BSDLY); ++ addFlag(c_oflag, oflag, OutputFlag.VTDLY, VTDLY); ++ addFlag(c_oflag, oflag, OutputFlag.OFDEL, OFDEL); ++ // Control flags ++ EnumSet cflag = attr.getControlFlags(); ++ addFlag(c_cflag, cflag, ControlFlag.CS5, CS5); ++ addFlag(c_cflag, cflag, ControlFlag.CS6, CS6); ++ addFlag(c_cflag, cflag, ControlFlag.CS7, CS7); ++ addFlag(c_cflag, cflag, ControlFlag.CS8, CS8); ++ addFlag(c_cflag, cflag, ControlFlag.CSTOPB, CSTOPB); ++ addFlag(c_cflag, cflag, ControlFlag.CREAD, CREAD); ++ addFlag(c_cflag, cflag, ControlFlag.PARENB, PARENB); ++ addFlag(c_cflag, cflag, ControlFlag.PARODD, PARODD); ++ addFlag(c_cflag, cflag, ControlFlag.HUPCL, HUPCL); ++ addFlag(c_cflag, cflag, ControlFlag.CLOCAL, CLOCAL); ++ // Local flags ++ EnumSet lflag = attr.getLocalFlags(); ++ addFlag(c_lflag, lflag, LocalFlag.ECHOKE, ECHOKE); ++ addFlag(c_lflag, lflag, LocalFlag.ECHOE, ECHOE); ++ addFlag(c_lflag, lflag, LocalFlag.ECHOK, ECHOK); ++ addFlag(c_lflag, lflag, LocalFlag.ECHO, ECHO); ++ addFlag(c_lflag, lflag, LocalFlag.ECHONL, ECHONL); ++ addFlag(c_lflag, lflag, LocalFlag.ECHOPRT, ECHOPRT); ++ addFlag(c_lflag, lflag, LocalFlag.ECHOCTL, ECHOCTL); ++ addFlag(c_lflag, lflag, LocalFlag.ISIG, ISIG); ++ addFlag(c_lflag, lflag, LocalFlag.ICANON, ICANON); ++ addFlag(c_lflag, lflag, LocalFlag.IEXTEN, IEXTEN); ++ addFlag(c_lflag, lflag, LocalFlag.EXTPROC, EXTPROC); ++ addFlag(c_lflag, lflag, LocalFlag.TOSTOP, TOSTOP); ++ addFlag(c_lflag, lflag, LocalFlag.FLUSHO, FLUSHO); ++ addFlag(c_lflag, lflag, LocalFlag.PENDIN, PENDIN); ++ addFlag(c_lflag, lflag, LocalFlag.NOFLSH, NOFLSH); ++ // Control chars ++ EnumMap cc = attr.getControlChars(); ++ cc.put(ControlChar.VEOF, (int) c_cc[VEOF]); ++ cc.put(ControlChar.VEOL, (int) c_cc[VEOL]); ++ cc.put(ControlChar.VEOL2, (int) c_cc[VEOL2]); ++ cc.put(ControlChar.VERASE, (int) c_cc[VERASE]); ++ cc.put(ControlChar.VWERASE, (int) c_cc[VWERASE]); ++ cc.put(ControlChar.VKILL, (int) c_cc[VKILL]); ++ cc.put(ControlChar.VREPRINT, (int) c_cc[VREPRINT]); ++ cc.put(ControlChar.VINTR, (int) c_cc[VINTR]); ++ cc.put(ControlChar.VQUIT, (int) c_cc[VQUIT]); ++ cc.put(ControlChar.VSUSP, (int) c_cc[VSUSP]); ++ cc.put(ControlChar.VSTART, (int) c_cc[VSTART]); ++ cc.put(ControlChar.VSTOP, (int) c_cc[VSTOP]); ++ cc.put(ControlChar.VLNEXT, (int) c_cc[VLNEXT]); ++ cc.put(ControlChar.VDISCARD, (int) c_cc[VDISCARD]); ++ cc.put(ControlChar.VMIN, (int) c_cc[VMIN]); ++ cc.put(ControlChar.VTIME, (int) c_cc[VTIME]); ++ // Return ++ return attr; ++ } ++ ++ private > void addFlag(int value, EnumSet flags, T flag, int v) { ++ if ((value & v) != 0) { ++ flags.add(flag); ++ } ++ } ++ } ++ ++ // CONSTANTS ++ ++ int _TIOC = ('T' << 8); ++ int TIOCGWINSZ = (_TIOC | 104); ++ int TIOCSWINSZ = (_TIOC | 103); ++ ++ int VINTR = 0; ++ int VQUIT = 1; ++ int VERASE = 2; ++ int VKILL = 3; ++ int VEOF = 4; ++ int VTIME = 5; ++ int VMIN = 6; ++ int VSWTC = 7; ++ int VSTART = 8; ++ int VSTOP = 9; ++ int VSUSP = 10; ++ int VEOL = 11; ++ int VREPRINT = 12; ++ int VDISCARD = 13; ++ int VWERASE = 14; ++ int VLNEXT = 15; ++ int VEOL2 = 16; ++ ++ int IGNBRK = 0x0000001; ++ int BRKINT = 0x0000002; ++ int IGNPAR = 0x0000004; ++ int PARMRK = 0x0000010; ++ int INPCK = 0x0000020; ++ int ISTRIP = 0x0000040; ++ int INLCR = 0x0000100; ++ int IGNCR = 0x0000200; ++ int ICRNL = 0x0000400; ++ int IUCLC = 0x0001000; ++ int IXON = 0x0002000; ++ int IXANY = 0x0004000; ++ int IXOFF = 0x0010000; ++ int IMAXBEL = 0x0020000; ++ int IUTF8 = 0x0040000; ++ ++ int OPOST = 0x0000001; ++ int OLCUC = 0x0000002; ++ int ONLCR = 0x0000004; ++ int OCRNL = 0x0000010; ++ int ONOCR = 0x0000020; ++ int ONLRET = 0x0000040; ++ int OFILL = 0x0000100; ++ int OFDEL = 0x0000200; ++ int NLDLY = 0x0000400; ++ int NL0 = 0x0000000; ++ int NL1 = 0x0000400; ++ int CRDLY = 0x0003000; ++ int CR0 = 0x0000000; ++ int CR1 = 0x0001000; ++ int CR2 = 0x0002000; ++ int CR3 = 0x0003000; ++ int TABDLY = 0x0014000; ++ int TAB0 = 0x0000000; ++ int TAB1 = 0x0004000; ++ int TAB2 = 0x0010000; ++ int TAB3 = 0x0014000; ++ int XTABS = 0x0014000; ++ int BSDLY = 0x0020000; ++ int BS0 = 0x0000000; ++ int BS1 = 0x0020000; ++ int VTDLY = 0x0040000; ++ int VT0 = 0x0000000; ++ int VT1 = 0x0040000; ++ int FFDLY = 0x0100000; ++ int FF0 = 0x0000000; ++ int FF1 = 0x0100000; ++ ++ int CBAUD = 0x0010017; ++ int B0 = 0x0000000; ++ int B50 = 0x0000001; ++ int B75 = 0x0000002; ++ int B110 = 0x0000003; ++ int B134 = 0x0000004; ++ int B150 = 0x0000005; ++ int B200 = 0x0000006; ++ int B300 = 0x0000007; ++ int B600 = 0x0000010; ++ int B1200 = 0x0000011; ++ int B1800 = 0x0000012; ++ int B2400 = 0x0000013; ++ int B4800 = 0x0000014; ++ int B9600 = 0x0000015; ++ int B19200 = 0x0000016; ++ int B38400 = 0x0000017; ++ int EXTA = 0xB19200; ++ int EXTB = 0xB38400; ++ int CSIZE = 0x0000060; ++ int CS5 = 0x0000000; ++ int CS6 = 0x0000020; ++ int CS7 = 0x0000040; ++ int CS8 = 0x0000060; ++ int CSTOPB = 0x0000100; ++ int CREAD = 0x0000200; ++ int PARENB = 0x0000400; ++ int PARODD = 0x0001000; ++ int HUPCL = 0x0002000; ++ int CLOCAL = 0x0004000; ++ ++ int ISIG = 0x0000001; ++ int ICANON = 0x0000002; ++ int XCASE = 0x0000004; ++ int ECHO = 0x0000010; ++ int ECHOE = 0x0000020; ++ int ECHOK = 0x0000040; ++ int ECHONL = 0x0000100; ++ int NOFLSH = 0x0000200; ++ int TOSTOP = 0x0000400; ++ int ECHOCTL = 0x0001000; ++ int ECHOPRT = 0x0002000; ++ int ECHOKE = 0x0004000; ++ int FLUSHO = 0x0010000; ++ int PENDIN = 0x0040000; ++ int IEXTEN = 0x0100000; ++ int EXTPROC = 0x0200000; ++ ++ int TCSANOW = 0x0; ++ int TCSADRAIN = 0x1; ++ int TCSAFLUSH = 0x2; ++} +--- /dev/null ++++ b/src/jdk.internal.le/solaris/classes/jdk/internal/org/jline/terminal/impl/jna/solaris/CLibraryImpl.java 2023-06-02 10:52:24.003243641 +0100 +@@ -0,0 +1,66 @@ ++/* ++ * Copyright (c) 2023, Oracle and/or its affiliates. All rights reserved. ++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. ++ * ++ * This code is free software; you can redistribute it and/or modify it ++ * under the terms of the GNU General Public License version 2 only, as ++ * published by the Free Software Foundation. Oracle designates this ++ * particular file as subject to the "Classpath" exception as provided ++ * by Oracle in the LICENSE file that accompanied this code. ++ * ++ * This code is distributed in the hope that it will be useful, but WITHOUT ++ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or ++ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License ++ * version 2 for more details (a copy is included in the LICENSE file that ++ * accompanied this code). ++ * ++ * You should have received a copy of the GNU General Public License version ++ * 2 along with this work; if not, write to the Free Software Foundation, ++ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. ++ * ++ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA ++ * or visit www.oracle.com if you need additional information or have any ++ * questions. ++ */ ++package jdk.internal.org.jline.terminal.impl.jna.solaris; ++ ++import jdk.internal.org.jline.terminal.impl.jna.LastErrorException; ++ ++public final class CLibraryImpl implements CLibrary { ++ ++ static { ++ System.loadLibrary("le"); ++ initIDs(); ++ } ++ ++ private static native void initIDs(); ++ ++ @Override ++ public native void tcgetattr(int fd, termios termios) throws LastErrorException; ++ ++ @Override ++ public native void tcsetattr(int fd, int cmd, termios termios) throws LastErrorException; ++ ++ @Override ++ public void ioctl(int fd, long cmd, winsize data) throws LastErrorException { ++ if (cmd == CLibrary.TIOCGWINSZ || cmd == CLibrary.TIOCSWINSZ) { ++ ioctl0(fd, cmd, data); ++ } else { ++ throw new UnsupportedOperationException("Command: " + cmd + ", not supported."); ++ } ++ } ++ ++ private native void ioctl0(int fd, long cmd, winsize data) throws LastErrorException; ++ ++ @Override ++ public native int isatty(int fd); ++ ++ @Override ++ public native void ttyname_r(int fd, byte[] buf, int len) throws LastErrorException; ++ ++ @Override ++ public void openpty(int[] master, int[] slave, byte[] name, CLibrary.termios t, CLibrary.winsize s) throws LastErrorException { ++ throw new UnsupportedOperationException(); ++ } ++ ++} +--- /dev/null ++++ b/src/jdk.internal.le/solaris/classes/jdk/internal/org/jline/terminal/impl/jna/solaris/SolarisNativePty.java 2023-06-02 10:25:31.059689102 +0100 +@@ -0,0 +1,107 @@ ++/* ++ * Copyright (c) 2002-2020, the original author(s). ++ * ++ * This software is distributable under the BSD license. See the terms of the ++ * BSD license in the documentation provided with this software. ++ * ++ * https://opensource.org/licenses/BSD-3-Clause ++ */ ++package jdk.internal.org.jline.terminal.impl.jna.solaris; ++ ++import java.io.FileDescriptor; ++import java.io.IOException; ++ ++import jdk.internal.org.jline.terminal.Attributes; ++import jdk.internal.org.jline.terminal.Size; ++import jdk.internal.org.jline.terminal.impl.jna.JnaNativePty; ++import jdk.internal.org.jline.terminal.spi.TerminalProvider; ++ ++//import com.sun.jna.Native; ++//import com.sun.jna.Platform; ++ ++import static jdk.internal.org.jline.terminal.impl.jna.solaris.CLibrary.TCSANOW; ++import static jdk.internal.org.jline.terminal.impl.jna.solaris.CLibrary.TIOCGWINSZ; ++import static jdk.internal.org.jline.terminal.impl.jna.solaris.CLibrary.TIOCSWINSZ; ++import static jdk.internal.org.jline.terminal.impl.jna.solaris.CLibrary.termios; ++import static jdk.internal.org.jline.terminal.impl.jna.solaris.CLibrary.winsize; ++ ++public class SolarisNativePty extends JnaNativePty { ++ ++// private static final CLibrary C_LIBRARY = Native.load(Platform.C_LIBRARY_NAME, CLibrary.class); ++ private static final CLibrary C_LIBRARY = new CLibraryImpl(); ++ ++ public static SolarisNativePty current(TerminalProvider.Stream consoleStream) throws IOException { ++ switch (consoleStream) { ++ case Output: ++ return new SolarisNativePty(-1, null, 0, FileDescriptor.in, 1, FileDescriptor.out, ttyname(0)); ++ case Error: ++ return new SolarisNativePty(-1, null, 0, FileDescriptor.in, 2, FileDescriptor.err, ttyname(0)); ++ default: ++ throw new IllegalArgumentException("Unsupport stream for console: " + consoleStream); ++ } ++ } ++ ++ public static SolarisNativePty open(Attributes attr, Size size) throws IOException { ++ int[] master = new int[1]; ++ int[] slave = new int[1]; ++ byte[] buf = new byte[64]; ++ C_LIBRARY.openpty(master, slave, buf, ++ attr != null ? new termios(attr) : null, ++ size != null ? new winsize(size) : null); ++ int len = 0; ++ while (buf[len] != 0) { ++ len++; ++ } ++ String name = new String(buf, 0, len); ++ return new SolarisNativePty(master[0], newDescriptor(master[0]), slave[0], newDescriptor(slave[0]), name); ++ } ++ ++ public SolarisNativePty(int master, FileDescriptor masterFD, int slave, FileDescriptor slaveFD, String name) { ++ super(master, masterFD, slave, slaveFD, name); ++ } ++ ++ public SolarisNativePty(int master, FileDescriptor masterFD, int slave, FileDescriptor slaveFD, int slaveOut, FileDescriptor slaveOutFD, String name) { ++ super(master, masterFD, slave, slaveFD, slaveOut, slaveOutFD, name); ++ } ++ ++ @Override ++ public Attributes getAttr() throws IOException { ++ termios termios = new termios(); ++ C_LIBRARY.tcgetattr(getSlave(), termios); ++ return termios.toAttributes(); ++ } ++ ++ @Override ++ protected void doSetAttr(Attributes attr) throws IOException { ++ termios termios = new termios(attr); ++ C_LIBRARY.tcsetattr(getSlave(), TCSANOW, termios); ++ } ++ ++ @Override ++ public Size getSize() throws IOException { ++ winsize sz = new winsize(); ++ C_LIBRARY.ioctl(getSlave(), TIOCGWINSZ, sz); ++ return sz.toSize(); ++ } ++ ++ @Override ++ public void setSize(Size size) throws IOException { ++ winsize sz = new winsize(size); ++ C_LIBRARY.ioctl(getSlave(), TIOCSWINSZ, sz); ++ } ++ ++ public static int isatty(int fd) { ++ return C_LIBRARY.isatty(fd); ++ } ++ ++ public static String ttyname(int slave) { ++ byte[] buf = new byte[64]; ++ C_LIBRARY.ttyname_r(slave, buf, buf.length); ++ int len = 0; ++ while (buf[len] != 0) { ++ len++; ++ } ++ return new String(buf, 0, len); ++ } ++ ++} +--- /dev/null ++++ b/src/jdk.internal.le/solaris/native/lible/CLibrary.cpp 2023-06-02 11:05:11.905773520 +0100 +@@ -0,0 +1,191 @@ ++/* ++ * Copyright (c) 2023, Oracle and/or its affiliates. All rights reserved. ++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. ++ * ++ * This code is free software; you can redistribute it and/or modify it ++ * under the terms of the GNU General Public License version 2 only, as ++ * published by the Free Software Foundation. Oracle designates this ++ * particular file as subject to the "Classpath" exception as provided ++ * by Oracle in the LICENSE file that accompanied this code. ++ * ++ * This code is distributed in the hope that it will be useful, but WITHOUT ++ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or ++ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License ++ * version 2 for more details (a copy is included in the LICENSE file that ++ * accompanied this code). ++ * ++ * You should have received a copy of the GNU General Public License version ++ * 2 along with this work; if not, write to the Free Software Foundation, ++ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. ++ * ++ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA ++ * or visit www.oracle.com if you need additional information or have any ++ * questions. ++ */ ++ ++#include "jni.h" ++#include "jni_util.h" ++#include "jvm.h" ++#include "jdk_internal_org_jline_terminal_impl_jna_solaris_CLibraryImpl.h" ++ ++#include ++#include ++#include ++#include ++#include ++ ++static jclass lastErrorExceptionClass; ++static jmethodID lastErrorExceptionConstructor; ++ ++static jclass termios_j; ++static jfieldID c_iflag; ++static jfieldID c_oflag; ++static jfieldID c_cflag; ++static jfieldID c_lflag; ++static jfieldID c_cc; ++ ++static jclass winsize_j; ++static jfieldID ws_row; ++static jfieldID ws_col; ++static jfieldID ws_xpixel; ++static jfieldID ws_ypixel; ++ ++static void throw_errno(JNIEnv *env); ++ ++JNIEXPORT void JNICALL Java_jdk_internal_org_jline_terminal_impl_jna_solaris_CLibraryImpl_initIDs ++ (JNIEnv *env, jclass unused) { ++ jclass cls; ++ cls = env->FindClass("jdk/internal/org/jline/terminal/impl/jna/LastErrorException"); ++ CHECK_NULL(cls); ++ lastErrorExceptionClass = (jclass) env->NewGlobalRef(cls); ++ lastErrorExceptionConstructor = env->GetMethodID(lastErrorExceptionClass, "", "(J)V"); ++ CHECK_NULL(lastErrorExceptionConstructor); ++ ++ cls = env->FindClass("jdk/internal/org/jline/terminal/impl/jna/solaris/CLibrary$termios"); ++ CHECK_NULL(cls); ++ termios_j = (jclass) env->NewGlobalRef(cls); ++ c_iflag = env->GetFieldID(termios_j, "c_iflag", "I"); ++ CHECK_NULL(c_iflag); ++ c_oflag = env->GetFieldID(termios_j, "c_oflag", "I"); ++ CHECK_NULL(c_oflag); ++ c_cflag = env->GetFieldID(termios_j, "c_cflag", "I"); ++ CHECK_NULL(c_cflag); ++ c_lflag = env->GetFieldID(termios_j, "c_lflag", "I"); ++ CHECK_NULL(c_lflag); ++ c_cc = env->GetFieldID(termios_j, "c_cc", "[B"); ++ CHECK_NULL(c_cc); ++ ++ cls = env->FindClass("jdk/internal/org/jline/terminal/impl/jna/solaris/CLibrary$winsize"); ++ CHECK_NULL(cls); ++ winsize_j = (jclass) env->NewGlobalRef(cls); ++ ws_row = env->GetFieldID(winsize_j, "ws_row", "S"); ++ CHECK_NULL(ws_row); ++ ws_col = env->GetFieldID(winsize_j, "ws_col", "S"); ++ CHECK_NULL(ws_col); ++ ws_xpixel= env->GetFieldID(winsize_j, "ws_xpixel", "S"); ++ CHECK_NULL(ws_xpixel); ++ ws_ypixel= env->GetFieldID(winsize_j, "ws_ypixel", "S"); ++ CHECK_NULL(ws_ypixel); ++} ++ ++JNIEXPORT void JNICALL Java_jdk_internal_org_jline_terminal_impl_jna_solaris_CLibraryImpl_tcgetattr ++ (JNIEnv *env, jobject, jint fd, jobject result) { ++ termios data; ++ ++ if (tcgetattr(fd, &data) != 0) { ++ throw_errno(env); ++ return ; ++ } ++ ++ env->SetIntField(result, c_iflag, data.c_iflag); ++ env->SetIntField(result, c_oflag, data.c_oflag); ++ env->SetIntField(result, c_cflag, data.c_cflag); ++ env->SetIntField(result, c_lflag, data.c_lflag); ++ jbyteArray c_ccValue = (jbyteArray) env->GetObjectField(result, c_cc); ++ env->SetByteArrayRegion(c_ccValue, 0, NCCS, (signed char *) data.c_cc);//TODO: cast? ++} ++ ++/* ++ * Class: jdk_internal_org_jline_terminal_impl_jna_solaris_CLibraryImpl ++ * Method: tcsetattr ++ * Signature: (IILjdk/internal/org/jline/terminal/impl/jna/solaris/CLibrary/termios;)V ++ */ ++JNIEXPORT void JNICALL Java_jdk_internal_org_jline_terminal_impl_jna_solaris_CLibraryImpl_tcsetattr ++ (JNIEnv *env, jobject, jint fd, jint cmd, jobject input) { ++ termios data; ++ ++ data.c_iflag = env->GetIntField(input, c_iflag); ++ data.c_oflag = env->GetIntField(input, c_oflag); ++ data.c_cflag = env->GetIntField(input, c_cflag); ++ data.c_lflag = env->GetIntField(input, c_lflag); ++ jbyteArray c_ccValue = (jbyteArray) env->GetObjectField(input, c_cc); ++ env->GetByteArrayRegion(c_ccValue, 0, NCCS, (jbyte *) data.c_cc); ++ ++ if (tcsetattr(fd, cmd, &data) != 0) { ++ throw_errno(env); ++ } ++} ++ ++/* ++ * Class: jdk_internal_org_jline_terminal_impl_jna_solaris_CLibraryImpl ++ * Method: ioctl0 ++ * Signature: (IILjdk/internal/org/jline/terminal/impl/jna/solaris/CLibrary/winsize;)V ++ */ ++JNIEXPORT void JNICALL Java_jdk_internal_org_jline_terminal_impl_jna_solaris_CLibraryImpl_ioctl0 ++ (JNIEnv *env, jobject, jint fd, jlong cmd, jobject data) { ++ winsize ws; ++ ++ ws.ws_row = env->GetIntField(data, ws_row); ++ ws.ws_col = env->GetIntField(data, ws_col); ++ ws.ws_xpixel = env->GetIntField(data, ws_xpixel); ++ ws.ws_ypixel = env->GetIntField(data, ws_ypixel); ++ ++ if (ioctl(fd, cmd, &ws) != 0) { ++ throw_errno(env); ++ return ; ++ } ++ ++ env->SetIntField(data, ws_row, ws.ws_row); ++ env->SetIntField(data, ws_col, ws.ws_col); ++ env->SetIntField(data, ws_xpixel, ws.ws_xpixel); ++ env->SetIntField(data, ws_ypixel, ws.ws_ypixel); ++} ++ ++/* ++ * Class: jdk_internal_org_jline_terminal_impl_jna_solaris_CLibraryImpl ++ * Method: isatty ++ * Signature: (I)I ++ */ ++JNIEXPORT jint JNICALL Java_jdk_internal_org_jline_terminal_impl_jna_solaris_CLibraryImpl_isatty ++ (JNIEnv *, jobject, jint fd) { ++ return isatty(fd); ++} ++ ++/* ++ * Class: jdk_internal_org_jline_terminal_impl_jna_solaris_CLibraryImpl ++ * Method: ttyname_r ++ * Signature: (I[BI)V ++ */ ++JNIEXPORT void JNICALL Java_jdk_internal_org_jline_terminal_impl_jna_solaris_CLibraryImpl_ttyname_1r ++ (JNIEnv *env, jobject, jint fd, jbyteArray buf, jint len) { ++ char *data = new char[len]; ++ int error = ttyname_r(fd, data, len); ++ ++ if (error != 0) { ++ throw_errno(env); ++ return ; ++ } ++ ++ env->SetByteArrayRegion(buf, 0, len, (jbyte *) data); ++ delete[] data; ++} ++ ++/* ++ * Throws LastErrorException based on the errno: ++ */ ++static void throw_errno(JNIEnv *env) { ++ jobject exc = env->NewObject(lastErrorExceptionClass, ++ lastErrorExceptionConstructor, ++ errno); ++ env->Throw((jthrowable) exc); ++} +--- a/make/modules/jdk.internal.le/Lib.gmk Tue May 23 22:32:28 2023 ++++ b/make/modules/jdk.internal.le/Lib.gmk Fri Jun 2 11:33:06 2023 +@@ -27,7 +27,7 @@ + + ################################################################################ + +-ifeq ($(call isTargetOs, linux macosx windows), true) ++ifeq ($(call isTargetOs, linux macosx solaris windows), true) + + $(eval $(call SetupJdkLibrary, BUILD_LIBLE, \ + NAME := le, \ diff --git a/build/openjdk21/patches/illumos-pollerprovider.patch b/build/openjdk21/patches/illumos-pollerprovider.patch new file mode 100644 index 0000000000..baa15a435e --- /dev/null +++ b/build/openjdk21/patches/illumos-pollerprovider.patch @@ -0,0 +1,221 @@ +--- /dev/null Sun May 15 10:42:57 2022 ++++ a/src/java.base/solaris/classes/sun/nio/ch/DefaultPollerProvider.java Sun May 15 10:17:39 2022 +@@ -0,0 +1,44 @@ ++/* ++ * Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved. ++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. ++ * ++ * This code is free software; you can redistribute it and/or modify it ++ * under the terms of the GNU General Public License version 2 only, as ++ * published by the Free Software Foundation. Oracle designates this ++ * particular file as subject to the "Classpath" exception as provided ++ * by Oracle in the LICENSE file that accompanied this code. ++ * ++ * This code is distributed in the hope that it will be useful, but WITHOUT ++ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or ++ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License ++ * version 2 for more details (a copy is included in the LICENSE file that ++ * accompanied this code). ++ * ++ * You should have received a copy of the GNU General Public License version ++ * 2 along with this work; if not, write to the Free Software Foundation, ++ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. ++ * ++ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA ++ * or visit www.oracle.com if you need additional information or have any ++ * questions. ++ */ ++package sun.nio.ch; ++ ++import java.io.IOException; ++ ++/** ++ * Default PollerProvider for illumos/Solaris. ++ */ ++class DefaultPollerProvider extends PollerProvider { ++ DefaultPollerProvider() { } ++ ++ @Override ++ Poller readPoller() throws IOException { ++ return new SolarisEventPortPoller(true); ++ } ++ ++ @Override ++ Poller writePoller() throws IOException { ++ return new SolarisEventPortPoller(false); ++ } ++} +--- /dev/null Sun May 15 10:42:57 2022 ++++ a/src/java.base/solaris/classes/sun/nio/ch/DevPollPoller.java Sun May 15 10:17:09 2022 +@@ -0,0 +1,65 @@ ++/* ++ * Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved. ++ * Copyright 2022 Peter Tribble ++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. ++ * ++ * This code is free software; you can redistribute it and/or modify it ++ * under the terms of the GNU General Public License version 2 only, as ++ * published by the Free Software Foundation. Oracle designates this ++ * particular file as subject to the "Classpath" exception as provided ++ * by Oracle in the LICENSE file that accompanied this code. ++ * ++ * This code is distributed in the hope that it will be useful, but WITHOUT ++ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or ++ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License ++ * version 2 for more details (a copy is included in the LICENSE file that ++ * accompanied this code). ++ * ++ * You should have received a copy of the GNU General Public License version ++ * 2 along with this work; if not, write to the Free Software Foundation, ++ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. ++ * ++ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA ++ * or visit www.oracle.com if you need additional information or have any ++ * questions. ++ */ ++package sun.nio.ch; ++ ++import java.io.IOException; ++ ++/** ++ * Stub Poller implementation for illumos/Solaris. ++ * Returns UnsupportedOperationException for all calls. ++ * See SolarisEventPortPoller for an actual implementation. ++ */ ++ ++class DevPollPoller extends Poller { ++ ++ DevPollPoller(boolean read) throws IOException { ++ super(read); ++ } ++ ++ @Override ++ int fdVal() { ++ // Stub ++ throw new UnsupportedOperationException("Unimplemented on SunOS"); ++ } ++ ++ @Override ++ void implRegister(int fdVal) throws IOException { ++ // Stub ++ throw new UnsupportedOperationException("Unimplemented on SunOS"); ++ } ++ ++ @Override ++ void implDeregister(int fdVal) { ++ // Stub ++ throw new UnsupportedOperationException("Unimplemented on SunOS"); ++ } ++ ++ @Override ++ int poll(int timeout) throws IOException { ++ // Stub ++ throw new UnsupportedOperationException("Unimplemented on SunOS"); ++ } ++} +--- /dev/null ++++ a/src/java.base/solaris/classes/sun/nio/ch/SolarisEventPortPoller.java +@@ -0,0 +1,103 @@ ++/* ++* Copyright (c) 2008, 2020, Oracle and/or its affiliates. All rights reserved. ++* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. ++* ++* This code is free software; you can redistribute it and/or modify it ++* under the terms of the GNU General Public License version 2 only, as ++* published by the Free Software Foundation. Oracle designates this ++* particular file as subject to the "Classpath" exception as provided ++* by Oracle in the LICENSE file that accompanied this code. ++* ++* This code is distributed in the hope that it will be useful, but WITHOUT ++* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or ++* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License ++* version 2 for more details (a copy is included in the LICENSE file that ++* accompanied this code). ++* ++* You should have received a copy of the GNU General Public License version ++* 2 along with this work; if not, write to the Free Software Foundation, ++* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. ++* ++* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA ++* or visit www.oracle.com if you need additional information or have any ++* questions. ++*/ ++ ++package sun.nio.ch; ++ ++import java.io.IOException; ++import jdk.internal.misc.Unsafe; ++ ++import static sun.nio.ch.SolarisEventPort.OFFSETOF_OBJECT; ++import static sun.nio.ch.SolarisEventPort.POLLIN; ++import static sun.nio.ch.SolarisEventPort.POLLOUT; ++import static sun.nio.ch.SolarisEventPort.PORT_SOURCE_FD; ++import static sun.nio.ch.SolarisEventPort.SIZEOF_PORT_EVENT; ++ ++class SolarisEventPortPoller extends Poller { ++ ++ private static final Unsafe unsafe = Unsafe.getUnsafe(); ++ ++ private static final int MAX_EVENTS = 512; ++ ++ // File descriptor to event port. ++ private final int epid; ++ private final int event; ++ ++ // the poll array (populated by port_getn) ++ private final long pollArrayAddress; ++ private final AllocatedNativeObject pollArray; ++ ++ SolarisEventPortPoller(boolean read) throws IOException { ++ super(read); ++ this.epid = SolarisEventPort.port_create(); ++ this.event = (read) ? POLLIN : POLLOUT; ++ ++ int allocationSize = MAX_EVENTS * SIZEOF_PORT_EVENT; ++ this.pollArray = new AllocatedNativeObject(allocationSize, false); ++ this.pollArrayAddress = pollArray.address(); ++ } ++ ++ @Override ++ int fdVal() { ++ return epid; ++ } ++ ++ @Override ++ void implRegister(int fdVal) throws IOException { ++ boolean result = SolarisEventPort.port_associate(epid, PORT_SOURCE_FD, fdVal, event); ++ // 'SolarisEventPort.c' will already throw an IOException if the native 'port_associate' method returns ++ // an error code which is not 'EBADFD'. ++ if (!result) { ++ throw new IOException("Event ports 'port_associate' call failed. Error code: " + result); ++ } ++ } ++ ++ @Override ++ void implDeregister(int fdVal) { ++ try{ ++ SolarisEventPort.port_dissociate(epid, PORT_SOURCE_FD, fdVal); ++ } catch (IOException e) { ++ // Ignore. ++ } ++ } ++ ++ @Override ++ int poll(int timeout) throws IOException { ++ int numEvents = SolarisEventPort.port_getn(epid, pollArrayAddress, MAX_EVENTS, timeout); ++ if (numEvents < 0) { ++ throw new IOException("Event ports 'port_getn' call failed. Error code: " + numEvents); ++ } ++ ++ int i = 0; ++ while (i < numEvents) { ++ long eventAddress = pollArrayAddress + (SIZEOF_PORT_EVENT * i); ++ // pe->portev_object is file descriptor ++ int fdVal = (int)unsafe.getAddress(eventAddress + OFFSETOF_OBJECT); ++ polled(fdVal); ++ i++; ++ } ++ ++ return numEvents; ++ } ++} diff --git a/build/openjdk21/patches/illumos-port-10.patch b/build/openjdk21/patches/illumos-port-10.patch new file mode 100644 index 0000000000..6f6ef24393 --- /dev/null +++ b/build/openjdk21/patches/illumos-port-10.patch @@ -0,0 +1,13 @@ +--- a/make/autoconf/flags-ldflags.m4 Thu Nov 26 19:47:04 2020 ++++ b/make/autoconf/flags-ldflags.m4 Thu Nov 26 20:43:34 2020 +@@ -192,7 +192,9 @@ + test "x${OPENJDK_$1_CPU}" = xmips64el; then + $1_CPU_LDFLAGS="${$1_CPU_LDFLAGS} -Wl,--hash-style=sysv" + else +- $1_CPU_LDFLAGS="${$1_CPU_LDFLAGS} -Wl,--hash-style=gnu" ++ if test "x$OPENJDK_TARGET_OS" != xsolaris; then ++ $1_CPU_LDFLAGS="${$1_CPU_LDFLAGS} -Wl,--hash-style=gnu" ++ fi + fi + + elif test "x$TOOLCHAIN_TYPE" = xmicrosoft; then diff --git a/build/openjdk21/patches/illumos-port-11.patch b/build/openjdk21/patches/illumos-port-11.patch new file mode 100644 index 0000000000..cb83f3c3ff --- /dev/null +++ b/build/openjdk21/patches/illumos-port-11.patch @@ -0,0 +1,10 @@ +--- a/src/hotspot/share/runtime/os.cpp Thu Jan 14 11:21:25 2021 ++++ b/src/hotspot/share/runtime/os.cpp Thu Jan 14 11:44:00 2021 +@@ -82,6 +82,7 @@ + + # include + # include ++# include + + OSThread* os::_starting_thread = nullptr; + volatile unsigned int os::_rand_seed = 1234567; diff --git a/build/openjdk21/patches/illumos-port-12.patch b/build/openjdk21/patches/illumos-port-12.patch new file mode 100644 index 0000000000..e91b83dae4 --- /dev/null +++ b/build/openjdk21/patches/illumos-port-12.patch @@ -0,0 +1,15 @@ +--- a/make/autoconf/toolchain.m4 Sat Jul 3 15:56:43 2021 ++++ b/make/autoconf/toolchain.m4 Sat Jul 3 16:11:51 2021 +@@ -225,7 +225,11 @@ + # Linux x86_64 needs higher binutils after 8265783 + # (this really is a dependency on as version, but we take ld as a check for a general binutils version) + if test "x$OPENJDK_TARGET_CPU" = "xx86_64"; then +- TOOLCHAIN_MINIMUM_LD_VERSION_gcc="2.25" ++ if test "x$OPENJDK_TARGET_OS" = xsolaris; then ++ TOOLCHAIN_MINIMUM_LD_VERSION_gcc="" ++ else ++ TOOLCHAIN_MINIMUM_LD_VERSION_gcc="2.25" ++ fi + fi + + # Use indirect variable referencing diff --git a/build/openjdk21/patches/illumos-port-16.patch b/build/openjdk21/patches/illumos-port-16.patch new file mode 100644 index 0000000000..ca812d5cc7 --- /dev/null +++ b/build/openjdk21/patches/illumos-port-16.patch @@ -0,0 +1,132 @@ +This all looks very broken, but the SunOS-specific code calls this. +Should investigate if it actually needs to. + +--- jdk-jdk-19-7/src/java.base/unix/classes/java/lang/ProcessImpl.java Thu Jan 27 08:31:11 2022 ++++ jdk-jdk-19-6/src/java.base/unix/classes/java/lang/ProcessImpl.java Thu Jan 20 08:53:40 2022 +@@ -45,6 +45,7 @@ + import java.security.AccessController; + import java.security.PrivilegedActionException; + import java.security.PrivilegedExceptionAction; ++import java.util.Properties; + import jdk.internal.access.JavaIOFileDescriptorAccess; + import jdk.internal.access.SharedSecrets; + import jdk.internal.util.OperatingSystem; +@@ -712,6 +713,109 @@ + } + } + ++ // A FileInputStream that supports the deferment of the actual close ++ // operation until the last pending I/O operation on the stream has ++ // finished. This is required on Solaris because we must close the stdin ++ // and stdout streams in the destroy method in order to reclaim the ++ // underlying file descriptors. Doing so, however, causes any thread ++ // currently blocked in a read on one of those streams to receive an ++ // IOException("Bad file number"), which is incompatible with historical ++ // behavior. By deferring the close we allow any pending reads to see -1 ++ // (EOF) as they did before. ++ // ++ private static class DeferredCloseInputStream extends PipeInputStream { ++ DeferredCloseInputStream(FileDescriptor fd) { ++ super(fd); ++ } ++ ++ private Object lock = new Object(); // For the following fields ++ private boolean closePending = false; ++ private int useCount = 0; ++ private InputStream streamToClose; ++ ++ private void raise() { ++ synchronized (lock) { ++ useCount++; ++ } ++ } ++ ++ private void lower() throws IOException { ++ synchronized (lock) { ++ useCount--; ++ if (useCount == 0 && closePending) { ++ streamToClose.close(); ++ } ++ } ++ } ++ ++ // stc is the actual stream to be closed; it might be this object, or ++ // it might be an upstream object for which this object is downstream. ++ // ++ private void closeDeferred(InputStream stc) throws IOException { ++ synchronized (lock) { ++ if (useCount == 0) { ++ stc.close(); ++ } else { ++ closePending = true; ++ streamToClose = stc; ++ } ++ } ++ } ++ ++ public void close() throws IOException { ++ synchronized (lock) { ++ useCount = 0; ++ closePending = false; ++ } ++ super.close(); ++ } ++ ++ public int read() throws IOException { ++ raise(); ++ try { ++ return super.read(); ++ } finally { ++ lower(); ++ } ++ } ++ ++ public int read(byte[] b) throws IOException { ++ raise(); ++ try { ++ return super.read(b); ++ } finally { ++ lower(); ++ } ++ } ++ ++ public int read(byte[] b, int off, int len) throws IOException { ++ raise(); ++ try { ++ return super.read(b, off, len); ++ } finally { ++ lower(); ++ } ++ } ++ ++ public long skip(long n) throws IOException { ++ raise(); ++ try { ++ return super.skip(n); ++ } finally { ++ lower(); ++ } ++ } ++ ++ public int available() throws IOException { ++ raise(); ++ try { ++ return super.available(); ++ } finally { ++ lower(); ++ } ++ } ++ } ++ + /** + * A buffered input stream for a subprocess pipe file descriptor + * that allows the underlying file descriptor to be reclaimed when +@@ -725,7 +829,7 @@ + * will block if another thread is at the same time blocked in a file + * operation (e.g. 'read()') on the same file descriptor. We therefore + * combine 'ProcessPipeInputStream' approach used on Linux and Bsd +- * with the deferring 'close' of InputStream. This means ++ * with the DeferredCloseInputStream approach used on Solaris. This means + * that every potentially blocking operation on the file descriptor + * increments a counter before it is executed and decrements it once it + * finishes. The 'close()' operation will only be executed if there are diff --git a/build/openjdk21/patches/illumos-port-17.patch b/build/openjdk21/patches/illumos-port-17.patch new file mode 100644 index 0000000000..5ff6416718 --- /dev/null +++ b/build/openjdk21/patches/illumos-port-17.patch @@ -0,0 +1,57 @@ +The original solaris removal forgot this file, it's recently been removed +so we now have to put it back. It might be cleaner to remove DTrace in the +longer term. + +diff -urN a/src/hotspot/share/services/dtraceAttacher.hpp b/src/hotspot/share/services/dtraceAttacher.hpp +--- a/src/hotspot/share/services/dtraceAttacher.hpp 1970-01-01 01:00:00.000000000 +0000 ++++ b/src/hotspot/share/services/dtraceAttacher.hpp 2022-02-16 13:46:43.000000000 +0000 +@@ -0,0 +1,49 @@ ++/* ++ * Copyright (c) 2006, 2019, Oracle and/or its affiliates. All rights reserved. ++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. ++ * ++ * This code is free software; you can redistribute it and/or modify it ++ * under the terms of the GNU General Public License version 2 only, as ++ * published by the Free Software Foundation. ++ * ++ * This code is distributed in the hope that it will be useful, but WITHOUT ++ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or ++ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License ++ * version 2 for more details (a copy is included in the LICENSE file that ++ * accompanied this code). ++ * ++ * You should have received a copy of the GNU General Public License version ++ * 2 along with this work; if not, write to the Free Software Foundation, ++ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. ++ * ++ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA ++ * or visit www.oracle.com if you need additional information or have any ++ * questions. ++ * ++ */ ++ ++#ifndef SHARE_SERVICES_DTRACEATTACHER_HPP ++#define SHARE_SERVICES_DTRACEATTACHER_HPP ++ ++#define DTRACE_ALLOC_PROBES 0x1 ++#define DTRACE_METHOD_PROBES 0x2 ++#define DTRACE_MONITOR_PROBES 0x4 ++#define DTRACE_ALL_PROBES (DTRACE_ALLOC_PROBES | \ ++ DTRACE_METHOD_PROBES | \ ++ DTRACE_MONITOR_PROBES) ++ ++class DTrace : public AllStatic { ++ private: ++ // disable one or more probes - OR above constants ++ static void disable_dprobes(int probe_types); ++ ++ public: ++ // enable one or more probes - OR above constants ++ static void enable_dprobes(int probe_types); ++ // all clients detached, do any clean-up ++ static void detach_all_clients(); ++ // set DTraceMonitorProbes flag ++ static void set_monitor_dprobes(bool value); ++}; ++ ++#endif // SHARE_SERVICES_DTRACEATTACHER_HPP diff --git a/build/openjdk21/patches/illumos-port-18.patch b/build/openjdk21/patches/illumos-port-18.patch new file mode 100644 index 0000000000..019582d9df --- /dev/null +++ b/build/openjdk21/patches/illumos-port-18.patch @@ -0,0 +1,33 @@ +--- a/src/hotspot/share/runtime/mutex.hpp Wed Jul 6 08:12:32 2022 ++++ b/src/hotspot/share/runtime/mutex.hpp Thu Jul 7 13:59:23 2022 +@@ -28,7 +28,7 @@ + #include "memory/allocation.hpp" + #include "runtime/atomic.hpp" + +-#if defined(LINUX) || defined(AIX) || defined(BSD) ++#if defined(LINUX) || defined(AIX) || defined(BSD) || defined(SOLARIS) + # include "mutex_posix.hpp" + #else + # include OS_HEADER(mutex) +--- a/src/hotspot/share/runtime/park.hpp Wed Jul 6 08:12:32 2022 ++++ b/src/hotspot/share/runtime/park.hpp Thu Jul 7 14:01:18 2022 +@@ -28,7 +28,7 @@ + #include "utilities/debug.hpp" + #include "utilities/globalDefinitions.hpp" + +-#if defined(LINUX) || defined(AIX) || defined(BSD) ++#if defined(LINUX) || defined(AIX) || defined(BSD) || defined(SOLARIS) + # include "park_posix.hpp" + #else + # include OS_HEADER(park) +--- a/src/hotspot/share/runtime/threadCrashProtection.hpp Wed Jul 6 08:12:32 2022 ++++ b/src/hotspot/share/runtime/threadCrashProtection.hpp Thu Jul 7 14:11:04 2022 +@@ -27,7 +27,7 @@ + #define SHARE_RUNTIME_THREADCRASHPROTECTION_HPP + + #include "memory/allocation.hpp" +-#if defined(LINUX) || defined(AIX) || defined(BSD) ++#if defined(LINUX) || defined(AIX) || defined(BSD) || defined(SOLARIS) + # include "threadCrashProtection_posix.hpp" + #else + # include OS_HEADER(threadCrashProtection) diff --git a/build/openjdk21/patches/illumos-port-19.patch b/build/openjdk21/patches/illumos-port-19.patch new file mode 100644 index 0000000000..3c133e1441 --- /dev/null +++ b/build/openjdk21/patches/illumos-port-19.patch @@ -0,0 +1,11 @@ +--- a/src/hotspot/share/runtime/osThread.hpp Wed Jul 13 20:15:53 2022 ++++ b/src/hotspot/share/runtime/osThread.hpp Sun Jul 24 14:21:39 2022 +@@ -32,7 +32,7 @@ + #include "runtime/suspendedThreadTask.hpp" + #include "utilities/macros.hpp" + +-#if defined(LINUX) || defined(AIX) || defined(BSD) ++#if defined(LINUX) || defined(AIX) || defined(BSD) || defined(SOLARIS) + #include "suspendResume_posix.hpp" + #endif + diff --git a/build/openjdk21/patches/illumos-port-2.patch b/build/openjdk21/patches/illumos-port-2.patch new file mode 100644 index 0000000000..76544df3da --- /dev/null +++ b/build/openjdk21/patches/illumos-port-2.patch @@ -0,0 +1,78 @@ +--- a/src/java.base/unix/native/libnio/fs/UnixNativeDispatcher.c Thu May 28 11:43:30 2020 ++++ b/src/java.base/unix/native/libnio/fs/UnixNativeDispatcher.c Wed May 20 19:29:11 2020 +@@ -499,7 +499,41 @@ + return (jint)res; + } + ++JNIEXPORT jlong JNICALL ++Java_sun_nio_fs_UnixNativeDispatcher_fopen0(JNIEnv* env, jclass this, ++ jlong pathAddress, jlong modeAddress) ++{ ++ FILE* fp = NULL; ++ const char* path = (const char*)jlong_to_ptr(pathAddress); ++ const char* mode = (const char*)jlong_to_ptr(modeAddress); ++ ++ do { ++ fp = fopen(path, mode); ++ } while (fp == NULL && errno == EINTR); ++ ++ if (fp == NULL) { ++ throwUnixException(env, errno); ++ } ++ ++ return ptr_to_jlong(fp); ++} ++ + JNIEXPORT void JNICALL ++Java_sun_nio_fs_UnixNativeDispatcher_fclose(JNIEnv* env, jclass this, jlong stream) ++{ ++ FILE* fp = jlong_to_ptr(stream); ++ ++ /* NOTE: fclose() wrapper is only used with read-only streams. ++ * If it ever is used with write streams, it might be better to add ++ * RESTARTABLE(fflush(fp)) before closing, to make sure the stream ++ * is completely written even if fclose() failed. ++ */ ++ if (fclose(fp) == EOF && errno != EINTR) { ++ throwUnixException(env, errno); ++ } ++} ++ ++JNIEXPORT void JNICALL + Java_sun_nio_fs_UnixNativeDispatcher_rewind(JNIEnv* env, jclass this, jlong stream) + { + FILE* fp = jlong_to_ptr(stream); +@@ -1262,6 +1296,33 @@ + } + } + ++JNIEXPORT jlong JNICALL ++Java_sun_nio_fs_UnixNativeDispatcher_pathconf0(JNIEnv* env, jclass this, ++ jlong pathAddress, jint name) ++{ ++ long err; ++ const char* path = (const char*)jlong_to_ptr(pathAddress); ++ ++ err = pathconf(path, (int)name); ++ if (err == -1) { ++ throwUnixException(env, errno); ++ } ++ return (jlong)err; ++} ++ ++JNIEXPORT jlong JNICALL ++Java_sun_nio_fs_UnixNativeDispatcher_fpathconf(JNIEnv* env, jclass this, ++ jint fd, jint name) ++{ ++ long err; ++ ++ err = fpathconf((int)fd, (int)name); ++ if (err == -1) { ++ throwUnixException(env, errno); ++ } ++ return (jlong)err; ++} ++ + JNIEXPORT void JNICALL + Java_sun_nio_fs_UnixNativeDispatcher_mknod0(JNIEnv* env, jclass this, + jlong pathAddress, jint mode, jlong dev) diff --git a/build/openjdk21/patches/illumos-port-20.patch b/build/openjdk21/patches/illumos-port-20.patch new file mode 100644 index 0000000000..125694c460 --- /dev/null +++ b/build/openjdk21/patches/illumos-port-20.patch @@ -0,0 +1,11 @@ +--- a/src/hotspot/share/runtime/os.hpp Wed Aug 10 20:17:42 2022 ++++ b/src/hotspot/share/runtime/os.hpp Thu Aug 11 11:42:41 2022 +@@ -987,6 +987,8 @@ + class Bsd; + #elif defined(LINUX) + class Linux; ++#elif defined(SOLARIS) ++ class Solaris; + #elif defined(_WINDOWS) + class win32; + #endif diff --git a/build/openjdk21/patches/illumos-port-21.patch b/build/openjdk21/patches/illumos-port-21.patch new file mode 100644 index 0000000000..232a7477df --- /dev/null +++ b/build/openjdk21/patches/illumos-port-21.patch @@ -0,0 +1,123 @@ +--- a/src/java.base/solaris/classes/sun/nio/ch/FileDispatcherImpl.java Mon Oct 10 20:08:47 2022 ++++ b/src/java.base/solaris/classes/sun/nio/ch/FileDispatcherImpl.java Mon Oct 10 19:39:09 2022 +@@ -0,0 +1,45 @@ ++/* ++ * Copyright (c) 2000, 2022, Oracle and/or its affiliates. All rights reserved. ++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. ++ * ++ * This code is free software; you can redistribute it and/or modify it ++ * under the terms of the GNU General Public License version 2 only, as ++ * published by the Free Software Foundation. Oracle designates this ++ * particular file as subject to the "Classpath" exception as provided ++ * by Oracle in the LICENSE file that accompanied this code. ++ * ++ * This code is distributed in the hope that it will be useful, but WITHOUT ++ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or ++ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License ++ * version 2 for more details (a copy is included in the LICENSE file that ++ * accompanied this code). ++ * ++ * You should have received a copy of the GNU General Public License version ++ * 2 along with this work; if not, write to the Free Software Foundation, ++ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. ++ * ++ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA ++ * or visit www.oracle.com if you need additional information or have any ++ * questions. ++ */ ++ ++package sun.nio.ch; ++ ++import java.io.FileDescriptor; ++ ++class FileDispatcherImpl extends UnixFileDispatcherImpl { ++ FileDispatcherImpl() { ++ super(); ++ } ++ ++ long transferTo(FileDescriptor src, long position, long count, ++ FileDescriptor dst, boolean append) { ++ return transferTo0(src, position, count, dst, append); ++ } ++ ++ // -- Native methods -- ++ ++ static native long transferTo0(FileDescriptor src, long position, ++ long count, FileDescriptor dst, ++ boolean append); ++} +--- a/src/java.base/solaris/native/libnio/ch/FileDispatcherImpl.c Mon Oct 10 20:09:47 2022 ++++ b/src/java.base/solaris/native/libnio/ch/FileDispatcherImpl.c Mon Oct 10 19:39:25 2022 +@@ -0,0 +1,72 @@ ++/* ++ * Copyright (c) 2000, 2022, Oracle and/or its affiliates. All rights reserved. ++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. ++ * ++ * This code is free software; you can redistribute it and/or modify it ++ * under the terms of the GNU General Public License version 2 only, as ++ * published by the Free Software Foundation. Oracle designates this ++ * particular file as subject to the "Classpath" exception as provided ++ * by Oracle in the LICENSE file that accompanied this code. ++ * ++ * This code is distributed in the hope that it will be useful, but WITHOUT ++ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or ++ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License ++ * version 2 for more details (a copy is included in the LICENSE file that ++ * accompanied this code). ++ * ++ * You should have received a copy of the GNU General Public License version ++ * 2 along with this work; if not, write to the Free Software Foundation, ++ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. ++ * ++ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA ++ * or visit www.oracle.com if you need additional information or have any ++ * questions. ++ */ ++ ++#include ++#include ++ ++#include "jni.h" ++#include "nio.h" ++#include "nio_util.h" ++#include "sun_nio_ch_FileDispatcherImpl.h" ++ ++JNIEXPORT jlong JNICALL ++Java_sun_nio_ch_FileDispatcherImpl_transferTo0(JNIEnv *env, jobject this, ++ jobject srcFDO, ++ jlong position, jlong count, ++ jobject dstFDO, jboolean append) ++{ ++ jint srcFD = fdval(env, srcFDO); ++ jint dstFD = fdval(env, dstFDO); ++ ++ sendfilevec64_t sfv; ++ size_t numBytes = 0; ++ jlong result; ++ ++ sfv.sfv_fd = srcFD; ++ sfv.sfv_flag = 0; ++ sfv.sfv_off = (off64_t)position; ++ sfv.sfv_len = count; ++ ++ result = sendfilev64(dstFD, &sfv, 1, &numBytes); ++ ++ /* Solaris sendfilev() will return -1 even if some bytes have been ++ * transferred, so we check numBytes first. ++ */ ++ if (numBytes > 0) ++ return numBytes; ++ if (result < 0) { ++ if (errno == EAGAIN) ++ return IOS_UNAVAILABLE; ++ if (errno == EOPNOTSUPP) ++ return IOS_UNSUPPORTED_CASE; ++ if ((errno == EINVAL) && ((ssize_t)count >= 0)) ++ return IOS_UNSUPPORTED_CASE; ++ if (errno == EINTR) ++ return IOS_INTERRUPTED; ++ JNU_ThrowIOExceptionWithLastError(env, "Transfer failed"); ++ return IOS_THROWN; ++ } ++ return result; ++} diff --git a/build/openjdk21/patches/illumos-port-22.patch b/build/openjdk21/patches/illumos-port-22.patch new file mode 100644 index 0000000000..2cdf615d92 --- /dev/null +++ b/build/openjdk21/patches/illumos-port-22.patch @@ -0,0 +1,28 @@ +--- /dev/null Sat Mar 4 12:15:07 2023 ++++ a/make/data/charsetmapping/stdcs-solaris Sat Mar 4 12:03:56 2023 +@@ -0,0 +1,25 @@ ++# ++# generate these charsets into sun.nio.cs ++# ++Big5 ++Big5_Solaris ++Big5_HKSCS # always together with Big5 ++EUC_CN ++EUC_KR ++EUC_JP ++EUC_JP_LINUX ++EUC_JP_Open ++EUC_TW ++GBK ++ISO_8859_11 ++ISO_8859_3 ++ISO_8859_6 ++ISO_8859_8 ++Johab ++PCK ++TIS_620 ++JIS_X_0201 ++JIS_X_0208 ++JIS_X_0212 ++JIS_X_0208_Solaris ++JIS_X_0212_Solaris diff --git a/build/openjdk21/patches/illumos-port-23.patch b/build/openjdk21/patches/illumos-port-23.patch new file mode 100644 index 0000000000..57cd7566a6 --- /dev/null +++ b/build/openjdk21/patches/illumos-port-23.patch @@ -0,0 +1,38 @@ +--- a/src/java.base/share/classes/jdk/internal/util/OperatingSystem.java Wed Mar 29 20:12:02 2023 ++++ b/src/java.base/share/classes/jdk/internal/util/OperatingSystem.java Thu Mar 30 13:44:42 2023 +@@ -81,6 +81,10 @@ + * The AIX Operating system. + */ + AIX, ++ /** ++ * Operating systems based on Solaris or illumos. ++ */ ++ SOLARIS, + ; + + // The current OperatingSystem +@@ -118,6 +122,14 @@ + return PlatformProps.TARGET_OS_IS_AIX; + } + ++ /** ++ * {@return {@code true} if built for Solaris or illumos operating systems} ++ */ ++ @ForceInline ++ public static boolean isSolaris() { ++ return PlatformProps.TARGET_OS_IS_SOLARIS; ++ } ++ + /** + * {@return the current operating system} + */ +--- a/src/java.base/share/classes/jdk/internal/util/PlatformProps.java.template Wed Mar 29 20:12:02 2023 ++++ b/src/java.base/share/classes/jdk/internal/util/PlatformProps.java.template Thu Mar 30 13:43:29 2023 +@@ -39,6 +39,7 @@ + static final boolean TARGET_OS_IS_MACOS = "@@OPENJDK_TARGET_OS@@" == "macos"; + static final boolean TARGET_OS_IS_WINDOWS = "@@OPENJDK_TARGET_OS@@" == "windows"; + static final boolean TARGET_OS_IS_AIX = "@@OPENJDK_TARGET_OS@@" == "aix"; ++ static final boolean TARGET_OS_IS_SOLARIS = "@@OPENJDK_TARGET_OS@@" == "solaris"; + + // The Architecture value for the current architecture + static final String CURRENT_ARCH_STRING = "@@OPENJDK_TARGET_CPU@@"; diff --git a/build/openjdk21/patches/illumos-port-24.patch b/build/openjdk21/patches/illumos-port-24.patch new file mode 100644 index 0000000000..8fcbe5f0b0 --- /dev/null +++ b/build/openjdk21/patches/illumos-port-24.patch @@ -0,0 +1,33 @@ +While we do have stafs(2) it has a different signature, is deprecated and +undocumented, while statvfs() gives the behaviour we actually want. + +--- a/test/jdk/java/io/File/libGetXSpace.c Wed Apr 5 22:54:38 2023 ++++ b/test/jdk/java/io/File/libGetXSpace.c Thu Apr 6 14:28:43 2023 +@@ -34,9 +34,13 @@ + #include + #include + #else ++#ifdef __sun__ ++#include ++#else + #include + #endif + #endif ++#endif + + #ifdef __cplusplus + extern "C" { +@@ -142,8 +146,13 @@ + chars[len] = '\0'; + (*env)->ReleaseStringChars(env, root, strchars); + ++#ifdef __sun__ ++ struct statvfs buf; ++ int result = statvfs(chars, &buf); ++#else + struct statfs buf; + int result = statfs(chars, &buf); ++#endif + free(chars); + if (result < 0) { + JNU_ThrowByNameWithLastError(env, "java/lang/RuntimeException", diff --git a/build/openjdk21/patches/illumos-port-25.patch b/build/openjdk21/patches/illumos-port-25.patch new file mode 100644 index 0000000000..71b4ee6c7a --- /dev/null +++ b/build/openjdk21/patches/illumos-port-25.patch @@ -0,0 +1,10 @@ +--- a/src/hotspot/share/runtime/javaThread.cpp Wed Apr 12 04:15:39 2023 ++++ b/src/hotspot/share/runtime/javaThread.cpp Thu Apr 6 13:54:57 2023 +@@ -23,6 +23,7 @@ + * + */ + ++#include + #include "precompiled.hpp" + #include "cds/dynamicArchive.hpp" + #include "ci/ciEnv.hpp" diff --git a/build/openjdk21/patches/illumos-port-26.patch b/build/openjdk21/patches/illumos-port-26.patch new file mode 100644 index 0000000000..da2e05b11f --- /dev/null +++ b/build/openjdk21/patches/illumos-port-26.patch @@ -0,0 +1,10 @@ +--- a/src/java.base/share/native/libjava/jni_util.c Tue Mar 7 13:51:11 2023 ++++ b/src/java.base/share/native/libjava/jni_util.c Mon Apr 24 10:07:39 2023 +@@ -25,6 +25,7 @@ + + #include + #include ++#include + + #include "jvm.h" + #include "jni.h" diff --git a/build/openjdk21/patches/illumos-port-27.patch b/build/openjdk21/patches/illumos-port-27.patch new file mode 100644 index 0000000000..96a01761a4 --- /dev/null +++ b/build/openjdk21/patches/illumos-port-27.patch @@ -0,0 +1,13 @@ +--- a/src/java.desktop/unix/native/libawt_xawt/awt/screencast_pipewire.c Thu Jun 8 15:06:27 2023 ++++ b/src/java.desktop/unix/native/libawt_xawt/awt/screencast_pipewire.c Mon Jun 12 09:15:47 2023 +@@ -37,6 +37,10 @@ + #include "gtk_interface.h" + #include "gtk3_interface.h" + ++#ifndef MAX ++#define MAX(a,b) ((a) > (b) ? (a) : (b)) ++#endif ++ + int DEBUG_SCREENCAST_ENABLED = FALSE; + + #define EXCEPTION_CHECK_DESCRIBE() if ((*env)->ExceptionCheck(env)) { \ diff --git a/build/openjdk21/patches/illumos-port-3.patch b/build/openjdk21/patches/illumos-port-3.patch new file mode 100644 index 0000000000..5d7fdcaeca --- /dev/null +++ b/build/openjdk21/patches/illumos-port-3.patch @@ -0,0 +1,56 @@ +--- a/src/java.base/unix/classes/sun/nio/fs/UnixNativeDispatcher.java Thu May 28 00:44:10 2020 ++++ b/src/java.base/unix/classes/sun/nio/fs/UnixNativeDispatcher.java Wed May 20 19:29:11 2020 +@@ -123,6 +123,27 @@ + } + + /** ++ * FILE* fopen(const char *filename, const char* mode); ++ */ ++ static long fopen(UnixPath filename, String mode) throws UnixException { ++ NativeBuffer pathBuffer = copyToNativeBuffer(filename); ++ NativeBuffer modeBuffer = NativeBuffers.asNativeBuffer(Util.toBytes(mode)); ++ try { ++ return fopen0(pathBuffer.address(), modeBuffer.address()); ++ } finally { ++ modeBuffer.release(); ++ pathBuffer.release(); ++ } ++ } ++ private static native long fopen0(long pathAddress, long modeAddress) ++ throws UnixException; ++ ++ /** ++ * fclose(FILE* stream) ++ */ ++ static native void fclose(long stream) throws UnixException; ++ ++ /** + * void rewind(FILE* stream); + */ + static native void rewind(long stream) throws UnixException; +@@ -693,6 +714,25 @@ + throws UnixException; + + /** ++ * long int pathconf(const char *path, int name); ++ */ ++ static long pathconf(UnixPath path, int name) throws UnixException { ++ NativeBuffer buffer = copyToNativeBuffer(path); ++ try { ++ return pathconf0(buffer.address(), name); ++ } finally { ++ buffer.release(); ++ } ++ } ++ private static native long pathconf0(long pathAddress, int name) ++ throws UnixException; ++ ++ /** ++ * long fpathconf(int fildes, int name); ++ */ ++ static native long fpathconf(int filedes, int name) throws UnixException; ++ ++ /** + * char* strerror(int errnum) + */ + static native byte[] strerror(int errnum); diff --git a/build/openjdk21/patches/illumos-port-5.patch b/build/openjdk21/patches/illumos-port-5.patch new file mode 100644 index 0000000000..a7ed8b341a --- /dev/null +++ b/build/openjdk21/patches/illumos-port-5.patch @@ -0,0 +1,13 @@ +--- a/src/java.base/unix/classes/sun/nio/fs/UnixUserPrincipals.java Thu May 28 00:44:10 2020 ++++ b/src/java.base/unix/classes/sun/nio/fs/UnixUserPrincipals.java Wed May 20 19:29:11 2020 +@@ -67,6 +67,10 @@ + throw new AssertionError(); + } + ++ boolean isSpecial() { ++ return id == -1; ++ } ++ + @Override + public String getName() { + return name; diff --git a/build/openjdk21/patches/illumos-port-6.patch b/build/openjdk21/patches/illumos-port-6.patch new file mode 100644 index 0000000000..a6265bc42a --- /dev/null +++ b/build/openjdk21/patches/illumos-port-6.patch @@ -0,0 +1,26 @@ +See http://hg.openjdk.java.net/jdk/jdk/rev/1096ad4dbf62 + +The problem is that we want a guard based on platform, but +_GNU_SOURCE is a per-toolchain define for the gcc toolchain. +It "fixes" AIX because that's using the xlc toolchain. + +--- a/src/hotspot/share/runtime/os.cpp Wed Aug 12 16:38:30 2020 ++++ b/src/hotspot/share/runtime/os.cpp Thu Aug 13 19:44:36 2020 +@@ -163,7 +163,7 @@ + // No offset when dealing with UTC + time_t UTC_to_local = 0; + if (!utc) { +-#if (defined(_ALLBSD_SOURCE) || defined(_GNU_SOURCE)) && !defined(AIX) ++#if (defined(_ALLBSD_SOURCE) || defined(_BSD_SOURCE)) && !defined(AIX) + UTC_to_local = -(time_struct.tm_gmtoff); + #elif defined(_WINDOWS) + long zone; +@@ -174,7 +174,7 @@ + #endif + + // tm_gmtoff already includes adjustment for daylight saving +-#if !defined(_ALLBSD_SOURCE) && !defined(_GNU_SOURCE) ++#if !defined(_ALLBSD_SOURCE) && !defined(_BSD_SOURCE) + // If daylight savings time is in effect, + // we are 1 hour East of our time zone + if (time_struct.tm_isdst > 0) { diff --git a/build/openjdk21/patches/illumos-port-7.patch b/build/openjdk21/patches/illumos-port-7.patch new file mode 100644 index 0000000000..78dc0eab40 --- /dev/null +++ b/build/openjdk21/patches/illumos-port-7.patch @@ -0,0 +1,13 @@ +--- a/src/hotspot/share/prims/methodHandles.cpp Wed Aug 19 21:41:08 2020 ++++ b/src/hotspot/share/prims/methodHandles.cpp Fri Aug 21 10:42:08 2020 +@@ -1367,6 +1367,10 @@ + #define LANG "Ljava/lang/" + #define JLINV "Ljava/lang/invoke/" + ++#ifdef CS ++#undef CS ++#endif ++ + #define OBJ LANG "Object;" + #define CLS LANG "Class;" + #define STRG LANG "String;" diff --git a/build/openjdk21/patches/illumos-signal-1.patch b/build/openjdk21/patches/illumos-signal-1.patch new file mode 100644 index 0000000000..ae36f0a067 --- /dev/null +++ b/build/openjdk21/patches/illumos-signal-1.patch @@ -0,0 +1,11 @@ +--- a/src/hotspot/os/posix/signals_posix.cpp Wed Oct 7 17:21:51 2020 ++++ b/src/hotspot/os/posix/signals_posix.cpp Sat Oct 10 16:46:21 2020 +@@ -547,6 +547,8 @@ + #define JVM_HANDLE_XXX_SIGNAL JVM_handle_aix_signal + #elif defined(LINUX) + #define JVM_HANDLE_XXX_SIGNAL JVM_handle_linux_signal ++#elif defined(SOLARIS) ++#define JVM_HANDLE_XXX_SIGNAL JVM_handle_solaris_signal + #else + #error who are you? + #endif diff --git a/build/openjdk21/patches/java-solaris-sparc.patch b/build/openjdk21/patches/java-solaris-sparc.patch new file mode 100644 index 0000000000..1b0bc890f6 --- /dev/null +++ b/build/openjdk21/patches/java-solaris-sparc.patch @@ -0,0 +1,14991 @@ +--- old/bin/unshuffle_list.txt 2020-05-20 17:58:14.636050719 -0700 ++++ new/bin/unshuffle_list.txt 2020-05-20 17:58:14.240043115 -0700 +@@ -101,7 +100,6 @@ + src/langtools/sample : langtools/src/sample + src/linux : jdk/src/linux + src/sample : jdk/src/sample +-src/solaris : jdk/src/solaris + src/hotspot/share : hotspot/src/share/vm + src/hotspot/cpu/aarch64 : hotspot/src/cpu/aarch64/vm + src/hotspot/cpu/arm : hotspot/src/cpu/arm/vm +@@ -114,7 +112,6 @@ + src/hotspot/os/linux : hotspot/src/os/linux/vm + src/hotspot/os/posix/dtrace : hotspot/src/os/posix/dtrace + src/hotspot/os/posix : hotspot/src/os/posix/vm +-src/hotspot/os/solaris : hotspot/src/os/solaris/vm + src/hotspot/os/windows : hotspot/src/os/windows/vm + src/hotspot/os_cpu/aix_ppc : hotspot/src/os_cpu/aix_ppc/vm + src/hotspot/os_cpu/bsd_x86 : hotspot/src/os_cpu/bsd_x86/vm +@@ -125,7 +122,6 @@ + src/hotspot/os_cpu/linux_s390 : hotspot/src/os_cpu/linux_s390/vm + src/hotspot/os_cpu/linux_x86 : hotspot/src/os_cpu/linux_x86/vm + src/hotspot/os_cpu/linux_zero : hotspot/src/os_cpu/linux_zero/vm +-src/hotspot/os_cpu/solaris_x86 : hotspot/src/os_cpu/solaris_x86/vm + src/hotspot/os_cpu/windows_x86 : hotspot/src/os_cpu/windows_x86/vm + src/hotspot : hotspot/src + src/utils/IdealGraphVisualizer : hotspot/src/share/tools/IdealGraphVisualizer +--- old/make/RunTestsPrebuilt.gmk 2020-05-20 17:58:24.212234589 -0700 ++++ new/make/RunTestsPrebuilt.gmk 2020-05-20 17:58:23.828227215 -0700 +@@ -168,8 +168,6 @@ + OPENJDK_TARGET_OS := linux + else ifeq ($(UNAME_OS), Darwin) + OPENJDK_TARGET_OS := macosx +- else ifeq ($(UNAME_OS), SunOS) +- OPENJDK_TARGET_OS := solaris + else + OPENJDK_TARGET_OS := $(UNAME_OS) + endif +@@ -182,28 +180,15 @@ + # Assume little endian unless otherwise specified + OPENJDK_TARGET_CPU_ENDIAN := little + +-ifeq ($(OPENJDK_TARGET_OS), solaris) +- # On solaris, use uname -p +- UNAME_CPU := $(shell $(UNAME) -p) +- # Assume 64-bit platform +- OPENJDK_TARGET_CPU_BITS := 64 +- ifeq ($(UNAME_CPU), i386) +- OPENJDK_TARGET_CPU := x86_64 +- else +- OPENJDK_TARGET_CPU := $(UNAME_CPU) +- endif ++UNAME_CPU := $(shell $(UNAME) -m) ++ifeq ($(UNAME_CPU), i686) ++ OPENJDK_TARGET_CPU := x86 ++ OPENJDK_TARGET_CPU_BITS := 32 + else +- # ... all others use uname -m +- UNAME_CPU := $(shell $(UNAME) -m) +- ifeq ($(UNAME_CPU), i686) +- OPENJDK_TARGET_CPU := x86 +- OPENJDK_TARGET_CPU_BITS := 32 +- else +- # Assume all others are 64-bit. We use the same CPU name as uname for +- # at least x86_64 and aarch64. +- OPENJDK_TARGET_CPU := $(UNAME_CPU) +- OPENJDK_TARGET_CPU_BITS := 64 +- endif ++ # Assume all others are 64-bit. We use the same CPU name as uname for ++ # at least x86_64 and aarch64. ++ OPENJDK_TARGET_CPU := $(UNAME_CPU) ++ OPENJDK_TARGET_CPU_BITS := 64 + endif + + OPENJDK_TARGET_CPU_ARCH := $(OPENJDK_TARGET_CPU) +@@ -228,11 +213,6 @@ + else ifeq ($(OPENJDK_TARGET_OS), macosx) + NUM_CORES := $(shell /usr/sbin/sysctl -n hw.ncpu) + MEMORY_SIZE := $(shell $(EXPR) `/usr/sbin/sysctl -n hw.memsize` / 1024 / 1024) +-else ifeq ($(OPENJDK_TARGET_OS), solaris) +- NUM_CORES := $(shell /usr/sbin/psrinfo -v | $(GREP) -c on-line) +- MEMORY_SIZE := $(shell \ +- /usr/sbin/prtconf 2> /dev/null | $(GREP) "^Memory [Ss]ize" | $(AWK) '{print $$3}' \ +- ) + else ifeq ($(OPENJDK_TARGET_OS), windows) + NUM_CORES := $(NUMBER_OF_PROCESSORS) + MEMORY_SIZE := $(shell \ +--- old/make/RunTestsPrebuiltSpec.gmk 2020-05-20 17:58:25.304255556 -0700 ++++ new/make/RunTestsPrebuiltSpec.gmk 2020-05-20 17:58:24.916248106 -0700 +@@ -173,16 +173,6 @@ + FILE := file + ULIMIT := ulimit + +-# On Solaris gnu versions of some tools are required. +-ifeq ($(OPENJDK_BUILD_OS), solaris) +- AWK := gawk +- GREP := ggrep +- EGREP := ggrep -E +- FGREP := grep -F +- SED := gsed +- TAR := gtar +-endif +- + ifeq ($(OPENJDK_BUILD_OS), windows) + PATHTOOL := cygpath + endif +--- old/make/autoconf/basic_tools.m4 2020-05-20 17:58:27.308294035 -0700 ++++ new/make/autoconf/basic_tools.m4 2020-05-20 17:58:26.972287584 -0700 +@@ -289,8 +289,6 @@ + TAR_TYPE="bsd" + elif test "x$($TAR --version | $GREP "busybox")" != "x"; then + TAR_TYPE="busybox" +- elif test "x$OPENJDK_BUILD_OS" = "xsolaris"; then +- TAR_TYPE="solaris" + elif test "x$OPENJDK_BUILD_OS" = "xaix"; then + TAR_TYPE="aix" + fi +--- old/make/autoconf/build-aux/config.guess 2020-05-20 17:58:28.372314465 -0700 ++++ new/make/autoconf/build-aux/config.guess 2020-05-20 17:58:27.980306938 -0700 +@@ -53,14 +53,6 @@ + fi + fi + +-# Test and fix solaris on x86_64 +-echo $OUT | grep i386-pc-solaris > /dev/null 2> /dev/null +-if test $? = 0; then +- # isainfo -n returns either i386 or amd64 +- REAL_CPU=`isainfo -n` +- OUT=$REAL_CPU`echo $OUT | sed -e 's/[^-]*//'` +-fi +- + # Test and fix cygwin on x86_64 + echo $OUT | grep 86-pc-cygwin > /dev/null 2> /dev/null + if test $? != 0; then +--- old/make/autoconf/build-performance.m4 2020-05-20 17:58:29.436334895 -0700 ++++ new/make/autoconf/build-performance.m4 2020-05-20 17:58:29.052327522 -0700 +@@ -33,9 +33,6 @@ + if test "$NUM_CORES" -eq "0"; then + NUM_CORES=`cat /proc/cpuinfo | grep -c ^CPU` + fi +- elif test -x /usr/sbin/psrinfo; then +- # Looks like a Solaris system +- NUM_CORES=`/usr/sbin/psrinfo -v | grep -c on-line` + elif test -x /usr/sbin/sysctl; then + # Looks like a MacOSX system + NUM_CORES=`/usr/sbin/sysctl -n hw.ncpu` +@@ -68,7 +65,7 @@ + MEMORY_SIZE=`expr $MEMORY_SIZE / 1024` + FOUND_MEM=yes + elif test -x /usr/sbin/prtconf; then +- # Looks like a Solaris or AIX system ++ # Looks like an AIX system + MEMORY_SIZE=`/usr/sbin/prtconf 2> /dev/null | grep "^Memory [[Ss]]ize" | awk '{ print [$]3 }'` + FOUND_MEM=yes + elif test -x /usr/sbin/sysctl; then +--- old/make/autoconf/flags-cflags.m4 2020-05-20 17:58:30.492355171 -0700 ++++ new/make/autoconf/flags-cflags.m4 2020-05-20 17:58:30.108347798 -0700 +@@ -492,9 +492,6 @@ + if test "x$OPENJDK_TARGET_OS" = xlinux; then + CFLAGS_OS_DEF_JVM="-DLINUX -D_FILE_OFFSET_BITS=64" + CFLAGS_OS_DEF_JDK="-D_GNU_SOURCE -D_REENTRANT -D_LARGEFILE64_SOURCE" +- elif test "x$OPENJDK_TARGET_OS" = xsolaris; then +- CFLAGS_OS_DEF_JVM="-DSOLARIS" +- CFLAGS_OS_DEF_JDK="-D__solaris__" + elif test "x$OPENJDK_TARGET_OS" = xmacosx; then + CFLAGS_OS_DEF_JVM="-D_ALLBSD_SOURCE -D_DARWIN_C_SOURCE -D_XOPEN_SOURCE" + CFLAGS_OS_DEF_JDK="-D_ALLBSD_SOURCE -D_DARWIN_UNLIMITED_SELECT" +--- old/make/autoconf/jdk-options.m4 2020-05-20 17:58:35.812457321 -0700 ++++ new/make/autoconf/jdk-options.m4 2020-05-20 17:58:35.432450025 -0700 +@@ -285,7 +285,7 @@ + ZIP_EXTERNAL_DEBUG_SYMBOLS=false + elif test "x$with_native_debug_symbols" = xexternal; then + +- if test "x$OPENJDK_TARGET_OS" = xsolaris || test "x$OPENJDK_TARGET_OS" = xlinux; then ++ if test "x$OPENJDK_TARGET_OS" = xlinux; then + if test "x$OBJCOPY" = x; then + # enabling of enable-debug-symbols and can't find objcopy + # this is an error +@@ -298,7 +298,7 @@ + ZIP_EXTERNAL_DEBUG_SYMBOLS=false + elif test "x$with_native_debug_symbols" = xzipped; then + +- if test "x$OPENJDK_TARGET_OS" = xsolaris || test "x$OPENJDK_TARGET_OS" = xlinux; then ++ if test "x$OPENJDK_TARGET_OS" = xlinux; then + if test "x$OBJCOPY" = x; then + # enabling of enable-debug-symbols and can't find objcopy + # this is an error +--- old/make/autoconf/lib-freetype.m4 2020-05-20 17:58:37.892497260 -0700 ++++ new/make/autoconf/lib-freetype.m4 2020-05-20 17:58:37.512489963 -0700 +@@ -53,13 +53,6 @@ + if ! test -s "$POTENTIAL_FREETYPE_LIB_PATH/$FREETYPE_LIB_NAME"; then + AC_MSG_NOTICE([Could not find $POTENTIAL_FREETYPE_LIB_PATH/$FREETYPE_LIB_NAME. Ignoring location.]) + FOUND_FREETYPE=no +- else +- if test "x$OPENJDK_TARGET_OS" = "xsolaris" \ +- && test -s "$POTENTIAL_FREETYPE_LIB_PATH$OPENJDK_TARGET_CPU_ISADIR/$FREETYPE_LIB_NAME"; then +- # Found lib in isa dir, use that instead. +- POTENTIAL_FREETYPE_LIB_PATH="$POTENTIAL_FREETYPE_LIB_PATH$OPENJDK_TARGET_CPU_ISADIR" +- AC_MSG_NOTICE([Rewriting to use $POTENTIAL_FREETYPE_LIB_PATH instead]) +- fi + fi + fi + +@@ -167,15 +160,6 @@ + if test "x$PKG_CONFIG" != "x" ; then + PKG_CHECK_MODULES(FREETYPE, freetype2, [FOUND_FREETYPE=yes], [FOUND_FREETYPE=no]) + if test "x$FOUND_FREETYPE" = "xyes" ; then +- # On solaris, pkg_check adds -lz to freetype libs, which isn't +- # necessary for us. +- FREETYPE_LIBS=`$ECHO $FREETYPE_LIBS | $SED 's/-lz//g'` +- # 64-bit libs for Solaris x86 are installed in the amd64 +- # subdirectory, change lib to lib/amd64 +- if test "x$OPENJDK_TARGET_OS" = "xsolaris" && \ +- test "x$OPENJDK_TARGET_CPU" = "xx86_64" ; then +- FREETYPE_LIBS=`$ECHO $FREETYPE_LIBS | $SED 's?/lib?/lib/amd64?g'` +- fi + AC_MSG_CHECKING([for freetype]) + AC_MSG_RESULT([yes (using pkg-config)]) + fi +--- old/make/autoconf/libraries.m4 2020-05-20 17:58:41.188560546 -0700 ++++ new/make/autoconf/libraries.m4 2020-05-20 17:58:40.768552482 -0700 +@@ -139,15 +139,13 @@ + BASIC_JVM_LIBS="$LIBM" + + # Dynamic loading library +- if test "x$OPENJDK_TARGET_OS" = xlinux || test "x$OPENJDK_TARGET_OS" = xsolaris || test "x$OPENJDK_TARGET_OS" = xaix; then ++ if test "x$OPENJDK_TARGET_OS" = xlinux || test "x$OPENJDK_TARGET_OS" = xaix; then + BASIC_JVM_LIBS="$BASIC_JVM_LIBS $LIBDL" + fi + + # Threading library + if test "x$OPENJDK_TARGET_OS" = xlinux || test "x$OPENJDK_TARGET_OS" = xaix; then + BASIC_JVM_LIBS="$BASIC_JVM_LIBS -lpthread" +- elif test "x$OPENJDK_TARGET_OS" = xsolaris; then +- BASIC_JVM_LIBS="$BASIC_JVM_LIBS -lthread" + fi + + # librt for legacy clock_gettime +@@ -164,12 +162,6 @@ + BASIC_JVM_LIBS="$BASIC_JVM_LIBS -lperfstat" + fi + +- if test "x$OPENJDK_TARGET_OS" = xsolaris; then +- BASIC_JVM_LIBS="$BASIC_JVM_LIBS -lsocket -lsched -ldoor -lnsl \ +- -lrt -lkstat" +- BASIC_JVM_LIBS="$BASIC_JVM_LIBS $LIBCXX_JVM" +- fi +- + if test "x$OPENJDK_TARGET_OS" = xwindows; then + BASIC_JVM_LIBS="$BASIC_JVM_LIBS kernel32.lib user32.lib gdi32.lib winspool.lib \ + comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib powrprof.lib uuid.lib \ +--- old/make/autoconf/platform.m4 2020-05-20 17:58:42.328582435 -0700 ++++ new/make/autoconf/platform.m4 2020-05-20 17:58:41.904574294 -0700 +@@ -202,10 +202,6 @@ + VAR_OS=linux + VAR_OS_TYPE=unix + ;; +- *solaris*) +- VAR_OS=solaris +- VAR_OS_TYPE=unix +- ;; + *darwin*) + VAR_OS=macosx + VAR_OS_TYPE=unix +@@ -476,17 +472,6 @@ + fi + AC_SUBST(OPENJDK_$1_CPU_LEGACY_LIB) + +- # OPENJDK_$1_CPU_ISADIR is normally empty. On 64-bit Solaris systems, it is set to +- # /amd64 or /sparcv9. This string is appended to some library paths, like this: +- # /usr/lib${OPENJDK_$1_CPU_ISADIR}/libexample.so +- OPENJDK_$1_CPU_ISADIR="" +- if test "x$OPENJDK_$1_OS" = xsolaris; then +- if test "x$OPENJDK_$1_CPU" = xx86_64; then +- OPENJDK_$1_CPU_ISADIR="/amd64" +- fi +- fi +- AC_SUBST(OPENJDK_$1_CPU_ISADIR) +- + # Setup OPENJDK_$1_CPU_OSARCH, which is used to set the os.arch Java system property + OPENJDK_$1_CPU_OSARCH="$OPENJDK_$1_CPU" + if test "x$OPENJDK_$1_OS" = xlinux && test "x$OPENJDK_$1_CPU" = xx86; then +@@ -618,9 +603,6 @@ + + AC_DEFUN([PLATFORM_SET_RELEASE_FILE_OS_VALUES], + [ +- if test "x$OPENJDK_TARGET_OS" = "xsolaris"; then +- RELEASE_FILE_OS_NAME=SunOS +- fi + if test "x$OPENJDK_TARGET_OS" = "xlinux"; then + RELEASE_FILE_OS_NAME=Linux + fi +--- old/make/autoconf/spec.gmk.in 2020-05-20 17:58:43.488604709 -0700 ++++ new/make/autoconf/spec.gmk.in 2020-05-20 17:58:43.064596567 -0700 +@@ -93,7 +93,6 @@ + COMPILE_TYPE:=@COMPILE_TYPE@ + + # Legacy support +-OPENJDK_TARGET_CPU_ISADIR:=@OPENJDK_TARGET_CPU_ISADIR@ + OPENJDK_TARGET_CPU_LEGACY:=@OPENJDK_TARGET_CPU_LEGACY@ + OPENJDK_TARGET_CPU_LEGACY_LIB:=@OPENJDK_TARGET_CPU_LEGACY_LIB@ + OPENJDK_TARGET_CPU_OSARCH:=@OPENJDK_TARGET_CPU_OSARCH@ +--- old/make/autoconf/toolchain.m4 2020-05-20 17:58:44.612626291 -0700 ++++ new/make/autoconf/toolchain.m4 2020-05-20 17:58:44.216618687 -0700 +@@ -39,7 +39,6 @@ + + # These toolchains are valid on different platforms + VALID_TOOLCHAINS_linux="gcc clang" +-VALID_TOOLCHAINS_solaris="gcc" + VALID_TOOLCHAINS_macosx="clang" + VALID_TOOLCHAINS_aix="xlc clang" + VALID_TOOLCHAINS_windows="microsoft" +--- old/make/common/MakeBase.gmk 2020-05-20 17:58:45.708647335 -0700 ++++ new/make/common/MakeBase.gmk 2020-05-20 17:58:45.324639962 -0700 +@@ -267,33 +267,7 @@ + ################################################################################ + # All install-file and related macros automatically call DecodeSpace when needed. + +-ifeq ($(call isTargetOs, solaris), true) +- # On Solaris, if the target is a symlink and exists, cp won't overwrite. +- # Cp has to operate in recursive mode to allow for -P flag, to preserve soft links. If the +- # name of the target file differs from the source file, rename after copy. +- # If the source and target parent directories are the same, recursive copy doesn't work +- # so we fall back on regular copy, which isn't preserving symlinks. +- define install-file +- $(call MakeTargetDir) +- $(RM) '$(call DecodeSpace, $@)' +- if [ '$(call DecodeSpace, $(dir $(call EncodeSpace, $@)))' != \ +- '$(call DecodeSpace, $(dir $(call EncodeSpace, $<)))' ]; then \ +- $(CP) -f -r -P '$(call DecodeSpace, $<)' \ +- '$(call DecodeSpace, $(dir $(call EncodeSpace, $@)))'; \ +- if [ '$(call DecodeSpace, $(notdir $(call EncodeSpace, $@)))' != \ +- '$(call DecodeSpace, $(notdir $(call EncodeSpace, $(<))))' ]; then \ +- $(MV) '$(call DecodeSpace, $(dir $(call EncodeSpace, $@))/$(notdir $(call EncodeSpace, $<)))' \ +- '$(call DecodeSpace, $@)'; \ +- fi; \ +- else \ +- if [ -L '$(call DecodeSpace, $<)' ]; then \ +- $(ECHO) "Source file is a symlink and target is in the same directory: $< $@" ; \ +- exit 1; \ +- fi; \ +- $(CP) -f '$(call DecodeSpace, $<)' '$(call DecodeSpace, $@)'; \ +- fi +- endef +-else ifeq ($(call isTargetOs, macosx), true) ++ifeq ($(call isTargetOs, macosx), true) + # On mac, extended attributes sometimes creep into the source files, which may later + # cause the creation of ._* files which confuses testing. Clear these with xattr if + # set. Some files get their write permissions removed after being copied to the +--- old/make/common/NativeCompilation.gmk 2020-05-20 17:58:47.780687120 -0700 ++++ new/make/common/NativeCompilation.gmk 2020-05-20 17:58:47.440680591 -0700 +@@ -1058,7 +1058,7 @@ + $1_DEBUGINFO_FILES := $$($1_SYMBOLS_DIR)/$$($1_BASENAME).pdb \ + $$($1_SYMBOLS_DIR)/$$($1_BASENAME).map + +- else ifeq ($(call isTargetOs, linux solaris), true) ++ else ifeq ($(call isTargetOs, linux), true) + $1_DEBUGINFO_FILES := $$($1_SYMBOLS_DIR)/$$($1_NOSUFFIX).debuginfo + # Setup the command line creating debuginfo files, to be run after linking. + # It cannot be run separately since it updates the original target file +--- old/make/common/modules/LauncherCommon.gmk 2020-05-20 17:58:50.820745492 -0700 ++++ new/make/common/modules/LauncherCommon.gmk 2020-05-20 17:58:50.488739117 -0700 +@@ -163,7 +163,6 @@ + -DLAUNCHER_NAME='"$$(LAUNCHER_NAME)"' \ + -DPROGNAME='"$1"' \ + $$($1_CFLAGS), \ +- CFLAGS_solaris := -fPIC, \ + CFLAGS_windows := $$($1_CFLAGS_windows), \ + DISABLED_WARNINGS_gcc := unused-function, \ + LDFLAGS := $$(LDFLAGS_JDKEXE) \ +@@ -173,14 +172,11 @@ + -L$(call FindLibDirForModule, java.base), \ + LDFLAGS_macosx := $$(call SET_EXECUTABLE_ORIGIN,/../lib) \ + -L$(call FindLibDirForModule, java.base), \ +- LDFLAGS_solaris := $$(call SET_EXECUTABLE_ORIGIN,/../lib) \ +- -L$(call FindLibDirForModule, java.base), \ + LDFLAGS_aix := -L$(SUPPORT_OUTPUTDIR)/native/java.base, \ + LIBS := $(JDKEXE_LIBS) $$($1_LIBS), \ + LIBS_linux := -ljli -lpthread $(LIBDL), \ + LIBS_macosx := -ljli -framework Cocoa -framework Security \ + -framework ApplicationServices, \ +- LIBS_solaris := -ljli -lthread $(LIBDL), \ + LIBS_aix := -ljli_static, \ + LIBS_windows := $$($1_WINDOWS_JLI_LIB) \ + $(SUPPORT_OUTPUTDIR)/native/java.base/libjava/java.lib, \ +--- old/make/hotspot/gensrc/GensrcAdlc.gmk 2020-05-20 17:58:54.036807242 -0700 ++++ new/make/hotspot/gensrc/GensrcAdlc.gmk 2020-05-20 17:58:53.652799869 -0700 +@@ -36,9 +36,6 @@ + # NOTE: No optimization or debug flags set here + ifeq ($(call isBuildOs, linux), true) + ADLC_CFLAGS := -fno-exceptions -DLINUX +- else ifeq ($(call isBuildOs, solaris), true) +- ADLC_LDFLAGS := -m64 +- ADLC_CFLAGS := -m64 -fpermissive + else ifeq ($(call isBuildOs, aix), true) + ifeq ($(TOOLCHAIN_TYPE), clang) + ADLC_LDFLAGS += -m64 +@@ -98,8 +95,6 @@ + # ADLC flags depending on target OS + ifeq ($(call isTargetOs, linux), true) + ADLCFLAGS += -DLINUX=1 -D_GNU_SOURCE=1 +- else ifeq ($(call isTargetOs, solaris), true) +- ADLCFLAGS += -DSOLARIS=1 + else ifeq ($(call isTargetOs, aix), true) + ADLCFLAGS += -DAIX=1 + else ifeq ($(call isTargetOs, macosx), true) +--- old/make/hotspot/gensrc/GensrcDtrace.gmk 2020-05-20 17:58:55.056826827 -0700 ++++ new/make/hotspot/gensrc/GensrcDtrace.gmk 2020-05-20 17:58:54.720820376 -0700 +@@ -28,10 +28,7 @@ + + ifeq ($(call check-jvm-feature, dtrace), true) + +- ifeq ($(call isTargetOs, solaris), true) +- DTRACE_FLAGS := -64 +- DTRACE_CPP_FLAGS := -D_LP64 -x c +- else ifeq ($(call isTargetOs, macosx), true) ++ ifeq ($(call isTargetOs, macosx), true) + DTRACE_CPP_FLAGS := -D_LP64 -x c + else ifeq ($(call isTargetOs, linux), true) + DTRACE_CPP_FLAGS := -x c +@@ -54,59 +51,4 @@ + TARGETS += $(patsubst $(DTRACE_SOURCE_DIR)/%.d, \ + $(DTRACE_GENSRC_DIR)/%.h, $(wildcard $(DTRACE_SOURCE_DIR)/*.d)) + +- ifeq ($(call isTargetOs, solaris), true) +- ############################################################################ +- # First we need to generate the dtraceGenOffsets tool. When run, this will +- # produce two header files and a C++ file. Note that generateJvmOffsets.cpp +- # is using the same JVM_CFLAGS as libjvm.so. +- +- # Include support files that will setup JVM compiler flags. +- include lib/JvmFeatures.gmk +- include lib/JvmFlags.gmk +- +- # We cannot compile until the JVMTI and JFR gensrc has finished. +- # JFR_FILES is defined in GensrcJfr.gmk. +- JVMTI_H := $(JVM_VARIANT_OUTPUTDIR)/gensrc/jvmtifiles/jvmti.h +- +- $(eval $(call SetupNativeCompilation, BUILD_DTRACE_GEN_OFFSETS, \ +- NAME := dtraceGenOffsets, \ +- TYPE := EXECUTABLE, \ +- SRC := $(TOPDIR)/make/hotspot/src/native/dtrace, \ +- TOOLCHAIN := $(TOOLCHAIN_BUILD), \ +- LDFLAGS := -m64, \ +- CFLAGS := -m64 $(JVM_CFLAGS), \ +- EXTRA_DEPS := $(JVMTI_H) $(JFR_FILES), \ +- OBJECT_DIR := $(JVM_VARIANT_OUTPUTDIR)/tools/dtrace-gen-offsets/objs, \ +- OUTPUT_DIR := $(JVM_VARIANT_OUTPUTDIR)/tools/dtrace-gen-offsets, \ +- )) +- +- DTRACE_GEN_OFFSETS_TOOL := $(BUILD_DTRACE_GEN_OFFSETS_TARGET) +- +- # Argument 1: Output filename +- # Argument 2: dtrace-gen-offset tool command line option +- define SetupDtraceOffsetsGeneration +- $$(eval $$(call SetupExecute, dtrace_offset_$$(strip $2), \ +- INFO := Generating dtrace $2 file, \ +- DEPS := $$(BUILD_DTRACE_GEN_OFFSETS), \ +- OUTPUT_FILE := $1, \ +- COMMAND := ( $$(DTRACE_GEN_OFFSETS_TOOL) -$$(strip $2) > $1 ), \ +- )) +- +- TARGETS += $$(dtrace_offset_$$(strip $2)_TARGET) +- endef +- +- JVM_OFFSETS_H := $(DTRACE_GENSRC_DIR)/JvmOffsets.h +- JVM_OFFSETS_CPP := $(DTRACE_GENSRC_DIR)/JvmOffsets.cpp +- JVM_OFFSETS_INDEX_H := $(DTRACE_GENSRC_DIR)/JvmOffsetsIndex.h +- +- ############################################################################ +- # Run the dtrace-gen-offset tool to generate these three files. +- # The generated JvmOffsets.cpp is compiled with the rest of libjvm. +- # The header files are used by libjvm_db and jhelper.d, respectively. +- +- $(eval $(call SetupDtraceOffsetsGeneration, $(JVM_OFFSETS_H), header)) +- $(eval $(call SetupDtraceOffsetsGeneration, $(JVM_OFFSETS_INDEX_H), index)) +- $(eval $(call SetupDtraceOffsetsGeneration, $(JVM_OFFSETS_CPP), table)) +- endif +- + endif +--- old/make/hotspot/lib/CompileJvm.gmk 2020-05-20 17:58:57.164867303 -0700 ++++ new/make/hotspot/lib/CompileJvm.gmk 2020-05-20 17:58:56.788860083 -0700 +@@ -29,9 +29,6 @@ + include lib/JvmOverrideFiles.gmk + include lib/JvmFlags.gmk + +-# Include support files that will setup DTRACE_EXTRA_OBJECT_FILES. +-include lib/JvmDtraceObjects.gmk +- + ################################################################################ + # Setup compilation of the main Hotspot native library (libjvm). + +@@ -153,7 +150,6 @@ + EXCLUDES := $(JVM_EXCLUDES), \ + EXCLUDE_FILES := $(JVM_EXCLUDE_FILES), \ + EXCLUDE_PATTERNS := $(JVM_EXCLUDE_PATTERNS), \ +- EXTRA_OBJECT_FILES := $(DTRACE_EXTRA_OBJECT_FILES), \ + CFLAGS := $(JVM_CFLAGS), \ + abstract_vm_version.cpp_CXXFLAGS := $(CFLAGS_VM_VERSION), \ + arguments.cpp_CXXFLAGS := $(CFLAGS_VM_VERSION), \ +--- old/make/hotspot/lib/CompileLibraries.gmk 2020-05-20 17:58:58.224887656 -0700 ++++ new/make/hotspot/lib/CompileLibraries.gmk 2020-05-20 17:58:57.836880206 -0700 +@@ -32,7 +32,6 @@ + include HotspotCommon.gmk + + include lib/CompileJvm.gmk +-include lib/CompileDtraceLibraries.gmk + + ifneq ($(GTEST_FRAMEWORK_SRC), ) + ifneq ($(CREATING_BUILDJDK), true) +--- old/make/hotspot/lib/JvmMapfile.gmk 2020-05-20 17:59:00.372928900 -0700 ++++ new/make/hotspot/lib/JvmMapfile.gmk 2020-05-20 17:58:59.980921373 -0700 +@@ -48,18 +48,6 @@ + endif + endif + +-ifeq ($(call isTargetOs, solaris), true) +- ifeq ($(call check-jvm-feature, dtrace), true) +- # Additional mapfiles that are only used when dtrace is enabled +- ifeq ($(call check-jvm-feature, compiler2), true) +- # This also covers the case of compiler1+compiler2. +- SYMBOLS_SRC += $(TOPDIR)/make/hotspot/symbols/symbols-solaris-dtrace-compiler2 +- else ifeq ($(call check-jvm-feature, compiler1), true) +- SYMBOLS_SRC += $(TOPDIR)/make/hotspot/symbols/symbols-solaris-dtrace-compiler1 +- endif +- endif +-endif +- + ################################################################################ + # Create a dynamic list of symbols from the built object files. This is highly + # platform dependent. +@@ -76,20 +64,6 @@ + if ($$3 ~ /$(FILTER_SYMBOLS_PATTERN)/) print $$3; \ + }' + +-else ifeq ($(call isTargetOs, solaris), true) +- DUMP_SYMBOLS_CMD := $(NM) -p *.o +- ifneq ($(FILTER_SYMBOLS_PATTERN), ) +- FILTER_SYMBOLS_PATTERN := $(FILTER_SYMBOLS_PATTERN)| +- endif +- FILTER_SYMBOLS_PATTERN := $(FILTER_SYMBOLS_PATTERN)^__1c.*__vtbl_$$|^gHotSpotVM +- FILTER_SYMBOLS_PATTERN := $(FILTER_SYMBOLS_PATTERN)|^UseSharedSpaces$$ +- FILTER_SYMBOLS_PATTERN := $(FILTER_SYMBOLS_PATTERN)|^__1cJArgumentsRSharedArchivePath_$$ +- FILTER_SYMBOLS_AWK_SCRIPT := \ +- '{ \ +- if ($$2 == "U") next; \ +- if ($$3 ~ /$(FILTER_SYMBOLS_PATTERN)/) print $$3; \ +- }' +- + else ifeq ($(call isTargetOs, macosx), true) + # nm on macosx prints out "warning: nm: no name list" to stderr for + # files without symbols. Hide this, even at the expense of hiding real errors. +--- old/make/ide/visualstudio/hotspot/CreateVSProject.gmk 2020-05-20 17:59:05.797033047 -0700 ++++ new/make/ide/visualstudio/hotspot/CreateVSProject.gmk 2020-05-20 17:59:05.409025597 -0700 +@@ -76,7 +76,6 @@ + -ignorePath linux \ + -ignorePath posix \ + -ignorePath ppc \ +- -ignorePath solaris \ + -ignorePath x86_32 \ + -ignorePath zero \ + # +--- old/make/langtools/build.xml 2020-05-20 17:59:06.849053246 -0700 ++++ new/make/langtools/build.xml 2020-05-20 17:59:06.465045873 -0700 +@@ -100,7 +100,7 @@ + + + + + +--- old/make/modules/java.base/Copy.gmk 2020-05-20 17:59:07.941074214 -0700 ++++ new/make/modules/java.base/Copy.gmk 2020-05-20 17:59:07.553066764 -0700 +@@ -190,7 +190,7 @@ + + TARGETS += $(NET_PROPERTIES_DST) + +-ifeq ($(call isTargetOs, solaris linux), true) ++ifeq ($(call isTargetOs, linux), true) + $(eval $(call SetupCopyFiles, COPY_SDP_CONF, \ + FILES := $(TOPDIR)/src/java.base/$(OPENJDK_TARGET_OS_TYPE)/conf/sdp/sdp.conf.template, \ + DEST := $(CONF_DST_DIR)/sdp, \ +--- old/make/modules/java.base/Launcher.gmk 2020-05-20 17:59:09.001094567 -0700 ++++ new/make/modules/java.base/Launcher.gmk 2020-05-20 17:59:08.617087194 -0700 +@@ -64,7 +64,6 @@ + CFLAGS := $(CFLAGS_JDKEXE) \ + -I$(TOPDIR)/src/$(MODULE)/share/native/libjli, \ + CFLAGS_linux := -fPIC, \ +- CFLAGS_solaris := -KPIC, \ + LDFLAGS := $(LDFLAGS_JDKEXE), \ + OUTPUT_DIR := $(SUPPORT_OUTPUTDIR)/modules_libs/$(MODULE), \ + )) +@@ -74,7 +73,7 @@ + + ################################################################################ + +-ifeq ($(call isTargetOs, macosx solaris aix linux), true) ++ifeq ($(call isTargetOs, macosx aix linux), true) + $(eval $(call SetupJdkExecutable, BUILD_JSPAWNHELPER, \ + NAME := jspawnhelper, \ + SRC := $(TOPDIR)/src/$(MODULE)/unix/native/jspawnhelper, \ +--- old/make/modules/java.base/Lib.gmk 2020-05-20 17:59:10.037114459 -0700 ++++ new/make/modules/java.base/Lib.gmk 2020-05-20 17:59:09.661107240 -0700 +@@ -55,7 +55,6 @@ + LDFLAGS_windows := -delayload:secur32.dll -delayload:iphlpapi.dll, \ + LIBS_unix := -ljvm -ljava, \ + LIBS_linux := $(LIBDL), \ +- LIBS_solaris := -lnsl -lsocket $(LIBDL), \ + LIBS_aix := $(LIBDL),\ + LIBS_windows := ws2_32.lib jvm.lib secur32.lib iphlpapi.lib winhttp.lib \ + delayimp.lib $(WIN_JAVA_LIB) advapi32.lib, \ +@@ -82,8 +81,6 @@ + $(call SET_SHARED_LIBRARY_ORIGIN), \ + LIBS_unix := -ljava -lnet, \ + LIBS_linux := -lpthread $(LIBDL), \ +- LIBS_solaris := -ljvm -lsocket -lposix4 $(LIBDL) \ +- -lsendfile, \ + LIBS_aix := $(LIBDL), \ + LIBS_macosx := \ + -framework CoreFoundation -framework CoreServices, \ +@@ -136,7 +133,6 @@ + LDFLAGS := $(LDFLAGS_JDKLIB) \ + $(call SET_SHARED_LIBRARY_ORIGIN), \ + LIBS_linux := $(LIBDL), \ +- LIBS_solaris := $(LIBDL), \ + LIBS_aix := $(LIBDL), \ + )) + +--- old/make/modules/java.base/gensrc/GensrcMisc.gmk 2020-05-20 17:59:11.161136042 -0700 ++++ new/make/modules/java.base/gensrc/GensrcMisc.gmk 2020-05-20 17:59:10.769128515 -0700 +@@ -136,21 +136,6 @@ + + endif + +-################################################################################ +- +-ifeq ($(call isTargetOs, solaris), true) +- +- GENSRC_SC_FILE := $(SUPPORT_OUTPUTDIR)/gensrc/java.base/sun/nio/fs/SolarisConstants.java +- +- $(GENSRC_SC_FILE): \ +- $(TOPDIR)/src/java.base/solaris/classes/sun/nio/fs/SolarisConstants.java.template +- $(generate-preproc-src) +- +- TARGETS += $(GENSRC_SC_FILE) +- +-endif +- +-################################################################################ + # Create the javax/crypto/JceSecurity.class, using the build default. + # + ifeq ($(UNLIMITED_CRYPTO), true) +--- old/make/modules/java.base/lib/CoreLibraries.gmk 2020-05-20 17:59:12.217156318 -0700 ++++ new/make/modules/java.base/lib/CoreLibraries.gmk 2020-05-20 17:59:11.829148868 -0700 +@@ -26,7 +26,7 @@ + ########################################################################################## + + LIBVERIFY_OPTIMIZATION := HIGH +-ifeq ($(call isTargetOs, solaris linux), true) ++ifeq ($(call isTargetOs, linux), true) + ifeq ($(COMPILE_WITH_DEBUG_SYMBOLS), true) + LIBVERIFY_OPTIMIZATION := LOW + endif +@@ -68,7 +68,6 @@ + LDFLAGS_windows := -delayload:shell32.dll, \ + LIBS_unix := -ljvm, \ + LIBS_linux := $(LIBDL), \ +- LIBS_solaris := -lsocket -lnsl -lscf $(LIBDL), \ + LIBS_aix := $(LIBDL) $(LIBM),\ + LIBS_macosx := -framework CoreFoundation \ + -framework Foundation \ +@@ -179,7 +178,6 @@ + $(call SET_SHARED_LIBRARY_ORIGIN), \ + LIBS_unix := $(LIBZ_LIBS), \ + LIBS_linux := $(LIBDL) -lpthread, \ +- LIBS_solaris := $(LIBDL), \ + LIBS_aix := $(LIBDL),\ + LIBS_macosx := -framework Cocoa -framework Security -framework ApplicationServices, \ + LIBS_windows := advapi32.lib comctl32.lib user32.lib, \ +--- old/make/modules/java.desktop/Gensrc.gmk 2020-05-20 17:59:13.277176671 -0700 ++++ new/make/modules/java.desktop/Gensrc.gmk 2020-05-20 17:59:12.889169221 -0700 +@@ -32,7 +32,7 @@ + include gensrc/GensrcIcons.gmk + endif + +-ifeq ($(call isTargetOs, linux solaris aix), true) ++ifeq ($(call isTargetOs, linux aix), true) + include gensrc/GensrcX11Wrappers.gmk + endif + +--- old/make/modules/java.desktop/Lib.gmk 2020-05-20 17:59:14.281195949 -0700 ++++ new/make/modules/java.desktop/Lib.gmk 2020-05-20 17:59:13.949189574 -0700 +@@ -47,15 +47,10 @@ + -DX_PLATFORM=X_$(OPENJDK_TARGET_OS_UPPERCASE) \ + -DUSE_PORTS=TRUE \ + -DUSE_DAUDIO=TRUE \ ++ -DUSE_PLATFORM_MIDI_OUT=TRUE \ ++ -DUSE_PLATFORM_MIDI_IN=TRUE \ + # + +- ifeq ($(call isTargetOs, solaris), false) +- LIBJSOUND_CFLAGS += \ +- -DUSE_PLATFORM_MIDI_OUT=TRUE \ +- -DUSE_PLATFORM_MIDI_IN=TRUE \ +- # +- endif +- + ifeq ($(call isTargetOs, macosx), true) + LIBJSOUND_TOOLCHAIN := TOOLCHAIN_LINK_CXX + endif +--- old/make/modules/java.desktop/lib/Awt2dLibraries.gmk 2020-05-20 17:59:15.341216302 -0700 ++++ new/make/modules/java.desktop/lib/Awt2dLibraries.gmk 2020-05-20 17:59:14.945208698 -0700 +@@ -77,7 +77,7 @@ + # + endif + +-ifeq ($(call isTargetOs, solaris linux macosx aix), true) ++ifeq ($(call isTargetOs, linux macosx aix), true) + LIBAWT_EXFILES += awt_Font.c CUPSfuncs.c fontpath.c X11Color.c + endif + +@@ -154,7 +154,6 @@ + -delayload:comctl32.dll -delayload:shlwapi.dll, \ + LIBS_unix := -ljvm -ljava $(LIBM), \ + LIBS_linux := $(LIBDL), \ +- LIBS_solaris := $(LIBDL), \ + LIBS_aix := $(LIBDL),\ + LIBS_macosx := -lmlib_image \ + -framework Cocoa \ +@@ -403,7 +402,6 @@ + LDFLAGS_unix := -L$(INSTALL_LIBRARIES_HERE), \ + LIBS_unix := -lawt -ljvm -ljava, \ + LIBS_linux := $(LIBM) $(LIBDL), \ +- LIBS_solaris := $(LIBM) $(LIBDL) $(LIBCXX), \ + )) + + $(BUILD_LIBAWT_HEADLESS): $(BUILD_LIBAWT) +@@ -461,7 +459,7 @@ + -DHAVE_SYSCONF -DHAVE_SYS_MMAN_H -DHAVE_UNISTD_H \ + -DHB_NO_PRAGMA_GCC_DIAGNOSTIC + endif ++ ifeq ($(call isTargetOs, linux macosx), true) +- ifeq ($(call isTargetOs, solaris linux macosx), true) + HARFBUZZ_CFLAGS += -DHAVE_INTEL_ATOMIC_PRIMITIVES -DHB_NO_VISIBILITY + endif + +@@ -635,10 +633,7 @@ + ifeq ($(call isTargetOs, macosx), true) + JAWT_LIBS := -lawt_lwawt + else +- JAWT_LIBS := +- ifeq ($(call isTargetOs, solaris), false) +- JAWT_LIBS += -lawt +- endif ++ JAWT_LIBS := -lawt + ifeq ($(ENABLE_HEADLESS_ONLY), false) + JAWT_LIBS += -lawt_xawt + else +@@ -665,7 +660,6 @@ + LDFLAGS_unix := -L$(INSTALL_LIBRARIES_HERE), \ + LDFLAGS_macosx := -Wl$(COMMA)-rpath$(COMMA)@loader_path, \ + LIBS_unix := $(JAWT_LIBS) $(JDKLIB_LIBS), \ +- LIBS_solaris := $(X_LIBS) -lXrender, \ + LIBS_macosx := -framework Cocoa, \ + )) + +--- old/make/modules/java.instrument/Lib.gmk 2020-05-20 17:59:16.469237961 -0700 ++++ new/make/modules/java.instrument/Lib.gmk 2020-05-20 17:59:16.081230511 -0700 +@@ -44,13 +44,11 @@ + $(call SET_SHARED_LIBRARY_ORIGIN) \ + $(LIBINSTRUMENT_LDFLAGS), \ + LDFLAGS_linux := -L$(call FindLibDirForModule, java.base), \ +- LDFLAGS_solaris := -L$(call FindLibDirForModule, java.base), \ + LDFLAGS_macosx := -L$(call FindLibDirForModule, java.base), \ + LDFLAGS_aix := -L$(SUPPORT_OUTPUTDIR)/native/java.base, \ + LIBS := $(JDKLIB_LIBS), \ + LIBS_unix := -ljava -ljvm $(LIBZ_LIBS), \ + LIBS_linux := -ljli $(LIBDL), \ +- LIBS_solaris := -ljli $(LIBDL), \ + LIBS_aix := -liconv -ljli_static $(LIBDL), \ + LIBS_macosx := -ljli -liconv -framework Cocoa -framework Security \ + -framework ApplicationServices, \ +--- old/make/modules/java.management/Lib.gmk 2020-05-20 17:59:17.481257392 -0700 ++++ new/make/modules/java.management/Lib.gmk 2020-05-20 17:59:17.145250941 -0700 +@@ -28,7 +28,7 @@ + ################################################################################ + + LIBMANAGEMENT_OPTIMIZATION := HIGH +-ifeq ($(call isTargetOs, solaris linux), true) ++ifeq ($(call isTargetOs, linux), true) + ifeq ($(COMPILE_WITH_DEBUG_SYMBOLS), true) + LIBMANAGEMENT_OPTIMIZATION := LOW + endif +@@ -41,7 +41,6 @@ + LDFLAGS := $(LDFLAGS_JDKLIB) \ + $(call SET_SHARED_LIBRARY_ORIGIN), \ + LIBS := $(JDKLIB_LIBS), \ +- LIBS_solaris := -lkstat, \ + LIBS_aix := -lperfstat,\ + LIBS_windows := jvm.lib psapi.lib $(WIN_JAVA_LIB) advapi32.lib, \ + )) +--- old/make/modules/java.prefs/Lib.gmk 2020-05-20 17:59:18.521277362 -0700 ++++ new/make/modules/java.prefs/Lib.gmk 2020-05-20 17:59:18.141270065 -0700 +@@ -41,7 +41,6 @@ + $(call SET_SHARED_LIBRARY_ORIGIN), \ + LIBS_unix := -ljvm, \ + LIBS_linux := -ljava, \ +- LIBS_solaris := -ljava, \ + LIBS_aix := -ljava, \ + LIBS_macosx := -framework CoreFoundation -framework Foundation, \ + LIBS_windows := advapi32.lib jvm.lib $(WIN_JAVA_LIB), \ +--- old/make/modules/jdk.attach/Lib.gmk 2020-05-20 17:59:20.593317146 -0700 ++++ new/make/modules/jdk.attach/Lib.gmk 2020-05-20 17:59:20.209309773 -0700 +@@ -42,7 +42,6 @@ + LDFLAGS := $(LDFLAGS_JDKLIB) \ + $(call SET_SHARED_LIBRARY_ORIGIN), \ + LIBS := $(JDKLIB_LIBS), \ +- LIBS_solaris := -ldoor, \ + LIBS_windows := $(WIN_JAVA_LIB) advapi32.lib psapi.lib, \ + )) + +--- old/make/modules/jdk.hotspot.agent/Lib.gmk 2020-05-20 17:59:21.653337499 -0700 ++++ new/make/modules/jdk.hotspot.agent/Lib.gmk 2020-05-20 17:59:21.257329896 -0700 +@@ -68,11 +68,10 @@ + CFLAGS := $(CFLAGS_JDKLIB) $(SA_CFLAGS), \ + CXXFLAGS := $(CXXFLAGS_JDKLIB) $(SA_CFLAGS) $(SA_CXXFLAGS), \ + EXTRA_SRC := $(LIBSA_EXTRA_SRC), \ +- LDFLAGS := $(LDFLAGS_JDKLIB) $(SA_LDFLAGS) $(call SET_SHARED_LIBRARY_ORIGIN), \ ++ LDFLAGS := $(LDFLAGS_JDKLIB) $(call SET_SHARED_LIBRARY_ORIGIN), \ + LIBS := $(LIBCXX), \ + LIBS_unix := -ljava, \ + LIBS_linux := $(LIBDL), \ +- LIBS_solaris := -ldl -lstdc++ -lthread -lproc, \ + LIBS_macosx := -framework Foundation \ + -framework JavaRuntimeSupport -framework Security -framework CoreFoundation, \ + LIBS_windows := dbgeng.lib $(WIN_JAVA_LIB), \ +--- old/make/modules/jdk.jdwp.agent/Lib.gmk 2020-05-20 17:59:23.709376977 -0700 ++++ new/make/modules/jdk.jdwp.agent/Lib.gmk 2020-05-20 17:59:23.321369527 -0700 +@@ -38,7 +38,6 @@ + LDFLAGS := $(LDFLAGS_JDKLIB) \ + $(call SET_SHARED_LIBRARY_ORIGIN), \ + LIBS_linux := -lpthread, \ +- LIBS_solaris := -lnsl -lsocket, \ + LIBS_windows := $(JDKLIB_LIBS) ws2_32.lib iphlpapi.lib, \ + )) + +@@ -66,7 +65,6 @@ + $(call SET_SHARED_LIBRARY_ORIGIN), \ + LIBS := $(JDKLIB_LIBS), \ + LIBS_linux := $(LIBDL), \ +- LIBS_solaris := $(LIBDL), \ + LIBS_macosx := -liconv, \ + LIBS_aix := -liconv, \ + )) +--- old/make/modules/jdk.management/Lib.gmk 2020-05-20 17:59:24.761397176 -0700 ++++ new/make/modules/jdk.management/Lib.gmk 2020-05-20 17:59:24.373389726 -0700 +@@ -35,7 +35,7 @@ + endif + + LIBMANAGEMENT_EXT_OPTIMIZATION := HIGH +-ifeq ($(call isTargetOs, solaris linux), true) ++ifeq ($(call isTargetOs, linux), true) + ifeq ($(COMPILE_WITH_DEBUG_SYMBOLS), true) + LIBMANAGEMENT_EXT_OPTIMIZATION := LOW + endif +@@ -49,7 +49,6 @@ + LDFLAGS := $(LDFLAGS_JDKLIB) \ + $(call SET_SHARED_LIBRARY_ORIGIN), \ + LIBS := $(JDKLIB_LIBS), \ +- LIBS_solaris := -lkstat, \ + LIBS_aix := -lperfstat,\ + LIBS_windows := jvm.lib psapi.lib $(WIN_JAVA_LIB) advapi32.lib, \ + )) +--- old/make/modules/jdk.net/Lib.gmk 2020-05-20 17:59:25.877418605 -0700 ++++ new/make/modules/jdk.net/Lib.gmk 2020-05-20 17:59:25.493411232 -0700 +@@ -36,7 +36,6 @@ + LDFLAGS := $(LDFLAGS_JDKLIB) \ + $(call SET_SHARED_LIBRARY_ORIGIN), \ + LIBS_unix := -ljava, \ +- LIBS_solaris := -lsocket, \ + LIBS_linux := -ljvm, \ + LIBS_windows := jvm.lib ws2_32.lib $(WIN_JAVA_LIB), \ + )) +--- old/make/modules/jdk.sctp/Lib.gmk 2020-05-20 17:59:26.921438651 -0700 ++++ new/make/modules/jdk.sctp/Lib.gmk 2020-05-20 17:59:26.541431354 -0700 +@@ -42,7 +42,6 @@ + $(call SET_SHARED_LIBRARY_ORIGIN), \ + LIBS_unix := -lnio -lnet -ljava -ljvm, \ + LIBS_linux := -lpthread $(LIBDL), \ +- LIBS_solaris := -lsocket, \ + )) + + TARGETS += $(BUILD_LIBSCTP) +--- old/make/scripts/compare.sh 2020-05-20 17:59:27.985459081 -0700 ++++ new/make/scripts/compare.sh 2020-05-20 17:59:27.597451631 -0700 +@@ -73,14 +73,7 @@ + # Disassembly diff filters. These filters try to filter out ephemeral parts of the + # disassembly, such as hard-coded addresses, to be able to catch "actual" differences. + +-if [ "$OPENJDK_TARGET_OS" = "solaris" ]; then +- if [ "$OPENJDK_TARGET_CPU" = "x86_64" ]; then +- # Random strings looking like this differ: <.XAKoKoPIac2W0OA. +- DIS_DIFF_FILTER="$SED \ +- -e 's/<\.[A-Za-z0-9]\{\15}\./<.SYM./' \ +- " +- fi +-elif [ "$OPENJDK_TARGET_OS" = "windows" ]; then ++if [ "$OPENJDK_TARGET_OS" = "windows" ]; then + if [ "$OPENJDK_TARGET_CPU" = "x86" ]; then + DIS_DIFF_FILTER="$SED -r \ + -e 's/^ [0-9A-F]{16}: //' \ +@@ -447,14 +440,7 @@ + fi + + CONTENTS_DIFF_FILE=$WORK_DIR/$ZIP_FILE.diff +- # On solaris, there is no -q option. +- if [ "$OPENJDK_TARGET_OS" = "solaris" ]; then +- $DIFF -r $OTHER_UNZIPDIR $THIS_UNZIPDIR \ +- | $GREP -v -e "^<" -e "^>" -e "^Common subdirectories:" \ +- > $CONTENTS_DIFF_FILE +- else +- $DIFF -rq $OTHER_UNZIPDIR $THIS_UNZIPDIR > $CONTENTS_DIFF_FILE +- fi ++ $DIFF -rq $OTHER_UNZIPDIR $THIS_UNZIPDIR > $CONTENTS_DIFF_FILE + + ONLY_OTHER=$($GREP "^Only in $OTHER_UNZIPDIR" $CONTENTS_DIFF_FILE) + ONLY_THIS=$($GREP "^Only in $THIS_UNZIPDIR" $CONTENTS_DIFF_FILE) +@@ -474,14 +460,8 @@ + fi + + if [ "$CMP_ZIPS_CONTENTS" = "true" ]; then +- if [ "$OPENJDK_TARGET_OS" = "solaris" ]; then +- DIFFING_FILES=$($GREP -e 'differ$' -e '^diff ' $CONTENTS_DIFF_FILE \ +- | $SED -e 's/^Files //g' -e 's/diff -r //g' | $CUT -f 1 -d ' ' \ +- | $SED "s|$OTHER_UNZIPDIR/||g") +- else +- DIFFING_FILES=$($GREP -e "differ$" $CONTENTS_DIFF_FILE \ +- | $CUT -f 2 -d ' ' | $SED "s|$OTHER_UNZIPDIR/||g") +- fi ++ DIFFING_FILES=$($GREP -e "differ$" $CONTENTS_DIFF_FILE \ ++ | $CUT -f 2 -d ' ' | $SED "s|$OTHER_UNZIPDIR/||g") + + # Separate executable/library files from other files in zip. + DIFFING_TEXT_FILES= +@@ -826,10 +806,6 @@ + # to filter out that extra information. + $DUMPBIN -exports $OTHER_FILE | $GREP -E '^ +[0-9A-F]+ +[0-9A-F]+ [0-9A-F]+' | sed 's/ = .*//g' | cut -c27- | $SYM_SORT_CMD > $WORK_FILE_BASE.symbols.other + $DUMPBIN -exports $THIS_FILE | $GREP -E '^ +[0-9A-F]+ +[0-9A-F]+ [0-9A-F]+' | sed 's/ = .*//g' | cut -c27- | $SYM_SORT_CMD > $WORK_FILE_BASE.symbols.this +- elif [ "$OPENJDK_TARGET_OS" = "solaris" ]; then +- # Some symbols get seemingly random 15 character prefixes. Filter them out. +- $NM -a $ORIG_OTHER_FILE 2> /dev/null | $GREP -v $NAME | $AWK '{print $2, $3, $4, $5}' | $SED 's/^\([a-zA-Z] [\.\$]\)[a-zA-Z0-9_\$]\{15,15\}\./\1./g' | $SYM_SORT_CMD > $WORK_FILE_BASE.symbols.other +- $NM -a $ORIG_THIS_FILE 2> /dev/null | $GREP -v $NAME | $AWK '{print $2, $3, $4, $5}' | $SED 's/^\([a-zA-Z] [\.\$]\)[a-zA-Z0-9_\$]\{15,15\}\./\1./g' | $SYM_SORT_CMD > $WORK_FILE_BASE.symbols.this + elif [ "$OPENJDK_TARGET_OS" = "aix" ]; then + $OBJDUMP -T $ORIG_OTHER_FILE 2> /dev/null | $GREP -v $NAME | $AWK '{print $2, $3, $4, $5}' | $SYM_SORT_CMD > $WORK_FILE_BASE.symbols.other + $OBJDUMP -T $ORIG_THIS_FILE 2> /dev/null | $GREP -v $NAME | $AWK '{print $2, $3, $4, $5}' | $SYM_SORT_CMD > $WORK_FILE_BASE.symbols.this +--- old/make/scripts/compare_exceptions.sh.incl 2020-05-20 17:59:29.057479665 -0700 ++++ new/make/scripts/compare_exceptions.sh.incl 2020-05-20 17:59:28.665472137 -0700 +@@ -45,20 +45,6 @@ + ./hotspot/gtest/server/libjvm.so + " + fi +-elif [ "$OPENJDK_TARGET_OS" = "solaris" ]; then +- SKIP_BIN_DIFF="true" +- SKIP_FULLDUMP_DIFF="true" +- MAX_KNOWN_DIS_DIFF_SIZE="3000" +- SORT_SYMBOLS=" +- ./lib/libfontmanager.so +- ./lib/libjimage.so +- ./lib/server/libjvm.so +- ./hotspot/gtest/server/libjvm.so +- " +- KNOWN_DIS_DIFF=" +- ./lib/libfontmanager.so +- " +- STRIP_TESTS_BEFORE_COMPARE="true" + elif [ "$OPENJDK_TARGET_OS" = "windows" ]; then + SKIP_BIN_DIFF="true" + SKIP_FULLDUMP_DIFF="true" +--- old/make/scripts/hide_important_warnings_from_javac.sh 2020-05-20 17:59:30.069499096 -0700 ++++ new/make/scripts/hide_important_warnings_from_javac.sh 2020-05-20 17:59:29.733492644 -0700 +@@ -22,13 +22,8 @@ + # questions. + # + +-if [ -x /usr/bin/ggrep ] ; then +- # Gnu grep on Solaris +- # (reference configure and build/solaris-i586-clientANDserver-release/spec.gmk +- GREP=/usr/bin/ggrep +-else +- GREP=grep +-fi ++GREP=grep ++ + # + EXP="Note: Some input files use or override a deprecated API." + EXP="${EXP}|Note: Recompile with -Xlint:deprecation for details." +--- old/make/test/JtregNativeHotspot.gmk 2020-05-20 17:59:33.301561154 -0700 ++++ new/make/test/JtregNativeHotspot.gmk 2020-05-20 17:59:32.909553627 -0700 +@@ -865,10 +865,6 @@ + + BUILD_HOTSPOT_JTREG_EXECUTABLES_LIBS_exesigtest := -ljvm + +-ifeq ($(call isTargetOs, solaris), true) +- BUILD_HOTSPOT_JTREG_EXCLUDE += libterminatedThread.c +-endif +- + ifeq ($(call isTargetOs, windows), true) + BUILD_HOTSPOT_JTREG_EXECUTABLES_CFLAGS_exeFPRegs := -MT + BUILD_HOTSPOT_JTREG_EXCLUDE += exesigtest.c libterminatedThread.c libTestJNI.c libCompleteExit.c libMonitorWithDeadObjectTest.c libTestPsig.c libnativeStack.c exeGetCreatedJavaVMs.c +--- old/make/test/JtregNativeJdk.gmk 2020-05-20 17:59:34.437582966 -0700 ++++ new/make/test/JtregNativeJdk.gmk 2020-05-20 17:59:34.045575440 -0700 +@@ -107,9 +107,6 @@ + ifeq ($(call isTargetOs, linux), true) + BUILD_JDK_JTREG_LIBRARIES_LIBS_libInheritedChannel := -ljava + BUILD_JDK_JTREG_EXECUTABLES_LIBS_exelauncher := -ldl +- else ifeq ($(call isTargetOs, solaris), true) +- BUILD_JDK_JTREG_LIBRARIES_LIBS_libInheritedChannel := -ljava -lsocket -lnsl +- BUILD_JDK_JTREG_EXECUTABLES_LIBS_exelauncher := -lthread -ldl + endif + BUILD_JDK_JTREG_EXECUTABLES_LIBS_exeJliLaunchTest := -ljli + BUILD_JDK_JTREG_EXECUTABLES_LIBS_exeCallerAccessTest := -ljvm +--- old/src/hotspot/cpu/x86/globalDefinitions_x86.hpp 2020-05-20 17:59:37.533642413 -0700 ++++ new/src/hotspot/cpu/x86/globalDefinitions_x86.hpp 2020-05-20 17:59:37.197635961 -0700 +@@ -68,7 +68,7 @@ + #define INCLUDE_RTM_OPT 1 + #endif + +-#if defined(LINUX) || defined(SOLARIS) || defined(__APPLE__) ++#if defined(LINUX) || defined(__APPLE__) + #define SUPPORT_RESERVED_STACK_AREA + #endif + +--- old/src/hotspot/os/posix/include/jvm_md.h 2020-05-20 17:59:41.957727358 -0700 ++++ new/src/hotspot/os/posix/include/jvm_md.h 2020-05-20 17:59:41.561719755 -0700 +@@ -54,7 +54,7 @@ + #endif + #define JNI_LIB_NAME(NAME) JNI_LIB_PREFIX NAME JNI_LIB_SUFFIX + +-#if defined(AIX) || defined(SOLARIS) ++#if defined(AIX) + #define JVM_MAXPATHLEN MAXPATHLEN + #else + // Hack: MAXPATHLEN is 4095 on some Linux and 4096 on others. This may +@@ -87,14 +87,8 @@ + #define JVM_SIGTERM SIGTERM + + #define BREAK_SIGNAL SIGQUIT /* Thread dumping support. */ +-#ifdef SOLARIS +-#define ASYNC_SIGNAL SIGJVM2 /* Event-based suspend/resume support */ +-#endif // SOLARIS + #define SHUTDOWN1_SIGNAL SIGHUP /* Shutdown Hooks support. */ + #define SHUTDOWN2_SIGNAL SIGINT + #define SHUTDOWN3_SIGNAL SIGTERM + +-/* With 1.4.1 libjsig added versioning: used in os_solaris.cpp and jsig.c */ +-#define JSIG_VERSION_1_4_1 0x30140100 +- + #endif /* !_JAVASOFT_JVM_MD_H_ */ +--- old/src/hotspot/os/posix/os_posix.cpp 2020-05-20 17:59:42.965746713 -0700 ++++ new/src/hotspot/os/posix/os_posix.cpp 2020-05-20 17:59:42.629740261 -0700 +@@ -517,7 +517,7 @@ + st->print("%d", sysconf(_SC_CHILD_MAX)); + + print_rlimit(st, ", THREADS", RLIMIT_THREADS); +-#elif !defined(SOLARIS) ++#else + print_rlimit(st, ", NPROC", RLIMIT_NPROC); + #endif + +@@ -535,12 +535,6 @@ + print_rlimit(st, ", MEMLOCK", RLIMIT_MEMLOCK, true); + #endif + +-#if defined(SOLARIS) +- // maximum size of mapped address space of a process in bytes; +- // if the limit is exceeded, mmap and brk fail +- print_rlimit(st, ", VMEM", RLIMIT_VMEM, true); +-#endif +- + // MacOS; The maximum size (in bytes) to which a process's resident set size may grow. + #if defined(__APPLE__) + print_rlimit(st, ", RSS", RLIMIT_RSS, true); +--- old/src/hotspot/os/posix/os_posix.inline.hpp 2020-05-20 17:59:45.073787189 -0700 ++++ new/src/hotspot/os/posix/os_posix.inline.hpp 2020-05-20 17:59:44.701780046 -0700 +@@ -34,10 +34,8 @@ + #include + #include + +-#ifndef SOLARIS + // Aix does not have NUMA support but need these for compilation. + inline bool os::numa_has_group_homing() { AIX_ONLY(ShouldNotReachHere();) return false; } +-#endif // !SOLARIS + + // Platform Mutex/Monitor implementation + +--- old/src/hotspot/os/posix/vmError_posix.cpp 2020-05-20 17:59:46.085806620 -0700 ++++ new/src/hotspot/os/posix/vmError_posix.cpp 2020-05-20 17:59:45.745800092 -0700 +@@ -40,9 +40,6 @@ + #include + #include + #endif +-#ifdef SOLARIS +-#include +-#endif + #ifdef AIX + #include + #endif +--- old/src/hotspot/share/c1/c1_LIR.cpp 2020-05-20 17:59:59.318060690 -0700 ++++ new/src/hotspot/share/c1/c1_LIR.cpp 2020-05-20 17:59:58.926053163 -0700 +@@ -446,8 +446,6 @@ + case lir_monaddr: // input and result always valid, info always invalid + case lir_null_check: // input and info always valid, result always invalid + case lir_move: // input and result always valid, may have info +- case lir_pack64: // input and result always valid +- case lir_unpack64: // input and result always valid + { + assert(op->as_Op1() != nullptr, "must be"); + LIR_Op1* op1 = (LIR_Op1*)op; +@@ -1728,8 +1726,6 @@ + case lir_convert: s = "convert"; break; + case lir_alloc_object: s = "alloc_obj"; break; + case lir_monaddr: s = "mon_addr"; break; +- case lir_pack64: s = "pack64"; break; +- case lir_unpack64: s = "unpack64"; break; + // LIR_Op2 + case lir_cmp: s = "cmp"; break; + case lir_cmp_l2i: s = "cmp_l2i"; break; +--- old/src/hotspot/share/c1/c1_LIR.hpp 2020-05-20 18:00:00.446082348 -0700 ++++ new/src/hotspot/share/c1/c1_LIR.hpp 2020-05-20 18:00:00.042074591 -0700 +@@ -939,8 +939,6 @@ + , lir_monaddr + , lir_roundfp + , lir_safepoint +- , lir_pack64 +- , lir_unpack64 + , lir_unwind + , lir_load_klass + , end_op1 +@@ -2236,9 +2234,6 @@ + void logical_or (LIR_Opr left, LIR_Opr right, LIR_Opr dst) { append(new LIR_Op2(lir_logic_or, left, right, dst)); } + void logical_xor (LIR_Opr left, LIR_Opr right, LIR_Opr dst) { append(new LIR_Op2(lir_logic_xor, left, right, dst)); } + +- void pack64(LIR_Opr src, LIR_Opr dst) { append(new LIR_Op1(lir_pack64, src, dst, T_LONG, lir_patch_none, NULL)); } +- void unpack64(LIR_Opr src, LIR_Opr dst) { append(new LIR_Op1(lir_unpack64, src, dst, T_LONG, lir_patch_none, NULL)); } +- + void null_check(LIR_Opr opr, CodeEmitInfo* info, bool deoptimize_on_null = false); + void throw_exception(LIR_Opr exceptionPC, LIR_Opr exceptionOop, CodeEmitInfo* info) { + append(new LIR_Op2(lir_throw, exceptionPC, exceptionOop, LIR_OprFact::illegalOpr, info)); +--- old/src/hotspot/share/cds/classListParser.cpp 2020-05-20 18:00:04.798165911 -0700 ++++ new/src/hotspot/share/cds/classListParser.cpp 2020-05-20 18:00:04.402158309 -0700 +@@ -452,7 +452,7 @@ + // This function is used for loading classes for customized class loaders + // during archive dumping. + InstanceKlass* ClassListParser::load_class_from_source(Symbol* class_name, TRAPS) { +-#if !(defined(_LP64) && (defined(LINUX)|| defined(SOLARIS) || defined(__APPLE__) || defined(_WINDOWS))) ++#if !(defined(_LP64) && (defined(LINUX) || defined(__APPLE__) || defined(_WINDOWS))) + // The only supported platforms are: (1) Linux/64-bit and (2) Solaris/64-bit and + // (3) MacOSX/64-bit and (4) Windowss/64-bit + // This #if condition should be in sync with the areCustomLoadersSupportedForCDS +--- old/src/hotspot/share/runtime/abstract_vm_version.cpp 2020-05-20 18:00:26.906590409 -0700 ++++ new/src/hotspot/share/runtime/abstract_vm_version.cpp 2020-05-20 18:00:26.522583036 -0700 +@@ -167,7 +167,6 @@ + + #define OS LINUX_ONLY("linux") \ + WINDOWS_ONLY("windows") \ +- SOLARIS_ONLY("solaris") \ + AIX_ONLY("aix") \ + BSD_ONLY("bsd") + +--- old/src/hotspot/share/runtime/globals.hpp 2020-05-20 18:00:31.194672744 -0700 ++++ new/src/hotspot/share/runtime/globals.hpp 2020-05-20 18:00:30.854666216 -0700 +@@ -1599,10 +1599,8 @@ + product(int, ThreadPriorityPolicy, 0, \ + "0 : Normal. "\ + " VM chooses priorities that are appropriate for normal "\ +- " applications. On Solaris NORM_PRIORITY and above are mapped "\ +- " to normal native priority. Java priorities below " \ +- " NORM_PRIORITY map to lower native priority values. On "\ +- " Windows applications are allowed to use higher native "\ ++ " applications. "\ ++ " On Windows applications are allowed to use higher native "\ + " priorities. However, with ThreadPriorityPolicy=0, VM will "\ + " not use the highest possible native priority, "\ + " THREAD_PRIORITY_TIME_CRITICAL, as it may interfere with "\ +@@ -1884,8 +1882,7 @@ + product(bool, WhiteBoxAPI, false, DIAGNOSTIC, \ + "Enable internal testing APIs") \ + \ +- product(size_t, ArrayAllocatorMallocLimit, \ +- SOLARIS_ONLY(64*K) NOT_SOLARIS(SIZE_MAX), EXPERIMENTAL, \ ++ product(size_t, ArrayAllocatorMallocLimit, SIZE_MAX, EXPERIMENTAL, \ + "Allocation less than this value will be allocated " \ + "using malloc. Larger allocations will use mmap.") \ + \ +--- old/src/hotspot/share/runtime/semaphore.hpp 2020-05-20 18:00:35.454754540 -0700 ++++ new/src/hotspot/share/runtime/semaphore.hpp 2020-05-20 18:00:35.066747091 -0700 +@@ -28,7 +28,7 @@ + #include "memory/allocation.hpp" + #include "utilities/globalDefinitions.hpp" + +-#if defined(LINUX) || defined(SOLARIS) || defined(AIX) ++#if defined(LINUX) || defined(AIX) + # include "semaphore_posix.hpp" + #else + # include OS_HEADER(semaphore) +--- old/src/hotspot/share/services/memTracker.cpp 2020-05-20 18:00:38.698816829 -0700 ++++ new/src/hotspot/share/services/memTracker.cpp 2020-05-20 18:00:38.318809532 -0700 +@@ -48,12 +48,6 @@ + #include + #endif + +-#ifdef SOLARIS +- volatile bool NMT_stack_walkable = false; +-#else +- volatile bool NMT_stack_walkable = true; +-#endif +- + NMT_TrackingLevel MemTracker::_tracking_level = NMT_unknown; + + MemBaseline MemTracker::_baseline; +--- old/src/hotspot/share/services/memTracker.hpp 2020-05-20 18:00:39.774837489 -0700 ++++ new/src/hotspot/share/services/memTracker.hpp 2020-05-20 18:00:39.374829809 -0700 +@@ -34,11 +34,9 @@ + #include "utilities/debug.hpp" + #include "utilities/nativeCallStack.hpp" + +-extern volatile bool NMT_stack_walkable; +- +-#define CURRENT_PC ((MemTracker::tracking_level() == NMT_detail && NMT_stack_walkable) ? \ ++#define CURRENT_PC ((MemTracker::tracking_level() == NMT_detail) ? \ + NativeCallStack(0) : FAKE_CALLSTACK) +-#define CALLER_PC ((MemTracker::tracking_level() == NMT_detail && NMT_stack_walkable) ? \ ++#define CALLER_PC ((MemTracker::tracking_level() == NMT_detail) ? \ + NativeCallStack(1) : FAKE_CALLSTACK) + + class MemBaseline; +--- old/src/hotspot/share/utilities/debug.cpp 2020-05-20 18:00:41.782876045 -0700 ++++ new/src/hotspot/share/utilities/debug.cpp 2020-05-20 18:00:41.442869517 -0700 +@@ -612,12 +612,11 @@ + tty->print_cr(" findm(intptr_t pc) - finds Method*"); + tty->print_cr(" find(intptr_t x) - finds & prints nmethod/stub/bytecode/oop based on pointer into it"); + tty->print_cr(" pns(void* sp, void* fp, void* pc) - print native (i.e. mixed) stack trace. E.g."); +- tty->print_cr(" pns($sp, $rbp, $pc) on Linux/amd64 and Solaris/amd64 or"); ++ tty->print_cr(" pns($sp, $rbp, $pc) on Linux/amd64 or"); + tty->print_cr(" pns($sp, $ebp, $pc) on Linux/x86 or"); + tty->print_cr(" pns($sp, $fp, $pc) on Linux/AArch64 or"); + tty->print_cr(" pns($sp, 0, $pc) on Linux/ppc64 or"); + tty->print_cr(" pns($sp, $s8, $pc) on Linux/mips or"); +- tty->print_cr(" pns($sp + 0x7ff, 0, $pc) on Solaris/SPARC"); + tty->print_cr(" - in gdb do 'set overload-resolution off' before calling pns()"); + tty->print_cr(" - in dbx do 'frame 1' before calling pns()"); + tty->print_cr("class metadata."); +--- old/src/hotspot/share/utilities/globalDefinitions_gcc.hpp 2020-05-20 18:00:44.978937412 -0700 ++++ new/src/hotspot/share/utilities/globalDefinitions_gcc.hpp 2020-05-20 18:00:44.586929885 -0700 +@@ -39,36 +39,15 @@ + #include + #include + +-#ifdef SOLARIS +-#include +-#endif // SOLARIS +- + #include + #include + #include + #include + #include + +-#ifdef SOLARIS +-#include +-#endif // SOLARIS +- + #include + #include + +-#ifdef SOLARIS +-#include +-#include +-#include +-#include +-#include +-#include +-#endif // SOLARIS +- +-# ifdef SOLARIS_MUTATOR_LIBTHREAD +-# include +-# endif +- + #if defined(LINUX) || defined(_ALLBSD_SOURCE) + #include + #include +@@ -81,34 +61,6 @@ + #include + #endif // LINUX || _ALLBSD_SOURCE + +-// 4810578: varargs unsafe on 32-bit integer/64-bit pointer architectures +-// When __cplusplus is defined, NULL is defined as 0 (32-bit constant) in +-// system header files. On 32-bit architectures, there is no problem. +-// On 64-bit architectures, defining NULL as a 32-bit constant can cause +-// problems with varargs functions: C++ integral promotion rules say for +-// varargs, we pass the argument 0 as an int. So, if NULL was passed to a +-// varargs function it will remain 32-bits. Depending on the calling +-// convention of the machine, if the argument is passed on the stack then +-// only 32-bits of the "NULL" pointer may be initialized to zero. The +-// other 32-bits will be garbage. If the varargs function is expecting a +-// pointer when it extracts the argument, then we have a problem. +-// +-// Solution: For 64-bit architectures, redefine NULL as 64-bit constant 0. +-// +-// Note: this fix doesn't work well on Linux because NULL will be overwritten +-// whenever a system header file is included. Linux handles NULL correctly +-// through a special type '__null'. +-#ifdef SOLARIS +- #ifdef _LP64 +- #undef NULL +- #define NULL 0L +- #else +- #ifndef NULL +- #define NULL 0 +- #endif +- #endif +-#endif +- + // NULL vs NULL_WORD: + // On Linux NULL is defined as a special type '__null'. Assigning __null to + // integer variable will cause gcc warning. Use NULL_WORD in places where a +@@ -150,52 +101,8 @@ + + #endif // !LINUX && !_ALLBSD_SOURCE + +- +-#ifdef SOLARIS +-// ANSI C++ fixes +-// NOTE:In the ANSI committee's continuing attempt to make each version +-// of C++ incompatible with the previous version, you can no longer cast +-// pointers to functions without specifying linkage unless you want to get +-// warnings. +-// +-// This also means that pointers to functions can no longer be "hidden" +-// in opaque types like void * because at the invocation point warnings +-// will be generated. While this makes perfect sense from a type safety +-// point of view it causes a lot of warnings on old code using C header +-// files. Here are some typedefs to make the job of silencing warnings +-// a bit easier. +-// +-// The final kick in the teeth is that you can only have extern "C" linkage +-// specified at file scope. So these typedefs are here rather than in the +-// .hpp for the class (os:Solaris usually) that needs them. +- +-extern "C" { +- typedef int (*int_fnP_thread_t_iP_uP_stack_tP_gregset_t)(thread_t, int*, unsigned *, stack_t*, gregset_t); +- typedef int (*int_fnP_thread_t_i_gregset_t)(thread_t, int, gregset_t); +- typedef int (*int_fnP_thread_t_i)(thread_t, int); +- typedef int (*int_fnP_thread_t)(thread_t); +- +- typedef int (*int_fnP_cond_tP_mutex_tP_timestruc_tP)(cond_t *cv, mutex_t *mx, timestruc_t *abst); +- typedef int (*int_fnP_cond_tP_mutex_tP)(cond_t *cv, mutex_t *mx); +- +- // typedef for missing API in libc +- typedef int (*int_fnP_mutex_tP_i_vP)(mutex_t *, int, void *); +- typedef int (*int_fnP_mutex_tP)(mutex_t *); +- typedef int (*int_fnP_cond_tP_i_vP)(cond_t *cv, int scope, void *arg); +- typedef int (*int_fnP_cond_tP)(cond_t *cv); +-}; +-#endif // SOLARIS +- + // checking for nanness +-#ifdef SOLARIS +-#ifdef SPARC +-inline int g_isnan(float f) { return isnanf(f); } +-#else +-// isnanf() broken on Intel Solaris use isnand() +-inline int g_isnan(float f) { return isnand(f); } +-#endif +-inline int g_isnan(double f) { return isnand(f); } +-#elif defined(__APPLE__) ++#if defined(__APPLE__) + inline int g_isnan(double f) { return isnan(f); } + #elif defined(LINUX) || defined(_ALLBSD_SOURCE) + inline int g_isnan(float f) { return isnan(f); } +--- old/src/hotspot/share/utilities/macros.hpp 2020-05-20 18:00:46.046957918 -0700 ++++ new/src/hotspot/share/utilities/macros.hpp 2020-05-20 18:00:45.666950622 -0700 +@@ -401,14 +401,6 @@ + #define NOT_AIX(code) code + #endif + +-#ifdef SOLARIS +-#define SOLARIS_ONLY(code) code +-#define NOT_SOLARIS(code) +-#else +-#define SOLARIS_ONLY(code) +-#define NOT_SOLARIS(code) code +-#endif +- + #ifdef _WINDOWS + #define WINDOWS_ONLY(code) code + #define NOT_WINDOWS(code) +--- old/src/hotspot/share/utilities/ostream.cpp 2020-05-20 18:00:47.142978963 -0700 ++++ new/src/hotspot/share/utilities/ostream.cpp 2020-05-20 18:00:46.754971513 -0700 +@@ -1082,7 +1082,7 @@ + + #ifndef PRODUCT + +-#if defined(SOLARIS) || defined(LINUX) || defined(AIX) || defined(_ALLBSD_SOURCE) ++#if defined(LINUX) || defined(AIX) || defined(_ALLBSD_SOURCE) + #include + #include + #include +--- old/src/hotspot/share/utilities/vmError.cpp 2020-05-20 18:00:48.214999546 -0700 ++++ new/src/hotspot/share/utilities/vmError.cpp 2020-05-20 18:00:47.822992019 -0700 +@@ -1891,8 +1891,6 @@ + out.print_raw ("# Executing "); + #if defined(LINUX) || defined(_ALLBSD_SOURCE) + out.print_raw ("/bin/sh -c "); +-#elif defined(SOLARIS) +- out.print_raw ("/usr/bin/sh -c "); + #elif defined(_WINDOWS) + out.print_raw ("cmd /C "); + #endif +@@ -1957,8 +1955,6 @@ + tty->print("# Executing "); + #if defined(LINUX) + tty->print ("/bin/sh -c "); +-#elif defined(SOLARIS) +- tty->print ("/usr/bin/sh -c "); + #endif + tty->print_cr("\"%s\"...", cmd); + +--- old/src/java.base/share/classes/sun/net/sdp/SdpSupport.java 2020-05-20 18:00:49.295020283 -0700 ++++ new/src/java.base/share/classes/sun/net/sdp/SdpSupport.java 2020-05-20 18:00:48.903012757 -0700 +@@ -39,7 +39,7 @@ + */ + + public final class SdpSupport { +- private static final boolean isSupported = (OperatingSystem.isSolaris() || OperatingSystem.isLinux()); ++ private static final boolean isSupported = OperatingSystem.isLinux(); + private static final JavaIOFileDescriptorAccess fdAccess = + SharedSecrets.getJavaIOFileDescriptorAccess(); + +--- old/src/java.base/share/classes/sun/nio/ch/Net.java 2020-05-20 18:00:50.351040561 -0700 ++++ new/src/java.base/share/classes/sun/nio/ch/Net.java 2020-05-20 18:00:49.963033111 -0700 +@@ -512,7 +512,7 @@ + private static native boolean isReusePortAvailable0(); + + /* +- * Returns 1 for Windows and -1 for Solaris/Linux/Mac OS ++ * Returns 1 for Windows and -1 for Linux/Mac OS + */ + private static native int isExclusiveBindAvailable(); + +--- old/src/java.base/share/classes/sun/nio/ch/SocketOptionRegistry.java.template 2020-05-20 18:00:51.403060759 -0700 ++++ new/src/java.base/share/classes/sun/nio/ch/SocketOptionRegistry.java.template 2020-05-20 18:00:51.019053386 -0700 +@@ -43,8 +43,6 @@ + #define SO_REUSEPORT 0 + #elif defined(__linux__) + #define SO_REUSEPORT 15 +-#elif defined(__solaris__) +-#define SO_REUSEPORT 0x100e + #elif defined(AIX) || defined(MACOSX) + #define SO_REUSEPORT 0x0200 + #else +@@ -52,10 +50,6 @@ + #endif + #endif + +-/* On Solaris, "sun" is defined as a macro. Undefine to make package +- declaration valid */ +-#undef sun +- + /* To be able to name the Java constants the same as the C constants without + having the preprocessor rewrite those identifiers, add PREFIX_ to all + identifiers matching a C constant. The PREFIX_ is filtered out in the +--- old/src/java.base/share/conf/security/java.security 2020-05-20 18:00:54.519120590 -0700 ++++ new/src/java.base/share/conf/security/java.security 2020-05-20 18:00:54.183114138 -0700 +@@ -83,11 +83,7 @@ + #ifdef macosx + security.provider.tbd=Apple + #endif +-#ifdef solaris +-security.provider.tbd=SunPKCS11 ${java.home}/conf/security/sunpkcs11-solaris.cfg +-#else + security.provider.tbd=SunPKCS11 +-#endif + + # + # A list of preferred providers for specific algorithms. These providers will +--- old/src/java.base/share/native/libjli/jli_util.h 2020-05-20 18:00:56.651161527 -0700 ++++ new/src/java.base/share/native/libjli/jli_util.h 2020-05-20 18:00:56.263154077 -0700 +@@ -100,9 +100,6 @@ + #define JLI_StrCaseCmp(p1, p2) strcasecmp((p1), (p2)) + #define JLI_StrNCaseCmp(p1, p2, p3) strncasecmp((p1), (p2), (p3)) + #define JLI_Open open +-#ifdef __solaris__ +-#define JLI_Lseek llseek +-#endif + #ifdef __linux__ + #define _LARGFILE64_SOURCE + #define JLI_Lseek lseek64 +--- old/src/java.base/share/native/libnet/net_util.c 2020-05-20 18:00:57.667181035 -0700 ++++ new/src/java.base/share/native/libnet/net_util.c 2020-05-20 18:00:57.335174660 -0700 +@@ -81,7 +81,6 @@ + + /* check if SO_REUSEPORT is supported on this platform */ + REUSEPORT_available = reuseport_supported(IPv6_available); +- parseExclusiveBindProperty(env); + + return JNI_VERSION_1_2; + } +--- old/src/java.base/share/native/libnet/net_util.h 2020-05-20 18:00:58.723201311 -0700 ++++ new/src/java.base/share/native/libnet/net_util.h 2020-05-20 18:00:58.339193938 -0700 +@@ -142,8 +142,6 @@ + JNIEXPORT jobject JNICALL + NET_SockaddrToInetAddress(JNIEnv *env, SOCKETADDRESS *sa, int *port); + +-void parseExclusiveBindProperty(JNIEnv *env); +- + JNIEXPORT jint JNICALL NET_GetPortFromSockaddr(SOCKETADDRESS *sa); + + JNIEXPORT jboolean JNICALL +--- old/src/java.base/unix/classes/java/lang/ProcessImpl.java 2020-05-20 18:00:59.739220820 -0700 ++++ new/src/java.base/unix/classes/java/lang/ProcessImpl.java 2020-05-20 18:00:59.399214291 -0700 +@@ -83,9 +83,6 @@ + private /* final */ InputStream stdout; + private /* final */ InputStream stderr; + +- // only used on Solaris +- private /* final */ DeferredCloseInputStream stdout_inner_stream; +- + private static enum LaunchMechanism { + // order IS important! + FORK, +@@ -111,7 +108,6 @@ + return lm; // All options are valid for Linux + case AIX: + case MACOS: +- case SOLARIS: + if (lm != LaunchMechanism.VFORK) { + return lm; // All but VFORK are valid + } +@@ -368,44 +364,6 @@ + }); + break; + +- case SOLARIS: +- stdin = (fds[0] == -1) ? +- ProcessBuilder.NullOutputStream.INSTANCE : +- new BufferedOutputStream( +- new FileOutputStream(newFileDescriptor(fds[0]))); +- +- stdout = (fds[1] == -1 || forceNullOutputStream) ? +- ProcessBuilder.NullInputStream.INSTANCE : +- new BufferedInputStream( +- stdout_inner_stream = +- new DeferredCloseInputStream( +- newFileDescriptor(fds[1]))); +- +- stderr = (fds[2] == -1) ? +- ProcessBuilder.NullInputStream.INSTANCE : +- new DeferredCloseInputStream(newFileDescriptor(fds[2])); +- +- /* +- * For each subprocess forked a corresponding reaper task +- * is submitted. That task is the only thread which waits +- * for the subprocess to terminate and it doesn't hold any +- * locks while doing so. This design allows waitFor() and +- * exitStatus() to be safely executed in parallel (and they +- * need no native code). +- */ +- ProcessHandleImpl.completion(pid, true).handle((exitcode, throwable) -> { +- lock.lock(); +- try { +- this.exitcode = (exitcode == null) ? -1 : exitcode.intValue(); +- this.hasExited = true; +- condition.signalAll(); +- } finally { +- lock.unlock(); +- } +- return null; +- }); +- break; +- + case AIX: + stdin = (fds[0] == -1) ? + ProcessBuilder.NullOutputStream.INSTANCE : +@@ -519,32 +480,6 @@ + try { stderr.close(); } catch (IOException ignored) {} + break; + +- case SOLARIS: +- // There is a risk that pid will be recycled, causing us to +- // kill the wrong process! So we only terminate processes +- // that appear to still be running. Even with this check, +- // there is an unavoidable race condition here, but the window +- // is very small, and OSes try hard to not recycle pids too +- // soon, so this is quite safe. +- lock.lock(); +- try { +- if (!hasExited) +- processHandle.destroyProcess(force); +- } finally { +- lock.unlock(); +- } +- try { +- stdin.close(); +- if (stdout_inner_stream != null) +- stdout_inner_stream.closeDeferred(stdout); +- if (stderr instanceof DeferredCloseInputStream) +- ((DeferredCloseInputStream) stderr) +- .closeDeferred(stderr); +- } catch (IOException e) { +- // ignore +- } +- break; +- + default: throw new AssertionError("Unsupported platform: " + OperatingSystem.current()); + } + } +--- old/src/java.base/unix/classes/sun/net/PortConfig.java 2020-05-20 18:01:00.803241250 -0700 ++++ new/src/java.base/unix/classes/sun/net/PortConfig.java 2020-05-20 18:01:00.419233877 -0700 +@@ -47,10 +47,6 @@ + defaultLower = 32768; + defaultUpper = 61000; + break; +- case SOLARIS: +- defaultLower = 32768; +- defaultUpper = 65535; +- break; + case MACOS: + defaultLower = 49152; + defaultUpper = 65535; +--- old/src/java.base/unix/classes/sun/nio/fs/UnixConstants.java.template 2020-05-20 18:01:02.831280190 -0700 ++++ new/src/java.base/unix/classes/sun/nio/fs/UnixConstants.java.template 2020-05-20 18:01:02.495273738 -0700 +@@ -35,10 +35,6 @@ + #include + #endif + +-/* On Solaris, "sun" is defined as a macro. Undefine to make package +- declaration valid */ +-#undef sun +- + /* To be able to name the Java constants the same as the C constants without + having the preprocessor rewrite those identifiers, add PREFIX_ to all + identifiers matching a C constant. The PREFIX_ is filtered out in the +--- old/src/java.base/unix/classes/sun/nio/fs/UnixFileSystem.java 2020-05-20 18:01:03.927301234 -0700 ++++ new/src/java.base/unix/classes/sun/nio/fs/UnixFileSystem.java 2020-05-20 18:01:03.535293707 -0700 +@@ -127,10 +127,6 @@ + return rootDirectory; + } + +- boolean isSolaris() { +- return false; +- } +- + static List standardFileAttributeViews() { + return Arrays.asList("basic", "posix", "unix", "owner"); + } +--- old/src/java.base/unix/classes/sun/nio/fs/UnixPath.java 2020-05-20 18:01:04.971321280 -0700 ++++ new/src/java.base/unix/classes/sun/nio/fs/UnixPath.java 2020-05-20 18:01:04.583313830 -0700 +@@ -779,15 +779,7 @@ + ("NOFOLLOW_LINKS is not supported on this platform"); + flags |= O_NOFOLLOW; + } +- try { +- return open(this, flags, 0); +- } catch (UnixException x) { +- // HACK: EINVAL instead of ELOOP on Solaris 10 prior to u4 (see 6460380) +- if (getFileSystem().isSolaris() && x.errno() == EINVAL) +- x.setError(ELOOP); +- +- throw x; +- } ++ return open(this, flags, 0); + } + + void checkRead() { +--- old/src/java.base/unix/classes/sun/security/provider/NativePRNG.java 2020-05-20 18:01:06.091342785 -0700 ++++ new/src/java.base/unix/classes/sun/security/provider/NativePRNG.java 2020-05-20 18:01:05.707335412 -0700 +@@ -33,7 +33,7 @@ + import sun.security.util.Debug; + + /** +- * Native PRNG implementation for Solaris/Linux/MacOS. ++ * Native PRNG implementation for Linux/MacOS. + *

+ * It obtains seed and random numbers by reading system files such as + * the special device files /dev/random and /dev/urandom. This +--- old/src/java.base/unix/native/libjava/ProcessHandleImpl_unix.c 2020-05-20 18:01:07.167363445 -0700 ++++ new/src/java.base/unix/native/libjava/ProcessHandleImpl_unix.c 2020-05-20 18:01:06.779355995 -0700 +@@ -45,20 +45,10 @@ + #include + #include + +-/* For POSIX-compliant getpwuid_r on Solaris */ +-#if defined(__solaris__) +-#define _POSIX_PTHREAD_SEMANTICS +-#endif + #include + +-#ifdef _AIX +-#include +-#endif +-#ifdef __solaris__ +-#include +-#endif +- + #if defined(_AIX) ++ #include + #define DIR DIR64 + #define dirent dirent64 + #define opendir opendir64 +@@ -138,18 +128,13 @@ + #define WTERMSIG(status) ((status)&0x7F) + #endif + +-#ifdef __solaris__ + /* The child exited because of a signal. + * The best value to return is 0x80 + signal number, + * because that is what all Unix shells do, and because + * it allows callers to distinguish between process exit and + * process death by signal. +- * Unfortunately, the historical behavior on Solaris is to return +- * the signal number, and we preserve this for compatibility. */ +-#define WTERMSIG_RETURN(status) WTERMSIG(status) +-#else ++ */ + #define WTERMSIG_RETURN(status) (WTERMSIG(status) + 0x80) +-#endif + + #define RESTARTABLE(_cmd, _result) do { \ + do { \ +@@ -503,7 +488,7 @@ + * The following functions are for Linux + */ + +-#if defined(__solaris__) || defined (__linux__) ++#if defined (__linux__) + + /* + * Return pids of active processes, and optionally parent pids and +@@ -632,13 +617,13 @@ + return count; + } + +-#endif // defined(__solaris__) || defined (__linux__) ++#endif // defined (__linux__) + + /* +- * The following functions are common on Solaris and AIX. ++ * The following functions are for AIX. + */ + +-#if defined(__solaris__) || defined(_AIX) ++#if defined(_AIX) + + /** + * Helper function to get the 'psinfo_t' data from "/proc/%d/psinfo". +@@ -702,19 +687,6 @@ + int ret; + + /* +- * On Solaris, the full path to the executable command is the link in +- * /proc//paths/a.out. But it is only readable for processes we own. +- */ +-#if defined(__solaris__) +- snprintf(fn, sizeof fn, "/proc/%d/path/a.out", pid); +- if ((ret = readlink(fn, exePath, PATH_MAX - 1)) > 0) { +- // null terminate and create String to store for command +- exePath[ret] = '\0'; +- CHECK_NULL(cmdexe = JNU_NewStringPlatform(env, exePath)); +- } +-#endif +- +- /* + * Now try to open /proc/%d/psinfo + */ + if (getPsinfo(pid, &psinfo) < 0) { +@@ -743,4 +715,4 @@ + prargs[0] == '\0' ? NULL : prargs); + } + +-#endif // defined(__solaris__) || defined(_AIX) ++#endif // defined(_AIX) +--- old/src/java.base/unix/native/libjava/ProcessHandleImpl_unix.h 2020-05-20 18:01:08.239384029 -0700 ++++ new/src/java.base/unix/native/libjava/ProcessHandleImpl_unix.h 2020-05-20 18:01:07.851376579 -0700 +@@ -29,7 +29,7 @@ + * Declaration of ProcessHandleImpl functions common on all Unix platforms. + * 'unix_' functions have a single implementation in ProcessHandleImpl_unix.c + * 'os_' prefixed functions have different, os-specific implementations in the +- * various ProcessHandleImpl_{linux,macosx,solaris,aix}.c files. ++ * various ProcessHandleImpl_{linux,macosx,aix}.c files. + * See ProcessHandleImpl_unix.c for more details. + */ + +--- old/src/java.base/unix/native/libjava/ProcessImpl_md.c 2020-05-20 18:01:09.319404766 -0700 ++++ new/src/java.base/unix/native/libjava/ProcessImpl_md.c 2020-05-20 18:01:08.935397393 -0700 +@@ -230,14 +230,7 @@ + static const char* + defaultPath(void) + { +-#ifdef __solaris__ +- /* These really are the Solaris defaults! */ +- return (geteuid() == 0 || getuid() == 0) ? +- "/usr/xpg4/bin:/usr/bin:/opt/SUNWspro/bin:/usr/sbin" : +- "/usr/xpg4/bin:/usr/bin:/opt/SUNWspro/bin:"; +-#else +- return ":/bin:/usr/bin"; /* glibc */ +-#endif ++ return ":/bin:/usr/bin"; + } + + static const char* +@@ -454,7 +447,7 @@ + #endif + + /* vfork(2) is deprecated on Darwin */ +-#ifndef __solaris__ ++#ifndef __APPLE__ + static pid_t + vforkChild(ChildStuff *c) { + volatile pid_t resultPid; +@@ -618,7 +611,7 @@ + startChild(JNIEnv *env, jobject process, ChildStuff *c, const char *helperpath) { + switch (c->mode) { + /* vfork(2) is deprecated on Darwin*/ +- #ifndef __solaris__ ++ #ifndef __APPLE__ + case MODE_VFORK: + return vforkChild(c); + #endif +--- old/src/java.base/unix/native/libjava/TimeZone_md.c 2020-05-20 18:01:10.467426810 -0700 ++++ new/src/java.base/unix/native/libjava/TimeZone_md.c 2020-05-20 18:01:10.059418975 -0700 +@@ -35,9 +35,6 @@ + #include + #include + #include +-#if defined(__solaris__) +-#include +-#endif + + #include "jvm.h" + #include "TimeZone_md.h" +@@ -53,11 +50,9 @@ + } while((_result == -1) && (errno == EINTR)); \ + } while(0) + +-#if !defined(__solaris__) || defined(__sparcv9) || defined(amd64) + #define fileopen fopen + #define filegets fgets + #define fileclose fclose +-#endif + + #if defined(_ALLBSD_SOURCE) + #define stat64 stat +@@ -81,7 +76,7 @@ + static const char *ETC_ENVIRONMENT_FILE = "/etc/environment"; + #endif + +-#if defined(__linux__) || defined(MACOSX) || defined(__solaris__) ++#if defined(__linux__) || defined(MACOSX) + + /* + * remove repeated path separators ('/') in the given 'path'. +@@ -191,13 +186,6 @@ + */ + if ((strcmp(dp->d_name, "ROC") == 0) + || (strcmp(dp->d_name, "posixrules") == 0) +-#if defined(__solaris__) +- /* +- * Skip the "src" and "tab" directories on Solaris. +- */ +- || (strcmp(dp->d_name, "src") == 0) +- || (strcmp(dp->d_name, "tab") == 0) +-#endif + || (strcmp(dp->d_name, "localtime") == 0)) { + continue; + } +@@ -269,8 +257,6 @@ + return possibleMatch; + } + +-#if defined(__linux__) || defined(MACOSX) +- + /* + * Performs Linux specific mapping and returns a zone ID + * if found. Otherwise, NULL is returned. +@@ -382,183 +368,6 @@ + return tz; + } + +-#elif defined(__solaris__) +- +-/* +- * Performs Solaris dependent mapping. Returns a zone ID if +- * found. Otherwise, NULL is returned. Solaris libc looks up +- * "/etc/default/init" to get the default TZ value if TZ is not defined +- * as an environment variable. +- */ +-static char * +-getPlatformTimeZoneID() +-{ +- char *tz = NULL; +- FILE *fp; +- +- /* +- * Try the TZ entry in /etc/default/init. +- */ +- if ((fp = fileopen(SYS_INIT_FILE, "r")) != NULL) { +- char line[256]; +- char quote = '\0'; +- +- while (filegets(line, sizeof(line), fp) != NULL) { +- char *p = line; +- char *s; +- char c; +- +- /* quick check for comment lines */ +- if (*p == '#') { +- continue; +- } +- if (strncmp(p, "TZ=", 3) == 0) { +- p += 3; +- SKIP_SPACE(p); +- c = *p; +- if (c == '"' || c == '\'') { +- quote = c; +- p++; +- } +- +- /* +- * PSARC/2001/383: quoted string support +- */ +- for (s = p; (c = *s) != '\0' && c != '\n'; s++) { +- /* No '\\' is supported here. */ +- if (c == quote) { +- quote = '\0'; +- break; +- } +- if (c == ' ' && quote == '\0') { +- break; +- } +- } +- if (quote != '\0') { +- jio_fprintf(stderr, "ZoneInfo: unterminated time zone name in /etc/TIMEZONE\n"); +- } +- *s = '\0'; +- tz = strdup(p); +- break; +- } +- } +- (void) fileclose(fp); +- } +- return tz; +-} +- +-#define TIMEZONE_FMRI "svc:/system/timezone:default" +-#define TIMEZONE_PG "timezone" +-#define LOCALTIME_PROP "localtime" +- +-static void +-cleanupScf(scf_handle_t *h, +- scf_snapshot_t *snap, +- scf_instance_t *inst, +- scf_propertygroup_t *pg, +- scf_property_t *prop, +- scf_value_t *val, +- char *buf) { +- if (buf != NULL) { +- free(buf); +- } +- if (snap != NULL) { +- scf_snapshot_destroy(snap); +- } +- if (val != NULL) { +- scf_value_destroy(val); +- } +- if (prop != NULL) { +- scf_property_destroy(prop); +- } +- if (pg != NULL) { +- scf_pg_destroy(pg); +- } +- if (inst != NULL) { +- scf_instance_destroy(inst); +- } +- if (h != NULL) { +- scf_handle_destroy(h); +- } +-} +- +-/* +- * Returns a zone ID of Solaris when the TZ value is "localtime". +- * First, it tries scf. If scf fails, it looks for the same file as +- * /usr/share/lib/zoneinfo/localtime under /usr/share/lib/zoneinfo/. +- */ +-static char * +-getSolarisDefaultZoneID() { +- char *tz = NULL; +- struct stat64 statbuf; +- size_t size; +- char *buf; +- int fd; +- int res; +- /* scf specific variables */ +- scf_handle_t *h = NULL; +- scf_snapshot_t *snap = NULL; +- scf_instance_t *inst = NULL; +- scf_propertygroup_t *pg = NULL; +- scf_property_t *prop = NULL; +- scf_value_t *val = NULL; +- +- if ((h = scf_handle_create(SCF_VERSION)) != NULL +- && scf_handle_bind(h) == 0 +- && (inst = scf_instance_create(h)) != NULL +- && (snap = scf_snapshot_create(h)) != NULL +- && (pg = scf_pg_create(h)) != NULL +- && (prop = scf_property_create(h)) != NULL +- && (val = scf_value_create(h)) != NULL +- && scf_handle_decode_fmri(h, TIMEZONE_FMRI, NULL, NULL, inst, +- NULL, NULL, SCF_DECODE_FMRI_REQUIRE_INSTANCE) == 0 +- && scf_instance_get_snapshot(inst, "running", snap) == 0 +- && scf_instance_get_pg_composed(inst, snap, TIMEZONE_PG, pg) == 0 +- && scf_pg_get_property(pg, LOCALTIME_PROP, prop) == 0 +- && scf_property_get_value(prop, val) == 0) { +- ssize_t len; +- +- /* Gets the length of the zone ID string */ +- len = scf_value_get_astring(val, NULL, 0); +- if (len != -1) { +- tz = malloc(++len); /* +1 for a null byte */ +- if (tz != NULL && scf_value_get_astring(val, tz, len) != -1) { +- cleanupScf(h, snap, inst, pg, prop, val, NULL); +- return tz; +- } +- } +- } +- cleanupScf(h, snap, inst, pg, prop, val, tz); +- +- RESTARTABLE(stat64(DEFAULT_ZONEINFO_FILE, &statbuf), res); +- if (res == -1) { +- return NULL; +- } +- size = (size_t) statbuf.st_size; +- buf = malloc(size); +- if (buf == NULL) { +- return NULL; +- } +- RESTARTABLE(open(DEFAULT_ZONEINFO_FILE, O_RDONLY), fd); +- if (fd == -1) { +- free((void *) buf); +- return NULL; +- } +- +- RESTARTABLE(read(fd, buf, size), res); +- if (res != (ssize_t) size) { +- (void) close(fd); +- free((void *) buf); +- return NULL; +- } +- (void) close(fd); +- tz = findZoneinfoFile(buf, size, ZONEINFO_DIR); +- free((void *) buf); +- return tz; +-} +- +-#endif /* defined(__solaris__) */ +- + #elif defined(_AIX) + + static char * +@@ -852,15 +533,6 @@ + free((void *) freetz); + } + #else +-#if defined(__solaris__) +- /* Solaris might use localtime, so handle it here. */ +- if (strcmp(tz, "localtime") == 0) { +- javatz = getSolarisDefaultZoneID(); +- if (freetz != NULL) { +- free((void *) freetz); +- } +- } else +-#endif + if (freetz == NULL) { + /* strdup if we are still working on getenv result. */ + javatz = strdup(tz); +--- old/src/java.base/unix/native/libjava/UnixFileSystem_md.c 2020-05-20 18:01:11.571448007 -0700 ++++ new/src/java.base/unix/native/libjava/UnixFileSystem_md.c 2020-05-20 18:01:11.171440327 -0700 +@@ -63,10 +63,6 @@ + #define stat stat64 + #endif + +-#if defined(__solaris__) && !defined(NAME_MAX) +- #define NAME_MAX MAXNAMLEN +-#endif +- + #if defined(_ALLBSD_SOURCE) + #ifndef MACOSX + #define statvfs64 statvfs +--- old/src/java.base/unix/native/libjava/io_util_md.c 2020-05-20 18:01:12.679469282 -0700 ++++ new/src/java.base/unix/native/libjava/io_util_md.c 2020-05-20 18:01:12.271461448 -0700 +@@ -30,10 +30,6 @@ + #include + #include + +-#ifdef __solaris__ +-#include +-#endif +- + #if defined(__linux__) || defined(_ALLBSD_SOURCE) || defined(_AIX) + #include + #endif +--- old/src/java.base/unix/native/libjava/java_props_md.c 2020-05-20 18:01:13.743489712 -0700 ++++ new/src/java.base/unix/native/libjava/java_props_md.c 2020-05-20 18:01:13.351482185 -0700 +@@ -323,27 +323,6 @@ + } + #endif + +-#ifdef __solaris__ +- if (strcmp(p,"eucJP") == 0) { +- /* For Solaris use customized vendor defined character +- * customized EUC-JP converter +- */ +- *std_encoding = "eucJP-open"; +- } else if (strcmp(p, "Big5") == 0 || strcmp(p, "BIG5") == 0) { +- /* +- * Remap the encoding string to Big5_Solaris which augments +- * the default converter for Solaris Big5 locales to include +- * seven additional ideographic characters beyond those included +- * in the Java "Big5" converter. +- */ +- *std_encoding = "Big5_Solaris"; +- } else if (strcmp(p, "Big5-HKSCS") == 0) { +- /* +- * Solaris uses HKSCS2001 +- */ +- *std_encoding = "Big5-HKSCS-2001"; +- } +-#endif + #ifdef MACOSX + /* + * For the case on MacOS X where encoding is set to US-ASCII, but we +--- old/src/java.base/unix/native/libjava/jlong_md.h 2020-05-20 18:01:15.935531801 -0700 ++++ new/src/java.base/unix/native/libjava/jlong_md.h 2020-05-20 18:01:15.547524351 -0700 +@@ -23,8 +23,8 @@ + * questions. + */ + +-#ifndef _SOLARIS_JLONG_MD_H_ +-#define _SOLARIS_JLONG_MD_H_ ++#ifndef _UNIX_JLONG_MD_H_ ++#define _UNIX_JLONG_MD_H_ + + /* Make sure ptrdiff_t is defined */ + #include +@@ -97,4 +97,4 @@ + #define size_to_jlong(a) ((jlong)(a)) + #define long_to_jlong(a) ((jlong)(a)) + +-#endif /* !_SOLARIS_JLONG_MD_H_ */ ++#endif /* !_UNIX_JLONG_MD_H_ */ +--- old/src/java.base/unix/native/libjsig/jsig.c 2020-05-20 18:01:20.019610218 -0700 ++++ new/src/java.base/unix/native/libjsig/jsig.c 2020-05-20 18:01:19.603602231 -0700 +@@ -35,16 +35,6 @@ + + #include "jni.h" + +-#ifdef SOLARIS +-/* Our redeclarations of the system functions must not have a less +- * restrictive linker scoping, so we have to declare them as JNIEXPORT +- * before including signal.h */ +-#include "sys/signal.h" +-JNIEXPORT void (*signal(int sig, void (*disp)(int)))(int); +-JNIEXPORT void (*sigset(int sig, void (*disp)(int)))(int); +-JNIEXPORT int sigaction(int sig, const struct sigaction *act, struct sigaction *oact); +-#endif +- + #include + #include + #include +@@ -61,16 +51,9 @@ + #define false 0 + #endif + +-#ifdef SOLARIS +-#define MAX_SIGNALS (SIGRTMAX+1) +- +-/* On solaris, MAX_SIGNALS is a macro, not a constant, so we must allocate sact dynamically. */ +-static struct sigaction *sact = (struct sigaction *)NULL; /* saved signal handlers */ +-#else + #define MAX_SIGNALS NSIG + + static struct sigaction sact[MAX_SIGNALS]; /* saved signal handlers */ +-#endif + + static sigset_t jvmsigs; /* Signals used by jvm. */ + +@@ -95,20 +78,6 @@ + static bool jvm_signal_installed = false; + + +-/* assume called within signal_lock */ +-static void allocate_sact() { +-#ifdef SOLARIS +- if (sact == NULL) { +- sact = (struct sigaction *)malloc((MAX_SIGNALS) * (size_t)sizeof(struct sigaction)); +- if (sact == NULL) { +- printf("%s\n", "libjsig.so unable to allocate memory"); +- exit(0); +- } +- memset(sact, 0, (MAX_SIGNALS) * (size_t)sizeof(struct sigaction)); +- } +-#endif +-} +- + static void signal_lock() { + pthread_mutex_lock(&mutex); + /* When the jvm is installing its set of signal handlers, threads +@@ -168,18 +137,7 @@ + sact[sig].sa_handler = disp; + sigemptyset(&set); + sact[sig].sa_mask = set; +- if (!is_sigset) { +-#ifdef SOLARIS +- sact[sig].sa_flags = SA_NODEFER; +- if (sig != SIGILL && sig != SIGTRAP && sig != SIGPWR) { +- sact[sig].sa_flags |= SA_RESETHAND; +- } +-#else +- sact[sig].sa_flags = 0; +-#endif +- } else { +- sact[sig].sa_flags = 0; +- } ++ sact[sig].sa_flags = 0; + } + + static sa_handler_t set_signal(int sig, sa_handler_t disp, bool is_sigset) { +@@ -188,7 +146,6 @@ + bool sigblocked; + + signal_lock(); +- allocate_sact(); + + sigused = sigismember(&jvmsigs, sig); + if (jvm_signal_installed && sigused) { +@@ -200,13 +157,6 @@ + oldhandler = sact[sig].sa_handler; + save_signal_handler(sig, disp, is_sigset); + +-#ifdef SOLARIS +- if (is_sigset && sigblocked) { +- /* We won't honor the SIG_HOLD request to change the signal mask */ +- oldhandler = SIG_HOLD; +- } +-#endif +- + signal_unlock(); + return oldhandler; + } else if (jvm_signal_installing) { +@@ -284,7 +234,6 @@ + + signal_lock(); + +- allocate_sact(); + sigused = sigismember(&jvmsigs, sig); + if (jvm_signal_installed && sigused) { + /* jvm has installed its signal handler for this signal. */ +@@ -351,7 +300,6 @@ + } + + JNIEXPORT struct sigaction *JVM_get_signal_action(int sig) { +- allocate_sact(); + /* Does race condition make sense here? */ + if (sigismember(&jvmsigs, sig)) { + return &sact[sig]; +--- old/src/java.base/unix/native/libnet/Inet4AddressImpl.c 2020-05-20 18:01:21.071630418 -0700 ++++ new/src/java.base/unix/native/libnet/Inet4AddressImpl.c 2020-05-20 18:01:20.691623121 -0700 +@@ -66,27 +66,8 @@ + if (gethostname(hostname, sizeof(hostname)) != 0) { + strcpy(hostname, "localhost"); + } else { +-#if defined(__solaris__) +- // try to resolve hostname via nameservice +- // if it is known but getnameinfo fails, hostname will still be the +- // value from gethostname +- struct addrinfo hints, *res; +- + // make sure string is null-terminated + hostname[NI_MAXHOST] = '\0'; +- memset(&hints, 0, sizeof(hints)); +- hints.ai_flags = AI_CANONNAME; +- hints.ai_family = AF_INET; +- +- if (getaddrinfo(hostname, NULL, &hints, &res) == 0) { +- getnameinfo(res->ai_addr, res->ai_addrlen, hostname, sizeof(hostname), +- NULL, 0, NI_NAMEREQD); +- freeaddrinfo(res); +- } +-#else +- // make sure string is null-terminated +- hostname[NI_MAXHOST] = '\0'; +-#endif + } + return (*env)->NewStringUTF(env, hostname); + } +--- old/src/java.base/unix/native/libnet/Inet6AddressImpl.c 2020-05-20 18:01:22.055649312 -0700 ++++ new/src/java.base/unix/native/libnet/Inet6AddressImpl.c 2020-05-20 18:01:21.719642860 -0700 +@@ -67,27 +67,8 @@ + if (gethostname(hostname, sizeof(hostname)) != 0) { + strcpy(hostname, "localhost"); + } else { +-#if defined(__solaris__) +- // try to resolve hostname via nameservice +- // if it is known but getnameinfo fails, hostname will still be the +- // value from gethostname +- struct addrinfo hints, *res; +- + // make sure string is null-terminated + hostname[NI_MAXHOST] = '\0'; +- memset(&hints, 0, sizeof(hints)); +- hints.ai_flags = AI_CANONNAME; +- hints.ai_family = AF_UNSPEC; +- +- if (getaddrinfo(hostname, NULL, &hints, &res) == 0) { +- getnameinfo(res->ai_addr, res->ai_addrlen, hostname, sizeof(hostname), +- NULL, 0, NI_NAMEREQD); +- freeaddrinfo(res); +- } +-#else +- // make sure string is null-terminated +- hostname[NI_MAXHOST] = '\0'; +-#endif + } + return (*env)->NewStringUTF(env, hostname); + } +--- old/src/java.base/unix/native/libnet/NetworkInterface.c 2020-05-20 18:01:23.023667898 -0700 ++++ new/src/java.base/unix/native/libnet/NetworkInterface.c 2020-05-20 18:01:22.695661600 -0700 +@@ -37,12 +37,6 @@ + #include + #endif + +-#if defined(__solaris__) +-#include +-#include +-#include +-#endif +- + #if defined(_ALLBSD_SOURCE) + #include + #include +@@ -55,11 +49,6 @@ + + #if defined(__linux__) + #define _PATH_PROCNET_IFINET6 "/proc/net/if_inet6" +-#elif defined(__solaris__) +- #ifndef SIOCGLIFHWADDR +- #define SIOCGLIFHWADDR _IOWR('i', 192, struct lifreq) +- #endif +- #define DEV_PREFIX "/dev/" + #endif + + #ifdef LIFNAMSIZ +@@ -146,11 +135,6 @@ + const struct in_addr *addr, unsigned char *buf); + static int getMTU(JNIEnv *env, int sock, const char *ifname); + +-#if defined(__solaris__) +-static int getMacFromDevice(JNIEnv *env, const char *ifname, +- unsigned char *retbuf); +-#endif +- + /******************* Java entry points *****************************/ + + /* +@@ -1674,372 +1658,6 @@ + + #endif /* _AIX */ + +-/** Solaris **/ +-#if defined(__solaris__) +- +-/* +- * Opens a socket for further ioctl calls. Tries AF_INET socket first and +- * if it fails return AF_INET6 socket. +- */ +-static int openSocketWithFallback(JNIEnv *env, const char *ifname) { +- int sock, alreadyV6 = 0; +- struct lifreq if2; +- +- if ((sock = socket(AF_INET, SOCK_DGRAM, 0)) < 0) { +- if (errno == EPROTONOSUPPORT || errno == EAFNOSUPPORT) { +- if ((sock = socket(AF_INET6, SOCK_DGRAM, 0)) < 0) { +- JNU_ThrowByNameWithMessageAndLastError +- (env, JNU_JAVANETPKG "SocketException", "IPV6 Socket creation failed"); +- return -1; +- } +- alreadyV6 = 1; +- } else { // errno is not NOSUPPORT +- JNU_ThrowByNameWithMessageAndLastError +- (env, JNU_JAVANETPKG "SocketException", "IPV4 Socket creation failed"); +- return -1; +- } +- } +- +- // Solaris requires that we have an IPv6 socket to query an interface +- // without an IPv4 address - check it here. POSIX 1 require the kernel to +- // return ENOTTY if the call is inappropriate for a device e.g. the NETMASK +- // for a device having IPv6 only address but not all devices follow the +- // standard so fall back on any error. It's not an ecologically friendly +- // gesture but more reliable. +- if (!alreadyV6) { +- memset((char *)&if2, 0, sizeof(if2)); +- strncpy(if2.lifr_name, ifname, sizeof(if2.lifr_name) - 1); +- if (ioctl(sock, SIOCGLIFNETMASK, (char *)&if2) < 0) { +- close(sock); +- if ((sock = socket(AF_INET6, SOCK_DGRAM, 0)) < 0) { +- JNU_ThrowByNameWithMessageAndLastError +- (env, JNU_JAVANETPKG "SocketException", "IPV6 Socket creation failed"); +- return -1; +- } +- } +- } +- +- return sock; +-} +- +-/* +- * Enumerates and returns all IPv4 interfaces on Solaris. +- */ +-static netif *enumIPv4Interfaces(JNIEnv *env, int sock, netif *ifs) { +- struct lifconf ifc; +- struct lifreq *ifreqP; +- struct lifnum numifs; +- char *buf = NULL; +- unsigned i; +- +- // call SIOCGLIFNUM to get the interface count +- numifs.lifn_family = AF_INET; +- numifs.lifn_flags = 0; +- if (ioctl(sock, SIOCGLIFNUM, (char *)&numifs) < 0) { +- JNU_ThrowByNameWithMessageAndLastError +- (env, JNU_JAVANETPKG "SocketException", "ioctl(SIOCGLIFNUM) failed"); +- return ifs; +- } +- +- // call SIOCGLIFCONF to enumerate the interfaces +- ifc.lifc_len = numifs.lifn_count * sizeof(struct lifreq); +- CHECKED_MALLOC3(buf, char *, ifc.lifc_len); +- ifc.lifc_buf = buf; +- ifc.lifc_family = AF_INET; +- ifc.lifc_flags = 0; +- if (ioctl(sock, SIOCGLIFCONF, (char *)&ifc) < 0) { +- JNU_ThrowByNameWithMessageAndLastError +- (env, JNU_JAVANETPKG "SocketException", "ioctl(SIOCGLIFCONF) failed"); +- free(buf); +- return ifs; +- } +- +- // iterate through each interface +- ifreqP = ifc.lifc_req; +- for (i = 0; i < numifs.lifn_count; i++, ifreqP++) { +- struct sockaddr addr, *broadaddrP = NULL; +- +- // ignore non IPv4 addresses +- if (ifreqP->lifr_addr.ss_family != AF_INET) { +- continue; +- } +- +- // save socket address +- memcpy(&addr, &(ifreqP->lifr_addr), sizeof(struct sockaddr)); +- +- // determine broadcast address, if applicable +- if ((ioctl(sock, SIOCGLIFFLAGS, ifreqP) == 0) && +- ifreqP->lifr_flags & IFF_BROADCAST) { +- +- // restore socket address to ifreqP +- memcpy(&(ifreqP->lifr_addr), &addr, sizeof(struct sockaddr)); +- +- // query broadcast address and set pointer to it +- if (ioctl(sock, SIOCGLIFBRDADDR, ifreqP) == 0) { +- broadaddrP = (struct sockaddr *)&(ifreqP->lifr_broadaddr); +- } +- } +- +- // add to the list +- ifs = addif(env, sock, ifreqP->lifr_name, ifs, +- &addr, broadaddrP, AF_INET, (short)ifreqP->lifr_addrlen); +- +- // if an exception occurred we return immediately +- if ((*env)->ExceptionOccurred(env)) { +- free(buf); +- return ifs; +- } +- } +- +- // free buffer +- free(buf); +- return ifs; +-} +- +-/* +- * Enumerates and returns all IPv6 interfaces on Solaris. +- */ +-static netif *enumIPv6Interfaces(JNIEnv *env, int sock, netif *ifs) { +- struct lifconf ifc; +- struct lifreq *ifreqP; +- struct lifnum numifs; +- char *buf = NULL; +- unsigned i; +- +- // call SIOCGLIFNUM to get the interface count +- numifs.lifn_family = AF_INET6; +- numifs.lifn_flags = 0; +- if (ioctl(sock, SIOCGLIFNUM, (char *)&numifs) < 0) { +- JNU_ThrowByNameWithMessageAndLastError +- (env, JNU_JAVANETPKG "SocketException", "ioctl(SIOCGLIFNUM) failed"); +- return ifs; +- } +- +- // call SIOCGLIFCONF to enumerate the interfaces +- ifc.lifc_len = numifs.lifn_count * sizeof(struct lifreq); +- CHECKED_MALLOC3(buf, char *, ifc.lifc_len); +- ifc.lifc_buf = buf; +- ifc.lifc_family = AF_INET6; +- ifc.lifc_flags = 0; +- if (ioctl(sock, SIOCGLIFCONF, (char *)&ifc) < 0) { +- JNU_ThrowByNameWithMessageAndLastError +- (env, JNU_JAVANETPKG "SocketException", "ioctl(SIOCGLIFCONF) failed"); +- free(buf); +- return ifs; +- } +- +- // iterate through each interface +- ifreqP = ifc.lifc_req; +- for (i = 0; i < numifs.lifn_count; i++, ifreqP++) { +- +- // ignore non IPv6 addresses +- if (ifreqP->lifr_addr.ss_family != AF_INET6) { +- continue; +- } +- +- // set scope ID to interface index +- ((struct sockaddr_in6 *)&(ifreqP->lifr_addr))->sin6_scope_id = +- getIndex(sock, ifreqP->lifr_name); +- +- // add to the list +- ifs = addif(env, sock, ifreqP->lifr_name, ifs, +- (struct sockaddr *)&(ifreqP->lifr_addr), +- NULL, AF_INET6, (short)ifreqP->lifr_addrlen); +- +- // if an exception occurred we return immediately +- if ((*env)->ExceptionOccurred(env)) { +- free(buf); +- return ifs; +- } +- } +- +- // free buffer +- free(buf); +- return ifs; +-} +- +-/* +- * Try to get the interface index. +- * (Not supported on Solaris 2.6 or 7) +- */ +-static int getIndex(int sock, const char *name) { +- struct lifreq if2; +- memset((char *)&if2, 0, sizeof(if2)); +- strncpy(if2.lifr_name, name, sizeof(if2.lifr_name) - 1); +- +- if (ioctl(sock, SIOCGLIFINDEX, (char *)&if2) < 0) { +- return -1; +- } +- +- return if2.lifr_index; +-} +- +-/* +- * Solaris specific DLPI code to get hardware address from a device. +- * Unfortunately, at least up to Solaris X, you have to have special +- * privileges (i.e. be root). +- */ +-static int getMacFromDevice +- (JNIEnv *env, const char *ifname, unsigned char *retbuf) +-{ +- char style1dev[MAXPATHLEN]; +- int fd; +- dl_phys_addr_req_t dlpareq; +- dl_phys_addr_ack_t *dlpaack; +- dl_error_ack_t *dlerack; +- struct strbuf msg; +- char buf[128]; +- int flags = 0; +- +- // Device is in /dev. e.g.: /dev/bge0 +- strcpy(style1dev, DEV_PREFIX); +- strcat(style1dev, ifname); +- if ((fd = open(style1dev, O_RDWR)) < 0) { +- // Can't open it. We probably are missing the privilege. +- // We'll have to try something else +- return 0; +- } +- +- dlpareq.dl_primitive = DL_PHYS_ADDR_REQ; +- dlpareq.dl_addr_type = DL_CURR_PHYS_ADDR; +- +- msg.buf = (char *)&dlpareq; +- msg.len = DL_PHYS_ADDR_REQ_SIZE; +- +- if (putmsg(fd, &msg, NULL, 0) < 0) { +- JNU_ThrowByNameWithMessageAndLastError +- (env, JNU_JAVANETPKG "SocketException", "putmsg() failed"); +- return -1; +- } +- +- dlpaack = (dl_phys_addr_ack_t *)buf; +- +- msg.buf = (char *)buf; +- msg.len = 0; +- msg.maxlen = sizeof (buf); +- if (getmsg(fd, &msg, NULL, &flags) < 0) { +- JNU_ThrowByNameWithMessageAndLastError +- (env, JNU_JAVANETPKG "SocketException", "getmsg() failed"); +- return -1; +- } +- +- if (dlpaack->dl_primitive == DL_ERROR_ACK) { +- dlerack = (dl_error_ack_t *)buf; +- if (dlerack->dl_error_primitive != DL_PHYS_ADDR_REQ) { +- JNU_ThrowByName(env, JNU_JAVANETPKG "SocketException", +- "Couldn't obtain physical address\n"); +- return -1; +- } +- if (dlerack->dl_errno == DL_UNSUPPORTED) { +- // fallback to lookup in the ARP table +- return 0; +- } +- } +- +- if (msg.len < DL_PHYS_ADDR_ACK_SIZE || dlpaack->dl_primitive != DL_PHYS_ADDR_ACK) { +- JNU_ThrowByName(env, JNU_JAVANETPKG "SocketException", +- "Couldn't obtain phys addr\n"); +- return -1; +- } +- +- memcpy(retbuf, &buf[dlpaack->dl_addr_offset], dlpaack->dl_addr_length); +- return dlpaack->dl_addr_length; +-} +- +-/* +- * Gets the Hardware address (usually MAC address) for the named interface. +- * On return puts the data in buf, and returns the length, in byte, of the +- * MAC address. Returns -1 if there is no hardware address on that interface. +- */ +-static int getMacAddress +- (JNIEnv *env, const char *ifname, const struct in_addr *addr, +- unsigned char *buf) +-{ +- struct lifreq if2; +- int len, i, sock; +- +- if ((sock = openSocketWithFallback(env, ifname)) < 0) { +- return -1; +- } +- +- // First, try the new (S11) SIOCGLIFHWADDR ioctl(). If that fails +- // try the old way. +- memset((char *)&if2, 0, sizeof(if2)); +- strncpy(if2.lifr_name, ifname, sizeof(if2.lifr_name) - 1); +- +- if (ioctl(sock, SIOCGLIFHWADDR, &if2) != -1) { +- struct sockaddr_dl *sp; +- sp = (struct sockaddr_dl *)&if2.lifr_addr; +- memcpy(buf, &sp->sdl_data[0], sp->sdl_alen); +- close(sock); +- return sp->sdl_alen; +- } +- +- // On Solaris we have to use DLPI, but it will only work if we have +- // privileged access (i.e. root). If that fails, we try a lookup +- // in the ARP table, which requires an IPv4 address. +- if (((len = getMacFromDevice(env, ifname, buf)) == 0) && (addr != NULL)) { +- struct arpreq arpreq; +- struct sockaddr_in *sin; +- struct sockaddr_in ipAddr; +- +- len = 6; //??? +- +- sin = (struct sockaddr_in *)&arpreq.arp_pa; +- memset((char *)&arpreq, 0, sizeof(struct arpreq)); +- ipAddr.sin_port = 0; +- ipAddr.sin_family = AF_INET; +- memcpy(&ipAddr.sin_addr, addr, sizeof(struct in_addr)); +- memcpy(&arpreq.arp_pa, &ipAddr, sizeof(struct sockaddr_in)); +- arpreq.arp_flags= ATF_PUBL; +- +- if (ioctl(sock, SIOCGARP, &arpreq) < 0) { +- close(sock); +- return -1; +- } +- +- memcpy(buf, &arpreq.arp_ha.sa_data[0], len); +- } +- close(sock); +- +- // all bytes to 0 means no hardware address +- for (i = 0; i < len; i++) { +- if (buf[i] != 0) +- return len; +- } +- +- return -1; +-} +- +-static int getMTU(JNIEnv *env, int sock, const char *ifname) { +- struct lifreq if2; +- memset((char *)&if2, 0, sizeof(if2)); +- strncpy(if2.lifr_name, ifname, sizeof(if2.lifr_name) - 1); +- +- if (ioctl(sock, SIOCGLIFMTU, (char *)&if2) < 0) { +- JNU_ThrowByNameWithMessageAndLastError +- (env, JNU_JAVANETPKG "SocketException", "ioctl(SIOCGLIFMTU) failed"); +- return -1; +- } +- +- return if2.lifr_mtu; +-} +- +-static int getFlags(int sock, const char *ifname, int *flags) { +- struct lifreq if2; +- memset((char *)&if2, 0, sizeof(if2)); +- strncpy(if2.lifr_name, ifname, sizeof(if2.lifr_name) - 1); +- +- if (ioctl(sock, SIOCGLIFFLAGS, (char *)&if2) < 0) { +- return -1; +- } +- +- *flags = if2.lifr_flags; +- return 0; +-} +- +-#endif /* __solaris__ */ +- + /** BSD **/ + #if defined(_ALLBSD_SOURCE) + +--- old/src/java.base/unix/native/libnet/SdpSupport.c 2020-05-20 18:01:27.335750694 -0700 ++++ new/src/java.base/unix/native/libnet/SdpSupport.c 2020-05-20 18:01:26.955743397 -0700 +@@ -27,11 +27,7 @@ + #include + #include + +-#if defined(__solaris__) +- #if !defined(PROTO_SDP) +- #define PROTO_SDP 257 +- #endif +-#elif defined(__linux__) ++#if defined(__linux__) + #if !defined(AF_INET_SDP) + #define AF_INET_SDP 27 + #endif +@@ -55,10 +51,7 @@ + { + int s; + +-#if defined(__solaris__) +- int domain = ipv6_available() ? AF_INET6 : AF_INET; +- s = socket(domain, SOCK_STREAM, PROTO_SDP); +-#elif defined(__linux__) ++#if defined(__linux__) + /** + * IPv6 not supported by SDP on Linux + */ +--- old/src/java.base/unix/native/libnet/net_util_md.c 2020-05-20 18:01:28.435771815 -0700 ++++ new/src/java.base/unix/native/libnet/net_util_md.c 2020-05-20 18:01:28.059764595 -0700 +@@ -37,14 +37,6 @@ + #include + #endif + +-#if defined(__solaris__) +-#include +-#include +-#include +-#include +-#include +-#endif +- + #if defined(MACOSX) + #include + #endif +@@ -59,20 +51,6 @@ + #define IPV6_FLOWINFO_SEND 33 + #endif + +-#if defined(__solaris__) && !defined(MAXINT) +-#define MAXINT INT_MAX +-#endif +- +-/* +- * EXCLBIND socket options only on Solaris +- */ +-#if defined(__solaris__) && !defined(TCP_EXCLBIND) +-#define TCP_EXCLBIND 0x21 +-#endif +-#if defined(__solaris__) && !defined(UDP_EXCLBIND) +-#define UDP_EXCLBIND 0x0101 +-#endif +- + #define RESTARTABLE(_cmd, _result) do { \ + do { \ + _result = _cmd; \ +@@ -85,94 +63,6 @@ + return result; + } + +-#ifdef __solaris__ +-static int init_tcp_max_buf, init_udp_max_buf; +-static int tcp_max_buf; +-static int udp_max_buf; +-static int useExclBind = 0; +- +-/* +- * Get the specified parameter from the specified driver. The value +- * of the parameter is assumed to be an 'int'. If the parameter +- * cannot be obtained return -1 +- */ +-int net_getParam(char *driver, char *param) +-{ +- struct strioctl stri; +- char buf [64]; +- int s; +- int value; +- +- s = open (driver, O_RDWR); +- if (s < 0) { +- return -1; +- } +- strncpy (buf, param, sizeof(buf)); +- stri.ic_cmd = ND_GET; +- stri.ic_timout = 0; +- stri.ic_dp = buf; +- stri.ic_len = sizeof(buf); +- if (ioctl (s, I_STR, &stri) < 0) { +- value = -1; +- } else { +- value = atoi(buf); +- } +- close (s); +- return value; +-} +- +-/* +- * Iterative way to find the max value that SO_SNDBUF or SO_RCVBUF +- * for Solaris versions that do not support the ioctl() in net_getParam(). +- * Ugly, but only called once (for each sotype). +- * +- * As an optimization, we make a guess using the default values for Solaris +- * assuming they haven't been modified with ndd. +- */ +- +-#define MAX_TCP_GUESS 1024 * 1024 +-#define MAX_UDP_GUESS 2 * 1024 * 1024 +- +-#define FAIL_IF_NOT_ENOBUFS if (errno != ENOBUFS) return -1 +- +-static int findMaxBuf(int fd, int opt, int sotype) { +- int a = 0; +- int b = MAXINT; +- int initial_guess; +- int limit = -1; +- +- if (sotype == SOCK_DGRAM) { +- initial_guess = MAX_UDP_GUESS; +- } else { +- initial_guess = MAX_TCP_GUESS; +- } +- +- if (setsockopt(fd, SOL_SOCKET, opt, &initial_guess, sizeof(int)) == 0) { +- initial_guess++; +- if (setsockopt(fd, SOL_SOCKET, opt, &initial_guess,sizeof(int)) < 0) { +- FAIL_IF_NOT_ENOBUFS; +- return initial_guess - 1; +- } +- a = initial_guess; +- } else { +- FAIL_IF_NOT_ENOBUFS; +- b = initial_guess - 1; +- } +- do { +- int mid = a + (b-a)/2; +- if (setsockopt(fd, SOL_SOCKET, opt, &mid, sizeof(int)) == 0) { +- limit = mid; +- a = mid + 1; +- } else { +- FAIL_IF_NOT_ENOBUFS; +- b = mid - 1; +- } +- } while (b >= a); +- +- return limit; +-} +-#endif +- + void + NET_ThrowByNameWithLastError(JNIEnv *env, const char *name, + const char *defaultDetail) { +@@ -256,50 +146,6 @@ + } + #endif + +- /** +- * On Solaris 8 it's possible to create INET6 sockets even +- * though IPv6 is not enabled on all interfaces. Thus we +- * query the number of IPv6 addresses to verify that IPv6 +- * has been configured on at least one interface. +- * +- * On Linux it doesn't matter - if IPv6 is built-in the +- * kernel then IPv6 addresses will be bound automatically +- * to all interfaces. +- */ +-#ifdef __solaris__ +- +-#ifdef SIOCGLIFNUM +- { +- struct lifnum numifs; +- +- numifs.lifn_family = AF_INET6; +- numifs.lifn_flags = 0; +- if (ioctl(fd, SIOCGLIFNUM, (char *)&numifs) < 0) { +- /** +- * SIOCGLIFNUM failed - assume IPv6 not configured +- */ +- close(fd); +- return JNI_FALSE; +- } +- /** +- * If no IPv6 addresses then return false. If count > 0 +- * it's possible that all IPv6 addresses are "down" but +- * that's okay as they may be brought "up" while the +- * VM is running. +- */ +- if (numifs.lifn_count == 0) { +- close(fd); +- return JNI_FALSE; +- } +- } +-#else +- /* SIOCGLIFNUM not defined in build environment ??? */ +- close(fd); +- return JNI_FALSE; +-#endif +- +-#endif /* __solaris */ +- + /* + * OK we may have the stack available in the kernel, + * we should also check if the APIs are available. +@@ -364,26 +210,6 @@ + } + } + +-void parseExclusiveBindProperty(JNIEnv *env) { +-#ifdef __solaris__ +- jstring s, flagSet; +- jclass iCls; +- jmethodID mid; +- +- s = (*env)->NewStringUTF(env, "sun.net.useExclusiveBind"); +- CHECK_NULL(s); +- iCls = (*env)->FindClass(env, "java/lang/System"); +- CHECK_NULL(iCls); +- mid = (*env)->GetStaticMethodID(env, iCls, "getProperty", +- "(Ljava/lang/String;)Ljava/lang/String;"); +- CHECK_NULL(mid); +- flagSet = (*env)->CallStaticObjectMethod(env, iCls, mid, s); +- if (flagSet != NULL) { +- useExclBind = 1; +- } +-#endif +-} +- + JNIEXPORT jint JNICALL + NET_EnableFastTcpLoopback(int fd) { + return 0; +@@ -542,7 +368,7 @@ + *level = IPPROTO_IPV6; + *optname = IPV6_MULTICAST_LOOP; + return 0; +-#if (defined(__solaris__) || defined(MACOSX)) ++#if defined(MACOSX) + // Map IP_TOS request to IPV6_TCLASS + case java_net_SocketOptions_IP_TOS: + *level = IPPROTO_IPV6; +@@ -691,65 +517,6 @@ + *iptos &= (IPTOS_TOS_MASK | IPTOS_PREC_MASK); + } + +- /* +- * SOL_SOCKET/{SO_SNDBUF,SO_RCVBUF} - On Solaris we may need to clamp +- * the value when it exceeds the system limit. +- */ +-#ifdef __solaris__ +- if (level == SOL_SOCKET) { +- if (opt == SO_SNDBUF || opt == SO_RCVBUF) { +- int sotype=0; +- socklen_t arglen; +- int *bufsize, maxbuf; +- int ret; +- +- /* Attempt with the original size */ +- ret = setsockopt(fd, level, opt, arg, len); +- if ((ret == 0) || (ret == -1 && errno != ENOBUFS)) +- return ret; +- +- /* Exceeded system limit so clamp and retry */ +- +- arglen = sizeof(sotype); +- if (getsockopt(fd, SOL_SOCKET, SO_TYPE, (void *)&sotype, +- &arglen) < 0) { +- return -1; +- } +- +- /* +- * We try to get tcp_maxbuf (and udp_max_buf) using +- * an ioctl() that isn't available on all versions of Solaris. +- * If that fails, we use the search algorithm in findMaxBuf() +- */ +- if (!init_tcp_max_buf && sotype == SOCK_STREAM) { +- tcp_max_buf = net_getParam("/dev/tcp", "tcp_max_buf"); +- if (tcp_max_buf == -1) { +- tcp_max_buf = findMaxBuf(fd, opt, SOCK_STREAM); +- if (tcp_max_buf == -1) { +- return -1; +- } +- } +- init_tcp_max_buf = 1; +- } else if (!init_udp_max_buf && sotype == SOCK_DGRAM) { +- udp_max_buf = net_getParam("/dev/udp", "udp_max_buf"); +- if (udp_max_buf == -1) { +- udp_max_buf = findMaxBuf(fd, opt, SOCK_DGRAM); +- if (udp_max_buf == -1) { +- return -1; +- } +- } +- init_udp_max_buf = 1; +- } +- +- maxbuf = (sotype == SOCK_STREAM) ? tcp_max_buf : udp_max_buf; +- bufsize = (int *)arg; +- if (*bufsize > maxbuf) { +- *bufsize = maxbuf; +- } +- } +- } +-#endif +- + #ifdef _AIX + if (level == SOL_SOCKET) { + if (opt == SO_SNDBUF || opt == SO_RCVBUF) { +@@ -864,20 +631,10 @@ + * + * Linux allows a socket to bind to 127.0.0.255 which must be + * caught. +- * +- * On Solaris with IPv6 enabled we must use an exclusive +- * bind to guarantee a unique port number across the IPv4 and +- * IPv6 port spaces. +- * + */ + int + NET_Bind(int fd, SOCKETADDRESS *sa, int len) + { +-#if defined(__solaris__) +- int level = -1; +- int exclbind = -1; +- int arg, alen; +-#endif + int rv; + + #ifdef __linux__ +@@ -894,61 +651,8 @@ + } + #endif + +-#if defined(__solaris__) +- /* +- * Solaris has separate IPv4 and IPv6 port spaces so we +- * use an exclusive bind when SO_REUSEADDR is not used to +- * give the illusion of a unified port space. +- * This also avoids problems with IPv6 sockets connecting +- * to IPv4 mapped addresses whereby the socket conversion +- * results in a late bind that fails because the +- * corresponding IPv4 port is in use. +- */ +- alen = sizeof(arg); +- +- if (useExclBind || +- getsockopt(fd, SOL_SOCKET, SO_REUSEADDR, (char *)&arg, &alen) == 0) +- { +- if (useExclBind || arg == 0) { +- /* +- * SO_REUSEADDR is disabled or sun.net.useExclusiveBind +- * property is true so enable TCP_EXCLBIND or +- * UDP_EXCLBIND +- */ +- alen = sizeof(arg); +- if (getsockopt(fd, SOL_SOCKET, SO_TYPE, (char *)&arg, &alen) == 0) +- { +- if (arg == SOCK_STREAM) { +- level = IPPROTO_TCP; +- exclbind = TCP_EXCLBIND; +- } else { +- level = IPPROTO_UDP; +- exclbind = UDP_EXCLBIND; +- } +- } +- +- arg = 1; +- setsockopt(fd, level, exclbind, (char *)&arg, sizeof(arg)); +- } +- } +- +-#endif +- + rv = bind(fd, &sa->sa, len); + +-#if defined(__solaris__) +- if (rv < 0) { +- int en = errno; +- /* Restore *_EXCLBIND if the bind fails */ +- if (exclbind != -1) { +- int arg = 0; +- setsockopt(fd, level, exclbind, (char *)&arg, +- sizeof(arg)); +- } +- errno = en; +- } +-#endif +- + return rv; + } + +--- old/src/java.base/unix/native/libnet/net_util_md.h 2020-05-20 18:01:29.539793012 -0700 ++++ new/src/java.base/unix/native/libnet/net_util_md.h 2020-05-20 18:01:29.147785486 -0700 +@@ -47,8 +47,6 @@ + #ifndef SO_REUSEPORT + #ifdef __linux__ + #define SO_REUSEPORT 15 +-#elif defined(__solaris__) +-#define SO_REUSEPORT 0x100e + #elif defined(AIX) || defined(MACOSX) + #define SO_REUSEPORT 0x0200 + #else +@@ -82,8 +80,4 @@ + void NET_ThrowByNameWithLastError(JNIEnv *env, const char *name, + const char *defaultDetail); + +-#ifdef __solaris__ +-int net_getParam(char *driver, char *param); +-#endif +- + #endif /* NET_UTILS_MD_H */ +--- old/src/java.base/unix/native/libnet/portconfig.c 2020-05-20 18:01:30.539812214 -0700 ++++ new/src/java.base/unix/native/libnet/portconfig.c 2020-05-20 18:01:30.203805762 -0700 +@@ -60,13 +60,6 @@ + } + return -1; + } +- +-#elif defined(__solaris__) +- { +- range->higher = net_getParam("/dev/tcp", "tcp_largest_anon_port"); +- range->lower = net_getParam("/dev/tcp", "tcp_smallest_anon_port"); +- return 0; +- } + #elif defined(_ALLBSD_SOURCE) + { + int ret; +--- old/src/java.base/unix/native/libnio/ch/DatagramChannelImpl.c 2020-05-20 18:01:31.615832874 -0700 ++++ new/src/java.base/unix/native/libnio/ch/DatagramChannelImpl.c 2020-05-20 18:01:31.211825117 -0700 +@@ -50,9 +50,6 @@ + jint fd = fdval(env, fdo); + int rv; + +-#if defined(__solaris__) +- rv = connect(fd, 0, 0); +-#else + #if defined(__APPLE__) + // On macOS systems we use disconnectx + rv = disconnectx(fd, SAE_ASSOCID_ANY, SAE_CONNID_ANY); +@@ -86,8 +83,6 @@ + rv = errno = 0; + #endif // defined(_ALLBSD_SOURCE) || defined(_AIX) + +-#endif // defined(__solaris__) +- + if (rv < 0) + handleSocketError(env, errno); + } +--- old/src/java.base/unix/native/libnio/ch/NativeThread.c 2020-05-20 18:01:33.783874502 -0700 ++++ new/src/java.base/unix/native/libnio/ch/NativeThread.c 2020-05-20 18:01:33.371866591 -0700 +@@ -40,9 +40,6 @@ + #elif defined(_AIX) + /* Also defined in net/aix_close.c */ + #define INTERRUPT_SIGNAL (SIGRTMAX - 1) +-#elif defined(__solaris__) +- #include +- #define INTERRUPT_SIGNAL (SIGRTMAX - 2) + #elif defined(_ALLBSD_SOURCE) + /* Also defined in net/bsd_close.c */ + #define INTERRUPT_SIGNAL SIGIO +@@ -76,22 +73,14 @@ + JNIEXPORT jlong JNICALL + Java_sun_nio_ch_NativeThread_current0(JNIEnv *env, jclass cl) + { +-#ifdef __solaris__ +- return (jlong)thr_self(); +-#else + return (jlong)pthread_self(); +-#endif + } + + JNIEXPORT void JNICALL + Java_sun_nio_ch_NativeThread_signal0(JNIEnv *env, jclass cl, jlong thread) + { + int ret; +-#ifdef __solaris__ +- ret = thr_kill((thread_t)thread, INTERRUPT_SIGNAL); +-#else + ret = pthread_kill((pthread_t)thread, INTERRUPT_SIGNAL); +-#endif + #ifdef MACOSX + if (ret != 0 && ret != ESRCH) + #else +--- old/src/java.base/unix/native/libnio/ch/Net.c 2020-05-20 18:01:34.943896775 -0700 ++++ new/src/java.base/unix/native/libnio/ch/Net.c 2020-05-20 18:01:34.515888557 -0700 +@@ -215,7 +215,7 @@ + JNIEXPORT jboolean JNICALL + Java_sun_nio_ch_Net_canIPv6SocketJoinIPv4Group0(JNIEnv* env, jclass cl) + { +-#if defined(__linux__) || defined(__APPLE__) || defined(__solaris__) ++#if defined(__linux__) || defined(__APPLE__) + /* IPv6 sockets can join IPv4 multicast groups */ + return JNI_TRUE; + #else +@@ -227,7 +227,7 @@ + JNIEXPORT jboolean JNICALL + Java_sun_nio_ch_Net_canJoin6WithIPv4Group0(JNIEnv* env, jclass cl) + { +-#if defined(__APPLE__) || defined(__solaris__) ++#if defined(__APPLE__) + /* IPV6_ADD_MEMBERSHIP can be used to join IPv4 multicast groups */ + return JNI_TRUE; + #else +--- old/src/java.base/unix/native/libnio/ch/nio_util.h 2020-05-20 18:01:36.115919279 -0700 ++++ new/src/java.base/unix/native/libnio/ch/nio_util.h 2020-05-20 18:01:35.695911215 -0700 +@@ -41,8 +41,6 @@ + #ifndef SO_REUSEPORT + #ifdef __linux__ + #define SO_REUSEPORT 15 +-#elif defined(__solaris__) +-#define SO_REUSEPORT 0x100e + #elif defined(AIX) || defined(MACOSX) + #define SO_REUSEPORT 0x0200 + #else +--- old/src/java.base/unix/native/libnio/fs/UnixNativeDispatcher.c 2020-05-20 18:01:37.127938711 -0700 ++++ new/src/java.base/unix/native/libnio/fs/UnixNativeDispatcher.c 2020-05-20 18:01:36.787932182 -0700 +@@ -45,17 +45,10 @@ + #include + #endif + +-/* For POSIX-compliant getpwuid_r, getgrgid_r on Solaris */ +-#if defined(__solaris__) +-#define _POSIX_PTHREAD_SEMANTICS +-#endif ++/* For POSIX-compliant getpwuid_r */ + #include + #include + +-#ifdef __solaris__ +-#include +-#endif +- + #ifdef __linux__ + #include + #include // makedev macros +@@ -382,8 +375,7 @@ + + /* system calls that might not be available at run time */ + +-#if (defined(__solaris__) && defined(_LP64)) || defined(_ALLBSD_SOURCE) +- /* Solaris 64-bit does not have openat64/fstatat64 */ ++#if defined(_ALLBSD_SOURCE) + my_openat64_func = (openat64_func*)dlsym(RTLD_DEFAULT, "openat"); + my_fstatat64_func = (fstatat64_func*)dlsym(RTLD_DEFAULT, "fstatat"); + #else +--- old/src/java.base/windows/native/libnet/net_util_md.c 2020-05-20 18:01:38.255960369 -0700 ++++ new/src/java.base/windows/native/libnet/net_util_md.c 2020-05-20 18:01:37.863952843 -0700 +@@ -125,8 +125,6 @@ + } + return TRUE; + } +- +-void parseExclusiveBindProperty(JNIEnv *env) {} + + /* + * Since winsock doesn't have the equivalent of strerror(errno) +--- old/src/java.desktop/share/classes/sun/awt/FontConfiguration.java 2020-05-20 18:01:41.588024347 -0700 ++++ new/src/java.desktop/share/classes/sun/awt/FontConfiguration.java 2020-05-20 18:01:41.204016974 -0700 +@@ -1422,22 +1422,6 @@ + } + } + } +- if (OSInfo.getOSType() == OSInfo.OSType.SOLARIS) { +- for (int ii = 0; ii < table_awtfontpaths.length; ii++) { +- if (table_awtfontpaths[ii] == 0) { +- String script = getString(table_scriptIDs[ii]); +- if (script.contains("dingbats") || +- script.contains("symbol")) { +- continue; +- } +- System.err.println("\nError: " +- + " entry is missing!!!"); +- errors++; +- } +- } +- } + if (errors != 0) { + System.err.println("!!THERE ARE " + errors + " ERROR(S) IN " + + "THE FONTCONFIG FILE, PLEASE CHECK ITS CONTENT!!\n"); +--- old/src/java.desktop/share/classes/sun/awt/OSInfo.java 2020-05-20 18:01:42.704045776 -0700 ++++ new/src/java.desktop/share/classes/sun/awt/OSInfo.java 2020-05-20 18:01:42.320038402 -0700 +@@ -39,7 +39,6 @@ + public static enum OSType { + WINDOWS, + LINUX, +- SOLARIS, + MACOSX, + AIX, + UNKNOWN +@@ -96,7 +95,6 @@ + // Map OperatingSystem enum values to OSType enum values. + case WINDOWS -> WINDOWS; + case LINUX -> LINUX; +- case SOLARIS -> SOLARIS; + case MACOS -> MACOSX; + case AIX -> AIX; + default -> UNKNOWN; +--- old/src/java.desktop/share/classes/sun/font/FontUtilities.java 2020-05-20 18:01:48.020147849 -0700 ++++ new/src/java.desktop/share/classes/sun/font/FontUtilities.java 2020-05-20 18:01:47.620140168 -0700 +@@ -41,8 +41,6 @@ + */ + public final class FontUtilities { + +- public static boolean isSolaris; +- + public static boolean isLinux; + + public static boolean isMacOSX; +@@ -67,8 +65,6 @@ + @SuppressWarnings("deprecation") // PlatformLogger.setLevel is deprecated. + @Override + public Object run() { +- +- isSolaris = OSInfo.getOSType() == OSInfo.OSType.SOLARIS; + + isLinux = OSInfo.getOSType() == OSInfo.OSType.LINUX; + +--- old/src/java.desktop/share/native/libjsound/SoundDefs.h 2020-05-20 18:01:56.500310674 -0700 ++++ new/src/java.desktop/share/native/libjsound/SoundDefs.h 2020-05-20 18:01:56.112303224 -0700 +@@ -29,10 +29,9 @@ + + // types for X_PLATFORM + #define X_WINDOWS 1 +-#define X_SOLARIS 2 +-#define X_LINUX 3 +-#define X_BSD 4 +-#define X_MACOSX 5 ++#define X_LINUX 2 ++#define X_BSD 3 ++#define X_MACOSX 4 + + // ********************************** + // Make sure you set X_PLATFORM defines correctly. +@@ -45,7 +44,7 @@ + + + // following is needed for _LP64 +-#if ((X_PLATFORM == X_SOLARIS) || (X_PLATFORM == X_LINUX) || (X_PLATFORM == X_MACOSX)) ++#if ((X_PLATFORM == X_LINUX) || (X_PLATFORM == X_MACOSX)) + #include + #endif + +@@ -115,11 +114,6 @@ + #endif + + +-#if X_PLATFORM == X_SOLARIS +-#define INLINE +-#endif +- +- + #if X_PLATFORM == X_LINUX + #define INLINE inline + #endif +--- old/src/java.desktop/unix/classes/sun/awt/X11FontManager.java 2020-05-20 18:02:35.237054448 -0700 ++++ new/src/java.desktop/unix/classes/sun/awt/X11FontManager.java 2020-05-20 18:02:34.897047919 -0700 +@@ -686,8 +686,7 @@ + * and do the best we can. + */ + FontConfiguration mFontConfig = new MFontConfiguration(this); +- if ((FontUtilities.isLinux && !mFontConfig.foundOsSpecificFile()) || +- (FontUtilities.isSolaris && !mFontConfig.fontFilesArePresent())) { ++ if ((FontUtilities.isLinux && !mFontConfig.foundOsSpecificFile())) { + FcFontConfiguration fcFontConfig = + new FcFontConfiguration(this); + if (fcFontConfig.init()) { +--- old/src/java.desktop/unix/classes/sun/font/MFontConfiguration.java 2020-05-20 18:02:37.405096076 -0700 ++++ new/src/java.desktop/unix/classes/sun/font/MFontConfiguration.java 2020-05-20 18:02:37.021088702 -0700 +@@ -68,59 +68,7 @@ + */ + protected void initReorderMap() { + reorderMap = new HashMap<>(); +- if (osName == null) { /* null means SunOS */ +- initReorderMapForSolaris(); +- } else { +- initReorderMapForLinux(); +- } +- } +- +- private void initReorderMapForSolaris() { +- /* Don't create a no-op entry, so we can optimize this case +- * i.e. we don't need to do anything so can avoid slower paths in +- * the code. +- */ +-// reorderMap.put("UTF-8", "latin-1"); +- reorderMap.put("UTF-8.hi", "devanagari"); // NB is in Lucida. +- reorderMap.put("UTF-8.ja", +- new String[] {"japanese-x0201", "japanese-x0208", "japanese-x0212"}); +- reorderMap.put("UTF-8.ko", "korean-johab"); +- reorderMap.put("UTF-8.th", "thai"); +- reorderMap.put("UTF-8.zh.TW", "chinese-big5"); +- reorderMap.put("UTF-8.zh.HK", new String[] {"chinese-big5", "chinese-hkscs"}); +- reorderMap.put("UTF-8.zh.CN", +- new String[] {"chinese-gb18030-0", "chinese-gb18030-1"}); +- reorderMap.put("UTF-8.zh", +- new String[] {"chinese-big5", "chinese-hkscs", "chinese-gb18030-0,chinese-gb18030-1"}); +- reorderMap.put("Big5", "chinese-big5"); +- reorderMap.put("Big5-HKSCS", new String[] {"chinese-big5", "chinese-hkscs"}); +- reorderMap.put("GB2312", new String[] {"chinese-gbk", "chinese-gb2312"}); +- reorderMap.put("x-EUC-TW", +- new String[] {"chinese-cns11643-1", "chinese-cns11643-2", "chinese-cns11643-3"}); +- reorderMap.put("GBK", "chinese-gbk"); +- reorderMap.put("GB18030",new String[] {"chinese-gb18030-0", "chinese-gb18030-1"}); +- +- reorderMap.put("TIS-620", "thai"); +- reorderMap.put("x-PCK", +- new String[] {"japanese-x0201", "japanese-x0208", "japanese-x0212"}); +- reorderMap.put("x-eucJP-Open", +- new String[] {"japanese-x0201", "japanese-x0208", "japanese-x0212"}); +- reorderMap.put("EUC-KR", "korean"); +- /* Don't create a no-op entry, so we can optimize this case */ +-// reorderMap.put("ISO-8859-1", "latin-1"); +- reorderMap.put("ISO-8859-2", "latin-2"); +- reorderMap.put("ISO-8859-5", "cyrillic-iso8859-5"); +- reorderMap.put("windows-1251", "cyrillic-cp1251"); +- reorderMap.put("KOI8-R", "cyrillic-koi8-r"); +- reorderMap.put("ISO-8859-6", "arabic"); +- reorderMap.put("ISO-8859-7", "greek"); +- reorderMap.put("ISO-8859-8", "hebrew"); +- reorderMap.put("ISO-8859-9", "latin-5"); +- reorderMap.put("ISO-8859-13", "latin-7"); +- reorderMap.put("ISO-8859-15", "latin-9"); +- } + +- private void initReorderMapForLinux() { + reorderMap.put("UTF-8.ja.JP", "japanese-iso10646"); + reorderMap.put("UTF-8.ko.KR", "korean-iso10646"); + reorderMap.put("UTF-8.zh.TW", "chinese-tw-iso10646"); +@@ -130,12 +78,7 @@ + reorderMap.put("GB2312", "chinese-gb18030"); + reorderMap.put("Big5", "chinese-big5"); + reorderMap.put("EUC-KR", "korean"); +- if (osName.equals("Sun")){ +- reorderMap.put("GB18030", "chinese-cn-iso10646"); +- } +- else { +- reorderMap.put("GB18030", "chinese-gb18030"); +- } ++ reorderMap.put("GB18030", "chinese-gb18030"); + } + + /** +@@ -144,10 +87,7 @@ + protected void setOsNameAndVersion(){ + super.setOsNameAndVersion(); + +- if (osName.equals("SunOS")) { +- //don't care os name on Solaris +- osName = null; +- } else if (osName.equals("Linux")) { ++ if (osName.equals("Linux")) { + try { + File f; + if ((f = new File("/etc/fedora-release")).canRead()) { +--- old/src/java.desktop/unix/classes/sun/print/PrintServiceLookupProvider.java 2020-05-20 18:02:38.501117121 -0700 ++++ new/src/java.desktop/unix/classes/sun/print/PrintServiceLookupProvider.java 2020-05-20 18:02:38.117109747 -0700 +@@ -150,10 +150,6 @@ + return OSInfo.getOSType() == OSInfo.OSType.MACOSX; + } + +- static boolean isSysV() { +- return OSInfo.getOSType() == OSInfo.OSType.SOLARIS; +- } +- + static boolean isLinux() { + return OSInfo.getOSType() == OSInfo.OSType.LINUX; + } +@@ -305,7 +301,7 @@ + } + } + } else { +- if (isMac() || isSysV()) { ++ if (isMac()) { + printers = getAllPrinterNamesSysV(); + } else if (isAIX()) { + printers = getAllPrinterNamesAIX(); +@@ -489,7 +485,7 @@ + } + /* fallback if nothing not having a printer at this point */ + PrintService printer = null; +- if (isMac() || isSysV()) { ++ if (isMac()) { + printer = getNamedPrinterNameSysV(name); + } else if (isAIX()) { + printer = getNamedPrinterNameAIX(name); +@@ -660,7 +656,7 @@ + psuri = printerInfo[1]; + } + } else { +- if (isMac() || isSysV()) { ++ if (isMac()) { + defaultPrinter = getDefaultPrinterNameSysV(); + } else if (isAIX()) { + defaultPrinter = getDefaultPrinterNameAIX(); +@@ -880,7 +876,7 @@ + ArrayList results = null; + try { + final String[] cmd = new String[3]; +- if (isSysV() || isAIX()) { ++ if (isAIX()) { + cmd[0] = "/usr/bin/sh"; + cmd[1] = "-c"; + cmd[2] = "env LC_ALL=C " + command; +--- old/src/java.desktop/unix/classes/sun/print/UnixPrintJob.java 2020-05-20 18:02:39.605138318 -0700 ++++ new/src/java.desktop/unix/classes/sun/print/UnixPrintJob.java 2020-05-20 18:02:39.221130945 -0700 +@@ -872,51 +872,25 @@ + isAttributeCategorySupported(JobSheets.class)) { + ncomps+=1; + } +- if (PrintServiceLookupProvider.isSysV()) { +- ncomps+=1; // lp uses 1 more arg than lpr (make a copy) +- execCmd = new String[ncomps]; +- execCmd[n++] = "/usr/bin/lp"; +- execCmd[n++] = "-c"; // make a copy of the spool file +- if ((pFlags & PRINTER) != 0) { +- execCmd[n++] = "-d" + printer; +- } +- if ((pFlags & JOBTITLE) != 0) { +- String quoteChar = "\""; +- execCmd[n++] = "-t " + quoteChar+jobTitle+quoteChar; +- } +- if ((pFlags & COPIES) != 0) { +- execCmd[n++] = "-n " + copies; +- } +- if ((pFlags & NOSHEET) != 0) { +- execCmd[n++] = "-o nobanner"; +- } else if (getPrintService(). +- isAttributeCategorySupported(JobSheets.class)) { +- execCmd[n++] = "-o job-sheets=standard"; +- } +- if ((pFlags & OPTIONS) != 0) { +- execCmd[n++] = "-o " + options; +- } +- } else { +- execCmd = new String[ncomps]; +- execCmd[n++] = "/usr/bin/lpr"; +- if ((pFlags & PRINTER) != 0) { +- execCmd[n++] = "-P" + printer; +- } +- if ((pFlags & JOBTITLE) != 0) { +- execCmd[n++] = "-J " + jobTitle; +- } +- if ((pFlags & COPIES) != 0) { +- execCmd[n++] = "-#" + copies; +- } +- if ((pFlags & NOSHEET) != 0) { +- execCmd[n++] = "-h"; +- } else if (getPrintService(). +- isAttributeCategorySupported(JobSheets.class)) { +- execCmd[n++] = "-o job-sheets=standard"; +- } +- if ((pFlags & OPTIONS) != 0) { +- execCmd[n++] = "-o" + options; +- } ++ execCmd = new String[ncomps]; ++ execCmd[n++] = "/usr/bin/lpr"; ++ if ((pFlags & PRINTER) != 0) { ++ execCmd[n++] = "-P" + printer; ++ } ++ if ((pFlags & JOBTITLE) != 0) { ++ execCmd[n++] = "-J " + jobTitle; ++ } ++ if ((pFlags & COPIES) != 0) { ++ execCmd[n++] = "-#" + copies; ++ } ++ if ((pFlags & NOSHEET) != 0) { ++ execCmd[n++] = "-h"; ++ } else if (getPrintService(). ++ isAttributeCategorySupported(JobSheets.class)) { ++ execCmd[n++] = "-o job-sheets=standard"; ++ } ++ if ((pFlags & OPTIONS) != 0) { ++ execCmd[n++] = "-o" + options; + } + execCmd[n++] = spoolFile; + if (IPPPrintService.debugPrint) { +--- old/src/java.desktop/unix/classes/sun/print/UnixPrintService.java 2020-05-20 18:02:40.629157980 -0700 ++++ new/src/java.desktop/unix/classes/sun/print/UnixPrintService.java 2020-05-20 18:02:40.293151529 -0700 +@@ -220,31 +220,6 @@ + return name; + } + +- private PrinterIsAcceptingJobs getPrinterIsAcceptingJobsSysV() { +- String command = "/usr/bin/lpstat -a " + printer; +- String[] results= PrintServiceLookupProvider.execCmd(command); +- +- if (results != null && results.length > 0) { +- if (results[0].startsWith(printer + " accepting requests")) { +- return PrinterIsAcceptingJobs.ACCEPTING_JOBS; +- } +- else if (results[0].startsWith(printer)) { +- /* As well as "myprinter accepting requests", look for +- * "myprinter@somehost accepting requests". +- */ +- int index = printer.length(); +- String str = results[0]; +- if (str.length() > index && +- str.charAt(index) == '@' && +- str.indexOf(" accepting requests", index) > 0 && +- str.indexOf(" not accepting requests", index) == -1) { +- return PrinterIsAcceptingJobs.ACCEPTING_JOBS; +- } +- } +- } +- return PrinterIsAcceptingJobs.NOT_ACCEPTING_JOBS ; +- } +- + private PrinterIsAcceptingJobs getPrinterIsAcceptingJobsBSD() { + if (PrintServiceLookupProvider.cmdIndex == + PrintServiceLookupProvider.UNINITIALIZED) { +@@ -322,9 +297,7 @@ + } + + private PrinterIsAcceptingJobs getPrinterIsAcceptingJobs() { +- if (PrintServiceLookupProvider.isSysV()) { +- return getPrinterIsAcceptingJobsSysV(); +- } else if (PrintServiceLookupProvider.isBSD()) { ++ if (PrintServiceLookupProvider.isBSD()) { + return getPrinterIsAcceptingJobsBSD(); + } else if (PrintServiceLookupProvider.isAIX()) { + return getPrinterIsAcceptingJobsAIX(); +@@ -351,14 +324,6 @@ + } + } + +- private QueuedJobCount getQueuedJobCountSysV() { +- String command = "/usr/bin/lpstat -R " + printer; +- String[] results= PrintServiceLookupProvider.execCmd(command); +- int qlen = (results == null) ? 0 : results.length; +- +- return new QueuedJobCount(qlen); +- } +- + private QueuedJobCount getQueuedJobCountBSD() { + if (PrintServiceLookupProvider.cmdIndex == + PrintServiceLookupProvider.UNINITIALIZED) { +@@ -415,9 +380,7 @@ + } + + private QueuedJobCount getQueuedJobCount() { +- if (PrintServiceLookupProvider.isSysV()) { +- return getQueuedJobCountSysV(); +- } else if (PrintServiceLookupProvider.isBSD()) { ++ if (PrintServiceLookupProvider.isBSD()) { + return getQueuedJobCountBSD(); + } else if (PrintServiceLookupProvider.isAIX()) { + return getQueuedJobCountAIX(); +@@ -426,13 +389,6 @@ + } + } + +- private PrintServiceAttributeSet getSysVServiceAttributes() { +- PrintServiceAttributeSet attrs = new HashPrintServiceAttributeSet(); +- attrs.add(getQueuedJobCountSysV()); +- attrs.add(getPrinterIsAcceptingJobsSysV()); +- return attrs; +- } +- + private PrintServiceAttributeSet getBSDServiceAttributes() { + PrintServiceAttributeSet attrs = new HashPrintServiceAttributeSet(); + attrs.add(getQueuedJobCountBSD()); +@@ -471,9 +427,7 @@ + } + + private PrintServiceAttributeSet getDynamicAttributes() { +- if (PrintServiceLookupProvider.isSysV()) { +- return getSysVServiceAttributes(); +- } else if (PrintServiceLookupProvider.isAIX()) { ++ if (PrintServiceLookupProvider.isAIX()) { + return getAIXServiceAttributes(); + } else { + return getBSDServiceAttributes(); +--- old/src/java.desktop/unix/native/common/awt/fontpath.c 2020-05-20 18:02:43.805218963 -0700 ++++ new/src/java.desktop/unix/native/common/awt/fontpath.c 2020-05-20 18:02:43.465212435 -0700 +@@ -57,57 +57,7 @@ + + #define MAXFDIRS 512 /* Max number of directories that contain fonts */ + +-#if defined(__solaris__) +-/* +- * This can be set in the makefile to "/usr/X11" if so desired. +- */ +-#ifndef OPENWINHOMELIB +-#define OPENWINHOMELIB "/usr/openwin/lib/" +-#endif +- +-/* This is all known Solaris X11 directories on Solaris 8, 9 and 10. +- * It is ordered to give precedence to TrueType directories. +- * It is needed if fontconfig is not installed or configured properly. +- */ +-static char *fullSolarisFontPath[] = { +- OPENWINHOMELIB "X11/fonts/TrueType", +- OPENWINHOMELIB "locale/euro_fonts/X11/fonts/TrueType", +- OPENWINHOMELIB "locale/iso_8859_2/X11/fonts/TrueType", +- OPENWINHOMELIB "locale/iso_8859_5/X11/fonts/TrueType", +- OPENWINHOMELIB "locale/iso_8859_7/X11/fonts/TrueType", +- OPENWINHOMELIB "locale/iso_8859_8/X11/fonts/TrueType", +- OPENWINHOMELIB "locale/iso_8859_9/X11/fonts/TrueType", +- OPENWINHOMELIB "locale/iso_8859_13/X11/fonts/TrueType", +- OPENWINHOMELIB "locale/iso_8859_15/X11/fonts/TrueType", +- OPENWINHOMELIB "locale/ar/X11/fonts/TrueType", +- OPENWINHOMELIB "locale/hi_IN.UTF-8/X11/fonts/TrueType", +- OPENWINHOMELIB "locale/ja/X11/fonts/TT", +- OPENWINHOMELIB "locale/ko/X11/fonts/TrueType", +- OPENWINHOMELIB "locale/ko.UTF-8/X11/fonts/TrueType", +- OPENWINHOMELIB "locale/KOI8-R/X11/fonts/TrueType", +- OPENWINHOMELIB "locale/ru.ansi-1251/X11/fonts/TrueType", +- OPENWINHOMELIB "locale/th_TH/X11/fonts/TrueType", +- OPENWINHOMELIB "locale/zh_TW/X11/fonts/TrueType", +- OPENWINHOMELIB "locale/zh_TW.BIG5/X11/fonts/TT", +- OPENWINHOMELIB "locale/zh_HK.BIG5HK/X11/fonts/TT", +- OPENWINHOMELIB "locale/zh_CN.GB18030/X11/fonts/TrueType", +- OPENWINHOMELIB "locale/zh/X11/fonts/TrueType", +- OPENWINHOMELIB "locale/zh.GBK/X11/fonts/TrueType", +- OPENWINHOMELIB "X11/fonts/Type1", +- OPENWINHOMELIB "X11/fonts/Type1/sun", +- OPENWINHOMELIB "X11/fonts/Type1/sun/outline", +- OPENWINHOMELIB "locale/iso_8859_2/X11/fonts/Type1", +- OPENWINHOMELIB "locale/iso_8859_4/X11/fonts/Type1", +- OPENWINHOMELIB "locale/iso_8859_5/X11/fonts/Type1", +- OPENWINHOMELIB "locale/iso_8859_7/X11/fonts/Type1", +- OPENWINHOMELIB "locale/iso_8859_8/X11/fonts/Type1", +- OPENWINHOMELIB "locale/iso_8859_9/X11/fonts/Type1", +- OPENWINHOMELIB "locale/iso_8859_13/X11/fonts/Type1", +- OPENWINHOMELIB "locale/ar/X11/fonts/Type1", +- NULL, /* terminates the list */ +-}; +- +-#elif defined( __linux__) ++#if defined( __linux__) + /* All the known interesting locations we have discovered on + * various flavors of Linux + */ +@@ -223,14 +173,6 @@ + if (strstr(x11Path[i], ".gnome") != NULL) { + continue; + } +-#ifdef __solaris__ +- if (strstr(x11Path[i], "/F3/") != NULL) { +- continue; +- } +- if (strstr(x11Path[i], "bitmap") != NULL) { +- continue; +- } +-#endif + fontdirs[pos] = strdup(x11Path[i]); + slen = strlen(fontdirs[pos]); + if (slen > 0 && fontdirs[pos][slen-1] == '/') { +@@ -380,8 +322,6 @@ + + #if defined(__linux__) + knowndirs = fullLinuxFontPath; +-#elif defined(__solaris__) +- knowndirs = fullSolarisFontPath; + #elif defined(_AIX) + knowndirs = fullAixFontPath; + #endif +--- old/src/java.desktop/unix/native/libawt_xawt/awt/awt_GraphicsEnv.c 2020-05-20 18:02:46.009261282 -0700 ++++ new/src/java.desktop/unix/native/libawt_xawt/awt/awt_GraphicsEnv.c 2020-05-20 18:02:45.625253909 -0700 +@@ -402,12 +402,7 @@ + xrenderLibHandle = dlopen("libXrender.so", RTLD_LAZY | RTLD_GLOBAL); + } + +-#if defined(__solaris__) +- if (xrenderLibHandle == NULL) { +- xrenderLibHandle = dlopen("libXrender.so.1", +- RTLD_LAZY | RTLD_GLOBAL); +- } +-#elif defined(_AIX) ++#if defined(_AIX) + if (xrenderLibHandle == NULL) { + xrenderLibHandle = dlopen("libXrender.a(libXrender.so.0)", + RTLD_MEMBER | RTLD_LAZY | RTLD_GLOBAL); +--- old/src/java.desktop/unix/native/libawt_xawt/java2d/x11/XRBackendNative.c 2020-05-20 18:02:47.985299224 -0700 ++++ new/src/java.desktop/unix/native/libawt_xawt/java2d/x11/XRBackendNative.c 2020-05-20 18:02:47.661293003 -0700 +@@ -76,29 +61,6 @@ + + #include + +-#if defined(__solaris__) +-/* Solaris 10 will not have these symbols at compile time */ +- +-typedef Picture (*XRenderCreateLinearGradientFuncType) +- (Display *dpy, +- const XLinearGradient *gradient, +- const XFixed *stops, +- const XRenderColor *colors, +- int nstops); +- +-typedef Picture (*XRenderCreateRadialGradientFuncType) +- (Display *dpy, +- const XRadialGradient *gradient, +- const XFixed *stops, +- const XRenderColor *colors, +- int nstops); +- +-static +-XRenderCreateLinearGradientFuncType XRenderCreateLinearGradientFunc = NULL; +-static +- XRenderCreateRadialGradientFuncType XRenderCreateRadialGradientFunc = NULL; +-#endif +- + #define BUILD_TRANSFORM_MATRIX(TRANSFORM, M00, M01, M02, M10, M11, M12) \ + { \ + TRANSFORM.matrix[0][0] = M00; \ +@@ -166,27 +128,6 @@ + } else { + available = JNI_FALSE; + } +-#elif defined(__solaris__) +- xrenderlib = dlopen("libXrender.so",RTLD_GLOBAL|RTLD_LAZY); +- if (xrenderlib != NULL) { +- +- XRenderCreateLinearGradientFunc = +- (XRenderCreateLinearGradientFuncType) +- dlsym(xrenderlib, "XRenderCreateLinearGradient"); +- +- XRenderCreateRadialGradientFunc = +- (XRenderCreateRadialGradientFuncType) +- dlsym(xrenderlib, "XRenderCreateRadialGradient"); +- +- if (XRenderCreateLinearGradientFunc == NULL || +- XRenderCreateRadialGradientFunc == NULL) +- { +- available = JNI_FALSE; +- } +- dlclose(xrenderlib); +- } else { +- available = JNI_FALSE; +- } + #else + Dl_info info; + jboolean versionInfoIsFound = JNI_FALSE; +@@ -593,13 +534,7 @@ + colors[i].green = pixels[i*4 + 2]; + colors[i].blue = pixels[i*4 + 3]; + } +-#ifdef __solaris__ +- if (XRenderCreateLinearGradientFunc!=NULL) { +- gradient = (*XRenderCreateLinearGradientFunc)(awt_display, &grad, stops, colors, numStops); +- } +-#else + gradient = XRenderCreateLinearGradient(awt_display, &grad, stops, colors, numStops); +-#endif + free(colors); + free(stops); + +@@ -677,13 +612,7 @@ + colors[i].green = pixels[i*4 + 2]; + colors[i].blue = pixels[i*4 + 3]; + } +-#ifdef __solaris__ +- if (XRenderCreateRadialGradientFunc != NULL) { +- gradient = (jint) (*XRenderCreateRadialGradientFunc)(awt_display, &grad, stops, colors, numStops); +- } +-#else + gradient = (jint) XRenderCreateRadialGradient(awt_display, &grad, stops, colors, numStops); +-#endif + free(colors); + free(stops); + +--- old/src/java.security.jgss/share/classes/sun/security/jgss/wrapper/SunNativeProvider.java 2020-05-20 18:02:49.005318809 -0700 ++++ new/src/java.security.jgss/share/classes/sun/security/jgss/wrapper/SunNativeProvider.java 2020-05-20 18:02:48.665312280 -0700 +@@ -91,9 +91,6 @@ + = System.getProperty("sun.security.jgss.lib"); + if (defaultLib == null || defaultLib.trim().equals("")) { + gssLibs = switch (OperatingSystem.current()) { +- case SOLARIS -> new String[]{ +- "libgss.so", +- }; + case LINUX -> new String[]{ + "libgssapi.so", + "libgssapi_krb5.so", +--- old/src/java.security.jgss/share/classes/sun/security/krb5/Config.java 2020-05-20 18:02:50.089339623 -0700 ++++ new/src/java.security.jgss/share/classes/sun/security/krb5/Config.java 2020-05-20 18:02:49.705332249 -0700 +@@ -931,8 +931,6 @@ + if (name == null) { + name = "c:\\winnt\\krb5.ini"; + } +- } else if (OperatingSystem.isSolaris()) { +- name = "/etc/krb5/krb5.conf"; + } else if (OperatingSystem.isMacOS()) { + name = findMacosConfigFile(); + } else { +--- old/src/java.security.jgss/share/classes/sun/security/krb5/internal/rcache/DflCache.java 2020-05-20 18:02:51.185360667 -0700 ++++ new/src/java.security.jgss/share/classes/sun/security/krb5/internal/rcache/DflCache.java 2020-05-20 18:02:50.801353294 -0700 +@@ -107,7 +107,7 @@ + + private static long uid; + static { +- // Available on Solaris, Linux and Mac. Otherwise, -1 and no _euid suffix ++ // Available on Linux and Mac. Otherwise, -1 and no _euid suffix + uid = jdk.internal.misc.VM.geteuid(); + } + +--- old/src/java.smartcardio/unix/classes/sun/security/smartcardio/PlatformPCSC.java 2020-05-20 18:02:52.281381711 -0700 ++++ new/src/java.smartcardio/unix/classes/sun/security/smartcardio/PlatformPCSC.java 2020-05-20 18:02:51.897374338 -0700 +@@ -86,12 +86,8 @@ + if (k != -1) { + String libDir; + if ("64".equals(System.getProperty("sun.arch.data.model"))) { +- if ("SunOS".equals(System.getProperty("os.name"))) { +- libDir = "lib/64"; +- } else { +- // assume Linux convention +- libDir = "lib64"; +- } ++ // assume Linux convention ++ libDir = "lib64"; + } else { + // must be 32-bit + libDir = "lib"; +--- old/src/java.xml/share/classes/com/sun/org/apache/xalan/internal/xsltc/runtime/output/WriterOutputBuffer.java 2020-05-20 18:02:53.293401143 -0700 ++++ new/src/java.xml/share/classes/com/sun/org/apache/xalan/internal/xsltc/runtime/output/WriterOutputBuffer.java 2020-05-20 18:02:52.961394768 -0700 +@@ -33,21 +33,12 @@ + private static final int KB = 1024; + private static int BUFFER_SIZE = 4 * KB; + +- static { +- // Set a larger buffer size for Solaris +- final String osName = SecuritySupport.getSystemProperty("os.name"); +- if (osName.equalsIgnoreCase("solaris")) { +- BUFFER_SIZE = 32 * KB; +- } +- } +- + private Writer _writer; + + /** + * Initializes a WriterOutputBuffer by creating an instance of a + * BufferedWriter. The size of the buffer in this writer may have +- * a significant impact on throughput. Solaris prefers a larger +- * buffer, while Linux works better with a smaller one. ++ * a significant impact on throughput. + */ + public WriterOutputBuffer(Writer writer) { + _writer = new BufferedWriter(writer, BUFFER_SIZE); +--- old/src/jdk.charsets/share/classes/sun/nio/cs/ext/JISAutoDetect.java 2020-05-20 18:02:58.681504598 -0700 ++++ new/src/jdk.charsets/share/classes/sun/nio/cs/ext/JISAutoDetect.java 2020-05-20 18:02:58.345498147 -0700 +@@ -94,7 +94,7 @@ + private static class Decoder extends CharsetDecoder { + + private static final String SJISName = getSJISName(); +- private static final String EUCJPName = getEUCJPName(); ++ private static final String EUCJPName = "EUC_JP"; + private DelegatableDecoder detectedDecoder = null; + + public Decoder(Charset cs) { +@@ -222,24 +222,11 @@ + * Returned Shift_JIS Charset name is OS dependent + */ + private static String getSJISName() { +- if (OperatingSystem.isSolaris()) +- return("PCK"); +- else if (OperatingSystem.isWindows()) ++ if (OperatingSystem.isWindows()) + return("windows-31J"); + else + return("Shift_JIS"); + } + +- /** +- * Returned EUC-JP Charset name is OS dependent +- */ +- +- private static String getEUCJPName() { +- if (OperatingSystem.isSolaris()) +- return("x-eucjp-open"); +- else +- return("EUC_JP"); +- } +- + } + } +--- old/src/jdk.crypto.cryptoki/share/classes/sun/security/pkcs11/Config.java 2020-05-20 18:02:59.697524107 -0700 ++++ new/src/jdk.crypto.cryptoki/share/classes/sun/security/pkcs11/Config.java 2020-05-20 18:02:59.357517578 -0700 +@@ -711,15 +711,10 @@ + lib = expand(lib); + int i = lib.indexOf("/$ISA/"); + if (i != -1) { +- // replace "/$ISA/" with "/amd64/" on Solaris AMD64. +- // On all other platforms, just turn it into a "/" ++ // replace "/$ISA/" with "/" + String prefix = lib.substring(0, i); + String suffix = lib.substring(i + 5); +- if (osName.equals("SunOS") && osArch.equals("amd64")) { +- lib = prefix + "/amd64" + suffix; +- } else { +- lib = prefix + suffix; +- } ++ lib = prefix + suffix; + } + if (DEBUG) { + System.out.println(keyword + ": " + lib); +--- old/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/runtime/Threads.java 2020-05-20 18:03:16.561847914 -0700 ++++ new/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/runtime/Threads.java 2020-05-20 18:03:16.225841462 -0700 +@@ -28,8 +28,6 @@ + + import sun.jvm.hotspot.debugger.*; + import sun.jvm.hotspot.types.*; +-import sun.jvm.hotspot.runtime.solaris_x86.SolarisX86JavaThreadPDAccess; +-import sun.jvm.hotspot.runtime.solaris_amd64.SolarisAMD64JavaThreadPDAccess; + import sun.jvm.hotspot.runtime.win32_x86.Win32X86JavaThreadPDAccess; + import sun.jvm.hotspot.runtime.win32_amd64.Win32AMD64JavaThreadPDAccess; + import sun.jvm.hotspot.runtime.win32_aarch64.Win32AARCH64JavaThreadPDAccess; +@@ -101,13 +97,7 @@ + + access = null; + // FIXME: find the platform specific PD class by reflection? +- if (os.equals("solaris")) { +- if (cpu.equals("x86")) { +- access = new SolarisX86JavaThreadPDAccess(); +- } else if (cpu.equals("amd64")) { +- access = new SolarisAMD64JavaThreadPDAccess(); +- } +- } else if (os.equals("win32")) { ++ if (os.equals("win32")) { + if (cpu.equals("x86")) { + access = new Win32X86JavaThreadPDAccess(); + } else if (cpu.equals("amd64")) { +--- old/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/utilities/PlatformInfo.java 2020-05-20 18:03:17.573867346 -0700 ++++ new/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/utilities/PlatformInfo.java 2020-05-20 18:03:17.241860971 -0700 +@@ -28,14 +28,10 @@ + system. */ + + public class PlatformInfo { +- /* Returns "solaris" if on Solaris; "win32" if Windows; "linux" if +- Linux. Used to determine location of dbx and import module, or +- possible debugger agent on win32. */ ++ /* Returns "win32" if Windows; "linux" if Linux. */ + public static String getOS() throws UnsupportedPlatformException { + String os = System.getProperty("os.name"); +- if (os.equals("SunOS")) { +- return "solaris"; +- } else if (os.equals("Linux")) { ++ if (os.equals("Linux")) { + return "linux"; + } else if (os.equals("FreeBSD")) { + return "bsd"; +--- old/src/jdk.hotspot.agent/share/native/libsaproc/ps_core_common.c 2020-05-20 18:03:18.605887161 -0700 ++++ new/src/jdk.hotspot.agent/share/native/libsaproc/ps_core_common.c 2020-05-20 18:03:18.277880863 -0700 +@@ -22,8 +22,6 @@ + * + */ + +-#include // just include something, or else solaris compiler will complain that this file is empty +- + #if defined(LINUX) || defined(__APPLE__) + #include + #include +--- old/src/jdk.hotspot.agent/test/libproc/libproctest.sh 2020-05-20 18:03:20.517923873 -0700 ++++ new/src/jdk.hotspot.agent/test/libproc/libproctest.sh 2020-05-20 18:03:20.133916500 -0700 +@@ -59,10 +59,8 @@ + kill -9 $pid + + +-OPTIONS="-Djava.library.path=$STARTDIR/../src/os/solaris/proc/`uname -p`:$STARTDIR/../solaris/`uname -p`" +- + # run libproc client +-$SA_JAVA -showversion ${OPTIONS} -cp $STARTDIR/../../build/classes::$STARTDIR/../sa.jar:$STARTDIR LibprocClient x core.$pid ++$SA_JAVA -showversion -cp $STARTDIR/../../build/classes::$STARTDIR/../sa.jar:$STARTDIR LibprocClient x core.$pid + + # delete core + rm -f core.$pid +--- old/src/jdk.jdwp.agent/unix/native/libdt_socket/socket_md.c 2020-05-20 18:03:32.130146836 -0700 ++++ new/src/jdk.jdwp.agent/unix/native/libdt_socket/socket_md.c 2020-05-20 18:03:31.750139540 -0700 +@@ -33,12 +33,8 @@ + #include + #include + #include +-#ifdef __solaris__ +-#include +-#else + #include + #include +-#endif + + #include "socket_md.h" + #include "sysSocket.h" +@@ -275,35 +271,6 @@ + return 0; + } + +-#ifdef __solaris__ +-int +-dbgsysTlsAlloc() { +- thread_key_t tk; +- if (thr_keycreate(&tk, NULL)) { +- perror("thr_keycreate"); +- exit(-1); +- } +- return (int)tk; +-} +- +-void +-dbgsysTlsFree(int index) { +- /* no-op */ +-} +- +-void +-dbgsysTlsPut(int index, void *value) { +- thr_setspecific((thread_key_t)index, value) ; +-} +- +-void * +-dbgsysTlsGet(int index) { +- void* r = NULL; +- thr_getspecific((thread_key_t)index, &r); +- return r; +-} +- +-#else + int + dbgsysTlsAlloc() { + pthread_key_t key; +@@ -329,8 +296,6 @@ + return pthread_getspecific((pthread_key_t)index); + } + +-#endif +- + long + dbgsysCurrentTimeMillis() { + struct timeval t; +--- old/src/jdk.management/unix/native/libmanagement_ext/OperatingSystemImpl.c 2020-05-20 18:03:36.322227327 -0700 ++++ new/src/jdk.management/unix/native/libmanagement_ext/OperatingSystemImpl.c 2020-05-20 18:03:35.934219877 -0700 +@@ -85,63 +85,7 @@ + // true = get available swap in bytes + // false = get total swap in bytes + static jlong get_total_or_available_swap_space_size(JNIEnv* env, jboolean available) { +-#ifdef __solaris__ +- long total, avail; +- int nswap, i, count; +- swaptbl_t *stbl; +- char *strtab; +- +- // First get the number of swap resource entries +- if ((nswap = swapctl(SC_GETNSWP, NULL)) == -1) { +- throw_internal_error(env, "swapctl failed to get nswap"); +- return -1; +- } +- if (nswap == 0) { +- return 0; +- } +- +- // Allocate storage for resource entries +- stbl = (swaptbl_t*) malloc(nswap * sizeof(swapent_t) + +- sizeof(struct swaptable)); +- if (stbl == NULL) { +- JNU_ThrowOutOfMemoryError(env, 0); +- return -1; +- } +- +- // Allocate storage for the table +- strtab = (char*) malloc((nswap + 1) * MAXPATHLEN); +- if (strtab == NULL) { +- free(stbl); +- JNU_ThrowOutOfMemoryError(env, 0); +- return -1; +- } +- +- for (i = 0; i < (nswap + 1); i++) { +- stbl->swt_ent[i].ste_path = strtab + (i * MAXPATHLEN); +- } +- stbl->swt_n = nswap + 1; +- +- // Get the entries +- if ((count = swapctl(SC_LIST, stbl)) < 0) { +- free(stbl); +- free(strtab); +- throw_internal_error(env, "swapctl failed to get swap list"); +- return -1; +- } +- +- // Sum the entries to get total and free swap +- total = 0; +- avail = 0; +- for (i = 0; i < count; i++) { +- total += stbl->swt_ent[i].ste_pages; +- avail += stbl->swt_ent[i].ste_free; +- } +- +- free(stbl); +- free(strtab); +- return available ? ((jlong)avail * page_size) : +- ((jlong)total * page_size); +-#elif defined(__linux__) ++#if defined(__linux__) + int ret; + jlong total = 0, avail = 0; + +@@ -190,37 +134,7 @@ + Java_com_sun_management_internal_OperatingSystemImpl_getCommittedVirtualMemorySize0 + (JNIEnv *env, jobject mbean) + { +-#ifdef __solaris__ +- psinfo_t psinfo; +- ssize_t result; +- size_t remaining; +- char* addr; +- int fd; +- +- fd = open64("/proc/self/psinfo", O_RDONLY, 0); +- if (fd < 0) { +- throw_internal_error(env, "Unable to open /proc/self/psinfo"); +- return -1; +- } +- +- addr = (char *)&psinfo; +- for (remaining = sizeof(psinfo_t); remaining > 0;) { +- result = read(fd, addr, remaining); +- if (result < 0) { +- if (errno != EINTR) { +- close(fd); +- throw_internal_error(env, "Unable to read /proc/self/psinfo"); +- return -1; +- } +- } else { +- remaining -= result; +- addr += result; +- } +- } +- +- close(fd); +- return (jlong) psinfo.pr_size * 1024; +-#elif defined(__APPLE__) ++#if defined(__APPLE__) + struct task_basic_info t_info; + mach_msg_type_number_t t_info_count = TASK_BASIC_INFO_COUNT; + +@@ -276,7 +190,7 @@ + * BSDNOTE: FreeBSD implements _SC_CLK_TCK since FreeBSD 5, so + * add a magic to handle it + */ +-#if defined(__solaris__) || defined(_SC_CLK_TCK) ++#if defined(_SC_CLK_TCK) + clk_tck = (jlong) sysconf(_SC_CLK_TCK); + #elif defined(__linux__) || defined(_ALLBSD_SOURCE) + clk_tck = 100; +--- old/src/jdk.sctp/unix/classes/sun/nio/ch/sctp/SctpNet.java 2020-05-20 18:03:38.442268035 -0700 ++++ new/src/jdk.sctp/unix/classes/sun/nio/ch/sctp/SctpNet.java 2020-05-20 18:03:38.054260584 -0700 +@@ -44,12 +44,6 @@ + /* -- Miscellaneous SCTP utilities -- */ + + private static boolean IPv4MappedAddresses() { +- if (true) { +- /* FIXME - nonportable hack */ +- /* Solaris supports IPv4Mapped Addresses with bindx */ +- return true; +- } /* else { //other OS/implementations */ +- + /* lksctp/linux requires Ipv4 addresses */ + return false; + } +--- old/src/jdk.sctp/unix/native/libsctp/Sctp.h 2020-05-20 18:03:39.494288233 -0700 ++++ new/src/jdk.sctp/unix/native/libsctp/Sctp.h 2020-05-20 18:03:39.114280937 -0700 +@@ -26,48 +26,6 @@ + #ifndef SUN_NIO_CH_SCTP_H + #define SUN_NIO_CH_SCTP_H + +-#ifdef __solaris__ +- +-#define _XPG4_2 +-#define __EXTENSIONS__ +-#include +-#include +-#include "jni.h" +- +-/* Current Solaris headers don't comply with draft rfc */ +-#ifndef SCTP_EOF +-#define SCTP_EOF MSG_EOF +-#endif +- +-#ifndef SCTP_UNORDERED +-#define SCTP_UNORDERED MSG_UNORDERED +-#endif +- +-/* The current version of the socket API extension shipped with Solaris does +- * not define the following options that the Java API (optionally) supports */ +-#ifndef SCTP_EXPLICIT_EOR +-#define SCTP_EXPLICIT_EOR -1 +-#endif +-#ifndef SCTP_FRAGMENT_INTERLEAVE +-#define SCTP_FRAGMENT_INTERLEAVE -1 +-#endif +-#ifndef SCTP_SET_PEER_PRIMARY_ADDR +-#define SCTP_SET_PEER_PRIMARY_ADDR -1 +-#endif +- +-/* Function types to support dynamic linking of socket API extension functions +- * for SCTP. This is so that there is no linkage dependency during build or +- * runtime for libsctp.*/ +-typedef int sctp_getladdrs_func(int sock, sctp_assoc_t id, void **addrs); +-typedef int sctp_freeladdrs_func(void* addrs); +-typedef int sctp_getpaddrs_func(int sock, sctp_assoc_t id, void **addrs); +-typedef int sctp_freepaddrs_func(void *addrs); +-typedef int sctp_bindx_func(int sock, void *addrs, int addrcnt, int flags); +-typedef int sctp_peeloff_func(int sock, sctp_assoc_t id); +- +- +- +-#else /* __linux__ */ + #include + #include + #include +@@ -320,8 +278,6 @@ + typedef int sctp_peeloff_func(int sock, sctp_assoc_t id); + + +-#endif /* __linux__ */ +- + extern sctp_getladdrs_func* nio_sctp_getladdrs; + extern sctp_freeladdrs_func* nio_sctp_freeladdrs; + extern sctp_getpaddrs_func* nio_sctp_getpaddrs; +--- old/src/jdk.sctp/unix/native/libsctp/SctpChannelImpl.c 2020-05-20 18:03:40.558308663 -0700 ++++ new/src/jdk.sctp/unix/native/libsctp/SctpChannelImpl.c 2020-05-20 18:03:40.174301290 -0700 +@@ -331,10 +331,11 @@ + break; + case SCTP_ADDR_MADE_PRIM : + event = sun_nio_ch_sctp_PeerAddrChange_SCTP_ADDR_MADE_PRIM; +-#ifdef __linux__ /* Solaris currently doesn't support SCTP_ADDR_CONFIRMED */ + break; ++#ifdef __linux__ + case SCTP_ADDR_CONFIRMED : + event = sun_nio_ch_sctp_PeerAddrChange_SCTP_ADDR_CONFIRMED; ++ break; + #endif /* __linux__ */ + } + +--- old/src/jdk.sctp/unix/native/libsctp/SctpNet.c 2020-05-20 18:03:41.630329248 -0700 ++++ new/src/jdk.sctp/unix/native/libsctp/SctpNet.c 2020-05-20 18:03:41.242321797 -0700 +@@ -371,11 +371,7 @@ + int i, addrCount; + jobjectArray isaa; + +-#ifdef __solaris__ +- if ((addrCount = nio_sctp_getladdrs(fd, 0, (void **)&addr_buf)) == -1) { +-#else /* __linux__ */ + if ((addrCount = nio_sctp_getladdrs(fd, 0, (struct sockaddr **)&addr_buf)) == -1) { +-#endif + sctpHandleSocketError(env, errno); + return NULL; + } +@@ -420,11 +416,7 @@ + int i, addrCount; + jobjectArray isaa; + +-#if defined(__solaris__) +- if ((addrCount = nio_sctp_getpaddrs(fd, id, (void **)&addr_buf)) == -1) { +-#else /* __linux__ */ + if ((addrCount = nio_sctp_getpaddrs(fd, id, (struct sockaddr **)&addr_buf)) == -1) { +-#endif + sctpHandleSocketError(env, errno); + return NULL; + } +--- old/src/jdk.security.auth/share/classes/com/sun/security/auth/module/Krb5LoginModule.java 2020-05-20 18:03:42.730350368 -0700 ++++ new/src/jdk.security.auth/share/classes/com/sun/security/auth/module/Krb5LoginModule.java 2020-05-20 18:03:42.338342841 -0700 +@@ -104,7 +104,7 @@ + * to false if you do not want this module to use the ticket cache. + * (Default is False). + * This module will search for the ticket +- * cache in the following locations: On Solaris and Linux ++ * cache in the following locations: On Linux + * it will look for the ticket cache in /tmp/krb5cc_{@code uid} + * where the uid is numeric user identifier. If the ticket cache is + * not available in the above location, or if we are on a +--- old/src/jdk.security.auth/unix/native/libjaas/Unix.c 2020-05-20 18:03:43.842371720 -0700 ++++ new/src/jdk.security.auth/unix/native/libjaas/Unix.c 2020-05-20 18:03:43.450364193 -0700 +@@ -32,10 +32,6 @@ + #include + #include + +-/* For POSIX-compliant getpwuid_r on Solaris */ +-#if defined(__solaris__) +-#define _POSIX_PTHREAD_SEMANTICS +-#endif + #include + + /* +--- old/src/java.desktop/solaris/data/fontconfig/fontconfig.properties 2020-05-20 18:08:13.719553558 -0700 ++++ /dev/null 2020-03-09 18:57:19.455001459 -0700 +@@ -1,516 +0,0 @@ +-# +-# +-# Copyright (c) 2005, 2018, Oracle and/or its affiliates. All rights reserved. +-# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. +-# +-# This code is free software; you can redistribute it and/or modify it +-# under the terms of the GNU General Public License version 2 only, as +-# published by the Free Software Foundation. Oracle designates this +-# particular file as subject to the "Classpath" exception as provided +-# by Oracle in the LICENSE file that accompanied this code. +-# +-# This code is distributed in the hope that it will be useful, but WITHOUT +-# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +-# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +-# version 2 for more details (a copy is included in the LICENSE file that +-# accompanied this code). +-# +-# You should have received a copy of the GNU General Public License version +-# 2 along with this work; if not, write to the Free Software Foundation, +-# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. +-# +-# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA +-# or visit www.oracle.com if you need additional information or have any +-# questions. +-# +- +-# Version +- +-version=1 +- +-# Component Font Mappings +- +-allfonts.chinese-gb2312=-arphic-uming-medium-r-normal--*-%d-*-*-m-*-iso10646-1 +-allfonts.chinese-gbk=-arphic-uming-medium-r-normal--*-%d-*-*-m-*-iso10646-1 +-allfonts.chinese-gb18030-0=-arphic-uming-medium-r-normal--*-%d-*-*-m-*-iso10646-1 +-allfonts.chinese-gb18030-1=-arphic-uming-medium-r-normal--*-%d-*-*-m-*-iso10646-1 +-allfonts.chinese-cns11643-1=-arphic-uming-medium-r-normal--*-%d-*-*-m-*-iso10646-1 +-allfonts.chinese-cns11643-2=-arphic-uming-medium-r-normal--*-%d-*-*-m-*-iso10646-1 +-allfonts.chinese-cns11643-3=-arphic-uming-medium-r-normal--*-%d-*-*-m-*-iso10646-1 +-allfonts.chinese-big5=-arphic-uming-medium-r-normal--*-%d-*-*-m-*-iso10646-1 +-allfonts.chinese-hkscs=-arphic-uming-medium-r-normal--*-%d-*-*-m-*-iso10646-1 +-allfonts.dingbats=-microsoft-wingdings-medium-r-normal--*-%d-*-*-p-*-adobe-fontspecific +-allfonts.japanese-x0212=-misc-ipagothic-medium-r-normal--*-%d-*-*-m-*-iso10646-1 +-allfonts.korean=-hanyang-gothic-medium-r-normal--*-%d-*-*-m-*-iso10646-1 +-allfonts.korean-johab=-hanyang-gothic-medium-r-normal--*-%d-*-*-m-*-iso10646-1 +-allfonts.symbol=-monotype-symbol-medium-r-normal--*-%d-*-*-p-*-adobe-symbol +-allfonts.bengali=-misc-lohit bengali-medium-r-normal--0-0-0-0-p-0-iso10646-1 +-allfonts.gujarati=-misc-lohit gujarati-medium-r-normal--0-0-0-0-p-0-iso10646-1 +-allfonts.hindi=-misc-lohit hindi-medium-r-normal--0-0-0-0-p-0-iso10646-1 +-allfonts.kannada=-misc-lohit kannada-medium-r-normal--0-0-0-0-p-0-iso10646-1 +-allfonts.malayalam=-misc-lohit malayalam-medium-r-normal--0-0-0-0-p-0-iso10646-1 +-allfonts.marathi=-misc-lohit marathi-medium-r-normal--0-0-0-0-p-0-iso10646-1 +-allfonts.tamil=-misc-lohit tamil-medium-r-normal--0-0-0-0-p-0-iso10646-1 +-allfonts.telugu=-misc-lohit telugu-medium-r-normal--0-0-0-0-p-0-iso10646-1 +-allfonts.dejavusans=-misc-dejavu sans-medium-r-normal--0-0-0-0-p-0-iso10646-1 +- +-serif.plain.arabic=-monotype-times new roman-medium-r-normal--*-%d-*-*-p-*-iso10646-1 +-serif.plain.cyrillic-iso8859-5=-monotype-times new roman-medium-r-normal--*-%d-*-*-p-*-iso10646-1 +-serif.plain.cyrillic-cp1251=-monotype-times new roman-medium-r-normal--*-%d-*-*-p-*-iso10646-1 +-serif.plain.cyrillic-koi8-r=-monotype-times new roman-medium-r-normal--*-%d-*-*-p-*-iso10646-1 +-serif.plain.greek=-monotype-times new roman-medium-r-normal--*-%d-*-*-p-*-iso10646-1 +-serif.plain.hebrew=-monotype-times new roman-medium-r-normal--*-%d-*-*-p-*-iso10646-1 +-serif.plain.japanese-x0201=-misc-ipamincho-medium-r-normal--*-%d-*-*-m-*-iso10646-1 +-serif.plain.japanese-x0208=-misc-ipamincho-medium-r-normal--*-%d-*-*-m-*-iso10646-1 +-serif.plain.latin-1=-monotype-times new roman-medium-r-normal--*-%d-*-*-p-*-iso10646-1 +-serif.plain.latin-2=-monotype-times new roman-medium-r-normal--*-%d-*-*-p-*-iso10646-1 +-serif.plain.latin-5=-monotype-times new roman-medium-r-normal--*-%d-*-*-p-*-iso10646-1 +-serif.plain.latin-7=-monotype-times new roman-medium-r-normal--*-%d-*-*-p-*-iso10646-1 +-serif.plain.latin-9=-monotype-times new roman-medium-r-normal--*-%d-*-*-p-*-iso10646-1 +-serif.plain.thai=-monotype-angsana new-medium-r-normal--*-%d-*-*-p-*-iso10646-1 +- +-serif.bold.arabic=-monotype-times new roman-bold-r-normal--*-%d-*-*-p-*-iso10646-1 +-serif.bold.cyrillic-iso8859-5=-monotype-times new roman-bold-r-normal--*-%d-*-*-p-*-iso10646-1 +-serif.bold.cyrillic-cp1251=-monotype-times new roman-bold-r-normal--*-%d-*-*-p-*-iso10646-1 +-serif.bold.cyrillic-koi8-r=-monotype-times new roman-bold-r-normal--*-%d-*-*-p-*-iso10646-1 +-serif.bold.greek=-monotype-times new roman-bold-r-normal--*-%d-*-*-p-*-iso10646-1 +-serif.bold.hebrew=-monotype-times new roman-bold-r-normal--*-%d-*-*-p-*-iso10646-1 +-serif.bold.japanese-x0201=-misc-ipamincho-medium-r-normal--*-%d-*-*-m-*-iso10646-1 +-serif.bold.japanese-x0208=-misc-ipamincho-medium-r-normal--*-%d-*-*-m-*-iso10646-1 +-serif.bold.latin-1=-monotype-times new roman-bold-r-normal--*-%d-*-*-p-*-iso10646-1 +-serif.bold.latin-2=-monotype-times new roman-bold-r-normal--*-%d-*-*-p-*-iso10646-1 +-serif.bold.latin-5=-monotype-times new roman-bold-r-normal--*-%d-*-*-p-*-iso10646-1 +-serif.bold.latin-7=-monotype-times new roman-bold-r-normal--*-%d-*-*-p-*-iso10646-1 +-serif.bold.latin-9=-monotype-times new roman-bold-r-normal--*-%d-*-*-p-*-iso10646-1 +-serif.bold.thai=-monotype-angsana new-bold-r-normal--*-%d-*-*-p-*-iso10646-1 +- +-serif.italic.arabic=-monotype-times new roman-medium-i-normal--*-%d-*-*-p-*-iso10646-1 +-serif.italic.cyrillic-iso8859-5=-monotype-times new roman-medium-i-normal--*-%d-*-*-p-*-iso10646-1 +-serif.italic.cyrillic-cp1251=-monotype-times new roman-medium-i-normal--*-%d-*-*-p-*-iso10646-1 +-serif.italic.cyrillic-koi8-r=-monotype-times new roman-medium-i-normal--*-%d-*-*-p-*-iso10646-1 +-serif.italic.greek=-monotype-times new roman-medium-i-normal--*-%d-*-*-p-*-iso10646-1 +-serif.italic.hebrew=-monotype-times new roman-medium-i-normal--*-%d-*-*-p-*-iso10646-1 +-serif.italic.japanese-x0201=-misc-ipamincho-medium-r-normal--*-%d-*-*-m-*-iso10646-1 +-serif.italic.japanese-x0208=-misc-ipamincho-medium-r-normal--*-%d-*-*-m-*-iso10646-1 +-serif.italic.latin-1=-monotype-times new roman-medium-i-normal--*-%d-*-*-p-*-iso10646-1 +-serif.italic.latin-2=-monotype-times new roman-medium-i-normal--*-%d-*-*-p-*-iso10646-1 +-serif.italic.latin-5=-monotype-times new roman-medium-i-normal--*-%d-*-*-p-*-iso10646-1 +-serif.italic.latin-7=-monotype-times new roman-medium-i-normal--*-%d-*-*-p-*-iso10646-1 +-serif.italic.latin-9=-monotype-times new roman-medium-i-normal--*-%d-*-*-p-*-iso10646-1 +-serif.italic.thai=-monotype-angsana new-medium-i-normal--*-%d-*-*-p-*-iso10646-1 +- +-serif.bolditalic.arabic=-monotype-times new roman-bold-r-normal--*-%d-*-*-p-*-iso10646-1 +-serif.bolditalic.cyrillic-iso8859-5=-monotype-times new roman-bold-i-normal--*-%d-*-*-p-*-iso10646-1 +-serif.bolditalic.cyrillic-cp1251=-monotype-times new roman-bold-i-normal--*-%d-*-*-p-*-iso10646-1 +-serif.bolditalic.cyrillic-koi8-r=-monotype-times new roman-bold-i-normal--*-%d-*-*-p-*-iso10646-1 +-serif.bolditalic.greek=-monotype-times new roman-bold-i-normal--*-%d-*-*-p-*-iso10646-1 +-serif.bolditalic.hebrew=-monotype-times new roman-bold-i-normal--*-%d-*-*-p-*-iso10646-1 +-serif.bolditalic.japanese-x0201=-misc-ipamincho-medium-r-normal--*-%d-*-*-m-*-iso10646-1 +-serif.bolditalic.japanese-x0208=-misc-ipamincho-medium-r-normal--*-%d-*-*-m-*-iso10646-1 +-serif.bolditalic.latin-1=-monotype-times new roman-bold-i-normal--*-%d-*-*-p-*-iso10646-1 +-serif.bolditalic.latin-2=-monotype-times new roman-bold-i-normal--*-%d-*-*-p-*-iso10646-1 +-serif.bolditalic.latin-5=-monotype-times new roman-bold-i-normal--*-%d-*-*-p-*-iso10646-1 +-serif.bolditalic.latin-7=-monotype-times new roman-bold-i-normal--*-%d-*-*-p-*-iso10646-1 +-serif.bolditalic.latin-9=-monotype-times new roman-bold-i-normal--*-%d-*-*-p-*-iso10646-1 +-serif.bolditalic.thai=-monotype-angsana new-bold-i-normal--*-%d-*-*-p-*-iso10646-1 +- +-sansserif.plain.arabic=-monotype-arial-medium-r-normal--*-%d-*-*-p-*-iso10646-1 +-sansserif.plain.cyrillic-iso8859-5=-monotype-arial-medium-r-normal--*-%d-*-*-p-*-iso10646-1 +-sansserif.plain.cyrillic-cp1251=-monotype-arial-medium-r-normal--*-%d-*-*-p-*-iso10646-1 +-sansserif.plain.cyrillic-koi8-r=-monotype-arial-medium-r-normal--*-%d-*-*-p-*-iso10646-1 +-sansserif.plain.greek=-monotype-arial-medium-r-normal--*-%d-*-*-p-*-iso10646-1 +-sansserif.plain.hebrew=-monotype-arial-medium-r-normal--*-%d-*-*-p-*-iso10646-1 +-sansserif.plain.japanese-x0201=-misc-ipagothic-medium-r-normal--*-%d-*-*-m-*-iso10646-1 +-sansserif.plain.japanese-x0208=-misc-ipagothic-medium-r-normal--*-%d-*-*-m-*-iso10646-1 +-sansserif.plain.latin-1=-monotype-arial-medium-r-normal--*-%d-*-*-p-*-iso10646-1 +-sansserif.plain.latin-2=-monotype-arial-medium-r-normal--*-%d-*-*-p-*-iso10646-1 +-sansserif.plain.latin-5=-monotype-arial-medium-r-normal--*-%d-*-*-p-*-iso10646-1 +-sansserif.plain.latin-7=-monotype-arial-medium-r-normal--*-%d-*-*-p-*-iso10646-1 +-sansserif.plain.latin-9=-monotype-arial-medium-r-normal--*-%d-*-*-p-*-iso10646-1 +-sansserif.plain.thai=-monotype-browallia new-medium-r-normal--*-%d-*-*-p-*-iso10646-1 +- +-sansserif.bold.arabic=-monotype-arial-bold-r-normal--*-%d-*-*-p-*-iso10646-1 +-sansserif.bold.cyrillic-iso8859-5=-monotype-arial-bold-r-normal--*-%d-*-*-p-*-iso10646-1 +-sansserif.bold.cyrillic-cp1251=-monotype-arial-bold-r-normal--*-%d-*-*-p-*-iso10646-1 +-sansserif.bold.cyrillic-koi8-r=-monotype-arial-bold-r-normal--*-%d-*-*-p-*-iso10646-1 +-sansserif.bold.greek=-monotype-arial-bold-r-normal--*-%d-*-*-p-*-iso10646-1 +-sansserif.bold.hebrew=-monotype-arial-bold-r-normal--*-%d-*-*-p-*-iso10646-1 +-sansserif.bold.japanese-x0201=-misc-ipagothic-medium-r-normal--*-%d-*-*-m-*-iso10646-1 +-sansserif.bold.japanese-x0208=-misc-ipagothic-medium-r-normal--*-%d-*-*-m-*-iso10646-1 +-sansserif.bold.latin-1=-monotype-arial-bold-r-normal--*-%d-*-*-p-*-iso10646-1 +-sansserif.bold.latin-2=-monotype-arial-bold-r-normal--*-%d-*-*-p-*-iso10646-1 +-sansserif.bold.latin-5=-monotype-arial-bold-r-normal--*-%d-*-*-p-*-iso10646-1 +-sansserif.bold.latin-7=-monotype-arial-bold-r-normal--*-%d-*-*-p-*-iso10646-1 +-sansserif.bold.latin-9=-monotype-arial-bold-r-normal--*-%d-*-*-p-*-iso10646-1 +-sansserif.bold.thai=-monotype-browallia new-bold-r-normal--*-%d-*-*-p-*-iso10646-1 +- +-sansserif.italic.arabic=-monotype-arial-medium-i-normal--*-%d-*-*-p-*-iso10646-1 +-sansserif.italic.cyrillic-iso8859-5=-monotype-arial-medium-i-normal--*-%d-*-*-p-*-iso10646-1 +-sansserif.italic.cyrillic-cp1251=-monotype-arial-medium-i-normal--*-%d-*-*-p-*-iso10646-1 +-sansserif.italic.cyrillic-koi8-r=-monotype-arial-medium-i-normal--*-%d-*-*-p-*-iso10646-1 +-sansserif.italic.greek=-monotype-arial-medium-i-normal--*-%d-*-*-p-*-iso10646-1 +-sansserif.italic.hebrew=-monotype-arial-medium-i-normal--*-%d-*-*-p-*-iso10646-1 +-sansserif.italic.japanese-x0201=-misc-ipagothic-medium-r-normal--*-%d-*-*-m-*-iso10646-1 +-sansserif.italic.japanese-x0208=-misc-ipagothic-medium-r-normal--*-%d-*-*-m-*-iso10646-1 +-sansserif.italic.latin-1=-monotype-arial-medium-i-normal--*-%d-*-*-p-*-iso10646-1 +-sansserif.italic.latin-2=-monotype-arial-medium-i-normal--*-%d-*-*-p-*-iso10646-1 +-sansserif.italic.latin-5=-monotype-arial-medium-i-normal--*-%d-*-*-p-*-iso10646-1 +-sansserif.italic.latin-7=-monotype-arial-medium-i-normal--*-%d-*-*-p-*-iso10646-1 +-sansserif.italic.latin-9=-monotype-arial-medium-i-normal--*-%d-*-*-p-*-iso10646-1 +-sansserif.italic.thai=-monotype-browallia new-medium-i-normal--*-%d-*-*-p-*-iso10646-1 +- +-sansserif.bolditalic.arabic=-monotype-arial-bold-r-normal--*-%d-*-*-p-*-iso10646-1 +-sansserif.bolditalic.cyrillic-iso8859-5=-monotype-arial-bold-i-normal--*-%d-*-*-p-*-iso10646-1 +-sansserif.bolditalic.cyrillic-cp1251=-monotype-arial-bold-i-normal--*-%d-*-*-p-*-iso10646-1 +-sansserif.bolditalic.cyrillic-koi8-r=-monotype-arial-bold-i-normal--*-%d-*-*-p-*-iso10646-1 +-sansserif.bolditalic.greek=-monotype-arial-bold-i-normal--*-%d-*-*-p-*-iso10646-1 +-sansserif.bolditalic.hebrew=-monotype-arial-bold-i-normal--*-%d-*-*-p-*-iso10646-1 +-sansserif.bolditalic.japanese-x0201=-misc-ipagothic-medium-r-normal--*-%d-*-*-m-*-iso10646-1 +-sansserif.bolditalic.japanese-x0208=-misc-ipagothic-medium-r-normal--*-%d-*-*-m-*-iso10646-1 +-sansserif.bolditalic.latin-1=-monotype-arial-bold-i-normal--*-%d-*-*-p-*-iso10646-1 +-sansserif.bolditalic.latin-2=-monotype-arial-bold-i-normal--*-%d-*-*-p-*-iso10646-1 +-sansserif.bolditalic.latin-5=-monotype-arial-bold-i-normal--*-%d-*-*-p-*-iso10646-1 +-sansserif.bolditalic.latin-7=-monotype-arial-bold-i-normal--*-%d-*-*-p-*-iso10646-1 +-sansserif.bolditalic.latin-9=-monotype-arial-bold-i-normal--*-%d-*-*-p-*-iso10646-1 +-sansserif.bolditalic.thai=-monotype-browallia new-bold-i-normal--*-%d-*-*-p-*-iso10646-1 +- +-monospaced.plain.arabic=-monotype-courier new-medium-r-normal--*-%d-*-*-p-*-iso10646-1 +-monospaced.plain.cyrillic-iso8859-5=-monotype-courier new-medium-r-normal--*-%d-*-*-p-*-iso10646-1 +-monospaced.plain.cyrillic-cp1251=-monotype-courier new-medium-r-normal--*-%d-*-*-p-*-iso10646-1 +-monospaced.plain.cyrillic-koi8-r=-monotype-courier new-medium-r-normal--*-%d-*-*-p-*-iso10646-1 +-monospaced.plain.greek=-monotype-courier new-medium-r-normal--*-%d-*-*-p-*-iso10646-1 +-monospaced.plain.hebrew=-monotype-courier new-medium-r-normal--*-%d-*-*-p-*-iso10646-1 +-monospaced.plain.japanese-x0201=-misc-ipamincho-medium-r-normal--*-%d-*-*-m-*-iso10646-1 +-monospaced.plain.japanese-x0208=-misc-ipamincho-medium-r-normal--*-%d-*-*-m-*-iso10646-1 +-monospaced.plain.latin-1=-monotype-courier new-medium-r-normal--*-%d-*-*-p-*-iso10646-1 +-monospaced.plain.latin-2=-monotype-courier new-medium-r-normal--*-%d-*-*-p-*-iso10646-1 +-monospaced.plain.latin-5=-monotype-courier new-medium-r-normal--*-%d-*-*-p-*-iso10646-1 +-monospaced.plain.latin-7=-monotype-courier new-medium-r-normal--*-%d-*-*-p-*-iso10646-1 +-monospaced.plain.latin-9=-monotype-courier new-medium-r-normal--*-%d-*-*-p-*-iso10646-1 +-monospaced.plain.thai=-monotype-cordia new-medium-r-normal--*-%d-*-*-p-*-iso10646-1 +- +-monospaced.bold.arabic=-monotype-courier new-bold-r-normal--*-%d-*-*-p-*-iso10646-1 +-monospaced.bold.cyrillic-iso8859-5=-monotype-courier new-bold-r-normal--*-%d-*-*-p-*-iso10646-1 +-monospaced.bold.cyrillic-cp1251=-monotype-courier new-bold-r-normal--*-%d-*-*-p-*-iso10646-1 +-monospaced.bold.cyrillic-koi8-r=-monotype-courier new-bold-r-normal--*-%d-*-*-p-*-iso10646-1 +-monospaced.bold.greek=-monotype-courier new-bold-r-normal--*-%d-*-*-p-*-iso10646-1 +-monospaced.bold.hebrew=-monotype-courier new-bold-r-normal--*-%d-*-*-p-*-iso10646-1 +-monospaced.bold.japanese-x0201=-misc-ipamincho-medium-r-normal--*-%d-*-*-m-*-iso10646-1 +-monospaced.bold.japanese-x0208=-misc-ipamincho-medium-r-normal--*-%d-*-*-m-*-iso10646-1 +-monospaced.bold.latin-1=-monotype-courier new-bold-r-normal--*-%d-*-*-p-*-iso10646-1 +-monospaced.bold.latin-2=-monotype-courier new-bold-r-normal--*-%d-*-*-p-*-iso10646-1 +-monospaced.bold.latin-5=-monotype-courier new-bold-r-normal--*-%d-*-*-p-*-iso10646-1 +-monospaced.bold.latin-7=-monotype-courier new-bold-r-normal--*-%d-*-*-p-*-iso10646-1 +-monospaced.bold.latin-9=-monotype-courier new-bold-r-normal--*-%d-*-*-p-*-iso10646-1 +-monospaced.bold.thai=-monotype-cordia new-bold-r-normal--*-%d-*-*-p-*-iso10646-1 +- +-monospaced.italic.arabic=-monotype-courier new-medium-r-normal--*-%d-*-*-p-*-iso10646-1 +-monospaced.italic.cyrillic-iso8859-5=-monotype-courier new-medium-i-normal--*-%d-*-*-p-*-iso10646-1 +-monospaced.italic.cyrillic-cp1251=-monotype-courier new-medium-i-normal--*-%d-*-*-p-*-iso10646-1 +-monospaced.italic.cyrillic-koi8-r=-monotype-courier new-medium-i-normal--*-%d-*-*-p-*-iso10646-1 +-monospaced.italic.greek=-monotype-courier new-medium-i-normal--*-%d-*-*-p-*-iso10646-1 +-monospaced.italic.hebrew=-monotype-courier new-medium-i-normal--*-%d-*-*-p-*-iso10646-1 +-monospaced.italic.japanese-x0201=-misc-ipamincho-medium-r-normal--*-%d-*-*-m-*-iso10646-1 +-monospaced.italic.japanese-x0208=-misc-ipamincho-medium-r-normal--*-%d-*-*-m-*-iso10646-1 +-monospaced.italic.latin-1=-monotype-courier new-medium-i-normal--*-%d-*-*-p-*-iso10646-1 +-monospaced.italic.latin-2=-monotype-courier new-medium-i-normal--*-%d-*-*-p-*-iso10646-1 +-monospaced.italic.latin-5=-monotype-courier new-medium-i-normal--*-%d-*-*-p-*-iso10646-1 +-monospaced.italic.latin-7=-monotype-courier new-medium-i-normal--*-%d-*-*-p-*-iso10646-1 +-monospaced.italic.latin-9=-monotype-courier new-medium-i-normal--*-%d-*-*-p-*-iso10646-1 +-monospaced.italic.thai=-monotype-cordia new-medium-i-normal--*-%d-*-*-p-*-iso10646-1 +- +-monospaced.bolditalic.arabic=-monotype-courier new-bold-r-normal--*-%d-*-*-p-*-iso10646-1 +-monospaced.bolditalic.cyrillic-iso8859-5=-monotype-courier new-bold-i-normal--*-%d-*-*-p-*-iso10646-1 +-monospaced.bolditalic.cyrillic-cp1251=-monotype-courier new-bold-i-normal--*-%d-*-*-p-*-iso10646-1 +-monospaced.bolditalic.cyrillic-koi8-r=-monotype-courier new-bold-i-normal--*-%d-*-*-p-*-iso10646-1 +-monospaced.bolditalic.greek=-monotype-courier new-bold-i-normal--*-%d-*-*-p-*-iso10646-1 +-monospaced.bolditalic.hebrew=-monotype-courier new-bold-i-normal--*-%d-*-*-p-*-iso10646-1 +-monospaced.bolditalic.japanese-x0201=-misc-ipamincho-medium-r-normal--*-%d-*-*-m-*-iso10646-1 +-monospaced.bolditalic.japanese-x0208=-misc-ipamincho-medium-r-normal--*-%d-*-*-m-*-iso10646-1 +-monospaced.bolditalic.latin-1=-monotype-courier new-bold-i-normal--*-%d-*-*-p-*-iso10646-1 +-monospaced.bolditalic.latin-2=-monotype-courier new-bold-i-normal--*-%d-*-*-p-*-iso10646-1 +-monospaced.bolditalic.latin-5=-monotype-courier new-bold-i-normal--*-%d-*-*-p-*-iso10646-1 +-monospaced.bolditalic.latin-7=-monotype-courier new-bold-i-normal--*-%d-*-*-p-*-iso10646-1 +-monospaced.bolditalic.latin-9=-monotype-courier new-bold-i-normal--*-%d-*-*-p-*-iso10646-1 +-monospaced.bolditalic.thai=-monotype-cordia new-bold-i-normal--*-%d-*-*-p-*-iso10646-1 +- +-dialog.plain.arabic=-monotype-arial-medium-r-normal--*-%d-*-*-p-*-iso10646-1 +-dialog.plain.cyrillic-iso8859-5=-monotype-arial-medium-r-normal--*-%d-*-*-p-*-iso10646-1 +-dialog.plain.cyrillic-cp1251=-monotype-arial-medium-r-normal--*-%d-*-*-p-*-iso10646-1 +-dialog.plain.cyrillic-koi8-r=-monotype-arial-medium-r-normal--*-%d-*-*-p-*-iso10646-1 +-dialog.plain.greek=-monotype-arial-medium-r-normal--*-%d-*-*-p-*-iso10646-1 +-dialog.plain.hebrew=-monotype-arial-medium-r-normal--*-%d-*-*-p-*-iso10646-1 +-dialog.plain.japanese-x0201=-misc-ipagothic-medium-r-normal--*-%d-*-*-m-*-iso10646-1 +-dialog.plain.japanese-x0208=-misc-ipagothic-medium-r-normal--*-%d-*-*-m-*-iso10646-1 +-dialog.plain.latin-1=-monotype-arial-medium-r-normal--*-%d-*-*-p-*-iso10646-1 +-dialog.plain.latin-2=-monotype-arial-medium-r-normal--*-%d-*-*-p-*-iso10646-1 +-dialog.plain.latin-5=-monotype-arial-medium-r-normal--*-%d-*-*-p-*-iso10646-1 +-dialog.plain.latin-7=-monotype-arial-medium-r-normal--*-%d-*-*-p-*-iso10646-1 +-dialog.plain.latin-9=-monotype-arial-medium-r-normal--*-%d-*-*-p-*-iso10646-1 +-dialog.plain.thai=-monotype-browallia new-medium-r-normal--*-%d-*-*-p-*-iso10646-1 +- +-dialog.bold.arabic=-monotype-arial-bold-r-normal--*-%d-*-*-p-*-iso10646-1 +-dialog.bold.cyrillic-iso8859-5=-monotype-arial-bold-r-normal--*-%d-*-*-p-*-iso10646-1 +-dialog.bold.cyrillic-cp1251=-monotype-arial-bold-r-normal--*-%d-*-*-p-*-iso10646-1 +-dialog.bold.cyrillic-koi8-r=-monotype-arial-bold-r-normal--*-%d-*-*-p-*-iso10646-1 +-dialog.bold.greek=-monotype-arial-bold-r-normal--*-%d-*-*-p-*-iso10646-1 +-dialog.bold.hebrew=-monotype-arial-bold-r-normal--*-%d-*-*-p-*-iso10646-1 +-dialog.bold.japanese-x0201=-misc-ipagothic-medium-r-normal--*-%d-*-*-m-*-iso10646-1 +-dialog.bold.japanese-x0208=-misc-ipagothic-medium-r-normal--*-%d-*-*-m-*-iso10646-1 +-dialog.bold.latin-1=-monotype-arial-bold-r-normal--*-%d-*-*-p-*-iso10646-1 +-dialog.bold.latin-2=-monotype-arial-bold-r-normal--*-%d-*-*-p-*-iso10646-1 +-dialog.bold.latin-5=-monotype-arial-bold-r-normal--*-%d-*-*-p-*-iso10646-1 +-dialog.bold.latin-7=-monotype-arial-bold-r-normal--*-%d-*-*-p-*-iso10646-1 +-dialog.bold.latin-9=-monotype-arial-bold-r-normal--*-%d-*-*-p-*-iso10646-1 +-dialog.bold.thai=-monotype-browallia new-bold-r-normal--*-%d-*-*-p-*-iso10646-1 +- +-dialog.italic.arabic=-monotype-arial-medium-i-normal--*-%d-*-*-p-*-iso10646-1 +-dialog.italic.cyrillic-iso8859-5=-monotype-arial-medium-i-normal--*-%d-*-*-p-*-iso10646-1 +-dialog.italic.cyrillic-cp1251=-monotype-arial-medium-i-normal--*-%d-*-*-p-*-iso10646-1 +-dialog.italic.cyrillic-koi8-r=-monotype-arial-medium-i-normal--*-%d-*-*-p-*-iso10646-1 +-dialog.italic.greek=-monotype-arial-medium-i-normal--*-%d-*-*-p-*-iso10646-1 +-dialog.italic.hebrew=-monotype-arial-medium-i-normal--*-%d-*-*-p-*-iso10646-1 +-dialog.italic.japanese-x0201=-misc-ipagothic-medium-r-normal--*-%d-*-*-m-*-iso10646-1 +-dialog.italic.japanese-x0208=-misc-ipagothic-medium-r-normal--*-%d-*-*-m-*-iso10646-1 +-dialog.italic.latin-1=-monotype-arial-medium-i-normal--*-%d-*-*-p-*-iso10646-1 +-dialog.italic.latin-2=-monotype-arial-medium-i-normal--*-%d-*-*-p-*-iso10646-1 +-dialog.italic.latin-5=-monotype-arial-medium-i-normal--*-%d-*-*-p-*-iso10646-1 +-dialog.italic.latin-7=-monotype-arial-medium-i-normal--*-%d-*-*-p-*-iso10646-1 +-dialog.italic.latin-9=-monotype-arial-medium-i-normal--*-%d-*-*-p-*-iso10646-1 +-dialog.italic.thai=-monotype-browallia new-medium-i-normal--*-%d-*-*-p-*-iso10646-1 +- +-dialog.bolditalic.arabic=-monotype-arial-bold-r-normal--*-%d-*-*-p-*-iso10646-1 +-dialog.bolditalic.cyrillic-iso8859-5=-monotype-arial-bold-i-normal--*-%d-*-*-p-*-iso10646-1 +-dialog.bolditalic.cyrillic-cp1251=-monotype-arial-bold-i-normal--*-%d-*-*-p-*-iso10646-1 +-dialog.bolditalic.cyrillic-koi8-r=-monotype-arial-bold-i-normal--*-%d-*-*-p-*-iso10646-1 +-dialog.bolditalic.greek=-monotype-arial-bold-i-normal--*-%d-*-*-p-*-iso10646-1 +-dialog.bolditalic.hebrew=-monotype-arial-bold-i-normal--*-%d-*-*-p-*-iso10646-1 +-dialog.bolditalic.japanese-x0201=-misc-ipagothic-medium-r-normal--*-%d-*-*-m-*-iso10646-1 +-dialog.bolditalic.japanese-x0208=-misc-ipagothic-medium-r-normal--*-%d-*-*-m-*-iso10646-1 +-dialog.bolditalic.latin-1=-monotype-arial-bold-i-normal--*-%d-*-*-p-*-iso10646-1 +-dialog.bolditalic.latin-2=-monotype-arial-bold-i-normal--*-%d-*-*-p-*-iso10646-1 +-dialog.bolditalic.latin-5=-monotype-arial-bold-i-normal--*-%d-*-*-p-*-iso10646-1 +-dialog.bolditalic.latin-7=-monotype-arial-bold-i-normal--*-%d-*-*-p-*-iso10646-1 +-dialog.bolditalic.latin-9=-monotype-arial-bold-i-normal--*-%d-*-*-p-*-iso10646-1 +-dialog.bolditalic.thai=-monotype-browallia new-bold-i-normal--*-%d-*-*-p-*-iso10646-1 +- +-dialoginput.plain.arabic=-monotype-courier new-medium-r-normal--*-%d-*-*-p-*-iso10646-1 +-dialoginput.plain.cyrillic-iso8859-5=-monotype-courier new-medium-r-normal--*-%d-*-*-p-*-iso10646-1 +-dialoginput.plain.cyrillic-cp1251=-monotype-courier new-medium-r-normal--*-%d-*-*-p-*-iso10646-1 +-dialoginput.plain.cyrillic-koi8-r=-monotype-courier new-medium-r-normal--*-%d-*-*-p-*-iso10646-1 +-dialoginput.plain.greek=-monotype-courier new-medium-r-normal--*-%d-*-*-p-*-iso10646-1 +-dialoginput.plain.hebrew=-monotype-courier new-medium-r-normal--*-%d-*-*-p-*-iso10646-1 +-dialoginput.plain.japanese-x0201=-misc-ipamincho-medium-r-normal--*-%d-*-*-m-*-iso10646-1 +-dialoginput.plain.japanese-x0208=-misc-ipamincho-medium-r-normal--*-%d-*-*-m-*-iso10646-1 +-dialoginput.plain.latin-1=-monotype-courier new-medium-r-normal--*-%d-*-*-p-*-iso10646-1 +-dialoginput.plain.latin-2=-monotype-courier new-medium-r-normal--*-%d-*-*-p-*-iso10646-1 +-dialoginput.plain.latin-5=-monotype-courier new-medium-r-normal--*-%d-*-*-p-*-iso10646-1 +-dialoginput.plain.latin-7=-monotype-courier new-medium-r-normal--*-%d-*-*-p-*-iso10646-1 +-dialoginput.plain.latin-9=-monotype-courier new-medium-r-normal--*-%d-*-*-p-*-iso10646-1 +-dialoginput.plain.thai=-monotype-cordia new-medium-r-normal--*-%d-*-*-p-*-iso10646-1 +- +-dialoginput.bold.arabic=-monotype-courier new-bold-r-normal--*-%d-*-*-p-*-iso10646-1 +-dialoginput.bold.cyrillic-iso8859-5=-monotype-courier new-bold-r-normal--*-%d-*-*-p-*-iso10646-1 +-dialoginput.bold.cyrillic-cp1251=-monotype-courier new-bold-r-normal--*-%d-*-*-p-*-iso10646-1 +-dialoginput.bold.cyrillic-koi8-r=-monotype-courier new-bold-r-normal--*-%d-*-*-p-*-iso10646-1 +-dialoginput.bold.greek=-monotype-courier new-bold-r-normal--*-%d-*-*-p-*-iso10646-1 +-dialoginput.bold.hebrew=-monotype-courier new-bold-r-normal--*-%d-*-*-p-*-iso10646-1 +-dialoginput.bold.japanese-x0201=-misc-ipamincho-medium-r-normal--*-%d-*-*-m-*-iso10646-1 +-dialoginput.bold.japanese-x0208=-misc-ipamincho-medium-r-normal--*-%d-*-*-m-*-iso10646-1 +-dialoginput.bold.latin-1=-monotype-courier new-bold-r-normal--*-%d-*-*-p-*-iso10646-1 +-dialoginput.bold.latin-2=-monotype-courier new-bold-r-normal--*-%d-*-*-p-*-iso10646-1 +-dialoginput.bold.latin-5=-monotype-courier new-bold-r-normal--*-%d-*-*-p-*-iso10646-1 +-dialoginput.bold.latin-7=-monotype-courier new-bold-r-normal--*-%d-*-*-p-*-iso10646-1 +-dialoginput.bold.latin-9=-monotype-courier new-bold-r-normal--*-%d-*-*-p-*-iso10646-1 +-dialoginput.bold.thai=-monotype-cordia new-bold-r-normal--*-%d-*-*-p-*-iso10646-1 +- +-dialoginput.italic.arabic=-monotype-courier new-medium-r-normal--*-%d-*-*-p-*-iso10646-1 +-dialoginput.italic.cyrillic-iso8859-5=-monotype-courier new-medium-i-normal--*-%d-*-*-p-*-iso10646-1 +-dialoginput.italic.cyrillic-cp1251=-monotype-courier new-medium-i-normal--*-%d-*-*-p-*-iso10646-1 +-dialoginput.italic.cyrillic-koi8-r=-monotype-courier new-medium-i-normal--*-%d-*-*-p-*-iso10646-1 +-dialoginput.italic.greek=-monotype-courier new-medium-i-normal--*-%d-*-*-p-*-iso10646-1 +-dialoginput.italic.hebrew=-monotype-courier new-medium-i-normal--*-%d-*-*-p-*-iso10646-1 +-dialoginput.italic.japanese-x0201=-misc-ipamincho-medium-r-normal--*-%d-*-*-m-*-iso10646-1 +-dialoginput.italic.japanese-x0208=-misc-ipamincho-medium-r-normal--*-%d-*-*-m-*-iso10646-1 +-dialoginput.italic.latin-1=-monotype-courier new-medium-i-normal--*-%d-*-*-p-*-iso10646-1 +-dialoginput.italic.latin-2=-monotype-courier new-medium-i-normal--*-%d-*-*-p-*-iso10646-1 +-dialoginput.italic.latin-5=-monotype-courier new-medium-i-normal--*-%d-*-*-p-*-iso10646-1 +-dialoginput.italic.latin-7=-monotype-courier new-medium-i-normal--*-%d-*-*-p-*-iso10646-1 +-dialoginput.italic.latin-9=-monotype-courier new-medium-i-normal--*-%d-*-*-p-*-iso10646-1 +-dialoginput.italic.thai=-monotype-cordia new-medium-i-normal--*-%d-*-*-p-*-iso10646-1 +- +-dialoginput.bolditalic.arabic=-monotype-courier new-bold-r-normal--*-%d-*-*-p-*-iso10646-1 +-dialoginput.bolditalic.cyrillic-iso8859-5=-monotype-courier new-bold-i-normal--*-%d-*-*-p-*-iso10646-1 +-dialoginput.bolditalic.cyrillic-cp1251=-monotype-courier new-bold-i-normal--*-%d-*-*-p-*-iso10646-1 +-dialoginput.bolditalic.cyrillic-koi8-r=-monotype-courier new-bold-i-normal--*-%d-*-*-p-*-iso10646-1 +-dialoginput.bolditalic.greek=-monotype-courier new-bold-i-normal--*-%d-*-*-p-*-iso10646-1 +-dialoginput.bolditalic.hebrew=-monotype-courier new-bold-i-normal--*-%d-*-*-p-*-iso10646-1 +-dialoginput.bolditalic.japanese-x0201=-misc-ipamincho-medium-r-normal--*-%d-*-*-m-*-iso10646-1 +-dialoginput.bolditalic.japanese-x0208=-misc-ipamincho-medium-r-normal--*-%d-*-*-m-*-iso10646-1 +-dialoginput.bolditalic.latin-1=-monotype-courier new-bold-i-normal--*-%d-*-*-p-*-iso10646-1 +-dialoginput.bolditalic.latin-2=-monotype-courier new-bold-i-normal--*-%d-*-*-p-*-iso10646-1 +-dialoginput.bolditalic.latin-5=-monotype-courier new-bold-i-normal--*-%d-*-*-p-*-iso10646-1 +-dialoginput.bolditalic.latin-7=-monotype-courier new-bold-i-normal--*-%d-*-*-p-*-iso10646-1 +-dialoginput.bolditalic.latin-9=-monotype-courier new-bold-i-normal--*-%d-*-*-p-*-iso10646-1 +-dialoginput.bolditalic.thai=-monotype-cordia new-bold-i-normal--*-%d-*-*-p-*-iso10646-1 +- +-# Search Sequences +- +-sequence.allfonts=latin-1 +- +-sequence.allfonts.Big5=latin-1,chinese-big5 +- +-sequence.allfonts.Big5-HKSCS-2001=latin-1,chinese-big5,chinese-hkscs +- +-sequence.allfonts.windows-1251=cyrillic-cp1251,latin-1 +- +-sequence.allfonts.GB2312=latin-1,chinese-gb2312 +- +-sequence.allfonts.x-eucJP-Open=latin-1,japanese-x0201,japanese-x0208,japanese-x0212 +- +-sequence.allfonts.EUC-KR=latin-1,korean +- +-sequence.allfonts.x-EUC-TW=latin-1,chinese-cns11643-1,chinese-cns11643-2,chinese-cns11643-3 +- +-sequence.allfonts.GBK=latin-1,chinese-gbk +- +-sequence.allfonts.GB18030=latin-1,chinese-gb18030-0,chinese-gb18030-1 +- +-sequence.allfonts.ISO-8859-2=latin-2,latin-1 +- +-sequence.allfonts.ISO-8859-5=cyrillic-iso8859-5,latin-1 +- +-sequence.allfonts.ISO-8859-6=arabic,latin-1 +- +-sequence.allfonts.ISO-8859-7=latin-1,greek +- +-sequence.allfonts.ISO-8859-8=latin-1,hebrew +- +-sequence.allfonts.ISO-8859-9=latin-5,latin-1 +- +-sequence.allfonts.ISO-8859-13=latin-7,latin-1 +- +-sequence.allfonts.ISO-8859-15=latin-9 +- +-sequence.allfonts.KOI8-R=cyrillic-koi8-r,latin-1 +- +-sequence.allfonts.x-PCK=latin-1,japanese-x0201,japanese-x0208,japanese-x0212 +- +-sequence.allfonts.TIS-620=latin-1,thai +- +-sequence.allfonts.UTF-8=latin-1 +-sequence.allfonts.UTF-8.en=latin-1 +-sequence.allfonts.UTF-8.hi=latin-1,hindi +-sequence.allfonts.UTF-8.be=latin-1,bengali +-sequence.allfonts.UTF-8.te=latin-1,telugu +-sequence.allfonts.UTF-8.mr=latin-1,marathi +-sequence.allfonts.UTF-8.ta=latin-1,tamil +-sequence.allfonts.UTF-8.gu=latin-1,gujarati +-sequence.allfonts.UTF-8.kn=latin-1,kannada +-sequence.allfonts.UTF-8.ma=latin-1,malayalam +- +-sequence.allfonts.UTF-8.ko=latin-1,korean-johab,japanese-x0201,japanese-x0208,japanese-x0212 +- +-sequence.allfonts.UTF-8.th=latin-1,thai +- +-sequence.allfonts.UTF-8.zh.CN=latin-1,chinese-gb18030-0,chinese-gb18030-1,chinese-big5,chinese-hkscs +- +-sequence.allfonts.UTF-8.zh.HK=latin-1,chinese-big5,chinese-hkscs,chinese-gb18030-0,chinese-gb18030-1 +- +-sequence.allfonts.UTF-8.zh.TW=latin-1,chinese-big5,chinese-hkscs,chinese-gb18030-0,chinese-gb18030-1 +- +-# the fallback sequence omits the following character subsets: +-# - chinese: all same file : just use chinese-gb18030-0 +-# - japanese-x0208: same files as japanese-x0201 +-# - japanese-x0212: same files as japanese-x0201 +-# - korean: same file as korean-johab +-sequence.fallback=latin-1,latin-2,latin-7,cyrillic-iso8859-5,greek,latin-5,latin-9,\ +- arabic,hebrew,thai,\ +- chinese-gb18030-0,\ +- japanese-x0201,korean-johab,\ +- hindi,bengali,telugu,marathi,tamil,gujarati,kannada,malayalam,\ +- dejavusans,dingbats,symbol +- +-# Font File Names +- +-filename.-monotype-arial-medium-r-normal--*-%d-*-*-p-*-iso10646-1=/usr/share/fonts/TrueType/core/arial.ttf +-filename.-monotype-arial-medium-i-normal--*-%d-*-*-p-*-iso10646-1=/usr/share/fonts/TrueType/core/ariali.ttf +-filename.-monotype-arial-bold-r-normal--*-%d-*-*-p-*-iso10646-1=/usr/share/fonts/TrueType/core/arialbd.ttf +-filename.-monotype-arial-bold-i-normal--*-%d-*-*-p-*-iso10646-1=/usr/share/fonts/TrueType/core/arialbi.ttf +-filename.-monotype-courier_new-medium-r-normal--*-%d-*-*-p-*-iso10646-1=/usr/share/fonts/TrueType/core/cour.ttf +-filename.-monotype-courier_new-medium-i-normal--*-%d-*-*-p-*-iso10646-1=/usr/share/fonts/TrueType/core/couri.ttf +-filename.-monotype-courier_new-bold-r-normal--*-%d-*-*-p-*-iso10646-1=/usr/share/fonts/TrueType/core/courbd.ttf +-filename.-monotype-courier_new-bold-i-normal--*-%d-*-*-p-*-iso10646-1=/usr/share/fonts/TrueType/core/courbi.ttf +-filename.-monotype-times_new_roman-medium-r-normal--*-%d-*-*-p-*-iso10646-1=/usr/share/fonts/TrueType/core/times.ttf +-filename.-monotype-times_new_roman-medium-i-normal--*-%d-*-*-p-*-iso10646-1=/usr/share/fonts/TrueType/core/timesi.ttf +-filename.-monotype-times_new_roman-bold-r-normal--*-%d-*-*-p-*-iso10646-1=/usr/share/fonts/TrueType/core/timesbd.ttf +-filename.-monotype-times_new_roman-bold-i-normal--*-%d-*-*-p-*-iso10646-1=/usr/share/fonts/TrueType/core/timesbi.ttf +- +-filename.-monotype-angsana_new-medium-r-normal--*-%d-*-*-p-*-iso10646-1=/usr/share/fonts/TrueType/core/angsa.ttf +-filename.-monotype-angsana_new-medium-i-normal--*-%d-*-*-p-*-iso10646-1=/usr/share/fonts/TrueType/core/angsai.ttf +-filename.-monotype-angsana_new-bold-r-normal--*-%d-*-*-p-*-iso10646-1=/usr/share/fonts/TrueType/core/angsab.ttf +-filename.-monotype-angsana_new-bold-i-normal--*-%d-*-*-p-*-iso10646-1=/usr/share/fonts/TrueType/core/angsaz.ttf +-filename.-monotype-browallia_new-medium-r-normal--*-%d-*-*-p-*-iso10646-1=/usr/share/fonts/TrueType/core/browa.ttf +-filename.-monotype-browallia_new-medium-i-normal--*-%d-*-*-p-*-iso10646-1=/usr/share/fonts/TrueType/core/browai.ttf +-filename.-monotype-browallia_new-bold-r-normal--*-%d-*-*-p-*-iso10646-1=/usr/share/fonts/TrueType/core/browab.ttf +-filename.-monotype-browallia_new-bold-i-normal--*-%d-*-*-p-*-iso10646-1=/usr/share/fonts/TrueType/core/browaz.ttf +-filename.-monotype-cordia_new-medium-r-normal--*-%d-*-*-p-*-iso10646-1=/usr/share/fonts/TrueType/core/cordia.ttf +-filename.-monotype-cordia_new-medium-i-normal--*-%d-*-*-p-*-iso10646-1=/usr/share/fonts/TrueType/core/cordiai.ttf +-filename.-monotype-cordia_new-bold-r-normal--*-%d-*-*-p-*-iso10646-1=/usr/share/fonts/TrueType/core/cordiab.ttf +-filename.-monotype-cordia_new-bold-i-normal--*-%d-*-*-p-*-iso10646-1=/usr/share/fonts/TrueType/core/cordiaz.ttf +- +-filename.-misc-ipagothic-medium-r-normal--*-%d-*-*-m-*-iso10646-1=/usr/share/fonts/TrueType/ipafont/ipag.otf +-filename.-misc-ipamincho-medium-r-normal--*-%d-*-*-m-*-iso10646-1=/usr/share/fonts/TrueType/ipafont/ipam.otf +-filename.-hanyang-gothic-medium-r-normal--*-%d-*-*-m-*-iso10646-1=/usr/share/fonts/TrueType/hanyang/h2gtrm.ttf +-filename.-arphic-uming-medium-r-normal--*-%d-*-*-m-*-iso10646-1=/usr/share/fonts/TrueType/arphic/uming.ttf +-filename.-monotype-symbol-medium-r-normal--*-%d-*-*-p-*-adobe-symbol=/usr/share/fonts/TrueType/core/symbol.ttf +-filename.-microsoft-wingdings-medium-r-normal--*-%d-*-*-p-*-adobe-fontspecific=/usr/share/fonts/TrueType/core/wingdings.ttf +-filename.-misc-lohit_bengali-medium-r-normal--0-0-0-0-p-0-iso10646-1=/usr/share/fonts/TrueType/lohit/Lohit-Bengali.ttf +-filename.-misc-lohit_gujarati-medium-r-normal--0-0-0-0-p-0-iso10646-1=/usr/share/fonts/TrueType/lohit/Lohit-Gujarati.ttf +-filename.-misc-lohit_hindi-medium-r-normal--0-0-0-0-p-0-iso10646-1=/usr/share/fonts/TrueType/lohit/Lohit-Hindi.ttf +-filename.-misc-lohit_kannada-medium-r-normal--0-0-0-0-p-0-iso10646-1=/usr/share/fonts/TrueType/lohit/Lohit-Kannada.ttf +-filename.-misc-lohit_malayalam-medium-r-normal--0-0-0-0-p-0-iso10646-1=/usr/share/fonts/TrueType/lohit/Lohit-Malayalam.ttf +-filename.-misc-lohit_marathi-medium-r-normal--0-0-0-0-p-0-iso10646-1=/usr/share/fonts/TrueType/lohit/Lohit-Marathi.ttf +-filename.-misc-lohit_tamil-medium-r-normal--0-0-0-0-p-0-iso10646-1=/usr/share/fonts/TrueType/lohit/Lohit-Tamil.ttf +-filename.-misc-lohit_telugu-medium-r-normal--0-0-0-0-p-0-iso10646-1=/usr/share/fonts/TrueType/lohit/Lohit-Telugu.ttf +-filename.-misc-dejavu_sans-medium-r-normal--0-0-0-0-p-0-iso10646-1=/usr/share/fonts/TrueType/dejavu/DejaVuSans.ttf +- +-# AWT X11 font paths +-awtfontpath.latin-1=/usr/share/fonts/TrueType/core +-awtfontpath.latin-2=/usr/share/fonts/TrueType/core +-awtfontpath.latin-5=/usr/share/fonts/TrueType/core +-awtfontpath.latin-7=/usr/share/fonts/TrueType/core +-awtfontpath.latin-9=/usr/share/fonts/TrueType/core +-awtfontpath.hebrew=/usr/share/fonts/TrueType/core +-awtfontpath.arabic=/usr/share/fonts/TrueType/core +-awtfontpath.thai=/usr/share/fonts/TrueType/core +-awtfontpath.greek=/usr/share/fonts/TrueType/core +-awtfontpath.cyrillic-iso8859-5=/usr/share/fonts/TrueType/core +-awtfontpath.cyrillic-cp1251=/usr/share/fonts/TrueType/core +-awtfontpath.cyrillic-koi8-r=/usr/share/fonts/TrueType/core +-awtfontpath.korean=/usr/share/fonts/TrueType/hanyang +-awtfontpath.korean-johab=/usr/share/fonts/TrueType/hanyang +-awtfontpath.japanese-x0201=/usr/share/fonts/TrueType/ipafont +-awtfontpath.japanese-x0208=/usr/share/fonts/TrueType/ipafont +-awtfontpath.japanese-x0212=/usr/share/fonts/TrueType/ipafont +-awtfontpath.chinese-gbk=/usr/share/fonts/TrueType/arphic +-awtfontpath.chinese-cns11643-1=/usr/share/fonts/TrueType/arphic +-awtfontpath.chinese-cns11643-2=/usr/share/fonts/TrueType/arphic +-awtfontpath.chinese-cns11643-3=/usr/share/fonts/TrueType/arphic +-awtfontpath.chinese-big5=/usr/share/fonts/TrueType/arphic +-awtfontpath.chinese-gb2312=/usr/share/fonts/TrueType/arphic +-awtfontpath.chinese-gb18030-0=/usr/share/fonts/TrueType/arphic +-awtfontpath.chinese-gb18030-1=/usr/share/fonts/TrueType/arphic +-awtfontpath.chinese-hkscs=/usr/share/fonts/TrueType/arphic +-awtfontpath.bengali=/usr/share/fonts/TrueType/lohit +-awtfontpath.gujarati=/usr/share/fonts/TrueType/lohit +-awtfontpath.hindi=/usr/share/fonts/TrueType/lohit +-awtfontpath.kannada=/usr/share/fonts/TrueType/lohit +-awtfontpath.malayalam=/usr/share/fonts/TrueType/lohit +-awtfontpath.marathi=/usr/share/fonts/TrueType/lohit +-awtfontpath.tamil=/usr/share/fonts/TrueType/lohit +-awtfontpath.telugu=/usr/share/fonts/TrueType/lohit +-awtfontpath.dejavusans=/usr/share/fonts/TrueType/dejavu +- +-# Appended Font Path +- +--- old/make/hotspot/lib/CompileDtraceLibraries.gmk 2020-05-20 18:08:16.611609088 -0700 ++++ /dev/null 2020-03-09 18:57:19.455001459 -0700 +@@ -1,62 +0,0 @@ +-# +-# Copyright (c) 2013, 2019, Oracle and/or its affiliates. All rights reserved. +-# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. +-# +-# This code is free software; you can redistribute it and/or modify it +-# under the terms of the GNU General Public License version 2 only, as +-# published by the Free Software Foundation. Oracle designates this +-# particular file as subject to the "Classpath" exception as provided +-# by Oracle in the LICENSE file that accompanied this code. +-# +-# This code is distributed in the hope that it will be useful, but WITHOUT +-# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +-# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +-# version 2 for more details (a copy is included in the LICENSE file that +-# accompanied this code). +-# +-# You should have received a copy of the GNU General Public License version +-# 2 along with this work; if not, write to the Free Software Foundation, +-# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. +-# +-# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA +-# or visit www.oracle.com if you need additional information or have any +-# questions. +-# +- +-ifeq ($(call check-jvm-feature, dtrace), true) +- ifeq ($(call isTargetOs, solaris), true) +- JNI_INCLUDE_FLAGS := \ +- -I$(SUPPORT_OUTPUTDIR)/modules_include/java.base \ +- -I$(SUPPORT_OUTPUTDIR)/modules_include/java.base/$(OPENJDK_TARGET_OS_INCLUDE_SUBDIR) \ +- # +- +- ############################################################################ +- # Build the stand-alone dtrace libraries. +- +- LIBJVM_DTRACE_OUTPUTDIR := $(JVM_VARIANT_OUTPUTDIR)/libjvm_dtrace +- $(eval $(call SetupNativeCompilation, BUILD_LIBJVM_DTRACE, \ +- NAME := jvm_dtrace, \ +- OUTPUT_DIR := $(JVM_LIB_OUTPUTDIR), \ +- SRC := $(TOPDIR)/src/java.base/solaris/native/libjvm_dtrace, \ +- CFLAGS := $(JNI_INCLUDE_FLAGS) -m64 -G -mt -KPIC -xldscope=hidden, \ +- LDFLAGS := -m64 -mt -xnolib $(SHARED_LIBRARY_FLAGS), \ +- LIBS := $(LIBDL) -lthread -ldoor, \ +- OBJECT_DIR := $(LIBJVM_DTRACE_OUTPUTDIR)/objs, \ +- )) +- +- # Note that libjvm_db.c has tests for COMPILER2, but this was never set by +- # the old build. +- LIBJVM_DB_OUTPUTDIR := $(JVM_VARIANT_OUTPUTDIR)/libjvm_db +- $(eval $(call SetupNativeCompilation, BUILD_LIBJVM_DB, \ +- NAME := jvm_db, \ +- OUTPUT_DIR := $(JVM_LIB_OUTPUTDIR), \ +- SRC := $(TOPDIR)/src/java.base/solaris/native/libjvm_db, \ +- CFLAGS := -I$(DTRACE_GENSRC_DIR) $(JNI_INCLUDE_FLAGS) -m64 -G -mt -KPIC -xldscope=hidden, \ +- LDFLAGS := -m64 -mt -xnolib $(SHARED_LIBRARY_FLAGS), \ +- OBJECT_DIR := $(LIBJVM_DB_OUTPUTDIR)/objs, \ +- )) +- +- TARGETS += $(BUILD_LIBJVM_DTRACE) $(BUILD_LIBJVM_DB) +- +- endif +-endif +--- old/make/hotspot/lib/JvmDtraceObjects.gmk 2020-05-20 18:08:17.355623374 -0700 ++++ /dev/null 2020-03-09 18:57:19.455001459 -0700 +@@ -1,122 +0,0 @@ +-# +-# Copyright (c) 2013, 2019, Oracle and/or its affiliates. All rights reserved. +-# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. +-# +-# This code is free software; you can redistribute it and/or modify it +-# under the terms of the GNU General Public License version 2 only, as +-# published by the Free Software Foundation. Oracle designates this +-# particular file as subject to the "Classpath" exception as provided +-# by Oracle in the LICENSE file that accompanied this code. +-# +-# This code is distributed in the hope that it will be useful, but WITHOUT +-# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +-# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +-# version 2 for more details (a copy is included in the LICENSE file that +-# accompanied this code). +-# +-# You should have received a copy of the GNU General Public License version +-# 2 along with this work; if not, write to the Free Software Foundation, +-# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. +-# +-# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA +-# or visit www.oracle.com if you need additional information or have any +-# questions. +-# +- +-ifeq ($(call check-jvm-feature, dtrace), true) +- ifeq ($(call isTargetOs, solaris), true) +- +- ############################################################################ +- # Integrate with libjvm. Here we generate two object files which are +- # linked with libjvm.so. This step is complicated from a dependency +- # perspective. We add these two files to the linking of libjvm using +- # EXTRA_OBJECT_FILES, but they need to be created outside the call to +- # SetupNativeCompilation. Also, one of the files is dependent on compiled +- # object files from the libjvm compilation, so this generation must happen +- # as a part of the libjvm compilation. +- +- DTRACE_OBJ := $(JVM_OUTPUTDIR)/objs/dtrace.o +- DTRACE_JHELPER_OBJ := $(JVM_OUTPUTDIR)/objs/dtrace_jhelper.o +- +- DTRACE_EXTRA_OBJECT_FILES := $(DTRACE_OBJ) $(DTRACE_JHELPER_OBJ) +- +- ############################################################################ +- # Generate DTRACE_OBJ which is linked with libjvm.so. It depends on a set of +- # object files from the compilation. +- +- # Concatenate all *.d files into a single file +- DTRACE_SOURCE_FILES := $(addprefix $(TOPDIR)/src/hotspot/os/posix/dtrace/, \ +- hotspot_jni.d \ +- hotspot.d \ +- hs_private.d \ +- ) +- +- # *.d in the objs dir is used for generated make dependency files, so use +- # *.dt for dtrace files to avoid clashes. +- $(JVM_OUTPUTDIR)/objs/dtrace.dt: $(DTRACE_SOURCE_FILES) +- $(call LogInfo, Generating $(@F)) +- $(call MakeDir, $(@D)) +- $(CAT) $^ > $@ +- +- DTRACE_INSTRUMENTED_OBJS := $(addprefix $(JVM_OUTPUTDIR)/objs/, \ +- ciEnv.o \ +- classLoadingService.o \ +- compileBroker.o \ +- gcVMOperations.o \ +- hashtable.o \ +- instanceKlass.o \ +- java.o \ +- jni.o \ +- jvm.o \ +- memoryManager.o \ +- nmethod.o \ +- objectMonitor.o \ +- runtimeService.o \ +- sharedRuntime.o \ +- synchronizer.o \ +- thread.o \ +- unsafe.o \ +- vmThread.o \ +- ) +- +- ifeq ($(call check-jvm-feature, parallelgc), true) +- DTRACE_INSTRUMENTED_OBJS += $(addprefix $(JVM_OUTPUTDIR)/objs/, \ +- psVMOperations.o \ +- ) +- endif +- +- DTRACE_FLAGS := -64 -G +- DTRACE_CPP_FLAGS := -D_LP64 +- +- # Make sure we run our selected compiler for preprocessing instead of letting +- # the dtrace tool pick it on it's own. +- $(DTRACE_OBJ): $(JVM_OUTPUTDIR)/objs/dtrace.dt $(DTRACE_INSTRUMENTED_OBJS) +- $(call LogInfo, Generating $(@F) from $( $(DTRACE_SUPPORT_DIR)/$(@F).dt)) +- $(call ExecuteWithLog, $@, $(DTRACE) $(DTRACE_FLAGS) -xlazyload -o $@ \ +- -s $(DTRACE_SUPPORT_DIR)/$(@F).dt $(sort $(DTRACE_INSTRUMENTED_OBJS))) +- +- ############################################################################ +- # Generate DTRACE_JHELPER_OBJ which is linked with libjvm.so. +- +- JHELPER_DTRACE_SRC := $(TOPDIR)/src/hotspot/os/solaris/dtrace/jhelper.d +- +- # jhelper.d includes JvmOffsetsIndex.h which was created by the gensrc step. +- DTRACE_GENSRC_DIR := $(JVM_VARIANT_OUTPUTDIR)/gensrc/dtracefiles +- JVM_OFFSETS_INDEX_H := $(DTRACE_GENSRC_DIR)/JvmOffsetsIndex.h +- +- # Make sure we run our selected compiler for preprocessing instead of letting +- # the dtrace tool pick it on it's own. +- $(DTRACE_JHELPER_OBJ): $(JHELPER_DTRACE_SRC) $(JVM_OFFSETS_INDEX_H) +- $(call LogInfo, Running dtrace for $( $(DTRACE_SUPPORT_DIR)/$(@F).dt)) +- $(call ExecuteWithLog, $@, $(DTRACE) $(DTRACE_FLAGS) -o $@ \ +- -s $(DTRACE_SUPPORT_DIR)/$(@F).dt) +- +- endif +-endif +--- old/make/hotspot/src/native/dtrace/generateJvmOffsets.cpp 2020-05-20 18:08:18.051636738 -0700 ++++ /dev/null 2020-03-09 18:57:19.455001459 -0700 +@@ -1,316 +0,0 @@ +-/* +- * Copyright (c) 2003, 2019, Oracle and/or its affiliates. All rights reserved. +- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. +- * +- * This code is free software; you can redistribute it and/or modify it +- * under the terms of the GNU General Public License version 2 only, as +- * published by the Free Software Foundation. +- * +- * This code is distributed in the hope that it will be useful, but WITHOUT +- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +- * version 2 for more details (a copy is included in the LICENSE file that +- * accompanied this code). +- * +- * You should have received a copy of the GNU General Public License version +- * 2 along with this work; if not, write to the Free Software Foundation, +- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. +- * +- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA +- * or visit www.oracle.com if you need additional information or have any +- * questions. +- * +- */ +- +-/* +- * This is to provide sanity check in jhelper.d which compares SCCS +- * versions of generateJvmOffsets.cpp used to create and extract +- * contents of __JvmOffsets[] table. +- * The __JvmOffsets[] table is located in generated JvmOffsets.cpp. +- * +- * GENOFFS_SCCS_VER 34 +- */ +- +-#include +-#include +- +-/* A workaround for private and protected fields */ +-#define private public +-#define protected public +- +-#include +-#include "gc/shared/collectedHeap.hpp" +-#include "memory/heap.hpp" +-#include "oops/compressedOops.hpp" +-#include "runtime/vmStructs.hpp" +- +-typedef enum GEN_variant { +- GEN_OFFSET = 0, +- GEN_INDEX = 1, +- GEN_TABLE = 2 +-} GEN_variant; +- +-#ifdef COMPILER1 +-#ifdef ASSERT +- +-/* +- * To avoid the most part of potential link errors +- * we link this program with -z nodefs . +- * +- * But for 'debug1' and 'fastdebug1' we still have to provide +- * a particular workaround for the following symbols below. +- * It will be good to find out a generic way in the future. +- */ +- +-#pragma weak tty +- +-#if defined(i386) || defined(__i386) || defined(__amd64) +-#pragma weak noreg +-#endif /* i386 */ +- +-LIR_Opr LIR_OprFact::illegalOpr = (LIR_Opr) 0; +- +-address StubRoutines::_call_stub_return_address = NULL; +- +-StubQueue* AbstractInterpreter::_code = NULL; +- +-#endif /* ASSERT */ +-#endif /* COMPILER1 */ +- +-#define GEN_OFFS_NAME(Type,Name,OutputType) \ +- switch(gen_variant) { \ +- case GEN_OFFSET: \ +- printf("#define OFFSET_%-33s %ld\n", \ +- #OutputType #Name, offset_of(Type, Name)); \ +- break; \ +- case GEN_INDEX: \ +- printf("#define IDX_OFFSET_%-33s %d\n", \ +- #OutputType #Name, index++); \ +- break; \ +- case GEN_TABLE: \ +- printf("\tOFFSET_%s,\n", #OutputType #Name); \ +- break; \ +- } +- +-#define GEN_OFFS(Type,Name) \ +- GEN_OFFS_NAME(Type,Name,Type) +- +-#define GEN_SIZE(Type) \ +- switch(gen_variant) { \ +- case GEN_OFFSET: \ +- printf("#define SIZE_%-35s %ld\n", \ +- #Type, sizeof(Type)); \ +- break; \ +- case GEN_INDEX: \ +- printf("#define IDX_SIZE_%-35s %d\n", \ +- #Type, index++); \ +- break; \ +- case GEN_TABLE: \ +- printf("\tSIZE_%s,\n", #Type); \ +- break; \ +- } +- +-#define GEN_VALUE(String,Value) \ +- switch(gen_variant) { \ +- case GEN_OFFSET: \ +- printf("#define %-40s %d\n", #String, Value); \ +- break; \ +- case GEN_INDEX: \ +- printf("#define IDX_%-40s %d\n", #String, index++); \ +- break; \ +- case GEN_TABLE: \ +- printf("\t" #String ",\n"); \ +- break; \ +- } +- +-void gen_prologue(GEN_variant gen_variant) { +- const char *suffix = "Undefined-Suffix"; +- +- switch(gen_variant) { +- case GEN_OFFSET: suffix = ".h"; break; +- case GEN_INDEX: suffix = "Index.h"; break; +- case GEN_TABLE: suffix = ".cpp"; break; +- } +- +- printf("/*\n"); +- printf(" * JvmOffsets%s !!!DO NOT EDIT!!! \n", suffix); +- printf(" * The generateJvmOffsets program generates this file!\n"); +- printf(" */\n\n"); +- switch(gen_variant) { +- +- case GEN_OFFSET: +- case GEN_INDEX: +- break; +- +- case GEN_TABLE: +- printf("#include \"JvmOffsets.h\"\n"); +- printf("\n"); +- printf("int __JvmOffsets[] = {\n"); +- break; +- } +-} +- +-void gen_epilogue(GEN_variant gen_variant) { +- if (gen_variant != GEN_TABLE) { +- return; +- } +- printf("};\n\n"); +- return; +-} +- +-int generateJvmOffsets(GEN_variant gen_variant) { +- int index = 0; /* It is used to generate JvmOffsetsIndex.h */ +- int pointer_size = sizeof(void *); +- int data_model = (pointer_size == 4) ? PR_MODEL_ILP32 : PR_MODEL_LP64; +- +- gen_prologue(gen_variant); +- +- GEN_VALUE(DATA_MODEL, data_model); +- GEN_VALUE(POINTER_SIZE, pointer_size); +-#if COMPILER1_AND_COMPILER2 +- GEN_VALUE(COMPILER, 3); +-#elif COMPILER1 +- GEN_VALUE(COMPILER, 1); +-#elif COMPILER2 +- GEN_VALUE(COMPILER, 2); +-#else +- GEN_VALUE(COMPILER, 0); +-#endif // COMPILER1 && COMPILER2 +- printf("\n"); +- +- GEN_OFFS(CollectedHeap, _reserved); +- GEN_OFFS(MemRegion, _start); +- GEN_OFFS(MemRegion, _word_size); +- GEN_SIZE(HeapWord); +- printf("\n"); +- +- GEN_OFFS(VMStructEntry, typeName); +- GEN_OFFS(VMStructEntry, fieldName); +- GEN_OFFS(VMStructEntry, address); +- GEN_SIZE(VMStructEntry); +- printf("\n"); +- +- GEN_VALUE(MAX_METHOD_CODE_SIZE, max_method_code_size); +-#if defined(i386) || defined(__i386) || defined(__amd64) +- GEN_VALUE(OFFSET_interpreter_frame_sender_sp, -1 * pointer_size); +- GEN_VALUE(OFFSET_interpreter_frame_method, -3 * pointer_size); +- GEN_VALUE(OFFSET_interpreter_frame_bcp_offset, -7 * pointer_size); +-#endif +- +- GEN_OFFS(Klass, _name); +- GEN_OFFS(ConstantPool, _pool_holder); +- printf("\n"); +- +- GEN_VALUE(OFFSET_HeapBlockHeader_used, (int) offset_of(HeapBlock::Header, _used)); +- GEN_OFFS(oopDesc, _metadata); +- printf("\n"); +- +- GEN_VALUE(AccessFlags_NATIVE, JVM_ACC_NATIVE); +- GEN_VALUE(ConstMethod_has_linenumber_table, ConstMethod::_has_linenumber_table); +- GEN_OFFS(AccessFlags, _flags); +- GEN_OFFS(Symbol, _length); +- GEN_OFFS(Symbol, _body); +- printf("\n"); +- +- GEN_OFFS(Method, _constMethod); +- GEN_OFFS(Method, _access_flags); +- printf("\n"); +- +- GEN_OFFS(ConstMethod, _constants); +- GEN_OFFS(ConstMethod, _flags); +- GEN_OFFS(ConstMethod, _code_size); +- GEN_OFFS(ConstMethod, _name_index); +- GEN_OFFS(ConstMethod, _signature_index); +- printf("\n"); +- +- GEN_OFFS(CodeHeap, _memory); +- GEN_OFFS(CodeHeap, _segmap); +- GEN_OFFS(CodeHeap, _log2_segment_size); +- printf("\n"); +- +- GEN_OFFS(VirtualSpace, _low_boundary); +- GEN_OFFS(VirtualSpace, _high_boundary); +- GEN_OFFS(VirtualSpace, _low); +- GEN_OFFS(VirtualSpace, _high); +- printf("\n"); +- +- /* We need to use different names here because of the template parameter */ +- GEN_OFFS_NAME(GrowableArray, _data, GrowableArray_CodeHeap); +- GEN_OFFS_NAME(GrowableArray, _len, GrowableArray_CodeHeap); +- printf("\n"); +- +- GEN_OFFS(CodeBlob, _name); +- GEN_OFFS(CodeBlob, _header_size); +- GEN_OFFS(CodeBlob, _content_begin); +- GEN_OFFS(CodeBlob, _code_begin); +- GEN_OFFS(CodeBlob, _code_end); +- GEN_OFFS(CodeBlob, _data_offset); +- GEN_OFFS(CodeBlob, _frame_size); +- printf("\n"); +- +- GEN_OFFS(nmethod, _method); +- GEN_OFFS(nmethod, _dependencies_offset); +- GEN_OFFS(nmethod, _metadata_offset); +- GEN_OFFS(nmethod, _scopes_data_begin); +- GEN_OFFS(nmethod, _scopes_pcs_offset); +- GEN_OFFS(nmethod, _handler_table_offset); +- GEN_OFFS(nmethod, _deopt_handler_begin); +- GEN_OFFS(nmethod, _orig_pc_offset); +- +- GEN_OFFS(PcDesc, _pc_offset); +- GEN_OFFS(PcDesc, _scope_decode_offset); +- +- printf("\n"); +- +- GEN_OFFS(NarrowPtrStruct, _base); +- GEN_OFFS(NarrowPtrStruct, _shift); +- printf("\n"); +- +- GEN_VALUE(SIZE_HeapBlockHeader, (int) sizeof(HeapBlock::Header)); +- GEN_SIZE(oopDesc); +- GEN_SIZE(ConstantPool); +- printf("\n"); +- +- GEN_SIZE(PcDesc); +- GEN_SIZE(Method); +- GEN_SIZE(ConstMethod); +- GEN_SIZE(nmethod); +- GEN_SIZE(CodeBlob); +- GEN_SIZE(BufferBlob); +- GEN_SIZE(SingletonBlob); +- GEN_SIZE(RuntimeStub); +- GEN_SIZE(SafepointBlob); +- +- gen_epilogue(gen_variant); +- printf("\n"); +- +- fflush(stdout); +- return 0; +-} +- +-const char *HELP = +- "HELP: generateJvmOffsets {-header | -index | -table} \n"; +- +-int main(int argc, const char *argv[]) { +- GEN_variant gen_var; +- +- if (argc != 2) { +- printf("%s", HELP); +- return 1; +- } +- +- if (0 == strcmp(argv[1], "-header")) { +- gen_var = GEN_OFFSET; +- } +- else if (0 == strcmp(argv[1], "-index")) { +- gen_var = GEN_INDEX; +- } +- else if (0 == strcmp(argv[1], "-table")) { +- gen_var = GEN_TABLE; +- } +- else { +- printf("%s", HELP); +- return 1; +- } +- return generateJvmOffsets(gen_var); +-} +--- old/make/hotspot/symbols/symbols-solaris 2020-05-20 18:08:18.759650332 -0700 ++++ /dev/null 2020-03-09 18:57:19.455001459 -0700 +@@ -1,25 +0,0 @@ +-# +-# Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved. +-# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. +-# +-# This code is free software; you can redistribute it and/or modify it +-# under the terms of the GNU General Public License version 2 only, as +-# published by the Free Software Foundation. +-# +-# This code is distributed in the hope that it will be useful, but WITHOUT +-# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +-# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +-# version 2 for more details (a copy is included in the LICENSE file that +-# accompanied this code). +-# +-# You should have received a copy of the GNU General Public License version +-# 2 along with this work; if not, write to the Free Software Foundation, +-# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. +-# +-# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA +-# or visit www.oracle.com if you need additional information or have any +-# questions. +-# +- +-JVM_handle_solaris_signal +-sysThreadAvailableStackWithSlack +--- old/make/hotspot/symbols/symbols-solaris-dtrace-compiler1 2020-05-20 18:08:19.459663773 -0700 ++++ /dev/null 2020-03-09 18:57:19.455001459 -0700 +@@ -1,34 +0,0 @@ +-# +-# Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved. +-# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. +-# +-# This code is free software; you can redistribute it and/or modify it +-# under the terms of the GNU General Public License version 2 only, as +-# published by the Free Software Foundation. +-# +-# This code is distributed in the hope that it will be useful, but WITHOUT +-# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +-# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +-# version 2 for more details (a copy is included in the LICENSE file that +-# accompanied this code). +-# +-# You should have received a copy of the GNU General Public License version +-# 2 along with this work; if not, write to the Free Software Foundation, +-# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. +-# +-# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA +-# or visit www.oracle.com if you need additional information or have any +-# questions. +-# +- +-__1cGMethodG__vtbl_ +-__1cHnmethodG__vtbl_ +-__1cICodeBlobG__vtbl_ +-__1cIUniverseO_collectedHeap_ +-__1cJCodeCacheG_heaps_ +-__1cKBufferBlobG__vtbl_ +-__1cLRuntimeStubG__vtbl_ +-__1cNSafepointBlobG__vtbl_ +-__1cSDeoptimizationBlobG__vtbl_ +- +-__JvmOffsets +--- old/make/hotspot/symbols/symbols-solaris-dtrace-compiler2 2020-05-20 18:08:20.203678058 -0700 ++++ /dev/null 2020-03-09 18:57:19.455001459 -0700 +@@ -1,36 +0,0 @@ +-# +-# Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved. +-# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. +-# +-# This code is free software; you can redistribute it and/or modify it +-# under the terms of the GNU General Public License version 2 only, as +-# published by the Free Software Foundation. +-# +-# This code is distributed in the hope that it will be useful, but WITHOUT +-# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +-# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +-# version 2 for more details (a copy is included in the LICENSE file that +-# accompanied this code). +-# +-# You should have received a copy of the GNU General Public License version +-# 2 along with this work; if not, write to the Free Software Foundation, +-# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. +-# +-# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA +-# or visit www.oracle.com if you need additional information or have any +-# questions. +-# +- +-__1cGMethodG__vtbl_ +-__1cHnmethodG__vtbl_ +-__1cICodeBlobG__vtbl_ +-__1cIUniverseO_collectedHeap_ +-__1cJCodeCacheG_heaps_ +-__1cKBufferBlobG__vtbl_ +-__1cLRuntimeStubG__vtbl_ +-__1cNSafepointBlobG__vtbl_ +-__1cSDeoptimizationBlobG__vtbl_ +-__1cNExceptionBlobG__vtbl_ +-__1cQUncommonTrapBlobG__vtbl_ +- +-__JvmOffsets +--- old/make/modules/jdk.crypto.cryptoki/Copy.gmk 2020-05-20 18:08:20.931692037 -0700 ++++ /dev/null 2020-03-09 18:57:19.455001459 -0700 +@@ -1,45 +0,0 @@ +-# +-# Copyright (c) 2014, 2019, Oracle and/or its affiliates. All rights reserved. +-# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. +-# +-# This code is free software; you can redistribute it and/or modify it +-# under the terms of the GNU General Public License version 2 only, as +-# published by the Free Software Foundation. Oracle designates this +-# particular file as subject to the "Classpath" exception as provided +-# by Oracle in the LICENSE file that accompanied this code. +-# +-# This code is distributed in the hope that it will be useful, but WITHOUT +-# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +-# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +-# version 2 for more details (a copy is included in the LICENSE file that +-# accompanied this code). +-# +-# You should have received a copy of the GNU General Public License version +-# 2 along with this work; if not, write to the Free Software Foundation, +-# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. +-# +-# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA +-# or visit www.oracle.com if you need additional information or have any +-# questions. +-# +- +-include CopyCommon.gmk +- +-################################################################################ +- +-ifeq ($(call isTargetOs, solaris), true) +- +- SUNPKCS11_CFG_SRC := \ +- $(TOPDIR)/src/jdk.crypto.cryptoki/solaris/conf/security/sunpkcs11-solaris.cfg +- SUNPKCS11_CFG_DST := $(CONF_DST_DIR)/security/sunpkcs11-solaris.cfg +- +- $(SUNPKCS11_CFG_DST): $(SUNPKCS11_CFG_SRC) +- $(call install-file) +- +- SECURITY_PKCS11_CONF_FILES += $(SUNPKCS11_CFG_DST) +- +- TARGETS := $(SUNPKCS11_CFG_DST) +- +-endif +- +-################################################################################ +--- old/src/hotspot/share/services/dtraceAttacher.cpp 2020-05-20 18:10:08.361754658 -0700 ++++ /dev/null 2020-03-09 18:57:19.455001459 -0700 +@@ -1,99 +0,0 @@ +-/* +- * Copyright (c) 2006, 2019, Oracle and/or its affiliates. All rights reserved. +- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. +- * +- * This code is free software; you can redistribute it and/or modify it +- * under the terms of the GNU General Public License version 2 only, as +- * published by the Free Software Foundation. +- * +- * This code is distributed in the hope that it will be useful, but WITHOUT +- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +- * version 2 for more details (a copy is included in the LICENSE file that +- * accompanied this code). +- * +- * You should have received a copy of the GNU General Public License version +- * 2 along with this work; if not, write to the Free Software Foundation, +- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. +- * +- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA +- * or visit www.oracle.com if you need additional information or have any +- * questions. +- * +- */ +- +-#include "precompiled.hpp" +-#include "code/codeCache.hpp" +-#include "memory/resourceArea.hpp" +-#include "runtime/deoptimization.hpp" +-#include "runtime/flags/jvmFlag.hpp" +-#include "runtime/vmThread.hpp" +-#include "runtime/vmOperations.hpp" +-#include "services/dtraceAttacher.hpp" +-#include "runtime/flags/jvmFlagAccess.hpp" +- +-#ifdef SOLARIS +- +-static void set_bool_flag(const char* name, bool value) { +- JVMFlag* flag = JVMFlag::find_flag(name); +- JVMFlagAccess::set_bool(flag, &value, JVMFlagOrigin::ATTACH_ON_DEMAND); +-} +- +-// Enable the "fine grained" flags. +-void DTrace::enable_dprobes(int probes) { +- bool changed = false; +- if (!DTraceAllocProbes && (probes & DTRACE_ALLOC_PROBES)) { +- set_bool_flag("DTraceAllocProbes", true); +- changed = true; +- } +- if (!DTraceMethodProbes && (probes & DTRACE_METHOD_PROBES)) { +- set_bool_flag("DTraceMethodProbes", true); +- changed = true; +- } +- if (!DTraceMonitorProbes && (probes & DTRACE_MONITOR_PROBES)) { +- set_bool_flag("DTraceMonitorProbes", true); +- changed = true; +- } +- +- if (changed) { +- // one or more flags changed, need to deoptimize +- DeoptimizationScope deopt_scope; +- CodeCache::mark_all_nmethods_for_deoptimization(&deopt_scope); +- deopt_scope.deoptimize_marked(); +- } +-} +- +-// Disable the "fine grained" flags. +-void DTrace::disable_dprobes(int probes) { +- bool changed = false; +- if (DTraceAllocProbes && (probes & DTRACE_ALLOC_PROBES)) { +- set_bool_flag("DTraceAllocProbes", false); +- changed = true; +- } +- if (DTraceMethodProbes && (probes & DTRACE_METHOD_PROBES)) { +- set_bool_flag("DTraceMethodProbes", false); +- changed = true; +- } +- if (DTraceMonitorProbes && (probes & DTRACE_MONITOR_PROBES)) { +- set_bool_flag("DTraceMonitorProbes", false); +- changed = true; +- } +- if (changed) { +- // one or more flags changed, need to deoptimize +- DeoptimizationScope deopt_scope; +- CodeCache::mark_all_nmethods_for_deoptimization(&deopt_scope); +- deopt_scope.deoptimize_marked(); +- } +-} +- +-// Do clean-up on "all door clients detached" event. +-void DTrace::detach_all_clients() { +- disable_dprobes(DTRACE_ALL_PROBES); +-} +- +-void DTrace::set_monitor_dprobes(bool flag) { +- // explicit setting of DTraceMonitorProbes flag +- set_bool_flag("DTraceMonitorProbes", flag); +-} +- +-#endif /* SOLARIS */ +--- old/src/java.base/solaris/classes/sun/nio/ch/DefaultAsynchronousChannelProvider.java 2020-05-20 18:10:11.253810182 -0700 ++++ /dev/null 2020-03-09 18:57:19.455001459 -0700 +@@ -1,47 +0,0 @@ +-/* +- * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved. +- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. +- * +- * This code is free software; you can redistribute it and/or modify it +- * under the terms of the GNU General Public License version 2 only, as +- * published by the Free Software Foundation. Oracle designates this +- * particular file as subject to the "Classpath" exception as provided +- * by Oracle in the LICENSE file that accompanied this code. +- * +- * This code is distributed in the hope that it will be useful, but WITHOUT +- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +- * version 2 for more details (a copy is included in the LICENSE file that +- * accompanied this code). +- * +- * You should have received a copy of the GNU General Public License version +- * 2 along with this work; if not, write to the Free Software Foundation, +- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. +- * +- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA +- * or visit www.oracle.com if you need additional information or have any +- * questions. +- */ +- +-package sun.nio.ch; +- +-import java.nio.channels.spi.AsynchronousChannelProvider; +- +-/** +- * Creates this platform's default AsynchronousChannelProvider +- */ +- +-public class DefaultAsynchronousChannelProvider { +- +- /** +- * Prevent instantiation. +- */ +- private DefaultAsynchronousChannelProvider() { } +- +- /** +- * Returns the default AsynchronousChannelProvider. +- */ +- public static AsynchronousChannelProvider create() { +- return new SolarisAsynchronousChannelProvider(); +- } +-} +--- old/src/java.base/solaris/classes/sun/nio/ch/DefaultSelectorProvider.java 2020-05-20 18:10:11.945823468 -0700 ++++ /dev/null 2020-03-09 18:57:19.455001459 -0700 +@@ -1,54 +0,0 @@ +-/* +- * Copyright (c) 2015, 2019, Oracle and/or its affiliates. All rights reserved. +- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. +- * +- * This code is free software; you can redistribute it and/or modify it +- * under the terms of the GNU General Public License version 2 only, as +- * published by the Free Software Foundation. Oracle designates this +- * particular file as subject to the "Classpath" exception as provided +- * by Oracle in the LICENSE file that accompanied this code. +- * +- * This code is distributed in the hope that it will be useful, but WITHOUT +- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +- * version 2 for more details (a copy is included in the LICENSE file that +- * accompanied this code). +- * +- * You should have received a copy of the GNU General Public License version +- * 2 along with this work; if not, write to the Free Software Foundation, +- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. +- * +- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA +- * or visit www.oracle.com if you need additional information or have any +- * questions. +- */ +- +-package sun.nio.ch; +- +-import java.security.AccessController; +-import java.security.PrivilegedAction; +- +-/** +- * Creates this platform's default SelectorProvider +- */ +- +-@SuppressWarnings("removal") +-public class DefaultSelectorProvider { +- private static final SelectorProviderImpl INSTANCE; +- static { +- PrivilegedAction pa = DevPollSelectorProvider::new; +- INSTANCE = AccessController.doPrivileged(pa); +- } +- +- /** +- * Prevent instantiation. +- */ +- private DefaultSelectorProvider() { } +- +- /** +- * Returns the default SelectorProvider implementation. +- */ +- public static SelectorProviderImpl get() { +- return INSTANCE; +- } +-} +--- old/src/java.base/solaris/classes/sun/nio/ch/DevPollArrayWrapper.java 2020-05-20 18:10:12.657837138 -0700 ++++ /dev/null 2020-03-09 18:57:19.455001459 -0700 +@@ -1,127 +0,0 @@ +-/* +- * Copyright (c) 2001, 2018, Oracle and/or its affiliates. All rights reserved. +- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. +- * +- * This code is free software; you can redistribute it and/or modify it +- * under the terms of the GNU General Public License version 2 only, as +- * published by the Free Software Foundation. Oracle designates this +- * particular file as subject to the "Classpath" exception as provided +- * by Oracle in the LICENSE file that accompanied this code. +- * +- * This code is distributed in the hope that it will be useful, but WITHOUT +- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +- * version 2 for more details (a copy is included in the LICENSE file that +- * accompanied this code). +- * +- * You should have received a copy of the GNU General Public License version +- * 2 along with this work; if not, write to the Free Software Foundation, +- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. +- * +- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA +- * or visit www.oracle.com if you need additional information or have any +- * questions. +- */ +- +-package sun.nio.ch; +- +-import java.io.IOException; +- +-/** +- * Manipulates a native array of pollfd structs on Solaris: +- * +- * typedef struct pollfd { +- * int fd; +- * short events; +- * short revents; +- * } pollfd_t; +- * +- * @author Mike McCloskey +- * @since 1.4 +- */ +- +-class DevPollArrayWrapper { +- +- // special event to remove a file descriptor from the driver +- static final short POLLREMOVE = 0x0800; +- +- // struct pollfd constants +- static final short SIZE_POLLFD = 8; +- static final short FD_OFFSET = 0; +- static final short EVENT_OFFSET = 4; +- static final short REVENT_OFFSET = 6; +- +- // maximum number of pollfd structure to poll or update at a time +- // dpwrite/ioctl(DP_POLL) allows up to file descriptor limit minus 1 +- static final int NUM_POLLFDS = Math.min(IOUtil.fdLimit()-1, 1024); +- +- // The pollfd array for results from devpoll driver +- private final AllocatedNativeObject pollArray; +- +- // Base address of the native pollArray +- private final long pollArrayAddress; +- +- // The fd of the devpoll driver +- private int wfd; +- +- DevPollArrayWrapper() throws IOException { +- this.wfd = init(); +- +- int allocationSize = NUM_POLLFDS * SIZE_POLLFD; +- this.pollArray = new AllocatedNativeObject(allocationSize, true); +- this.pollArrayAddress = pollArray.address(); +- } +- +- void close() throws IOException { +- FileDispatcherImpl.closeIntFD(wfd); +- pollArray.free(); +- } +- +- void register(int fd, int ops) throws IOException { +- register(wfd, fd, ops); +- } +- +- void registerMultiple(int numfds) throws IOException { +- registerMultiple(wfd, pollArrayAddress, numfds); +- } +- +- int poll(long timeout) throws IOException { +- return poll0(pollArrayAddress, NUM_POLLFDS, timeout, wfd); +- } +- +- int getDescriptor(int i) { +- int offset = SIZE_POLLFD * i + FD_OFFSET; +- return pollArray.getInt(offset); +- } +- +- short getEventOps(int i) { +- int offset = SIZE_POLLFD * i + EVENT_OFFSET; +- return pollArray.getShort(offset); +- } +- +- short getReventOps(int i) { +- int offset = SIZE_POLLFD * i + REVENT_OFFSET; +- return pollArray.getShort(offset); +- } +- +- /** +- * Updates the pollfd structure at the given index +- */ +- void putPollFD(int index, int fd, short event) { +- int structIndex = SIZE_POLLFD * index; +- pollArray.putInt(structIndex + FD_OFFSET, fd); +- pollArray.putShort(structIndex + EVENT_OFFSET, event); +- pollArray.putShort(structIndex + REVENT_OFFSET, (short)0); +- } +- +- private native int init() throws IOException; +- private native void register(int wfd, int fd, int mask) throws IOException; +- private native void registerMultiple(int wfd, long address, int len) +- throws IOException; +- private native int poll0(long pollAddress, int numfds, long timeout, int wfd) +- throws IOException; +- +- static { +- IOUtil.load(); +- } +-} +--- old/src/java.base/solaris/classes/sun/nio/ch/DevPollSelectorImpl.java 2020-05-20 18:10:13.409851575 -0700 ++++ /dev/null 2020-03-09 18:57:19.455001459 -0700 +@@ -1,263 +0,0 @@ +-/* +- * Copyright (c) 2001, 2018, Oracle and/or its affiliates. All rights reserved. +- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. +- * +- * This code is free software; you can redistribute it and/or modify it +- * under the terms of the GNU General Public License version 2 only, as +- * published by the Free Software Foundation. Oracle designates this +- * particular file as subject to the "Classpath" exception as provided +- * by Oracle in the LICENSE file that accompanied this code. +- * +- * This code is distributed in the hope that it will be useful, but WITHOUT +- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +- * version 2 for more details (a copy is included in the LICENSE file that +- * accompanied this code). +- * +- * You should have received a copy of the GNU General Public License version +- * 2 along with this work; if not, write to the Free Software Foundation, +- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. +- * +- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA +- * or visit www.oracle.com if you need additional information or have any +- * questions. +- */ +- +-package sun.nio.ch; +- +-import java.io.IOException; +-import java.nio.channels.ClosedSelectorException; +-import java.nio.channels.SelectionKey; +-import java.nio.channels.Selector; +-import java.nio.channels.spi.SelectorProvider; +-import java.util.ArrayDeque; +-import java.util.Deque; +-import java.util.HashMap; +-import java.util.Map; +-import java.util.concurrent.TimeUnit; +-import java.util.function.Consumer; +- +-import static sun.nio.ch.DevPollArrayWrapper.NUM_POLLFDS; +-import static sun.nio.ch.DevPollArrayWrapper.POLLREMOVE; +- +-/** +- * Solaris /dev/poll based Selector implementation +- */ +- +-class DevPollSelectorImpl +- extends SelectorImpl +-{ +- // provides access to /dev/poll driver +- private final DevPollArrayWrapper pollWrapper; +- +- // file descriptors used for interrupt +- private final int fd0; +- private final int fd1; +- +- // maps file descriptor to selection key, synchronize on selector +- private final Map fdToKey = new HashMap<>(); +- +- // pending new registrations/updates, queued by setEventOps +- private final Object updateLock = new Object(); +- private final Deque updateKeys = new ArrayDeque<>(); +- +- // interrupt triggering and clearing +- private final Object interruptLock = new Object(); +- private boolean interruptTriggered; +- +- DevPollSelectorImpl(SelectorProvider sp) throws IOException { +- super(sp); +- this.pollWrapper = new DevPollArrayWrapper(); +- try { +- long fds = IOUtil.makePipe(false); +- this.fd0 = (int) (fds >>> 32); +- this.fd1 = (int) fds; +- } catch (IOException ioe) { +- pollWrapper.close(); +- throw ioe; +- } +- +- // register one end of the socket pair for wakeups +- pollWrapper.register(fd0, Net.POLLIN); +- } +- +- private void ensureOpen() { +- if (!isOpen()) +- throw new ClosedSelectorException(); +- } +- +- @Override +- protected int doSelect(Consumer action, long timeout) +- throws IOException +- { +- assert Thread.holdsLock(this); +- +- long to = timeout; +- boolean blocking = (to != 0); +- boolean timedPoll = (to > 0); +- +- int numEntries; +- processUpdateQueue(); +- processDeregisterQueue(); +- try { +- begin(blocking); +- +- do { +- long startTime = timedPoll ? System.nanoTime() : 0; +- numEntries = pollWrapper.poll(to); +- if (numEntries == IOStatus.INTERRUPTED && timedPoll) { +- // timed poll interrupted so need to adjust timeout +- long adjust = System.nanoTime() - startTime; +- to -= TimeUnit.MILLISECONDS.convert(adjust, TimeUnit.NANOSECONDS); +- if (to <= 0) { +- // timeout expired so no retry +- numEntries = 0; +- } +- } +- } while (numEntries == IOStatus.INTERRUPTED); +- assert IOStatus.check(numEntries); +- +- } finally { +- end(blocking); +- } +- processDeregisterQueue(); +- return processEvents(numEntries, action); +- } +- +- /** +- * Process changes to the interest ops. +- */ +- private void processUpdateQueue() throws IOException { +- assert Thread.holdsLock(this); +- +- synchronized (updateLock) { +- SelectionKeyImpl ski; +- +- // Translate the queued updates to changes to the set of monitored +- // file descriptors. The changes are written to the /dev/poll driver +- // in bulk. +- int index = 0; +- while ((ski = updateKeys.pollFirst()) != null) { +- if (ski.isValid()) { +- int fd = ski.getFDVal(); +- // add to fdToKey if needed +- SelectionKeyImpl previous = fdToKey.putIfAbsent(fd, ski); +- assert (previous == null) || (previous == ski); +- +- int newEvents = ski.translateInterestOps(); +- int registeredEvents = ski.registeredEvents(); +- if (newEvents != registeredEvents) { +- if (registeredEvents != 0) +- pollWrapper.putPollFD(index++, fd, POLLREMOVE); +- if (newEvents != 0) +- pollWrapper.putPollFD(index++, fd, (short)newEvents); +- ski.registeredEvents(newEvents); +- +- // write to /dev/poll +- if (index > (NUM_POLLFDS-2)) { +- pollWrapper.registerMultiple(index); +- index = 0; +- } +- } +- } +- } +- +- // write any remaining changes +- if (index > 0) +- pollWrapper.registerMultiple(index); +- } +- } +- +- /** +- * Process the polled events. +- * If the interrupt fd has been selected, drain it and clear the interrupt. +- */ +- private int processEvents(int numEntries, Consumer action) +- throws IOException +- { +- assert Thread.holdsLock(this); +- +- boolean interrupted = false; +- int numKeysUpdated = 0; +- for (int i=0; i fdToKey = new HashMap<>(); +- +- // the last update operation, incremented by processUpdateQueue +- private int lastUpdate; +- +- // pending new registrations/updates, queued by setEventOps and +- // updateSelectedKeys +- private final Object updateLock = new Object(); +- private final Deque updateKeys = new ArrayDeque<>(); +- +- // interrupt triggering and clearing +- private final Object interruptLock = new Object(); +- private boolean interruptTriggered; +- +- EventPortSelectorImpl(SelectorProvider sp) throws IOException { +- super(sp); +- +- this.pfd = port_create(); +- +- int allocationSize = MAX_EVENTS * SIZEOF_PORT_EVENT; +- this.pollArray = new AllocatedNativeObject(allocationSize, false); +- this.pollArrayAddress = pollArray.address(); +- } +- +- private void ensureOpen() { +- if (!isOpen()) +- throw new ClosedSelectorException(); +- } +- +- @Override +- protected int doSelect(Consumer action, long timeout) +- throws IOException +- { +- assert Thread.holdsLock(this); +- +- long to = timeout; +- boolean blocking = (to != 0); +- boolean timedPoll = (to > 0); +- +- int numEvents; +- processUpdateQueue(); +- processDeregisterQueue(); +- try { +- begin(blocking); +- +- do { +- long startTime = timedPoll ? System.nanoTime() : 0; +- numEvents = port_getn(pfd, pollArrayAddress, MAX_EVENTS, to); +- if (numEvents == IOStatus.INTERRUPTED && timedPoll) { +- // timed poll interrupted so need to adjust timeout +- long adjust = System.nanoTime() - startTime; +- to -= TimeUnit.MILLISECONDS.convert(adjust, TimeUnit.NANOSECONDS); +- if (to <= 0) { +- // timeout also expired so no retry +- numEvents = 0; +- } +- } +- } while (numEvents == IOStatus.INTERRUPTED); +- assert IOStatus.check(numEvents); +- +- } finally { +- end(blocking); +- } +- processDeregisterQueue(); +- return processPortEvents(numEvents, action); +- } +- +- /** +- * Process new registrations and changes to the interest ops. +- */ +- private void processUpdateQueue() throws IOException { +- assert Thread.holdsLock(this); +- +- // bump lastUpdate to ensure that the interest ops are changed at most +- // once per bulk update +- lastUpdate++; +- +- synchronized (updateLock) { +- SelectionKeyImpl ski; +- while ((ski = updateKeys.pollFirst()) != null) { +- if (ski.isValid()) { +- int fd = ski.getFDVal(); +- // add to fdToKey if needed +- SelectionKeyImpl previous = fdToKey.putIfAbsent(fd, ski); +- assert (previous == null) || (previous == ski); +- +- int newEvents = ski.translateInterestOps(); +- if (newEvents != ski.registeredEvents()) { +- if (newEvents == 0) { +- port_dissociate(pfd, PORT_SOURCE_FD, fd); +- } else { +- port_associate(pfd, PORT_SOURCE_FD, fd, newEvents); +- } +- ski.registeredEvents(newEvents); +- } +- } +- } +- } +- } +- +- /** +- * Process the polled events and re-queue the selected keys so the file +- * descriptors are re-associated at the next select operation. +- */ +- private int processPortEvents(int numEvents, Consumer action) +- throws IOException +- { +- assert Thread.holdsLock(this); +- +- int numKeysUpdated = 0; +- boolean interrupted = false; +- +- // Process the polled events while holding the update lock. This allows +- // keys to be queued for ready file descriptors so they can be +- // re-associated at the next select. The selected-key can be updated +- // in this pass. +- synchronized (updateLock) { +- for (int i = 0; i < numEvents; i++) { +- short source = getSource(i); +- if (source == PORT_SOURCE_FD) { +- int fd = getDescriptor(i); +- SelectionKeyImpl ski = fdToKey.get(fd); +- if (ski != null) { +- ski.registeredEvents(0); +- updateKeys.addLast(ski); +- +- // update selected-key set if no action specified +- if (action == null) { +- int rOps = getEventOps(i); +- numKeysUpdated += processReadyEvents(rOps, ski, null); +- } +- +- } +- } else if (source == PORT_SOURCE_USER) { +- interrupted = true; +- } else { +- assert false; +- } +- } +- } +- +- // if an action specified then iterate over the polled events again so +- // that the action is performed without holding the update lock. +- if (action != null) { +- for (int i = 0; i < numEvents; i++) { +- short source = getSource(i); +- if (source == PORT_SOURCE_FD) { +- int fd = getDescriptor(i); +- SelectionKeyImpl ski = fdToKey.get(fd); +- if (ski != null) { +- int rOps = getEventOps(i); +- numKeysUpdated += processReadyEvents(rOps, ski, action); +- } +- } +- } +- } +- +- if (interrupted) { +- clearInterrupt(); +- } +- return numKeysUpdated; +- } +- +- @Override +- protected void implClose() throws IOException { +- assert !isOpen(); +- assert Thread.holdsLock(this); +- +- // prevent further wakeup +- synchronized (interruptLock) { +- interruptTriggered = true; +- } +- +- port_close(pfd); +- pollArray.free(); +- } +- +- @Override +- protected void implDereg(SelectionKeyImpl ski) throws IOException { +- assert !ski.isValid(); +- assert Thread.holdsLock(this); +- +- int fd = ski.getFDVal(); +- if (fdToKey.remove(fd) != null) { +- if (ski.registeredEvents() != 0) { +- port_dissociate(pfd, PORT_SOURCE_FD, fd); +- ski.registeredEvents(0); +- } +- } else { +- assert ski.registeredEvents() == 0; +- } +- } +- +- @Override +- public void setEventOps(SelectionKeyImpl ski) { +- ensureOpen(); +- synchronized (updateLock) { +- updateKeys.addLast(ski); +- } +- } +- +- @Override +- public Selector wakeup() { +- synchronized (interruptLock) { +- if (!interruptTriggered) { +- try { +- port_send(pfd, 0); +- } catch (IOException ioe) { +- throw new InternalError(ioe); +- } +- interruptTriggered = true; +- } +- } +- return this; +- } +- +- private void clearInterrupt() throws IOException { +- synchronized (interruptLock) { +- interruptTriggered = false; +- } +- } +- +- private short getSource(int i) { +- int offset = SIZEOF_PORT_EVENT * i + OFFSETOF_SOURCE; +- return pollArray.getShort(offset); +- } +- +- private int getEventOps(int i) { +- int offset = SIZEOF_PORT_EVENT * i + OFFSETOF_EVENTS; +- return pollArray.getInt(offset); +- } +- +- private int getDescriptor(int i) { +- //assert Unsafe.getUnsafe().addressSize() == 8; +- int offset = SIZEOF_PORT_EVENT * i + OFFSETOF_OBJECT; +- return (int) pollArray.getLong(offset); +- } +-} +--- old/src/java.base/solaris/classes/sun/nio/ch/EventPortSelectorProvider.java 2020-05-20 18:10:15.545892585 -0700 ++++ /dev/null 2020-03-09 18:57:19.455001459 -0700 +@@ -1,42 +0,0 @@ +-/* +- * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved. +- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. +- * +- * This code is free software; you can redistribute it and/or modify it +- * under the terms of the GNU General Public License version 2 only, as +- * published by the Free Software Foundation. Oracle designates this +- * particular file as subject to the "Classpath" exception as provided +- * by Oracle in the LICENSE file that accompanied this code. +- * +- * This code is distributed in the hope that it will be useful, but WITHOUT +- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +- * version 2 for more details (a copy is included in the LICENSE file that +- * accompanied this code). +- * +- * You should have received a copy of the GNU General Public License version +- * 2 along with this work; if not, write to the Free Software Foundation, +- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. +- * +- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA +- * or visit www.oracle.com if you need additional information or have any +- * questions. +- */ +- +-package sun.nio.ch; +- +-import java.io.IOException; +-import java.nio.channels.*; +-import java.nio.channels.spi.*; +- +-public class EventPortSelectorProvider +- extends SelectorProviderImpl +-{ +- public AbstractSelector openSelector() throws IOException { +- return new EventPortSelectorImpl(this); +- } +- +- public Channel inheritedChannel() throws IOException { +- return InheritedChannel.getChannel(); +- } +-} +--- old/src/java.base/solaris/classes/sun/nio/ch/SolarisAsynchronousChannelProvider.java 2020-05-20 18:10:16.241905948 -0700 ++++ /dev/null 2020-03-09 18:57:19.455001459 -0700 +@@ -1,93 +0,0 @@ +-/* +- * Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved. +- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. +- * +- * This code is free software; you can redistribute it and/or modify it +- * under the terms of the GNU General Public License version 2 only, as +- * published by the Free Software Foundation. Oracle designates this +- * particular file as subject to the "Classpath" exception as provided +- * by Oracle in the LICENSE file that accompanied this code. +- * +- * This code is distributed in the hope that it will be useful, but WITHOUT +- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +- * version 2 for more details (a copy is included in the LICENSE file that +- * accompanied this code). +- * +- * You should have received a copy of the GNU General Public License version +- * 2 along with this work; if not, write to the Free Software Foundation, +- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. +- * +- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA +- * or visit www.oracle.com if you need additional information or have any +- * questions. +- */ +- +-package sun.nio.ch; +- +-import java.nio.channels.*; +-import java.nio.channels.spi.AsynchronousChannelProvider; +-import java.util.concurrent.ExecutorService; +-import java.util.concurrent.ThreadFactory; +-import java.io.IOException; +- +-public class SolarisAsynchronousChannelProvider +- extends AsynchronousChannelProvider +-{ +- private static volatile SolarisEventPort defaultEventPort; +- +- private SolarisEventPort defaultEventPort() throws IOException { +- if (defaultEventPort == null) { +- synchronized (SolarisAsynchronousChannelProvider.class) { +- if (defaultEventPort == null) { +- defaultEventPort = +- new SolarisEventPort(this, ThreadPool.getDefault()).start(); +- } +- } +- } +- return defaultEventPort; +- } +- +- public SolarisAsynchronousChannelProvider() { +- } +- +- @Override +- public AsynchronousChannelGroup openAsynchronousChannelGroup(int nThreads, ThreadFactory factory) +- throws IOException +- { +- return new SolarisEventPort(this, ThreadPool.create(nThreads, factory)).start(); +- } +- +- @Override +- public AsynchronousChannelGroup openAsynchronousChannelGroup(ExecutorService executor, int initialSize) +- throws IOException +- { +- return new SolarisEventPort(this, ThreadPool.wrap(executor, initialSize)).start(); +- } +- +- private SolarisEventPort toEventPort(AsynchronousChannelGroup group) +- throws IOException +- { +- if (group == null) { +- return defaultEventPort(); +- } else { +- if (!(group instanceof SolarisEventPort)) +- throw new IllegalChannelGroupException(); +- return (SolarisEventPort)group; +- } +- } +- +- @Override +- public AsynchronousServerSocketChannel openAsynchronousServerSocketChannel(AsynchronousChannelGroup group) +- throws IOException +- { +- return new UnixAsynchronousServerSocketChannelImpl(toEventPort(group)); +- } +- +- @Override +- public AsynchronousSocketChannel openAsynchronousSocketChannel(AsynchronousChannelGroup group) +- throws IOException +- { +- return new UnixAsynchronousSocketChannelImpl(toEventPort(group)); +- } +-} +--- old/src/java.base/solaris/classes/sun/nio/ch/SolarisEventPort.java 2020-05-20 18:10:16.985920232 -0700 ++++ /dev/null 2020-03-09 18:57:19.455001459 -0700 +@@ -1,273 +0,0 @@ +-/* +- * Copyright (c) 2008, 2020, Oracle and/or its affiliates. All rights reserved. +- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. +- * +- * This code is free software; you can redistribute it and/or modify it +- * under the terms of the GNU General Public License version 2 only, as +- * published by the Free Software Foundation. Oracle designates this +- * particular file as subject to the "Classpath" exception as provided +- * by Oracle in the LICENSE file that accompanied this code. +- * +- * This code is distributed in the hope that it will be useful, but WITHOUT +- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +- * version 2 for more details (a copy is included in the LICENSE file that +- * accompanied this code). +- * +- * You should have received a copy of the GNU General Public License version +- * 2 along with this work; if not, write to the Free Software Foundation, +- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. +- * +- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA +- * or visit www.oracle.com if you need additional information or have any +- * questions. +- */ +- +-package sun.nio.ch; +- +-import java.nio.channels.spi.AsynchronousChannelProvider; +-import java.util.concurrent.RejectedExecutionException; +-import java.io.IOException; +-import jdk.internal.misc.Unsafe; +- +-/** +- * Provides an AsynchronousChannelGroup implementation based on the Solaris 10 +- * event port framework and also provides direct access to that framework. +- */ +- +-class SolarisEventPort +- extends Port +-{ +- private static final Unsafe unsafe = Unsafe.getUnsafe(); +- private static final int addressSize = unsafe.addressSize(); +- +- private static int dependsArch(int value32, int value64) { +- return (addressSize == 4) ? value32 : value64; +- } +- +- /* +- * typedef struct port_event { +- * int portev_events; +- * ushort_t portev_source; +- * ushort_t portev_pad; +- * uintptr_t portev_object; +- * void *portev_user; +- * } port_event_t; +- */ +- static final int SIZEOF_PORT_EVENT = dependsArch(16, 24); +- static final int OFFSETOF_EVENTS = 0; +- static final int OFFSETOF_SOURCE = 4; +- static final int OFFSETOF_OBJECT = 8; +- +- // port sources +- static final short PORT_SOURCE_USER = 3; +- static final short PORT_SOURCE_FD = 4; +- +- // events (sys/poll.h) +- static final int POLLIN = 0x0001; +- static final int POLLOUT = 0x0004; +- +- // file descriptor to event port. +- private final int port; +- +- // true when port is closed +- private boolean closed; +- +- SolarisEventPort(AsynchronousChannelProvider provider, ThreadPool pool) +- throws IOException +- { +- super(provider, pool); +- +- // create event port +- this.port = port_create(); +- } +- +- SolarisEventPort start() { +- startThreads(new EventHandlerTask()); +- return this; +- } +- +- // releass resources +- private void implClose() { +- synchronized (this) { +- if (closed) +- return; +- closed = true; +- } +- port_close(port); +- } +- +- private void wakeup() { +- try { +- port_send(port, 0); +- } catch (IOException x) { +- throw new AssertionError(x); +- } +- } +- +- @Override +- void executeOnHandlerTask(Runnable task) { +- synchronized (this) { +- if (closed) +- throw new RejectedExecutionException(); +- offerTask(task); +- wakeup(); +- } +- } +- +- @Override +- void shutdownHandlerTasks() { +- /* +- * If no tasks are running then just release resources; otherwise +- * write to the one end of the socketpair to wakeup any polling threads.. +- */ +- int nThreads = threadCount(); +- if (nThreads == 0) { +- implClose(); +- } else { +- // send user event to wakeup each thread +- while (nThreads-- > 0) { +- try { +- port_send(port, 0); +- } catch (IOException x) { +- throw new AssertionError(x); +- } +- } +- } +- } +- +- @Override +- void startPoll(int fd, int events) { +- // (re-)associate file descriptor +- // no need to translate events +- try { +- port_associate(port, PORT_SOURCE_FD, fd, events); +- } catch (IOException x) { +- throw new AssertionError(); // should not happen +- } +- } +- +- /* +- * Task to read a single event from the port and dispatch it to the +- * channel's onEvent handler. +- */ +- private class EventHandlerTask implements Runnable { +- public void run() { +- Invoker.GroupAndInvokeCount myGroupAndInvokeCount = +- Invoker.getGroupAndInvokeCount(); +- final boolean isPooledThread = (myGroupAndInvokeCount != null); +- boolean replaceMe = false; +- long address = unsafe.allocateMemory(SIZEOF_PORT_EVENT); +- try { +- for (;;) { +- // reset invoke count +- if (isPooledThread) +- myGroupAndInvokeCount.resetInvokeCount(); +- +- // wait for I/O completion event +- // A error here is fatal (thread will not be replaced) +- replaceMe = false; +- try { +- int n; +- do { +- n = port_get(port, address); +- } while (n == IOStatus.INTERRUPTED); +- } catch (IOException x) { +- x.printStackTrace(); +- return; +- } +- +- // event source +- short source = unsafe.getShort(address + OFFSETOF_SOURCE); +- if (source != PORT_SOURCE_FD) { +- // user event is trigger to invoke task or shutdown +- if (source == PORT_SOURCE_USER) { +- Runnable task = pollTask(); +- if (task == null) { +- // shutdown request +- return; +- } +- // run task (may throw error/exception) +- replaceMe = true; +- task.run(); +- } +- // ignore +- continue; +- } +- +- // pe->portev_object is file descriptor +- int fd = (int)unsafe.getAddress(address + OFFSETOF_OBJECT); +- // pe->portev_events +- int events = unsafe.getInt(address + OFFSETOF_EVENTS); +- +- // lookup channel +- PollableChannel ch; +- fdToChannelLock.readLock().lock(); +- try { +- ch = fdToChannel.get(fd); +- } finally { +- fdToChannelLock.readLock().unlock(); +- } +- +- // notify channel +- if (ch != null) { +- replaceMe = true; +- // no need to translate events +- ch.onEvent(events, isPooledThread); +- } +- } +- } finally { +- // free per-thread resources +- unsafe.freeMemory(address); +- // last task to exit when shutdown release resources +- int remaining = threadExit(this, replaceMe); +- if (remaining == 0 && isShutdown()) +- implClose(); +- } +- } +- } +- +- /** +- * Creates an event port +- */ +- static native int port_create() throws IOException; +- +- /** +- * Associates specific events of a given object with a port +- */ +- static native boolean port_associate(int port, int source, long object, int events) +- throws IOException; +- +- /** +- * Removes the association of an object with a port. +- */ +- static native boolean port_dissociate(int port, int source, long object) +- throws IOException; +- +- /** +- * Retrieves a single event from a port +- */ +- static native int port_get(int port, long address) throws IOException; +- +- /** +- * Retrieves at most {@code max} events from a port. A time-out of {@code < 0} means +- * never time-out. +- */ +- static native int port_getn(int port, long address, int max, long timeout) +- throws IOException; +- +- /** +- * Sends a user-defined eventto a specified port. +- */ +- static native void port_send(int port, int events) throws IOException; +- +- /** +- * Closes a port. +- */ +- static native void port_close(int port); +- +- +- static { +- IOUtil.load(); +- } +-} +--- old/src/java.base/solaris/classes/sun/nio/fs/DefaultFileSystemProvider.java 2020-05-20 18:10:17.693933825 -0700 ++++ /dev/null 2020-03-09 18:57:19.455001459 -0700 +@@ -1,53 +0,0 @@ +-/* +- * Copyright (c) 2017, 2018, Oracle and/or its affiliates. All rights reserved. +- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. +- * +- * This code is free software; you can redistribute it and/or modify it +- * under the terms of the GNU General Public License version 2 only, as +- * published by the Free Software Foundation. Oracle designates this +- * particular file as subject to the "Classpath" exception as provided +- * by Oracle in the LICENSE file that accompanied this code. +- * +- * This code is distributed in the hope that it will be useful, but WITHOUT +- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +- * version 2 for more details (a copy is included in the LICENSE file that +- * accompanied this code). +- * +- * You should have received a copy of the GNU General Public License version +- * 2 along with this work; if not, write to the Free Software Foundation, +- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. +- * +- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA +- * or visit www.oracle.com if you need additional information or have any +- * questions. +- */ +- +-package sun.nio.fs; +- +-import java.nio.file.FileSystem; +- +-/** +- * Creates this platform's default FileSystemProvider. +- */ +- +-public class DefaultFileSystemProvider { +- private static final SolarisFileSystemProvider INSTANCE +- = new SolarisFileSystemProvider(); +- +- private DefaultFileSystemProvider() { } +- +- /** +- * Returns the platform's default file system provider. +- */ +- public static SolarisFileSystemProvider instance() { +- return INSTANCE; +- } +- +- /** +- * Returns the platform's default file system. +- */ +- public static FileSystem theFileSystem() { +- return INSTANCE.theFileSystem(); +- } +-} +--- old/src/java.base/solaris/classes/sun/nio/fs/SolarisAclFileAttributeView.java 2020-05-20 18:10:18.445948263 -0700 ++++ /dev/null 2020-03-09 18:57:19.455001459 -0700 +@@ -1,414 +0,0 @@ +-/* +- * Copyright (c) 2008, 2015, Oracle and/or its affiliates. All rights reserved. +- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. +- * +- * This code is free software; you can redistribute it and/or modify it +- * under the terms of the GNU General Public License version 2 only, as +- * published by the Free Software Foundation. Oracle designates this +- * particular file as subject to the "Classpath" exception as provided +- * by Oracle in the LICENSE file that accompanied this code. +- * +- * This code is distributed in the hope that it will be useful, but WITHOUT +- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +- * version 2 for more details (a copy is included in the LICENSE file that +- * accompanied this code). +- * +- * You should have received a copy of the GNU General Public License version +- * 2 along with this work; if not, write to the Free Software Foundation, +- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. +- * +- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA +- * or visit www.oracle.com if you need additional information or have any +- * questions. +- */ +- +-package sun.nio.fs; +- +-import java.nio.file.*; +-import java.nio.file.attribute.*; +-import java.util.*; +-import java.io.IOException; +-import jdk.internal.misc.Unsafe; +- +-import static sun.nio.fs.UnixConstants.*; +-import static sun.nio.fs.SolarisConstants.*; +-import static sun.nio.fs.SolarisNativeDispatcher.*; +- +- +-/** +- * Solaris implementation of AclFileAttributeView with native support for +- * NFSv4 ACLs on ZFS. +- */ +- +-class SolarisAclFileAttributeView +- extends AbstractAclFileAttributeView +-{ +- private static final Unsafe unsafe = Unsafe.getUnsafe(); +- +- // Maximum number of entries allowed in an ACL +- private static final int MAX_ACL_ENTRIES = 1024; +- +- /** +- * typedef struct ace { +- * uid_t a_who; +- * uint32_t a_access_mask; +- * uint16_t a_flags; +- * uint16_t a_type; +- * } ace_t; +- */ +- private static final short SIZEOF_ACE_T = 12; +- private static final short OFFSETOF_UID = 0; +- private static final short OFFSETOF_MASK = 4; +- private static final short OFFSETOF_FLAGS = 8; +- private static final short OFFSETOF_TYPE = 10; +- +- private final UnixPath file; +- private final boolean followLinks; +- +- SolarisAclFileAttributeView(UnixPath file, boolean followLinks) { +- this.file = file; +- this.followLinks = followLinks; +- } +- +- /** +- * Permission checks to access file +- */ +- private void checkAccess(UnixPath file, +- boolean checkRead, +- boolean checkWrite) +- { +- @SuppressWarnings("removal") +- SecurityManager sm = System.getSecurityManager(); +- if (sm != null) { +- if (checkRead) +- file.checkRead(); +- if (checkWrite) +- file.checkWrite(); +- sm.checkPermission(new RuntimePermission("accessUserInformation")); +- } +- } +- +- /** +- * Encode the ACL to the given buffer +- */ +- private static void encode(List acl, long address) { +- long offset = address; +- for (AclEntry ace: acl) { +- int flags = 0; +- +- // map UserPrincipal to uid and flags +- UserPrincipal who = ace.principal(); +- if (!(who instanceof UnixUserPrincipals.User)) +- throw new ProviderMismatchException(); +- UnixUserPrincipals.User user = (UnixUserPrincipals.User)who; +- int uid; +- if (user.isSpecial()) { +- uid = -1; +- if (who == UnixUserPrincipals.SPECIAL_OWNER) +- flags |= ACE_OWNER; +- else if (who == UnixUserPrincipals.SPECIAL_GROUP) +- flags |= (ACE_GROUP | ACE_IDENTIFIER_GROUP); +- else if (who == UnixUserPrincipals.SPECIAL_EVERYONE) +- flags |= ACE_EVERYONE; +- else +- throw new AssertionError("Unable to map special identifier"); +- } else { +- if (user instanceof UnixUserPrincipals.Group) { +- uid = user.gid(); +- flags |= ACE_IDENTIFIER_GROUP; +- } else { +- uid = user.uid(); +- } +- } +- +- // map ACE type +- int type; +- switch (ace.type()) { +- case ALLOW: +- type = ACE_ACCESS_ALLOWED_ACE_TYPE; +- break; +- case DENY: +- type = ACE_ACCESS_DENIED_ACE_TYPE; +- break; +- case AUDIT: +- type = ACE_SYSTEM_AUDIT_ACE_TYPE; +- break; +- case ALARM: +- type = ACE_SYSTEM_ALARM_ACE_TYPE; +- break; +- default: +- throw new AssertionError("Unable to map ACE type"); +- } +- +- // map permissions +- Set aceMask = ace.permissions(); +- int mask = 0; +- if (aceMask.contains(AclEntryPermission.READ_DATA)) +- mask |= ACE_READ_DATA; +- if (aceMask.contains(AclEntryPermission.WRITE_DATA)) +- mask |= ACE_WRITE_DATA; +- if (aceMask.contains(AclEntryPermission.APPEND_DATA)) +- mask |= ACE_APPEND_DATA; +- if (aceMask.contains(AclEntryPermission.READ_NAMED_ATTRS)) +- mask |= ACE_READ_NAMED_ATTRS; +- if (aceMask.contains(AclEntryPermission.WRITE_NAMED_ATTRS)) +- mask |= ACE_WRITE_NAMED_ATTRS; +- if (aceMask.contains(AclEntryPermission.EXECUTE)) +- mask |= ACE_EXECUTE; +- if (aceMask.contains(AclEntryPermission.DELETE_CHILD)) +- mask |= ACE_DELETE_CHILD; +- if (aceMask.contains(AclEntryPermission.READ_ATTRIBUTES)) +- mask |= ACE_READ_ATTRIBUTES; +- if (aceMask.contains(AclEntryPermission.WRITE_ATTRIBUTES)) +- mask |= ACE_WRITE_ATTRIBUTES; +- if (aceMask.contains(AclEntryPermission.DELETE)) +- mask |= ACE_DELETE; +- if (aceMask.contains(AclEntryPermission.READ_ACL)) +- mask |= ACE_READ_ACL; +- if (aceMask.contains(AclEntryPermission.WRITE_ACL)) +- mask |= ACE_WRITE_ACL; +- if (aceMask.contains(AclEntryPermission.WRITE_OWNER)) +- mask |= ACE_WRITE_OWNER; +- if (aceMask.contains(AclEntryPermission.SYNCHRONIZE)) +- mask |= ACE_SYNCHRONIZE; +- +- // FIXME - it would be desirable to know here if the file is a +- // directory or not. Solaris returns EINVAL if an ACE has a directory +- // -only flag and the file is not a directory. +- Set aceFlags = ace.flags(); +- if (aceFlags.contains(AclEntryFlag.FILE_INHERIT)) +- flags |= ACE_FILE_INHERIT_ACE; +- if (aceFlags.contains(AclEntryFlag.DIRECTORY_INHERIT)) +- flags |= ACE_DIRECTORY_INHERIT_ACE; +- if (aceFlags.contains(AclEntryFlag.NO_PROPAGATE_INHERIT)) +- flags |= ACE_NO_PROPAGATE_INHERIT_ACE; +- if (aceFlags.contains(AclEntryFlag.INHERIT_ONLY)) +- flags |= ACE_INHERIT_ONLY_ACE; +- +- unsafe.putInt(offset + OFFSETOF_UID, uid); +- unsafe.putInt(offset + OFFSETOF_MASK, mask); +- unsafe.putShort(offset + OFFSETOF_FLAGS, (short)flags); +- unsafe.putShort(offset + OFFSETOF_TYPE, (short)type); +- +- offset += SIZEOF_ACE_T; +- } +- } +- +- /** +- * Decode the buffer, returning an ACL +- */ +- private static List decode(long address, int n) { +- ArrayList acl = new ArrayList<>(n); +- for (int i=0; i 0) { +- who = UnixUserPrincipals.SPECIAL_OWNER; +- } else if ((flags & ACE_GROUP) > 0) { +- who = UnixUserPrincipals.SPECIAL_GROUP; +- } else if ((flags & ACE_EVERYONE) > 0) { +- who = UnixUserPrincipals.SPECIAL_EVERYONE; +- } else if ((flags & ACE_IDENTIFIER_GROUP) > 0) { +- who = UnixUserPrincipals.fromGid(uid); +- } else { +- who = UnixUserPrincipals.fromUid(uid); +- } +- +- AclEntryType aceType = null; +- switch (type) { +- case ACE_ACCESS_ALLOWED_ACE_TYPE: +- aceType = AclEntryType.ALLOW; +- break; +- case ACE_ACCESS_DENIED_ACE_TYPE: +- aceType = AclEntryType.DENY; +- break; +- case ACE_SYSTEM_AUDIT_ACE_TYPE: +- aceType = AclEntryType.AUDIT; +- break; +- case ACE_SYSTEM_ALARM_ACE_TYPE: +- aceType = AclEntryType.ALARM; +- break; +- default: +- assert false; +- } +- +- Set aceMask = EnumSet.noneOf(AclEntryPermission.class); +- if ((mask & ACE_READ_DATA) > 0) +- aceMask.add(AclEntryPermission.READ_DATA); +- if ((mask & ACE_WRITE_DATA) > 0) +- aceMask.add(AclEntryPermission.WRITE_DATA); +- if ((mask & ACE_APPEND_DATA ) > 0) +- aceMask.add(AclEntryPermission.APPEND_DATA); +- if ((mask & ACE_READ_NAMED_ATTRS) > 0) +- aceMask.add(AclEntryPermission.READ_NAMED_ATTRS); +- if ((mask & ACE_WRITE_NAMED_ATTRS) > 0) +- aceMask.add(AclEntryPermission.WRITE_NAMED_ATTRS); +- if ((mask & ACE_EXECUTE) > 0) +- aceMask.add(AclEntryPermission.EXECUTE); +- if ((mask & ACE_DELETE_CHILD ) > 0) +- aceMask.add(AclEntryPermission.DELETE_CHILD); +- if ((mask & ACE_READ_ATTRIBUTES) > 0) +- aceMask.add(AclEntryPermission.READ_ATTRIBUTES); +- if ((mask & ACE_WRITE_ATTRIBUTES) > 0) +- aceMask.add(AclEntryPermission.WRITE_ATTRIBUTES); +- if ((mask & ACE_DELETE) > 0) +- aceMask.add(AclEntryPermission.DELETE); +- if ((mask & ACE_READ_ACL) > 0) +- aceMask.add(AclEntryPermission.READ_ACL); +- if ((mask & ACE_WRITE_ACL) > 0) +- aceMask.add(AclEntryPermission.WRITE_ACL); +- if ((mask & ACE_WRITE_OWNER) > 0) +- aceMask.add(AclEntryPermission.WRITE_OWNER); +- if ((mask & ACE_SYNCHRONIZE) > 0) +- aceMask.add(AclEntryPermission.SYNCHRONIZE); +- +- Set aceFlags = EnumSet.noneOf(AclEntryFlag.class); +- if ((flags & ACE_FILE_INHERIT_ACE) > 0) +- aceFlags.add(AclEntryFlag.FILE_INHERIT); +- if ((flags & ACE_DIRECTORY_INHERIT_ACE) > 0) +- aceFlags.add(AclEntryFlag.DIRECTORY_INHERIT); +- if ((flags & ACE_NO_PROPAGATE_INHERIT_ACE) > 0) +- aceFlags.add(AclEntryFlag.NO_PROPAGATE_INHERIT); +- if ((flags & ACE_INHERIT_ONLY_ACE) > 0) +- aceFlags.add(AclEntryFlag.INHERIT_ONLY); +- +- // build the ACL entry and add it to the list +- AclEntry ace = AclEntry.newBuilder() +- .setType(aceType) +- .setPrincipal(who) +- .setPermissions(aceMask).setFlags(aceFlags).build(); +- acl.add(ace); +- } +- +- return acl; +- } +- +- // Returns true if NFSv4 ACLs not enabled on file system +- private static boolean isAclsEnabled(int fd) { +- try { +- long enabled = fpathconf(fd, _PC_ACL_ENABLED); +- if (enabled == _ACL_ACE_ENABLED) +- return true; +- } catch (UnixException x) { +- } +- return false; +- } +- +- @Override +- public List getAcl() +- throws IOException +- { +- // permission check +- checkAccess(file, true, false); +- +- // open file (will fail if file is a link and not following links) +- int fd = -1; +- try { +- fd = file.openForAttributeAccess(followLinks); +- } catch (UnixException x) { +- x.rethrowAsIOException(file); +- } +- try { +- long address = unsafe.allocateMemory(SIZEOF_ACE_T * MAX_ACL_ENTRIES); +- try { +- // read ACL and decode it +- int n = facl(fd, ACE_GETACL, MAX_ACL_ENTRIES, address); +- assert n >= 0; +- return decode(address, n); +- } catch (UnixException x) { +- if ((x.errno() == ENOSYS) || !isAclsEnabled(fd)) { +- throw new FileSystemException(file.getPathForExceptionMessage(), +- null, x.getMessage() + " (file system does not support NFSv4 ACLs)"); +- } +- x.rethrowAsIOException(file); +- return null; // keep compiler happy +- } finally { +- unsafe.freeMemory(address); +- } +- } finally { +- close(fd, e -> null); +- } +- } +- +- @Override +- public void setAcl(List acl) throws IOException { +- // permission check +- checkAccess(file, false, true); +- +- // open file (will fail if file is a link and not following links) +- int fd = -1; +- try { +- fd = file.openForAttributeAccess(followLinks); +- } catch (UnixException x) { +- x.rethrowAsIOException(file); +- } +- try { +- // SECURITY: need to copy list as can change during processing +- acl = new ArrayList(acl); +- int n = acl.size(); +- +- long address = unsafe.allocateMemory(SIZEOF_ACE_T * n); +- try { +- encode(acl, address); +- facl(fd, ACE_SETACL, n, address); +- } catch (UnixException x) { +- if ((x.errno() == ENOSYS) || !isAclsEnabled(fd)) { +- throw new FileSystemException(file.getPathForExceptionMessage(), +- null, x.getMessage() + " (file system does not support NFSv4 ACLs)"); +- } +- if (x.errno() == EINVAL && (n < 3)) +- throw new IOException("ACL must contain at least 3 entries"); +- x.rethrowAsIOException(file); +- } finally { +- unsafe.freeMemory(address); +- } +- } finally { +- close(fd, e -> null); +- } +- } +- +- @Override +- public UserPrincipal getOwner() +- throws IOException +- { +- checkAccess(file, true, false); +- +- try { +- UnixFileAttributes attrs = +- UnixFileAttributes.get(file, followLinks); +- return UnixUserPrincipals.fromUid(attrs.uid()); +- } catch (UnixException x) { +- x.rethrowAsIOException(file); +- return null; // keep compile happy +- } +- } +- +- @Override +- public void setOwner(UserPrincipal owner) throws IOException { +- checkAccess(file, true, false); +- +- if (!(owner instanceof UnixUserPrincipals.User)) +- throw new ProviderMismatchException(); +- if (owner instanceof UnixUserPrincipals.Group) +- throw new IOException("'owner' parameter is a group"); +- int uid = ((UnixUserPrincipals.User)owner).uid(); +- +- try { +- if (followLinks) { +- lchown(file, uid, -1); +- } else { +- chown(file, uid, -1); +- } +- } catch (UnixException x) { +- x.rethrowAsIOException(file); +- } +- } +-} +--- old/src/java.base/solaris/classes/sun/nio/fs/SolarisConstants.java.template 2020-05-20 18:10:19.181962393 -0700 ++++ /dev/null 2020-03-09 18:57:19.455001459 -0700 +@@ -1,89 +0,0 @@ +-/* +- * Copyright (c) 2008, 2016, Oracle and/or its affiliates. All rights reserved. +- * +- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. +- * +- * This code is free software; you can redistribute it and/or modify it +- * under the terms of the GNU General Public License version 2 only, as +- * published by the Free Software Foundation. Oracle designates this +- * particular file as subject to the "Classpath" exception as provided +- * by Oracle in the LICENSE file that accompanied this code. +- * +- * This code is distributed in the hope that it will be useful, but WITHOUT +- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +- * version 2 for more details (a copy is included in the LICENSE file that +- * accompanied this code). +- * +- * You should have received a copy of the GNU General Public License version +- * 2 along with this work; if not, write to the Free Software Foundation, +- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. +- * +- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA +- * or visit www.oracle.com if you need additional information or have any +- * questions. +- */ +- +-@@END_COPYRIGHT@@ +- +-#include +-#include +-#include +-#include +-#include +-#include +- +-/* On Solaris, "sun" is defined as a macro. Undefine to make package +- declaration valid */ +-#undef sun +- +-/* To be able to name the Java constants the same as the C constants without +- having the preprocessor rewrite those identifiers, add PREFIX_ to all +- identifiers matching a C constant. The PREFIX_ is filtered out in the +- makefile. */ +- +-@@START_HERE@@ +- +-package sun.nio.fs; +-class SolarisConstants { +- +- private SolarisConstants() { } +- +- static final int PREFIX_O_XATTR = O_XATTR; +- static final int PREFIX__PC_XATTR_ENABLED = _PC_XATTR_ENABLED; +- static final int PREFIX__PC_ACL_ENABLED = _PC_ACL_ENABLED; +- static final int PREFIX__ACL_ACE_ENABLED = _ACL_ACE_ENABLED; +- static final int PREFIX_ACE_GETACL = ACE_GETACL; +- static final int PREFIX_ACE_SETACL = ACE_SETACL; +- static final int PREFIX_ACE_ACCESS_ALLOWED_ACE_TYPE = ACE_ACCESS_ALLOWED_ACE_TYPE; +- static final int PREFIX_ACE_ACCESS_DENIED_ACE_TYPE = ACE_ACCESS_DENIED_ACE_TYPE; +- static final int PREFIX_ACE_SYSTEM_AUDIT_ACE_TYPE = ACE_SYSTEM_AUDIT_ACE_TYPE; +- static final int PREFIX_ACE_SYSTEM_ALARM_ACE_TYPE = ACE_SYSTEM_ALARM_ACE_TYPE; +- static final int PREFIX_ACE_READ_DATA = ACE_READ_DATA; +- static final int PREFIX_ACE_LIST_DIRECTORY = ACE_LIST_DIRECTORY; +- static final int PREFIX_ACE_WRITE_DATA = ACE_WRITE_DATA; +- static final int PREFIX_ACE_ADD_FILE = ACE_ADD_FILE; +- static final int PREFIX_ACE_APPEND_DATA = ACE_APPEND_DATA; +- static final int PREFIX_ACE_ADD_SUBDIRECTORY = ACE_ADD_SUBDIRECTORY; +- static final int PREFIX_ACE_READ_NAMED_ATTRS = ACE_READ_NAMED_ATTRS; +- static final int PREFIX_ACE_WRITE_NAMED_ATTRS = ACE_WRITE_NAMED_ATTRS; +- static final int PREFIX_ACE_EXECUTE = ACE_EXECUTE; +- static final int PREFIX_ACE_DELETE_CHILD = ACE_DELETE_CHILD; +- static final int PREFIX_ACE_READ_ATTRIBUTES = ACE_READ_ATTRIBUTES; +- static final int PREFIX_ACE_WRITE_ATTRIBUTES = ACE_WRITE_ATTRIBUTES; +- static final int PREFIX_ACE_DELETE = ACE_DELETE; +- static final int PREFIX_ACE_READ_ACL = ACE_READ_ACL; +- static final int PREFIX_ACE_WRITE_ACL = ACE_WRITE_ACL; +- static final int PREFIX_ACE_WRITE_OWNER = ACE_WRITE_OWNER; +- static final int PREFIX_ACE_SYNCHRONIZE = ACE_SYNCHRONIZE; +- static final int PREFIX_ACE_FILE_INHERIT_ACE = ACE_FILE_INHERIT_ACE; +- static final int PREFIX_ACE_DIRECTORY_INHERIT_ACE = ACE_DIRECTORY_INHERIT_ACE; +- static final int PREFIX_ACE_NO_PROPAGATE_INHERIT_ACE = ACE_NO_PROPAGATE_INHERIT_ACE; +- static final int PREFIX_ACE_INHERIT_ONLY_ACE = ACE_INHERIT_ONLY_ACE; +- static final int PREFIX_ACE_SUCCESSFUL_ACCESS_ACE_FLAG = ACE_SUCCESSFUL_ACCESS_ACE_FLAG; +- static final int PREFIX_ACE_FAILED_ACCESS_ACE_FLAG = ACE_FAILED_ACCESS_ACE_FLAG; +- static final int PREFIX_ACE_IDENTIFIER_GROUP = ACE_IDENTIFIER_GROUP; +- static final int PREFIX_ACE_OWNER = ACE_OWNER; +- static final int PREFIX_ACE_GROUP = ACE_GROUP; +- static final int PREFIX_ACE_EVERYONE = ACE_EVERYONE; +-} +--- old/src/java.base/solaris/classes/sun/nio/fs/SolarisFileStore.java 2020-05-20 18:10:19.873975679 -0700 ++++ /dev/null 2020-03-09 18:57:19.455001459 -0700 +@@ -1,111 +0,0 @@ +-/* +- * Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved. +- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. +- * +- * This code is free software; you can redistribute it and/or modify it +- * under the terms of the GNU General Public License version 2 only, as +- * published by the Free Software Foundation. Oracle designates this +- * particular file as subject to the "Classpath" exception as provided +- * by Oracle in the LICENSE file that accompanied this code. +- * +- * This code is distributed in the hope that it will be useful, but WITHOUT +- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +- * version 2 for more details (a copy is included in the LICENSE file that +- * accompanied this code). +- * +- * You should have received a copy of the GNU General Public License version +- * 2 along with this work; if not, write to the Free Software Foundation, +- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. +- * +- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA +- * or visit www.oracle.com if you need additional information or have any +- * questions. +- */ +- +-package sun.nio.fs; +- +-import java.nio.file.attribute.*; +-import java.io.IOException; +- +-import static sun.nio.fs.UnixNativeDispatcher.*; +-import static sun.nio.fs.SolarisConstants.*; +- +-/** +- * Solaris implementation of FileStore +- */ +- +-class SolarisFileStore +- extends UnixFileStore +-{ +- private final boolean xattrEnabled; +- +- SolarisFileStore(UnixPath file) throws IOException { +- super(file); +- this.xattrEnabled = xattrEnabled(); +- } +- +- SolarisFileStore(UnixFileSystem fs, UnixMountEntry entry) throws IOException { +- super(fs, entry); +- this.xattrEnabled = xattrEnabled(); +- } +- +- // returns true if extended attributes enabled +- private boolean xattrEnabled() { +- long res = 0L; +- try { +- res = pathconf(file(), _PC_XATTR_ENABLED); +- } catch (UnixException x) { +- // ignore +- } +- return (res != 0L); +- } +- +- @Override +- UnixMountEntry findMountEntry() throws IOException { +- // On Solaris iterate over the entries in the mount table to find device +- for (UnixMountEntry entry: file().getFileSystem().getMountEntries()) { +- if (entry.dev() == dev()) { +- return entry; +- } +- } +- throw new IOException("Device not found in mnttab"); +- } +- +- @Override +- public boolean supportsFileAttributeView(Class type) { +- if (type == AclFileAttributeView.class) { +- // lookup fstypes.properties +- FeatureStatus status = checkIfFeaturePresent("nfsv4acl"); +- switch (status) { +- case PRESENT : return true; +- case NOT_PRESENT : return false; +- default : +- // AclFileAttributeView available on ZFS +- return (type().equals("zfs")); +- } +- } +- if (type == UserDefinedFileAttributeView.class) { +- // lookup fstypes.properties +- FeatureStatus status = checkIfFeaturePresent("xattr"); +- switch (status) { +- case PRESENT : return true; +- case NOT_PRESENT : return false; +- default : +- // UserDefinedFileAttributeView available if extended +- // attributes supported +- return xattrEnabled; +- } +- } +- return super.supportsFileAttributeView(type); +- } +- +- @Override +- public boolean supportsFileAttributeView(String name) { +- if (name.equals("acl")) +- return supportsFileAttributeView(AclFileAttributeView.class); +- if (name.equals("user")) +- return supportsFileAttributeView(UserDefinedFileAttributeView.class); +- return super.supportsFileAttributeView(name); +- } +-} +--- old/src/java.base/solaris/classes/sun/nio/fs/SolarisFileSystem.java 2020-05-20 18:10:20.625990118 -0700 ++++ /dev/null 2020-03-09 18:57:19.455001459 -0700 +@@ -1,127 +0,0 @@ +-/* +- * Copyright (c) 2008, 2012, Oracle and/or its affiliates. All rights reserved. +- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. +- * +- * This code is free software; you can redistribute it and/or modify it +- * under the terms of the GNU General Public License version 2 only, as +- * published by the Free Software Foundation. Oracle designates this +- * particular file as subject to the "Classpath" exception as provided +- * by Oracle in the LICENSE file that accompanied this code. +- * +- * This code is distributed in the hope that it will be useful, but WITHOUT +- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +- * version 2 for more details (a copy is included in the LICENSE file that +- * accompanied this code). +- * +- * You should have received a copy of the GNU General Public License version +- * 2 along with this work; if not, write to the Free Software Foundation, +- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. +- * +- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA +- * or visit www.oracle.com if you need additional information or have any +- * questions. +- */ +- +-package sun.nio.fs; +- +-import java.nio.file.*; +-import java.io.IOException; +-import java.util.*; +-import sun.security.action.GetPropertyAction; +-import static sun.nio.fs.SolarisNativeDispatcher.*; +- +-/** +- * Solaris implementation of FileSystem +- */ +- +-class SolarisFileSystem extends UnixFileSystem { +- private final boolean hasSolaris11Features; +- +- SolarisFileSystem(UnixFileSystemProvider provider, String dir) { +- super(provider, dir); +- +- // check os.version +- String osversion = GetPropertyAction.privilegedGetProperty("os.version"); +- String[] vers = Util.split(osversion, '.'); +- assert vers.length >= 2; +- int majorVersion = Integer.parseInt(vers[0]); +- int minorVersion = Integer.parseInt(vers[1]); +- this.hasSolaris11Features = +- (majorVersion > 5 || (majorVersion == 5 && minorVersion >= 11)); +- } +- +- @Override +- boolean isSolaris() { +- return true; +- } +- +- @Override +- public WatchService newWatchService() +- throws IOException +- { +- // FEN available since Solaris 11 +- if (hasSolaris11Features) { +- return new SolarisWatchService(this); +- } else { +- return new PollingWatchService(); +- } +- } +- +- +- // lazy initialization of the list of supported attribute views +- private static class SupportedFileFileAttributeViewsHolder { +- static final Set supportedFileAttributeViews = +- supportedFileAttributeViews(); +- private static Set supportedFileAttributeViews() { +- Set result = new HashSet<>(); +- result.addAll(standardFileAttributeViews()); +- // additional Solaris-specific views +- result.add("acl"); +- result.add("user"); +- return Collections.unmodifiableSet(result); +- } +- } +- +- @Override +- public Set supportedFileAttributeViews() { +- return SupportedFileFileAttributeViewsHolder.supportedFileAttributeViews; +- } +- +- @Override +- void copyNonPosixAttributes(int ofd, int nfd) { +- SolarisUserDefinedFileAttributeView.copyExtendedAttributes(ofd, nfd); +- // TDB: copy ACL from source to target +- } +- +- /** +- * Returns object to iterate over entries in /etc/mnttab +- */ +- @Override +- Iterable getMountEntries() { +- ArrayList entries = new ArrayList<>(); +- try { +- UnixPath mnttab = new UnixPath(this, "/etc/mnttab"); +- long fp = fopen(mnttab, "r"); +- try { +- for (;;) { +- UnixMountEntry entry = new UnixMountEntry(); +- int res = getextmntent(fp, entry); +- if (res < 0) +- break; +- entries.add(entry); +- } +- } finally { +- fclose(fp); +- } +- } catch (UnixException x) { +- // nothing we can do +- } +- return entries; +- } +- +- @Override +- FileStore getFileStore(UnixMountEntry entry) throws IOException { +- return new SolarisFileStore(this, entry); +- } +-} +--- old/src/java.base/solaris/classes/sun/nio/fs/SolarisFileSystemProvider.java 2020-05-20 18:10:21.314003326 -0700 ++++ /dev/null 2020-03-09 18:57:19.455001459 -0700 +@@ -1,94 +0,0 @@ +-/* +- * Copyright (c) 2008, 2018, Oracle and/or its affiliates. All rights reserved. +- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. +- * +- * This code is free software; you can redistribute it and/or modify it +- * under the terms of the GNU General Public License version 2 only, as +- * published by the Free Software Foundation. Oracle designates this +- * particular file as subject to the "Classpath" exception as provided +- * by Oracle in the LICENSE file that accompanied this code. +- * +- * This code is distributed in the hope that it will be useful, but WITHOUT +- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +- * version 2 for more details (a copy is included in the LICENSE file that +- * accompanied this code). +- * +- * You should have received a copy of the GNU General Public License version +- * 2 along with this work; if not, write to the Free Software Foundation, +- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. +- * +- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA +- * or visit www.oracle.com if you need additional information or have any +- * questions. +- */ +- +-package sun.nio.fs; +- +-import java.nio.file.*; +-import java.nio.file.attribute.*; +-import java.nio.file.spi.FileTypeDetector; +-import java.io.IOException; +-import jdk.internal.util.StaticProperty; +-import sun.security.action.GetPropertyAction; +- +-/** +- * Solaris implementation of FileSystemProvider +- */ +- +-class SolarisFileSystemProvider extends UnixFileSystemProvider { +- public SolarisFileSystemProvider() { +- super(); +- } +- +- @Override +- SolarisFileSystem newFileSystem(String dir) { +- return new SolarisFileSystem(this, dir); +- } +- +- @Override +- SolarisFileStore getFileStore(UnixPath path) throws IOException { +- return new SolarisFileStore(path); +- } +- +- +- @Override +- @SuppressWarnings("unchecked") +- public V getFileAttributeView(Path obj, +- Class type, +- LinkOption... options) +- { +- if (type == AclFileAttributeView.class) { +- return (V) new SolarisAclFileAttributeView(UnixPath.toUnixPath(obj), +- Util.followLinks(options)); +- } +- if (type == UserDefinedFileAttributeView.class) { +- return(V) new SolarisUserDefinedFileAttributeView(UnixPath.toUnixPath(obj), +- Util.followLinks(options)); +- } +- return super.getFileAttributeView(obj, type, options); +- } +- +- @Override +- public DynamicFileAttributeView getFileAttributeView(Path obj, +- String name, +- LinkOption... options) +- { +- if (name.equals("acl")) +- return new SolarisAclFileAttributeView(UnixPath.toUnixPath(obj), +- Util.followLinks(options)); +- if (name.equals("user")) +- return new SolarisUserDefinedFileAttributeView(UnixPath.toUnixPath(obj), +- Util.followLinks(options)); +- return super.getFileAttributeView(obj, name, options); +- } +- +- @Override +- FileTypeDetector getFileTypeDetector() { +- Path userMimeTypes = Path.of(StaticProperty.userHome(), ".mime.types"); +- Path etcMimeTypes = Path.of("/etc/mime.types"); +- +- return chain(new MimeTypesFileTypeDetector(userMimeTypes), +- new MimeTypesFileTypeDetector(etcMimeTypes)); +- } +-} +--- old/src/java.base/solaris/classes/sun/nio/fs/SolarisNativeDispatcher.java 2020-05-20 18:10:22.002016535 -0700 ++++ /dev/null 2020-03-09 18:57:19.455001459 -0700 +@@ -1,55 +0,0 @@ +-/* +- * Copyright (c) 2008, 2019, Oracle and/or its affiliates. All rights reserved. +- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. +- * +- * This code is free software; you can redistribute it and/or modify it +- * under the terms of the GNU General Public License version 2 only, as +- * published by the Free Software Foundation. Oracle designates this +- * particular file as subject to the "Classpath" exception as provided +- * by Oracle in the LICENSE file that accompanied this code. +- * +- * This code is distributed in the hope that it will be useful, but WITHOUT +- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +- * version 2 for more details (a copy is included in the LICENSE file that +- * accompanied this code). +- * +- * You should have received a copy of the GNU General Public License version +- * 2 along with this work; if not, write to the Free Software Foundation, +- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. +- * +- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA +- * or visit www.oracle.com if you need additional information or have any +- * questions. +- */ +- +-package sun.nio.fs; +- +-/** +- * Solaris specific system calls. +- */ +- +-class SolarisNativeDispatcher extends UnixNativeDispatcher { +- private SolarisNativeDispatcher() { } +- +- /** +- * int getextmntent(FILE *fp, struct extmnttab *mp, int len); +- */ +- static native int getextmntent(long fp, UnixMountEntry entry) +- throws UnixException; +- +- /** +- * int facl(int filedes, int cmd, int nentries, void aclbufp) +- */ +- static native int facl(int fd, int cmd, int nentries, long aclbufp) +- throws UnixException; +- +- +- // initialize +- private static native void init(); +- +- static { +- jdk.internal.loader.BootLoader.loadLibrary("nio"); +- init(); +- } +-} +--- old/src/java.base/solaris/classes/sun/nio/fs/SolarisUserDefinedFileAttributeView.java 2020-05-20 18:10:22.750030897 -0700 ++++ /dev/null 2020-03-09 18:57:19.455001459 -0700 +@@ -1,41 +0,0 @@ +-/* +- * Copyright (c) 2008, 2015, Oracle and/or its affiliates. All rights reserved. +- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. +- * +- * This code is free software; you can redistribute it and/or modify it +- * under the terms of the GNU General Public License version 2 only, as +- * published by the Free Software Foundation. Oracle designates this +- * particular file as subject to the "Classpath" exception as provided +- * by Oracle in the LICENSE file that accompanied this code. +- * +- * This code is distributed in the hope that it will be useful, but WITHOUT +- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +- * version 2 for more details (a copy is included in the LICENSE file that +- * accompanied this code). +- * +- * You should have received a copy of the GNU General Public License version +- * 2 along with this work; if not, write to the Free Software Foundation, +- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. +- * +- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA +- * or visit www.oracle.com if you need additional information or have any +- * questions. +- */ +- +-package sun.nio.fs; +- +-class SolarisUserDefinedFileAttributeView +- extends UnixUserDefinedFileAttributeView +-{ +- +- SolarisUserDefinedFileAttributeView(UnixPath file, boolean followLinks) { +- super(file, followLinks); +- } +- +- @Override +- protected int maxNameLength() { +- return 255; +- } +- +-} +--- old/src/java.base/solaris/classes/sun/nio/fs/SolarisWatchService.java 2020-05-20 18:10:23.522045718 -0700 ++++ /dev/null 2020-03-09 18:57:19.455001459 -0700 +@@ -1,821 +0,0 @@ +-/* +- * Copyright (c) 2008, 2019, Oracle and/or its affiliates. All rights reserved. +- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. +- * +- * This code is free software; you can redistribute it and/or modify it +- * under the terms of the GNU General Public License version 2 only, as +- * published by the Free Software Foundation. Oracle designates this +- * particular file as subject to the "Classpath" exception as provided +- * by Oracle in the LICENSE file that accompanied this code. +- * +- * This code is distributed in the hope that it will be useful, but WITHOUT +- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +- * version 2 for more details (a copy is included in the LICENSE file that +- * accompanied this code). +- * +- * You should have received a copy of the GNU General Public License version +- * 2 along with this work; if not, write to the Free Software Foundation, +- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. +- * +- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA +- * or visit www.oracle.com if you need additional information or have any +- * questions. +- */ +- +-package sun.nio.fs; +- +-import java.nio.file.*; +-import java.util.*; +-import java.io.IOException; +-import jdk.internal.misc.Unsafe; +- +-import static sun.nio.fs.UnixConstants.*; +- +-/** +- * Solaris implementation of WatchService based on file events notification +- * facility. +- */ +- +-class SolarisWatchService +- extends AbstractWatchService +-{ +- private static final Unsafe unsafe = Unsafe.getUnsafe(); +- private static int addressSize = unsafe.addressSize(); +- +- private static int dependsArch(int value32, int value64) { +- return (addressSize == 4) ? value32 : value64; +- } +- +- /* +- * typedef struct port_event { +- * int portev_events; +- * ushort_t portev_source; +- * ushort_t portev_pad; +- * uintptr_t portev_object; +- * void *portev_user; +- * } port_event_t; +- */ +- private static final int SIZEOF_PORT_EVENT = dependsArch(16, 24); +- private static final int OFFSETOF_EVENTS = 0; +- private static final int OFFSETOF_SOURCE = 4; +- private static final int OFFSETOF_OBJECT = 8; +- +- /* +- * typedef struct file_obj { +- * timestruc_t fo_atime; +- * timestruc_t fo_mtime; +- * timestruc_t fo_ctime; +- * uintptr_t fo_pad[3]; +- * char *fo_name; +- * } file_obj_t; +- */ +- private static final int SIZEOF_FILEOBJ = dependsArch(40, 80); +- private static final int OFFSET_FO_NAME = dependsArch(36, 72); +- +- // port sources +- private static final short PORT_SOURCE_USER = 3; +- private static final short PORT_SOURCE_FILE = 7; +- +- // user-watchable events +- private static final int FILE_MODIFIED = 0x00000002; +- private static final int FILE_ATTRIB = 0x00000004; +- private static final int FILE_NOFOLLOW = 0x10000000; +- +- // exception events +- private static final int FILE_DELETE = 0x00000010; +- private static final int FILE_RENAME_TO = 0x00000020; +- private static final int FILE_RENAME_FROM = 0x00000040; +- private static final int UNMOUNTED = 0x20000000; +- private static final int MOUNTEDOVER = 0x40000000; +- +- // background thread to read change events +- private final Poller poller; +- +- SolarisWatchService(UnixFileSystem fs) throws IOException { +- int port = -1; +- try { +- port = portCreate(); +- } catch (UnixException x) { +- throw new IOException(x.errorString()); +- } +- +- this.poller = new Poller(fs, this, port); +- this.poller.start(); +- } +- +- @Override +- WatchKey register(Path dir, +- WatchEvent.Kind[] events, +- WatchEvent.Modifier... modifiers) +- throws IOException +- { +- // delegate to poller +- return poller.register(dir, events, modifiers); +- } +- +- @Override +- void implClose() throws IOException { +- // delegate to poller +- poller.close(); +- } +- +- /** +- * WatchKey implementation +- */ +- private class SolarisWatchKey extends AbstractWatchKey +- implements DirectoryNode +- { +- private final UnixFileKey fileKey; +- +- // pointer to native file_obj object +- private final long object; +- +- // events (may be changed). set to null when watch key is invalid +- private volatile Set> events; +- +- // map of entries in directory; created lazily; accessed only by +- // poller thread. +- private Map children = new HashMap<>(); +- +- SolarisWatchKey(SolarisWatchService watcher, +- UnixPath dir, +- UnixFileKey fileKey, +- long object, +- Set> events) +- { +- super(dir, watcher); +- this.fileKey = fileKey; +- this.object = object; +- this.events = events; +- } +- +- UnixPath getDirectory() { +- return (UnixPath)watchable(); +- } +- +- UnixFileKey getFileKey() { +- return fileKey; +- } +- +- @Override +- public long object() { +- return object; +- } +- +- void invalidate() { +- events = null; +- } +- +- Set> events() { +- return events; +- } +- +- void setEvents(Set> events) { +- this.events = events; +- } +- +- Map children() { +- return children; +- } +- +- @Override +- public boolean isValid() { +- return events != null; +- } +- +- @Override +- public void cancel() { +- if (isValid()) { +- // delegate to poller +- poller.cancel(this); +- } +- } +- +- @Override +- public void addChild(Path name, EntryNode node) { +- children.put(name, node); +- } +- +- @Override +- public void removeChild(Path name) { +- children.remove(name); +- } +- +- @Override +- public EntryNode getChild(Path name) { +- return children.get(name); +- } +- } +- +- /** +- * Background thread to read from port +- */ +- private class Poller extends AbstractPoller { +- +- // maximum number of events to read per call to port_getn +- private static final int MAX_EVENT_COUNT = 128; +- +- // events that map to ENTRY_DELETE +- private static final int FILE_REMOVED = +- (FILE_DELETE|FILE_RENAME_TO|FILE_RENAME_FROM); +- +- // events that tell us not to re-associate the object +- private static final int FILE_EXCEPTION = +- (FILE_REMOVED|UNMOUNTED|MOUNTEDOVER); +- +- // address of event buffers (used to receive events with port_getn) +- private final long bufferAddress; +- +- private final SolarisWatchService watcher; +- +- // the I/O port +- private final int port; +- +- // maps file key (dev/inode) to WatchKey +- private final Map fileKey2WatchKey; +- +- // maps file_obj object to Node +- private final Map object2Node; +- +- /** +- * Create a new instance +- */ +- Poller(UnixFileSystem fs, SolarisWatchService watcher, int port) { +- this.watcher = watcher; +- this.port = port; +- this.bufferAddress = +- unsafe.allocateMemory(SIZEOF_PORT_EVENT * MAX_EVENT_COUNT); +- this.fileKey2WatchKey = new HashMap(); +- this.object2Node = new HashMap(); +- } +- +- @Override +- void wakeup() throws IOException { +- // write to port to wakeup polling thread +- try { +- portSend(port, 0); +- } catch (UnixException x) { +- throw new IOException(x.errorString()); +- } +- } +- +- @Override +- Object implRegister(Path obj, +- Set> events, +- WatchEvent.Modifier... modifiers) +- { +- // no modifiers supported at this time +- if (modifiers.length > 0) { +- for (WatchEvent.Modifier modifier: modifiers) { +- if (modifier == null) +- return new NullPointerException(); +- if (!ExtendedOptions.SENSITIVITY_HIGH.matches(modifier) && +- !ExtendedOptions.SENSITIVITY_MEDIUM.matches(modifier) && +- !ExtendedOptions.SENSITIVITY_LOW.matches(modifier)) { +- return new UnsupportedOperationException("Modifier not supported"); +- } +- } +- } +- +- UnixPath dir = (UnixPath)obj; +- +- // check file is directory +- UnixFileAttributes attrs = null; +- try { +- attrs = UnixFileAttributes.get(dir, true); +- } catch (UnixException x) { +- return x.asIOException(dir); +- } +- if (!attrs.isDirectory()) { +- return new NotDirectoryException(dir.getPathForExceptionMessage()); +- } +- +- // if already registered then update the events and return existing key +- UnixFileKey fileKey = attrs.fileKey(); +- SolarisWatchKey watchKey = fileKey2WatchKey.get(fileKey); +- if (watchKey != null) { +- try { +- updateEvents(watchKey, events); +- } catch (UnixException x) { +- return x.asIOException(dir); +- } +- return watchKey; +- } +- +- // register directory +- long object = 0L; +- try { +- object = registerImpl(dir, (FILE_MODIFIED | FILE_ATTRIB)); +- } catch (UnixException x) { +- return x.asIOException(dir); +- } +- +- // create watch key and insert it into maps +- watchKey = new SolarisWatchKey(watcher, dir, fileKey, object, events); +- object2Node.put(object, watchKey); +- fileKey2WatchKey.put(fileKey, watchKey); +- +- // register all entries in directory +- registerChildren(dir, watchKey, false, false); +- +- return watchKey; +- } +- +- // release resources for single entry +- void releaseChild(EntryNode node) { +- long object = node.object(); +- if (object != 0L) { +- object2Node.remove(object); +- releaseObject(object, true); +- node.setObject(0L); +- } +- } +- +- // release resources for entries in directory +- void releaseChildren(SolarisWatchKey key) { +- for (EntryNode node: key.children().values()) { +- releaseChild(node); +- } +- } +- +- // cancel single key +- @Override +- void implCancelKey(WatchKey obj) { +- SolarisWatchKey key = (SolarisWatchKey)obj; +- if (key.isValid()) { +- fileKey2WatchKey.remove(key.getFileKey()); +- +- // release resources for entries +- releaseChildren(key); +- +- // release resources for directory +- long object = key.object(); +- object2Node.remove(object); +- releaseObject(object, true); +- +- // and finally invalidate the key +- key.invalidate(); +- } +- } +- +- // close watch service +- @Override +- void implCloseAll() { +- // release all native resources +- for (Long object: object2Node.keySet()) { +- releaseObject(object, true); +- } +- +- // invalidate all keys +- for (Map.Entry entry: fileKey2WatchKey.entrySet()) { +- entry.getValue().invalidate(); +- } +- +- // clean-up +- object2Node.clear(); +- fileKey2WatchKey.clear(); +- +- // free global resources +- unsafe.freeMemory(bufferAddress); +- UnixNativeDispatcher.close(port, e -> null); +- } +- +- /** +- * Poller main loop. Blocks on port_getn waiting for events and then +- * processes them. +- */ +- @Override +- public void run() { +- try { +- for (;;) { +- int n = portGetn(port, bufferAddress, MAX_EVENT_COUNT); +- assert n > 0; +- +- long address = bufferAddress; +- for (int i=0; iportev_source +- short source = unsafe.getShort(address + OFFSETOF_SOURCE); +- // pe->portev_object +- long object = unsafe.getAddress(address + OFFSETOF_OBJECT); +- // pe->portev_events +- int events = unsafe.getInt(address + OFFSETOF_EVENTS); +- +- // user event is trigger to process pending requests +- if (source != PORT_SOURCE_FILE) { +- if (source == PORT_SOURCE_USER) { +- // process any pending requests +- boolean shutdown = processRequests(); +- if (shutdown) +- return true; +- } +- return false; +- } +- +- // lookup object to get Node +- Node node = object2Node.get(object); +- if (node == null) { +- // should not happen +- return false; +- } +- +- // As a workaround for 6642290 and 6636438/6636412 we don't use +- // FILE_EXCEPTION events to tell use not to register the file. +- // boolean reregister = (events & FILE_EXCEPTION) == 0; +- boolean reregister = true; +- +- // If node is EntryNode then event relates to entry in directory +- // If node is a SolarisWatchKey (DirectoryNode) then event relates +- // to a watched directory. +- boolean isDirectory = (node instanceof SolarisWatchKey); +- if (isDirectory) { +- processDirectoryEvents((SolarisWatchKey)node, events); +- } else { +- boolean ignore = processEntryEvents((EntryNode)node, events); +- if (ignore) +- reregister = false; +- } +- +- // need to re-associate to get further events +- if (reregister) { +- try { +- events = FILE_MODIFIED | FILE_ATTRIB; +- if (!isDirectory) events |= FILE_NOFOLLOW; +- portAssociate(port, +- PORT_SOURCE_FILE, +- object, +- events); +- } catch (UnixException x) { +- // unable to re-register +- reregister = false; +- } +- } +- +- // object is not re-registered so release resources. If +- // object is a watched directory then signal key +- if (!reregister) { +- // release resources +- object2Node.remove(object); +- releaseObject(object, false); +- +- // if watch key then signal it +- if (isDirectory) { +- SolarisWatchKey key = (SolarisWatchKey)node; +- fileKey2WatchKey.remove( key.getFileKey() ); +- key.invalidate(); +- key.signal(); +- } else { +- // if entry then remove it from parent +- EntryNode entry = (EntryNode)node; +- SolarisWatchKey key = (SolarisWatchKey)entry.parent(); +- key.removeChild(entry.name()); +- } +- } +- +- return false; +- } +- +- /** +- * Process directory events. If directory is modified then re-scan +- * directory to register any new entries +- */ +- void processDirectoryEvents(SolarisWatchKey key, int mask) { +- if ((mask & (FILE_MODIFIED | FILE_ATTRIB)) != 0) { +- registerChildren(key.getDirectory(), key, +- key.events().contains(StandardWatchEventKinds.ENTRY_CREATE), +- key.events().contains(StandardWatchEventKinds.ENTRY_DELETE)); +- } +- } +- +- /** +- * Process events for entries in registered directories. Returns {@code +- * true} if events are ignored because the watch key has been cancelled. +- */ +- boolean processEntryEvents(EntryNode node, int mask) { +- SolarisWatchKey key = (SolarisWatchKey)node.parent(); +- Set> events = key.events(); +- if (events == null) { +- // key has been cancelled so ignore event +- return true; +- } +- +- // entry modified +- if (((mask & (FILE_MODIFIED | FILE_ATTRIB)) != 0) && +- events.contains(StandardWatchEventKinds.ENTRY_MODIFY)) +- { +- key.signalEvent(StandardWatchEventKinds.ENTRY_MODIFY, node.name()); +- } +- +- +- return false; +- } +- +- /** +- * Registers all entries in the given directory +- * +- * The {@code sendCreateEvents} and {@code sendDeleteEvents} parameters +- * indicates if ENTRY_CREATE and ENTRY_DELETE events should be queued +- * when new entries are found. When initially registering a directory +- * they will always be false. When re-scanning a directory then it +- * depends on if the events are enabled or not. +- */ +- void registerChildren(UnixPath dir, +- SolarisWatchKey parent, +- boolean sendCreateEvents, +- boolean sendDeleteEvents) +- { +- boolean isModifyEnabled = +- parent.events().contains(StandardWatchEventKinds.ENTRY_MODIFY) ; +- +- // reset visited flag on entries so that we can detect file deletes +- for (EntryNode node: parent.children().values()) { +- node.setVisited(false); +- } +- +- try (DirectoryStream stream = Files.newDirectoryStream(dir)) { +- for (Path entry: stream) { +- Path name = entry.getFileName(); +- +- // skip entry if already registered +- EntryNode node = parent.getChild(name); +- if (node != null) { +- node.setVisited(true); +- continue; +- } +- +- // new entry found +- +- long object = 0L; +- int errno = 0; +- boolean addNode = false; +- +- // if ENTRY_MODIFY enabled then we register the entry for events +- if (isModifyEnabled) { +- try { +- UnixPath path = (UnixPath)entry; +- int events = (FILE_NOFOLLOW | FILE_MODIFIED | FILE_ATTRIB); +- object = registerImpl(path, events); +- addNode = true; +- } catch (UnixException x) { +- errno = x.errno(); +- } +- } else { +- addNode = true; +- } +- +- if (addNode) { +- // create node +- node = new EntryNode(object, (UnixPath)entry.getFileName(), parent); +- node.setVisited(true); +- // tell the parent about it +- parent.addChild(entry.getFileName(), node); +- if (object != 0L) +- object2Node.put(object, node); +- } +- +- // send ENTRY_CREATE event for the new file +- // send ENTRY_DELETE event for files that were deleted immediately +- boolean deleted = (errno == ENOENT); +- if (sendCreateEvents && (addNode || deleted)) +- parent.signalEvent(StandardWatchEventKinds.ENTRY_CREATE, name); +- if (sendDeleteEvents && deleted) +- parent.signalEvent(StandardWatchEventKinds.ENTRY_DELETE, name); +- +- } +- } catch (DirectoryIteratorException | IOException x) { +- // queue OVERFLOW event so that user knows to re-scan directory +- parent.signalEvent(StandardWatchEventKinds.OVERFLOW, null); +- return; +- } +- +- // clean-up and send ENTRY_DELETE events for any entries that were +- // not found +- Iterator> iterator = +- parent.children().entrySet().iterator(); +- while (iterator.hasNext()) { +- Map.Entry entry = iterator.next(); +- EntryNode node = entry.getValue(); +- if (!node.isVisited()) { +- long object = node.object(); +- if (object != 0L) { +- object2Node.remove(object); +- releaseObject(object, true); +- } +- if (sendDeleteEvents) +- parent.signalEvent(StandardWatchEventKinds.ENTRY_DELETE, node.name()); +- iterator.remove(); +- } +- } +- } +- +- /** +- * Update watch key's events. If ENTRY_MODIFY changes to be enabled +- * then register each file in the directory; If ENTRY_MODIFY changed to +- * be disabled then unregister each file. +- */ +- void updateEvents(SolarisWatchKey key, Set> events) +- throws UnixException +- { +- +- // update events, remembering if ENTRY_MODIFY was previously +- // enabled or disabled. +- boolean oldModifyEnabled = key.events() +- .contains(StandardWatchEventKinds.ENTRY_MODIFY); +- key.setEvents(events); +- +- // check if ENTRY_MODIFY has changed +- boolean newModifyEnabled = events +- .contains(StandardWatchEventKinds.ENTRY_MODIFY); +- if (newModifyEnabled != oldModifyEnabled) { +- UnixException ex = null; +- for (EntryNode node: key.children().values()) { +- if (newModifyEnabled) { +- // register +- UnixPath path = key.getDirectory().resolve(node.name()); +- int ev = (FILE_NOFOLLOW | FILE_MODIFIED | FILE_ATTRIB); +- try { +- long object = registerImpl(path, ev); +- object2Node.put(object, node); +- node.setObject(object); +- } catch (UnixException x) { +- // if file has been deleted then it will be detected +- // as a FILE_MODIFIED event on the directory +- if (x.errno() != ENOENT) { +- ex = x; +- break; +- } +- } +- } else { +- // unregister +- releaseChild(node); +- } +- } +- +- // an error occurred +- if (ex != null) { +- releaseChildren(key); +- throw ex; +- } +- } +- } +- +- /** +- * Calls port_associate to register the given path. +- * Returns pointer to fileobj structure that is allocated for +- * the registration. +- */ +- long registerImpl(UnixPath dir, int events) +- throws UnixException +- { +- // allocate memory for the path (file_obj->fo_name field) +- byte[] path = dir.getByteArrayForSysCalls(); +- int len = path.length; +- long name = unsafe.allocateMemory(len+1); +- unsafe.copyMemory(path, Unsafe.ARRAY_BYTE_BASE_OFFSET, null, +- name, (long)len); +- unsafe.putByte(name + len, (byte)0); +- +- // allocate memory for filedatanode structure - this is the object +- // to port_associate +- long object = unsafe.allocateMemory(SIZEOF_FILEOBJ); +- unsafe.setMemory(null, object, SIZEOF_FILEOBJ, (byte)0); +- unsafe.putAddress(object + OFFSET_FO_NAME, name); +- +- // associate the object with the port +- try { +- portAssociate(port, +- PORT_SOURCE_FILE, +- object, +- events); +- } catch (UnixException x) { +- // debugging +- if (x.errno() == EAGAIN) { +- System.err.println("The maximum number of objects associated "+ +- "with the port has been reached"); +- } +- +- unsafe.freeMemory(name); +- unsafe.freeMemory(object); +- throw x; +- } +- return object; +- } +- +- /** +- * Frees all resources for an file_obj object; optionally remove +- * association from port +- */ +- void releaseObject(long object, boolean dissociate) { +- // remove association +- if (dissociate) { +- try { +- portDissociate(port, PORT_SOURCE_FILE, object); +- } catch (UnixException x) { +- // ignore +- } +- } +- +- // free native memory +- long name = unsafe.getAddress(object + OFFSET_FO_NAME); +- unsafe.freeMemory(name); +- unsafe.freeMemory(object); +- } +- } +- +- /** +- * A node with native (file_obj) resources +- */ +- private static interface Node { +- long object(); +- } +- +- /** +- * A directory node with a map of the entries in the directory +- */ +- private static interface DirectoryNode extends Node { +- void addChild(Path name, EntryNode node); +- void removeChild(Path name); +- EntryNode getChild(Path name); +- } +- +- /** +- * An implementation of a node that is an entry in a directory. +- */ +- private static class EntryNode implements Node { +- private long object; +- private final UnixPath name; +- private final DirectoryNode parent; +- private boolean visited; +- +- EntryNode(long object, UnixPath name, DirectoryNode parent) { +- this.object = object; +- this.name = name; +- this.parent = parent; +- } +- +- @Override +- public long object() { +- return object; +- } +- +- void setObject(long ptr) { +- this.object = ptr; +- } +- +- UnixPath name() { +- return name; +- } +- +- DirectoryNode parent() { +- return parent; +- } +- +- boolean isVisited() { +- return visited; +- } +- +- void setVisited(boolean v) { +- this.visited = v; +- } +- } +- +- // -- native methods -- +- +- private static native void init(); +- +- private static native int portCreate() throws UnixException; +- +- private static native void portAssociate(int port, int source, long object, int events) +- throws UnixException; +- +- private static native void portDissociate(int port, int source, long object) +- throws UnixException; +- +- private static native void portSend(int port, int events) +- throws UnixException; +- +- private static native int portGetn(int port, long address, int max) +- throws UnixException; +- +- static { +- jdk.internal.loader.BootLoader.loadLibrary("nio"); +- init(); +- } +-} +--- old/src/java.base/solaris/native/libjava/ProcessHandleImpl_solaris.c 2020-05-20 18:10:25.002074133 -0700 ++++ /dev/null 2020-03-09 18:57:19.455001459 -0700 +@@ -1,51 +0,0 @@ +-/* +- * Copyright (c) 2014, 2015, Oracle and/or its affiliates. All rights reserved. +- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. +- * +- * This code is free software; you can redistribute it and/or modify it +- * under the terms of the GNU General Public License version 2 only, as +- * published by the Free Software Foundation. Oracle designates this +- * particular file as subject to the "Classpath" exception as provided +- * by Oracle in the LICENSE file that accompanied this code. +- * +- * This code is distributed in the hope that it will be useful, but WITHOUT +- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +- * version 2 for more details (a copy is included in the LICENSE file that +- * accompanied this code). +- * +- * You should have received a copy of the GNU General Public License version +- * 2 along with this work; if not, write to the Free Software Foundation, +- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. +- * +- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA +- * or visit www.oracle.com if you need additional information or have any +- * questions. +- */ +- +-#include "jni.h" +- +-#include "ProcessHandleImpl_unix.h" +- +-#include +- +-/* +- * Implementation of native ProcessHandleImpl functions for Solaris. +- * See ProcessHandleImpl_unix.c for more details. +- */ +- +-void os_initNative(JNIEnv *env, jclass clazz) {} +- +-jint os_getChildren(JNIEnv *env, jlong jpid, jlongArray jarray, +- jlongArray jparentArray, jlongArray jstimesArray) { +- return unix_getChildren(env, jpid, jarray, jparentArray, jstimesArray); +-} +- +-pid_t os_getParentPidAndTimings(JNIEnv *env, pid_t pid, jlong *total, jlong *start) { +- return unix_getParentPidAndTimings(env, pid, total, start); +-} +- +-void os_getCmdlineAndUserInfo(JNIEnv *env, jobject jinfo, pid_t pid) { +- unix_getCmdlineAndUserInfo(env, jinfo, pid); +-} +- +--- old/src/java.base/solaris/native/libjvm_db/libjvm_db.c 2020-05-20 18:10:25.750088494 -0700 ++++ /dev/null 2020-03-09 18:57:19.455001459 -0700 +@@ -1,1552 +0,0 @@ +-/* +- * Copyright (c) 2003, 2018, Oracle and/or its affiliates. All rights reserved. +- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. +- * +- * This code is free software; you can redistribute it and/or modify it +- * under the terms of the GNU General Public License version 2 only, as +- * published by the Free Software Foundation. +- * +- * This code is distributed in the hope that it will be useful, but WITHOUT +- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +- * version 2 for more details (a copy is included in the LICENSE file that +- * accompanied this code). +- * +- * You should have received a copy of the GNU General Public License version +- * 2 along with this work; if not, write to the Free Software Foundation, +- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. +- * +- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA +- * or visit www.oracle.com if you need additional information or have any +- * questions. +- * +- */ +- +-#include +-#include +-#include +-#include +-#include +- +-#include "libjvm_db.h" +-#include "JvmOffsets.h" +- +-#define LIBJVM_SO "libjvm.so" +- +-#if defined(i386) || defined(__i386) || defined(__amd64) +-#ifdef COMPILER2 +-#define X86_COMPILER2 +-#endif /* COMPILER2 */ +-#endif /* i386 */ +- +-typedef struct { +- short vf_cnt; /* number of recognized java vframes */ +- short bci; /* current frame method byte code index */ +- int line; /* current frame method source line */ +- uint64_t new_fp; /* fp for the next frame */ +- uint64_t new_pc; /* pc for the next frame */ +- uint64_t new_sp; /* "raw" sp for the next frame (includes extension by interpreter/adapter */ +- char locinf; /* indicates there is valid location info */ +-} Jframe_t; +- +-int Jlookup_by_regs(jvm_agent_t* J, const prgregset_t regs, char *name, +- size_t size, Jframe_t *jframe); +- +-int main(int arg) { return arg; } +- +-static int debug = 0; +- +-static void failed(int err, const char * file, int line) { +- if (debug) { +- fprintf(stderr, "failed %d at %s:%d\n", err, file, line); +- } +-} +- +-static void warn(const char * file, int line, const char * msg) { +- if (debug) { +- fprintf(stderr, "warning: %s at %s:%d\n", msg, file, line); +- } +-} +- +-static void warn1(const char * file, int line, const char * msg, intptr_t arg1) { +- if (debug) { +- fprintf(stderr, "warning: "); +- fprintf(stderr, msg, arg1); +- fprintf(stderr, " at %s:%d\n", file, line); +- } +-} +- +-#define CHECK_FAIL(err) \ +- if (err != PS_OK) { failed(err, __FILE__, __LINE__); goto fail; } +-#define WARN(msg) warn(__FILE__, __LINE__, msg) +-#define WARN1(msg, arg1) warn1(__FILE__, __LINE__, msg, arg1) +- +-typedef struct VMStructEntry { +- const char * typeName; /* The type name containing the given field (example: "Klass") */ +- const char * fieldName; /* The field name within the type (example: "_name") */ +- uint64_t address; /* Address of field; only used for static fields */ +- /* ("offset" can not be reused because of apparent solstudio compiler bug */ +- /* in generation of initializer data) */ +-} VMStructEntry; +- +-/* Prototyping inlined methods */ +- +-int sprintf(char *s, const char *format, ...); +- +-#define SZ16 sizeof(int16_t) +-#define SZ32 sizeof(int32_t) +- +-#define COMP_METHOD_SIGN '*' +- +-#define MAX_VFRAMES_CNT 256 +- +-typedef struct vframe { +- uint64_t method; +- int32_t sender_decode_offset; +- int32_t methodIdx; +- int32_t bci; +- int32_t line; +-} Vframe_t; +- +-typedef struct frame { +- uintptr_t fp; +- uintptr_t pc; +- uintptr_t sp; +- uintptr_t sender_sp; // The unextended sp of the caller +-} Frame_t; +- +-typedef struct Nmethod_t { +- struct jvm_agent* J; +- Jframe_t *jframe; +- +- uint64_t nm; /* _nmethod */ +- uint64_t pc; +- uint64_t pc_desc; +- +- int32_t orig_pc_offset; /* _orig_pc_offset */ +- uint64_t instrs_beg; /* _code_offset */ +- uint64_t instrs_end; +- uint64_t deopt_beg; /* _deoptimize_offset */ +- uint64_t scopes_data_beg; /* _scopes_data_begin */ +- int32_t scopes_data_end; +- int32_t metadata_beg; /* _metadata_offset */ +- int32_t metadata_end; +- int32_t scopes_pcs_beg; /* _scopes_pcs_offset */ +- int32_t scopes_pcs_end; +- +- int vf_cnt; +- Vframe_t vframes[MAX_VFRAMES_CNT]; +-} Nmethod_t; +- +-struct jvm_agent { +- struct ps_prochandle* P; +- +- uint64_t nmethod_vtbl; +- uint64_t CodeBlob_vtbl; +- uint64_t BufferBlob_vtbl; +- uint64_t RuntimeStub_vtbl; +- uint64_t Method_vtbl; +- +- uint64_t Use_Compressed_Oops_address; +- uint64_t Universe_narrow_oop_base_address; +- uint64_t Universe_narrow_oop_shift_address; +- uint64_t CodeCache_heaps_address; +- +- /* Volatiles */ +- uint8_t Use_Compressed_Oops; +- uint64_t Universe_narrow_oop_base; +- uint32_t Universe_narrow_oop_shift; +- // Code cache heaps +- int32_t Number_of_heaps; +- uint64_t* Heap_low; +- uint64_t* Heap_high; +- uint64_t* Heap_segmap_low; +- uint64_t* Heap_segmap_high; +- +- int32_t SIZE_CodeCache_log2_segment; +- +- uint64_t methodPtr; +- uint64_t bcp; +- +- Nmethod_t *N; /*Inlined methods support */ +- Frame_t prev_fr; +- Frame_t curr_fr; +-}; +- +-static int +-read_string(struct ps_prochandle *P, +- char *buf, /* caller's buffer */ +- size_t size, /* upper limit on bytes to read */ +- uintptr_t addr) /* address in process */ +-{ +- int err = PS_OK; +- while (size-- > 1 && err == PS_OK) { +- err = ps_pread(P, addr, buf, 1); +- if (*buf == '\0') { +- return PS_OK; +- } +- addr += 1; +- buf += 1; +- } +- return -1; +-} +- +-static int read_compressed_pointer(jvm_agent_t* J, uint64_t base, uint32_t *ptr) { +- int err = -1; +- uint32_t ptr32; +- err = ps_pread(J->P, base, &ptr32, sizeof(uint32_t)); +- *ptr = ptr32; +- return err; +-} +- +-static int read_pointer(jvm_agent_t* J, uint64_t base, uint64_t* ptr) { +- int err = -1; +- uint32_t ptr32; +- +- switch (DATA_MODEL) { +- case PR_MODEL_LP64: +- err = ps_pread(J->P, base, ptr, sizeof(uint64_t)); +- break; +- case PR_MODEL_ILP32: +- err = ps_pread(J->P, base, &ptr32, sizeof(uint32_t)); +- *ptr = ptr32; +- break; +- } +- +- return err; +-} +- +-static int read_string_pointer(jvm_agent_t* J, uint64_t base, const char ** stringp) { +- uint64_t ptr; +- int err; +- char buffer[1024]; +- +- *stringp = NULL; +- err = read_pointer(J, base, &ptr); +- CHECK_FAIL(err); +- if (ptr != 0) { +- err = read_string(J->P, buffer, sizeof(buffer), ptr); +- CHECK_FAIL(err); +- *stringp = strdup(buffer); +- } +- return PS_OK; +- +- fail: +- return err; +-} +- +-static int parse_vmstruct_entry(jvm_agent_t* J, uint64_t base, VMStructEntry* vmp) { +- uint64_t ptr; +- int err; +- +- err = read_string_pointer(J, base + OFFSET_VMStructEntrytypeName, &vmp->typeName); +- CHECK_FAIL(err); +- err = read_string_pointer(J, base + OFFSET_VMStructEntryfieldName, &vmp->fieldName); +- CHECK_FAIL(err); +- err = read_pointer(J, base + OFFSET_VMStructEntryaddress, &vmp->address); +- CHECK_FAIL(err); +- +- return PS_OK; +- +- fail: +- if (vmp->typeName != NULL) free((void*)vmp->typeName); +- if (vmp->fieldName != NULL) free((void*)vmp->fieldName); +- return err; +-} +- +-static int parse_vmstructs(jvm_agent_t* J) { +- VMStructEntry vmVar; +- VMStructEntry* vmp = &vmVar; +- uint64_t gHotSpotVMStructs; +- psaddr_t sym_addr; +- uint64_t base; +- int err; +- +- /* Clear *vmp now in case we jump to fail: */ +- memset(vmp, 0, sizeof(VMStructEntry)); +- +- err = ps_pglobal_lookup(J->P, LIBJVM_SO, "gHotSpotVMStructs", &sym_addr); +- CHECK_FAIL(err); +- err = read_pointer(J, sym_addr, &gHotSpotVMStructs); +- CHECK_FAIL(err); +- base = gHotSpotVMStructs; +- +- err = PS_OK; +- while (err == PS_OK) { +- memset(vmp, 0, sizeof(VMStructEntry)); +- err = parse_vmstruct_entry(J, base, vmp); +- if (err != PS_OK || vmp->typeName == NULL) { +- break; +- } +- +- if (vmp->typeName[0] == 'C' && strcmp("CodeCache", vmp->typeName) == 0) { +- /* Read _heaps field of type GrowableArray* */ +- if (strcmp("_heaps", vmp->fieldName) == 0) { +- err = read_pointer(J, vmp->address, &J->CodeCache_heaps_address); +- } +- } else if (vmp->typeName[0] == 'U' && strcmp("Universe", vmp->typeName) == 0) { +- if (strcmp("_narrow_oop._base", vmp->fieldName) == 0) { +- J->Universe_narrow_oop_base_address = vmp->address; +- } +- if (strcmp("_narrow_oop._shift", vmp->fieldName) == 0) { +- J->Universe_narrow_oop_shift_address = vmp->address; +- } +- } +- CHECK_FAIL(err); +- +- base += SIZE_VMStructEntry; +- if (vmp->typeName != NULL) free((void*)vmp->typeName); +- if (vmp->fieldName != NULL) free((void*)vmp->fieldName); +- } +- +- return PS_OK; +- +- fail: +- if (vmp->typeName != NULL) free((void*)vmp->typeName); +- if (vmp->fieldName != NULL) free((void*)vmp->fieldName); +- return -1; +-} +- +-static int find_symbol(jvm_agent_t* J, const char *name, uint64_t* valuep) { +- psaddr_t sym_addr; +- int err; +- +- err = ps_pglobal_lookup(J->P, LIBJVM_SO, name, &sym_addr); +- if (err != PS_OK) goto fail; +- *valuep = sym_addr; +- return PS_OK; +- +- fail: +- return err; +-} +- +-static int read_volatiles(jvm_agent_t* J) { +- int i; +- uint64_t array_data; +- uint64_t code_heap_address; +- int err; +- +- err = find_symbol(J, "UseCompressedOops", &J->Use_Compressed_Oops_address); +- if (err == PS_OK) { +- err = ps_pread(J->P, J->Use_Compressed_Oops_address, &J->Use_Compressed_Oops, sizeof(uint8_t)); +- CHECK_FAIL(err); +- } else { +- J->Use_Compressed_Oops = 0; +- } +- +- err = read_pointer(J, J->Universe_narrow_oop_base_address, &J->Universe_narrow_oop_base); +- CHECK_FAIL(err); +- err = ps_pread(J->P, J->Universe_narrow_oop_shift_address, &J->Universe_narrow_oop_shift, sizeof(uint32_t)); +- CHECK_FAIL(err); +- +- /* CodeCache_heaps_address points to GrowableArray, read _data field +- pointing to the first entry of type CodeCache* in the array */ +- err = read_pointer(J, J->CodeCache_heaps_address + OFFSET_GrowableArray_CodeHeap_data, &array_data); +- /* Read _len field containing the number of code heaps */ +- err = ps_pread(J->P, J->CodeCache_heaps_address + OFFSET_GrowableArray_CodeHeap_len, +- &J->Number_of_heaps, sizeof(J->Number_of_heaps)); +- +- /* Allocate memory for heap configurations */ +- J->Heap_low = (uint64_t*)calloc(J->Number_of_heaps, sizeof(uint64_t)); +- J->Heap_high = (uint64_t*)calloc(J->Number_of_heaps, sizeof(uint64_t)); +- J->Heap_segmap_low = (uint64_t*)calloc(J->Number_of_heaps, sizeof(uint64_t)); +- J->Heap_segmap_high = (uint64_t*)calloc(J->Number_of_heaps, sizeof(uint64_t)); +- +- /* Read code heap configurations */ +- for (i = 0; i < J->Number_of_heaps; ++i) { +- /* Read address of heap */ +- err = read_pointer(J, array_data, &code_heap_address); +- CHECK_FAIL(err); +- +- err = read_pointer(J, code_heap_address + OFFSET_CodeHeap_memory + +- OFFSET_VirtualSpace_low, &J->Heap_low[i]); +- CHECK_FAIL(err); +- err = read_pointer(J, code_heap_address + OFFSET_CodeHeap_memory + +- OFFSET_VirtualSpace_high, &J->Heap_high[i]); +- CHECK_FAIL(err); +- err = read_pointer(J, code_heap_address + OFFSET_CodeHeap_segmap + +- OFFSET_VirtualSpace_low, &J->Heap_segmap_low[i]); +- CHECK_FAIL(err); +- err = read_pointer(J, code_heap_address + OFFSET_CodeHeap_segmap + +- OFFSET_VirtualSpace_high, &J->Heap_segmap_high[i]); +- CHECK_FAIL(err); +- +- /* Increment pointer to next entry */ +- array_data = array_data + POINTER_SIZE; +- } +- +- err = ps_pread(J->P, code_heap_address + OFFSET_CodeHeap_log2_segment_size, +- &J->SIZE_CodeCache_log2_segment, sizeof(J->SIZE_CodeCache_log2_segment)); +- CHECK_FAIL(err); +- +- return PS_OK; +- +- fail: +- return err; +-} +- +-static int codeheap_contains(int heap_num, jvm_agent_t* J, uint64_t ptr) { +- return (J->Heap_low[heap_num] <= ptr && ptr < J->Heap_high[heap_num]); +-} +- +-static int codecache_contains(jvm_agent_t* J, uint64_t ptr) { +- int i; +- for (i = 0; i < J->Number_of_heaps; ++i) { +- if (codeheap_contains(i, J, ptr)) { +- return 1; +- } +- } +- return 0; +-} +- +-static uint64_t segment_for(int heap_num, jvm_agent_t* J, uint64_t p) { +- return (p - J->Heap_low[heap_num]) >> J->SIZE_CodeCache_log2_segment; +-} +- +-static uint64_t block_at(int heap_num, jvm_agent_t* J, int i) { +- return J->Heap_low[heap_num] + (i << J->SIZE_CodeCache_log2_segment); +-} +- +-static int find_start(jvm_agent_t* J, uint64_t ptr, uint64_t *startp) { +- int err; +- int i; +- +- for (i = 0; i < J->Number_of_heaps; ++i) { +- *startp = 0; +- if (codeheap_contains(i, J, ptr)) { +- int32_t used; +- uint64_t segment = segment_for(i, J, ptr); +- uint64_t block = J->Heap_segmap_low[i]; +- uint8_t tag; +- err = ps_pread(J->P, block + segment, &tag, sizeof(tag)); +- CHECK_FAIL(err); +- if (tag == 0xff) +- return PS_OK; +- while (tag > 0) { +- err = ps_pread(J->P, block + segment, &tag, sizeof(tag)); +- CHECK_FAIL(err); +- segment -= tag; +- } +- block = block_at(i, J, segment); +- err = ps_pread(J->P, block + OFFSET_HeapBlockHeader_used, &used, sizeof(used)); +- CHECK_FAIL(err); +- if (used) { +- *startp = block + SIZE_HeapBlockHeader; +- } +- } +- return PS_OK; +- } +- +- fail: +- return -1; +-} +- +-static int find_jlong_constant(jvm_agent_t* J, const char *name, uint64_t* valuep) { +- psaddr_t sym_addr; +- int err = ps_pglobal_lookup(J->P, LIBJVM_SO, name, &sym_addr); +- if (err == PS_OK) { +- err = ps_pread(J->P, sym_addr, valuep, sizeof(uint64_t)); +- return err; +- } +- *valuep = -1; +- return -1; +-} +- +-jvm_agent_t *Jagent_create(struct ps_prochandle *P, int vers) { +- jvm_agent_t* J; +- int err; +- +- if (vers != JVM_DB_VERSION) { +- errno = ENOTSUP; +- return NULL; +- } +- +- J = (jvm_agent_t*)calloc(sizeof(struct jvm_agent), 1); +- +- debug = getenv("LIBJVMDB_DEBUG") != NULL; +- if (debug) debug = 3; +- +- if (debug) { +- fprintf(stderr, "Jagent_create: debug=%d\n", debug); +-#ifdef X86_COMPILER2 +- fprintf(stderr, "Jagent_create: R_SP=%d, R_FP=%d, POINTER_SIZE=%d\n", R_SP, R_FP, POINTER_SIZE); +-#endif /* X86_COMPILER2 */ +- } +- +- J->P = P; +- +- // Initialize the initial previous frame +- +- J->prev_fr.fp = 0; +- J->prev_fr.pc = 0; +- J->prev_fr.sp = 0; +- J->prev_fr.sender_sp = 0; +- +- err = find_symbol(J, "__1cHnmethodG__vtbl_", &J->nmethod_vtbl); +- CHECK_FAIL(err); +- err = find_symbol(J, "__1cKBufferBlobG__vtbl_", &J->BufferBlob_vtbl); +- if (err != PS_OK) J->BufferBlob_vtbl = 0; +- err = find_symbol(J, "__1cICodeBlobG__vtbl_", &J->CodeBlob_vtbl); +- CHECK_FAIL(err); +- err = find_symbol(J, "__1cLRuntimeStubG__vtbl_", &J->RuntimeStub_vtbl); +- CHECK_FAIL(err); +- err = find_symbol(J, "__1cGMethodG__vtbl_", &J->Method_vtbl); +- CHECK_FAIL(err); +- +- err = parse_vmstructs(J); +- CHECK_FAIL(err); +- err = read_volatiles(J); +- CHECK_FAIL(err); +- +- return J; +- +- fail: +- Jagent_destroy(J); +- return NULL; +-} +- +-void Jagent_destroy(jvm_agent_t *J) { +- if (J != NULL) { +- free(J); +- } +-} +- +-static int is_method(jvm_agent_t* J, uint64_t methodPtr) { +- uint64_t klass; +- int err = read_pointer(J, methodPtr, &klass); +- if (err != PS_OK) goto fail; +- return klass == J->Method_vtbl; +- +- fail: +- return 0; +-} +- +-static int +-name_for_methodPtr(jvm_agent_t* J, uint64_t methodPtr, char * result, size_t size) +-{ +- short nameIndex; +- short signatureIndex; +- uint64_t constantPool; +- uint64_t constMethod; +- uint64_t nameSymbol; +- uint64_t signatureSymbol; +- uint64_t klassPtr; +- uint64_t klassSymbol; +- short klassSymbolLength; +- short nameSymbolLength; +- short signatureSymbolLength; +- char * nameString = NULL; +- char * klassString = NULL; +- char * signatureString = NULL; +- int err; +- +- err = read_pointer(J, methodPtr + OFFSET_Method_constMethod, &constMethod); +- CHECK_FAIL(err); +- err = read_pointer(J, constMethod + OFFSET_ConstMethod_constants, &constantPool); +- CHECK_FAIL(err); +- +- /* To get name string */ +- err = ps_pread(J->P, constMethod + OFFSET_ConstMethod_name_index, &nameIndex, 2); +- CHECK_FAIL(err); +- err = read_pointer(J, constantPool + nameIndex * POINTER_SIZE + SIZE_ConstantPool, &nameSymbol); +- CHECK_FAIL(err); +- // The symbol is a CPSlot and has lower bit set to indicate metadata +- nameSymbol &= (~1); // remove metadata lsb +- err = ps_pread(J->P, nameSymbol + OFFSET_Symbol_length, &nameSymbolLength, 2); +- CHECK_FAIL(err); +- nameString = (char*)calloc(nameSymbolLength + 1, 1); +- err = ps_pread(J->P, nameSymbol + OFFSET_Symbol_body, nameString, nameSymbolLength); +- CHECK_FAIL(err); +- +- /* To get signature string */ +- err = ps_pread(J->P, constMethod + OFFSET_ConstMethod_signature_index, &signatureIndex, 2); +- CHECK_FAIL(err); +- err = read_pointer(J, constantPool + signatureIndex * POINTER_SIZE + SIZE_ConstantPool, &signatureSymbol); +- CHECK_FAIL(err); +- signatureSymbol &= (~1); // remove metadata lsb +- err = ps_pread(J->P, signatureSymbol + OFFSET_Symbol_length, &signatureSymbolLength, 2); +- CHECK_FAIL(err); +- signatureString = (char*)calloc(signatureSymbolLength + 1, 1); +- err = ps_pread(J->P, signatureSymbol + OFFSET_Symbol_body, signatureString, signatureSymbolLength); +- CHECK_FAIL(err); +- +- /* To get klass string */ +- err = read_pointer(J, constantPool + OFFSET_ConstantPool_pool_holder, &klassPtr); +- CHECK_FAIL(err); +- err = read_pointer(J, klassPtr + OFFSET_Klass_name, &klassSymbol); +- CHECK_FAIL(err); +- err = ps_pread(J->P, klassSymbol + OFFSET_Symbol_length, &klassSymbolLength, 2); +- CHECK_FAIL(err); +- klassString = (char*)calloc(klassSymbolLength + 1, 1); +- err = ps_pread(J->P, klassSymbol + OFFSET_Symbol_body, klassString, klassSymbolLength); +- CHECK_FAIL(err); +- +- result[0] = '\0'; +- if (snprintf(result, size, +- "%s.%s%s", +- klassString, +- nameString, +- signatureString) >= size) { +- // truncation +- goto fail; +- } +- +- if (nameString != NULL) free(nameString); +- if (klassString != NULL) free(klassString); +- if (signatureString != NULL) free(signatureString); +- +- return PS_OK; +- +- fail: +- if (debug) { +- fprintf(stderr, "name_for_methodPtr: FAIL \n\n"); +- } +- if (nameString != NULL) free(nameString); +- if (klassString != NULL) free(klassString); +- if (signatureString != NULL) free(signatureString); +- return -1; +-} +- +-static int nmethod_info(Nmethod_t *N) +-{ +- jvm_agent_t *J = N->J; +- uint64_t nm = N->nm; +- int32_t err; +- +- if (debug > 2 ) +- fprintf(stderr, "\t nmethod_info: BEGIN \n"); +- +- /* Instructions */ +- err = read_pointer(J, nm + OFFSET_CodeBlob_code_begin, &N->instrs_beg); +- CHECK_FAIL(err); +- err = read_pointer(J, nm + OFFSET_CodeBlob_code_end, &N->instrs_end); +- CHECK_FAIL(err); +- err = read_pointer(J, nm + OFFSET_nmethod_deopt_handler_begin, &N->deopt_beg); +- CHECK_FAIL(err); +- err = ps_pread(J->P, nm + OFFSET_nmethod_orig_pc_offset, &N->orig_pc_offset, SZ32); +- CHECK_FAIL(err); +- +- /* Metadata */ +- err = ps_pread(J->P, nm + OFFSET_nmethod_metadata_offset, &N->metadata_beg, SZ32); +- CHECK_FAIL(err); +- err = ps_pread(J->P, nm + OFFSET_nmethod_scopes_data_begin, &N->metadata_end, SZ32); +- CHECK_FAIL(err); +- +- /* scopes_pcs */ +- err = ps_pread(J->P, nm + OFFSET_nmethod_scopes_pcs_offset, &N->scopes_pcs_beg, SZ32); +- CHECK_FAIL(err); +- err = ps_pread(J->P, nm + OFFSET_nmethod_dependencies_offset, &N->scopes_pcs_end, SZ32); +- CHECK_FAIL(err); +- +- /* scopes_data */ +- err = ps_pread(J->P, nm + OFFSET_nmethod_scopes_data_begin, &N->scopes_data_beg, POINTER_SIZE); +- CHECK_FAIL(err); +- +- if (debug > 2 ) { +- N->scopes_data_end = N->scopes_pcs_beg; +- +- fprintf(stderr, "\t nmethod_info: instrs_beg: %#x, instrs_end: %#x\n", +- N->instrs_beg, N->instrs_end); +- +- fprintf(stderr, "\t nmethod_info: deopt_beg: %#x \n", +- N->deopt_beg); +- +- fprintf(stderr, "\t nmethod_info: orig_pc_offset: %#x \n", +- N->orig_pc_offset); +- +- fprintf(stderr, "\t nmethod_info: metadata_beg: %#x, metadata_end: %#x\n", +- N->metadata_beg, N->metadata_end); +- +- fprintf(stderr, "\t nmethod_info: scopes_data_beg: %#x, scopes_data_end: %#x\n", +- N->scopes_data_beg, N->scopes_data_end); +- +- fprintf(stderr, "\t nmethod_info: scopes_pcs_beg: %#x, scopes_pcs_end: %#x\n", +- N->scopes_pcs_beg, N->scopes_pcs_end); +- +- fprintf(stderr, "\t nmethod_info: END \n\n"); +- } +- return PS_OK; +- +- fail: +- return err; +-} +- +-static int +-raw_read_int(jvm_agent_t* J, uint64_t *buffer, int32_t *val) +-{ +- int shift = 0; +- int value = 0; +- uint8_t ch = 0; +- int32_t err; +- int32_t sum; +- // Constants for UNSIGNED5 coding of Pack200 +- // see compressedStream.hpp +- enum { +- lg_H = 6, +- H = 1<P, (*buffer)++, &ch, sizeof(uint8_t)); +- CHECK_FAIL(err); +- if (debug > 2) +- fprintf(stderr, "\t\t\t raw_read_int: *buffer: %#llx, ch: %#x\n", *buffer, ch); +- +- sum = ch; +- if ( sum >= L ) { +- int32_t lg_H_i = lg_H; +- // Read maximum of 5 total bytes (we've already read 1). +- // See CompressedReadStream::read_int_mb +- for ( i = 0; i < 4; i++) { +- err = ps_pread(J->P, (*buffer)++, &ch, sizeof(uint8_t)); +- CHECK_FAIL(err); +- sum += ch << lg_H_i; +- if (ch < L ) { +- *val = sum; +- return PS_OK; +- } +- lg_H_i += lg_H; +- } +- } +- *val = sum; +- return PS_OK; +- +- fail: +- return err; +-} +- +-static int +-read_pair(jvm_agent_t* J, uint64_t *buffer, int32_t *bci, int32_t *line) +-{ +- uint8_t next = 0; +- int32_t bci_delta; +- int32_t line_delta; +- int32_t err; +- +- if (debug > 2) +- fprintf(stderr, "\t\t read_pair: BEGIN\n"); +- +- err = ps_pread(J->P, (*buffer)++, &next, sizeof(uint8_t)); +- CHECK_FAIL(err); +- +- if (next == 0) { +- if (debug > 2) +- fprintf(stderr, "\t\t read_pair: END: next == 0\n"); +- return 1; /* stream terminated */ +- } +- if (next == 0xFF) { +- if (debug > 2) +- fprintf(stderr, "\t\t read_pair: END: next == 0xFF\n"); +- +- /* Escape character, regular compression used */ +- +- err = raw_read_int(J, buffer, &bci_delta); +- CHECK_FAIL(err); +- +- err = raw_read_int(J, buffer, &line_delta); +- CHECK_FAIL(err); +- +- *bci += bci_delta; +- *line += line_delta; +- +- if (debug > 2) { +- fprintf(stderr, "\t\t read_pair: delta = (line %d: %d)\n", +- line_delta, bci_delta); +- fprintf(stderr, "\t\t read_pair: unpack= (line %d: %d)\n", +- *line, *bci); +- } +- } else { +- /* Single byte compression used */ +- *bci += next >> 3; +- *line += next & 0x7; +- if (debug > 2) { +- fprintf(stderr, "\t\t read_pair: delta = (line %d: %d)\n", +- next & 0x7, next >> 3); +- fprintf(stderr, "\t\t read_pair: unpack= (line %d: %d)\n", +- *line, *bci); +- } +- } +- if (debug > 2) +- fprintf(stderr, "\t\t read_pair: END\n"); +- return PS_OK; +- +- fail: +- if (debug) +- fprintf(stderr, "\t\t read_pair: FAIL\n"); +- return err; +-} +- +-static int +-line_number_from_bci(jvm_agent_t* J, Vframe_t *vf) +-{ +- uint64_t buffer; +- uint16_t code_size; +- uint64_t code_end_delta; +- uint64_t constMethod; +- int8_t access_flags; +- int32_t best_bci = 0; +- int32_t stream_bci = 0; +- int32_t stream_line = 0; +- int32_t err; +- +- if (debug > 2) { +- char name[256]; +- err = name_for_methodPtr(J, vf->method, name, 256); +- CHECK_FAIL(err); +- fprintf(stderr, "\t line_number_from_bci: BEGIN, method name: %s, targ bci: %d\n", +- name, vf->bci); +- } +- +- err = read_pointer(J, vf->method + OFFSET_Method_constMethod, &constMethod); +- CHECK_FAIL(err); +- +- vf->line = 0; +- err = ps_pread(J->P, constMethod + OFFSET_ConstMethod_flags, &access_flags, sizeof(int8_t)); +- CHECK_FAIL(err); +- +- if (!(access_flags & ConstMethod_has_linenumber_table)) { +- if (debug > 2) +- fprintf(stderr, "\t line_number_from_bci: END: !HAS_LINE_NUMBER_TABLE \n\n"); +- return PS_OK; +- } +- +- /* The line numbers are a short array of 2-tuples [start_pc, line_number]. +- * Not necessarily sorted and not necessarily one-to-one. +- */ +- +- err = ps_pread(J->P, constMethod + OFFSET_ConstMethod_code_size, &code_size, SZ16); +- CHECK_FAIL(err); +- +- /* inlined_table_start() */ +- code_end_delta = (uint64_t) (access_flags & AccessFlags_NATIVE) ? 2*POINTER_SIZE : 0; +- buffer = constMethod + (uint64_t) SIZE_ConstMethod + (uint64_t) code_size + code_end_delta; +- +- if (debug > 2) { +- fprintf(stderr, "\t\t line_number_from_bci: method: %#llx, native: %d\n", +- vf->method, (access_flags & AccessFlags_NATIVE)); +- fprintf(stderr, "\t\t line_number_from_bci: buffer: %#llx, code_size: %d\n", +- buffer, (int) code_size); +- } +- +- while (read_pair(J, &buffer, &stream_bci, &stream_line) == 0) { +- if (stream_bci == vf->bci) { +- /* perfect match */ +- if (debug > 2) +- fprintf(stderr, "\t line_number_from_bci: END: exact line: %d \n\n", vf->line); +- vf->line = stream_line; +- return PS_OK; +- } else { +- /* update best_bci/line */ +- if (stream_bci < vf->bci && stream_bci >= best_bci) { +- best_bci = stream_bci; +- vf->line = stream_line; +- if (debug > 2) { +- fprintf(stderr, "\t line_number_from_bci: best_bci: %d, best_line: %d\n", +- best_bci, vf->line); +- } +- } +- } +- } +- if (debug > 2) +- fprintf(stderr, "\t line_number_from_bci: END: line: %d \n\n", vf->line); +- return PS_OK; +- +- fail: +- if (debug) +- fprintf(stderr, "\t line_number_from_bci: FAIL\n"); +- return err; +-} +- +-static int +-get_real_pc(Nmethod_t *N, uint64_t pc_desc, uint64_t *real_pc) +-{ +- int32_t pc_offset; +- int32_t err; +- +- err = ps_pread(N->J->P, pc_desc + OFFSET_PcDesc_pc_offset, &pc_offset, SZ32); +- CHECK_FAIL(err); +- +- *real_pc = N->instrs_beg + pc_offset; +- if (debug > 2) { +- fprintf(stderr, "\t\t get_real_pc: pc_offset: %lx, real_pc: %llx\n", +- pc_offset, *real_pc); +- } +- return PS_OK; +- +- fail: +- return err; +-} +- +-/* Finds a PcDesc with real-pc equal to N->pc */ +-static int pc_desc_at(Nmethod_t *N) +-{ +- uint64_t pc_diff = 999; +- int32_t offs; +- int32_t err; +- +- if (debug > 2) +- fprintf(stderr, "\t pc_desc_at: BEGIN\n"); +- +- N->vf_cnt = 0; +- N->pc_desc = 0; +- +- for (offs = N->scopes_pcs_beg; offs < N->scopes_pcs_end; offs += SIZE_PcDesc) { +- uint64_t pd; +- uint64_t best_pc_diff = 16; /* some approximation */ +- uint64_t real_pc = 0; +- +- pd = N->nm + offs; +- err = get_real_pc(N, pd, &real_pc); +- CHECK_FAIL(err); +- +- pc_diff = real_pc - N->pc; +- +- /* In general, this fragment should work */ +- if (pc_diff == 0) { +- N->pc_desc = pd; +- if (debug) { +- fprintf(stderr, "\t pc_desc_at: END: pc_desc: FOUND: %#lx \n\n", pd); +- } +- return PS_OK; +- } +- /* This fragment is to be able to find out an appropriate +- * pc_desc entry even if pc_desc info is inaccurate. +- */ +- if (best_pc_diff > pc_diff && pc_diff > 0) { +- best_pc_diff = pc_diff; +- N->pc_desc = pd; +- } +- } +- if (debug) { +- fprintf(stderr, "\t pc_desc_at: END: pc_desc NOT FOUND"); +- if (pc_diff < 20) +- fprintf(stderr, ", best pc_diff: %d\n\n", pc_diff); +- else +- fprintf(stderr, "\n\n"); +- } +- return PS_OK; +- +- fail: +- return err; +-} +- +-static int +-scope_desc_at(Nmethod_t *N, int32_t decode_offset, Vframe_t *vf) +-{ +- uint64_t buffer; +- int32_t err; +- +- if (debug > 2) { +- fprintf(stderr, "\t\t scope_desc_at: BEGIN \n"); +- } +- +- buffer = N->scopes_data_beg + decode_offset; +- +- err = raw_read_int(N->J, &buffer, &vf->sender_decode_offset); +- CHECK_FAIL(err); +- +- err = raw_read_int(N->J, &buffer, &vf->methodIdx); +- CHECK_FAIL(err); +- +- err = raw_read_int(N->J, &buffer, &vf->bci); +- CHECK_FAIL(err); +- +- if (debug > 2) { +- fprintf(stderr, "\t\t scope_desc_at: sender_decode_offset: %#x\n", +- vf->sender_decode_offset); +- fprintf(stderr, "\t\t scope_desc_at: methodIdx: %d\n", vf->methodIdx); +- fprintf(stderr, "\t\t scope_desc_at: bci: %d\n", vf->bci); +- +- fprintf(stderr, "\t\t scope_desc_at: END \n\n"); +- } +- return PS_OK; +- +- fail: +- return err; +-} +- +-static int scopeDesc_chain(Nmethod_t *N) { +- int32_t decode_offset = 0; +- int32_t err; +- +- if (debug > 2) { +- fprintf(stderr, "\t scopeDesc_chain: BEGIN\n"); +- } +- +- err = ps_pread(N->J->P, N->pc_desc + OFFSET_PcDesc_scope_decode_offset, +- &decode_offset, SZ32); +- CHECK_FAIL(err); +- +- while (decode_offset > 0) { +- Vframe_t *vf = &N->vframes[N->vf_cnt]; +- +- if (debug > 2) { +- fprintf(stderr, "\t scopeDesc_chain: decode_offset: %#x\n", decode_offset); +- } +- +- err = scope_desc_at(N, decode_offset, vf); +- CHECK_FAIL(err); +- +- if (vf->methodIdx > ((N->metadata_end - N->metadata_beg) / POINTER_SIZE)) { +- fprintf(stderr, "\t scopeDesc_chain: (methodIdx > metadata length) !\n"); +- return -1; +- } +- err = read_pointer(N->J, N->nm + N->metadata_beg + (vf->methodIdx-1)*POINTER_SIZE, +- &vf->method); +- CHECK_FAIL(err); +- +- if (vf->method) { +- N->vf_cnt++; +- err = line_number_from_bci(N->J, vf); +- CHECK_FAIL(err); +- if (debug > 2) { +- fprintf(stderr, "\t scopeDesc_chain: method: %#8llx, line: %d\n", +- vf->method, vf->line); +- } +- } +- decode_offset = vf->sender_decode_offset; +- } +- if (debug > 2) { +- fprintf(stderr, "\t scopeDesc_chain: END \n\n"); +- } +- return PS_OK; +- +- fail: +- if (debug) { +- fprintf(stderr, "\t scopeDesc_chain: FAIL \n\n"); +- } +- return err; +-} +- +- +-static int +-name_for_nmethod(jvm_agent_t* J, +- uint64_t nm, +- uint64_t pc, +- uint64_t method, +- char *result, +- size_t size, +- Jframe_t *jframe +-) { +- Nmethod_t *N; +- Vframe_t *vf; +- int32_t err; +- int deoptimized = 0; +- +- if (debug) { +- fprintf(stderr, "name_for_nmethod: BEGIN: nmethod: %#llx, pc: %#llx\n", nm, pc); +- } +- if (J->N == NULL) { +- J->N = (Nmethod_t *) malloc(sizeof(Nmethod_t)); +- } +- memset(J->N, 0, sizeof(Nmethod_t)); /* Initial stat: all values are zeros */ +- N = J->N; +- N->J = J; +- N->nm = nm; +- N->pc = pc; +- N->jframe = jframe; +- +- err = nmethod_info(N); +- CHECK_FAIL(err); +- if (debug) { +- fprintf(stderr, "name_for_nmethod: pc: %#llx, deopt_pc: %#llx\n", +- pc, N->deopt_beg); +- } +- +- /* check for a deoptimized frame */ +- if ( pc == N->deopt_beg) { +- uint64_t base; +- if (debug) { +- fprintf(stderr, "name_for_nmethod: found deoptimized frame\n"); +- } +- if (J->prev_fr.sender_sp != 0) { +- base = J->prev_fr.sender_sp + N->orig_pc_offset; +- } else { +- base = J->curr_fr.sp + N->orig_pc_offset; +- } +- err = read_pointer(J, base, &N->pc); +- CHECK_FAIL(err); +- if (debug) { +- fprintf(stderr, "name_for_nmethod: found deoptimized frame converting pc from %#8llx to %#8llx\n", +- pc, N->pc); +- } +- deoptimized = 1; +- } +- +- err = pc_desc_at(N); +- CHECK_FAIL(err); +- +- if (N->pc_desc > 0) { +- jframe->locinf = 1; +- err = scopeDesc_chain(N); +- CHECK_FAIL(err); +- } +- result[0] = COMP_METHOD_SIGN; +- vf = &N->vframes[0]; +- if (N->vf_cnt > 0) { +- jframe->vf_cnt = N->vf_cnt; +- jframe->bci = vf->bci; +- jframe->line = vf->line; +- err = name_for_methodPtr(J, N->vframes[0].method, result+1, size-1); +- CHECK_FAIL(err); +- } else { +- err = name_for_methodPtr(J, method, result+1, size-1); +- CHECK_FAIL(err); +- } +- if (deoptimized) { +- strncat(result, " [deoptimized frame]; ", size - strlen(result) - 1); +- } else { +- strncat(result, " [compiled] ", size - strlen(result) - 1); +- } +- if (debug) +- fprintf(stderr, "name_for_nmethod: END: method name: %s, vf_cnt: %d\n\n", +- result, N->vf_cnt); +- return PS_OK; +- +- fail: +- if (debug) +- fprintf(stderr, "name_for_nmethod: FAIL \n\n"); +- return err; +-} +- +-static int +-name_for_imethod(jvm_agent_t* J, +- uint64_t bcp, +- uint64_t method, +- char *result, +- size_t size, +- Jframe_t *jframe +-) { +- uint64_t bci; +- uint64_t constMethod; +- Vframe_t vframe = {0}; +- Vframe_t *vf = &vframe; +- int32_t err; +- +- err = read_pointer(J, method + OFFSET_Method_constMethod, &constMethod); +- CHECK_FAIL(err); +- +- bci = bcp - (constMethod + (uint64_t) SIZE_ConstMethod); +- +- if (debug) +- fprintf(stderr, "\t name_for_imethod: BEGIN: method: %#llx\n", method); +- +- err = name_for_methodPtr(J, method, result, size); +- CHECK_FAIL(err); +- if (debug) +- fprintf(stderr, "\t name_for_imethod: method name: %s\n", result); +- +- if (bci > 0) { +- vf->method = method; +- vf->bci = bci; +- err = line_number_from_bci(J, vf); +- CHECK_FAIL(err); +- } +- jframe->bci = vf->bci; +- jframe->line = vf->line; +- jframe->locinf = 1; +- +- if (debug) { +- fprintf(stderr, "\t name_for_imethod: END: bci: %d, line: %d\n\n", +- vf->bci, vf->line); +- } +- return PS_OK; +- +- fail: +- if (debug) +- fprintf(stderr, "\t name_for_imethod: FAIL\n"); +- return err; +-} +- +-static int +-name_for_codecache(jvm_agent_t* J, uint64_t fp, uint64_t pc, char * result, +- size_t size, Jframe_t *jframe, int* is_interpreted) +-{ +- uint64_t start; +- uint64_t vtbl; +- int32_t err; +- *is_interpreted = 0; +- +- result[0] = '\0'; +- +- err = find_start(J, pc, &start); +- CHECK_FAIL(err); +- +- err = read_pointer(J, start, &vtbl); +- CHECK_FAIL(err); +- +- if (vtbl == J->nmethod_vtbl) { +- uint64_t method; +- +- err = read_pointer(J, start + OFFSET_nmethod_method, &method); +- CHECK_FAIL(err); +- +- if (debug) { +- fprintf(stderr, "name_for_codecache: start: %#8llx, pc: %#8llx, method: %#8llx \n", +- start, pc, method); +- } +- err = name_for_nmethod(J, start, pc, method, result, size, jframe); +- CHECK_FAIL(err); +- } else if (vtbl == J->BufferBlob_vtbl) { +- const char * name; +- +- err = read_string_pointer(J, start + OFFSET_CodeBlob_name, &name); +- +- /* +- * Temporary usage of string "Interpreter". +- * We need some other way to distinguish "StubRoutines" +- * and regular interpreted frames. +- */ +- if (err == PS_OK && strncmp(name, "Interpreter", 11) == 0) { +- *is_interpreted = 1; +- if (is_method(J, J->methodPtr)) { +- return name_for_imethod(J, J->bcp, J->methodPtr, result, size, jframe); +- } +- } +- +- if (err == PS_OK) { +- strncpy(result, name, size); +- free((void*)name); +- } else { +- strncpy(result, "", size); +- } +- /* return PS_OK; */ +- } else { +- const char * name; +- +- err = read_string_pointer(J, start + OFFSET_CodeBlob_name, &name); +- if (err == PS_OK) { +- strncpy(result, name, size); +- free((void*)name); +- } else { +- strncpy(result, "", size); +- WARN1("unknown CodeBlob: vtbl = 0x%x", vtbl); +- } +- } +- result[size-1] = '\0'; +- +-#ifdef X86_COMPILER2 +- if (vtbl != J->RuntimeStub_vtbl) { +- uint64_t trial_pc; +- int frame_size; +- err = ps_pread(J->P, start + OFFSET_CodeBlob_frame_size, +- &frame_size, SZ32); +- CHECK_FAIL(err); +- +- // frame_size is in words, we want bytes. +- frame_size *= POINTER_SIZE; /* word => byte conversion */ +- +- /* +- Because c2 doesn't use FP as a framepointer the value of sp/fp we receive +- in the initial entry to a set of stack frames containing server frames +- will pretty much be nonsense. We can detect that nonsense by looking to +- see if the PC we received is correct if we look at the expected storage +- location in relation to the FP (ie. POINTER_SIZE(FP) ) +- */ +- +- err = read_pointer(J, fp + POINTER_SIZE , &trial_pc); +- if ( (err != PS_OK || trial_pc != pc) && frame_size > 0 ) { +- // Either we couldn't even read at the "fp" or the pc didn't match +- // both are sure clues that the fp is bogus. We no search the stack +- // for a reasonable number of words trying to find the bogus fp +- // and the current pc in adjacent words. The we will be able to +- // deduce an approximation of the frame pointer and actually get +- // the correct stack pointer. Which we can then unwind for the +- // next frame. +- int i; +- uint64_t check; +- uint64_t base = J->curr_fr.sp; +- uint64_t prev_fp = 0; +- for ( i = 0; i < frame_size * 5 ; i++, base += POINTER_SIZE ) { +- err = read_pointer(J, base , &check); +- CHECK_FAIL(err); +- if (check == fp) { +- base += POINTER_SIZE; +- err = read_pointer(J, base , &check); +- CHECK_FAIL(err); +- if (check == pc) { +- if (debug) { +- fprintf(stderr, "name_for_codecache: found matching fp/pc combo at 0x%llx\n", base - POINTER_SIZE); +- } +- prev_fp = base - 2 * POINTER_SIZE; +- break; +- } +- } +- } +- if ( prev_fp != 0 ) { +- // real_sp is the sp we should have received for this frame +- uint64_t real_sp = prev_fp + 2 * POINTER_SIZE; +- // +POINTER_SIZE because callee owns the return address so caller's sp is +1 word +- jframe->new_sp = real_sp + frame_size + POINTER_SIZE; +- err = read_pointer(J, jframe->new_sp - POINTER_SIZE , &jframe->new_pc); +- CHECK_FAIL(err); +- err = read_pointer(J, jframe->new_sp - 2*POINTER_SIZE, &jframe->new_fp); +- CHECK_FAIL(err); +- return PS_OK; +- } +- } +- +- /* A prototype to workaround FP absence */ +- /* +- * frame_size can be 0 for StubRoutines (1) frame. +- * In this case it should work with fp as usual. +- */ +- if (frame_size > 0) { +- jframe->new_fp = J->prev_fr.fp + frame_size; +- jframe->new_sp = jframe->new_fp + 2 * POINTER_SIZE; +- } else { +- memset(&J->curr_fr, 0, sizeof(Frame_t)); +- err = read_pointer(J, fp, &jframe->new_fp); +- CHECK_FAIL(err); +- +- err = read_pointer(J, jframe->new_fp + POINTER_SIZE, &jframe->new_pc); +- CHECK_FAIL(err); +- } +- if (debug) { +- fprintf(stderr, "name_for_codecache: %s, frame_size=%#lx\n", +- result, frame_size); +- fprintf(stderr, "name_for_codecache: prev_fr.fp=%#lx, fp=%#lx\n", +- J->prev_fr.fp, jframe->new_fp); +- } +- } +-#endif /* X86_COMPILER2 */ +- +- return PS_OK; +- +- fail: +- return err; +-} +- +-int Jget_vframe(jvm_agent_t* J, int vframe_no, +- char *name, size_t size, Jframe_t *jframe) +-{ +- Nmethod_t *N = J->N; +- Vframe_t *vf; +- int32_t err; +- +- if (vframe_no >= N->vf_cnt) { +- (void) sprintf(name, "Wrong inlinedMethod%1d()", vframe_no); +- return -1; +- } +- vf = N->vframes + vframe_no; +- name[0] = COMP_METHOD_SIGN; +- err = name_for_methodPtr(J, vf->method, name + 1, size); +- CHECK_FAIL(err); +- +- jframe->bci = vf->bci; +- jframe->line = vf->line; +- if (debug) { +- fprintf(stderr, "\t Jget_vframe: method name: %s, line: %d\n", +- name, vf->line); +- } +- return PS_OK; +- +- fail: +- if (debug) { +- fprintf(stderr, "\t Jget_vframe: FAIL\n"); +- } +- return err; +-} +- +-#define MAX_SYM_SIZE 256 +- +-int Jlookup_by_regs(jvm_agent_t* J, const prgregset_t regs, char *name, +- size_t size, Jframe_t *jframe) { +- uintptr_t fp; +- uintptr_t pc; +- /* arguments given to read_pointer need to be worst case sized */ +- uint64_t methodPtr = 0; +- uint64_t sender_sp; +- uint64_t bcp = 0; +- int is_interpreted = 0; +- int result = PS_OK; +- int err = PS_OK; +- +- if (J == NULL) { +- return -1; +- } +- +- jframe->vf_cnt = 1; +- jframe->new_fp = 0; +- jframe->new_pc = 0; +- jframe->line = 0; +- jframe->bci = 0; +- jframe->locinf = 0; +- +- read_volatiles(J); +- pc = (uintptr_t) regs[R_PC]; +- J->curr_fr.pc = pc; +- J->curr_fr.fp = regs[R_FP]; +- J->curr_fr.sp = regs[R_SP]; +- +- if (debug) +- fprintf(stderr, "Jlookup_by_regs: BEGINs: fp=%#lx, pc=%#lx\n", regs[R_FP], pc); +- +-#if defined(i386) || defined(__i386) || defined(__amd64) +- +- fp = (uintptr_t) regs[R_FP]; +- if (J->prev_fr.fp == 0) { +-#ifdef X86_COMPILER2 +- /* A workaround for top java frames */ +- J->prev_fr.fp = (uintptr_t)(regs[R_SP] - 2 * POINTER_SIZE); +-#else +- J->prev_fr.fp = (uintptr_t)(regs[R_SP] - POINTER_SIZE); +-#endif /* COMPILER2 */ +- } +- if (debug > 2) { +- printf("Jlookup_by_regs: J->prev_fr.fp = %#lx\n", J->prev_fr.fp); +- } +- +- if (read_pointer(J, fp + OFFSET_interpreter_frame_method, &methodPtr) != PS_OK) { +- methodPtr = 0; +- } +- if (read_pointer(J, fp + OFFSET_interpreter_frame_sender_sp, &sender_sp) != PS_OK) { +- sender_sp = 0; +- } +- if (read_pointer(J, fp + OFFSET_interpreter_frame_bcp_offset, &bcp) != PS_OK) { +- bcp = 0; +- } +-#endif /* i386 */ +- +- J->methodPtr = methodPtr; +- J->bcp = bcp; +- +- /* On x86 with C2 JVM: native frame may have wrong regs[R_FP] +- * For example: JVM_SuspendThread frame points to the top interpreted frame. +- * If we call is_method(J, methodPtr) before codecache_contains(J, pc) +- * then we go over and omit both: nmethod and I2CAdapter frames. +- * Note, that regs[R_PC] is always correct if frame defined correctly. +- * So it is better to call codecache_contains(J, pc) from the beginning. +- */ +-#ifndef X86_COMPILER2 +- if (is_method(J, J->methodPtr)) { +- result = name_for_imethod(J, bcp, J->methodPtr, name, size, jframe); +- /* If the methodPtr is a method then this is highly likely to be +- an interpreter frame */ +- if (result >= 0) { +- is_interpreted = 1; +- } +- } else +-#endif /* ! X86_COMPILER2 */ +- +- if (codecache_contains(J, pc)) { +- result = name_for_codecache(J, fp, pc, name, size, jframe, &is_interpreted); +- } +-#ifdef X86_COMPILER2 +- else if (is_method(J, J->methodPtr)) { +- result = name_for_imethod(J, bcp, J->methodPtr, name, size, jframe); +- /* If the methodPtr is a method then this is highly likely to be +- an interpreter frame */ +- if (result >= 0) { +- is_interpreted = 1; +- } +- } +-#endif /* X86_COMPILER2 */ +- else { +- if (debug) { +- fprintf(stderr, "Jlookup_by_regs: END with -1\n\n"); +- } +- result = -1; +- } +- if (!is_interpreted) { +- sender_sp = 0; +- } +- J->curr_fr.sender_sp = sender_sp; +- +-#ifdef X86_COMPILER2 +- if (!J->curr_fr.fp) { +- J->curr_fr.fp = (jframe->new_fp) ? jframe->new_fp : (uintptr_t)regs[R_FP]; +- } +- if (!jframe->new_pc && jframe->new_fp) { +- // This seems dubious +- read_pointer(J, jframe->new_fp + POINTER_SIZE, &jframe->new_pc); +- CHECK_FAIL(err); +- if (debug > 2) { +- printf("Jlookup_by_regs: (update pc) jframe->new_fp: %#llx, jframe->new_pc: %#llx\n", +- jframe->new_fp, jframe->new_pc); +- } +- } +- +-#endif /* X86_COMPILER2 */ +- J->prev_fr = J->curr_fr; +- +- if (debug) +- fprintf(stderr, "Jlookup_by_regs: END\n\n"); +- +- return result; +- +- fail: +- return err; +-} +- +-void update_gregs(prgregset_t gregs, Jframe_t jframe) { +-#ifdef X86_COMPILER2 +- if (debug > 0) { +- fprintf(stderr, "update_gregs: before update sp = 0x%llx, fp = 0x%llx, pc = 0x%llx\n", gregs[R_SP], gregs[R_FP], gregs[R_PC]); +- } +- /* +- * A workaround for java C2 frames with unconventional FP. +- * may have to modify regset with new values for FP/PC/SP when needed. +- */ +- if (jframe.new_sp) { +- *((uintptr_t *) &gregs[R_SP]) = (uintptr_t) jframe.new_sp; +- } else { +- // *((uintptr_t *) &gregs[R_SP]) = (uintptr_t) gregs[R_FP] + 2 * POINTER_SIZE; +- } +- +- if (jframe.new_fp) { +- *((uintptr_t *) &gregs[R_FP]) = (uintptr_t) jframe.new_fp; +- } +- if (jframe.new_pc) { +- *((uintptr_t *) &gregs[R_PC]) = (uintptr_t) jframe.new_pc; +- } +- if (debug > 0) { +- fprintf(stderr, "update_gregs: after update sp = 0x%llx, fp = 0x%llx, pc = 0x%llx\n", gregs[R_SP], gregs[R_FP], gregs[R_PC]); +- } +-#endif /* X86_COMPILER2 */ +-} +- +-/* +- * Iterates over java frames at current location given by 'gregs'. +- * +- * Returns -1 if no java frames are present or if an error is encountered. +- * Returns the result of calling 'func' if the return value is non-zero. +- * Returns 0 otherwise. +- */ +-int Jframe_iter(jvm_agent_t *J, prgregset_t gregs, java_stack_f *func, void* cld) { +- char buf[MAX_SYM_SIZE + 1]; +- Jframe_t jframe; +- int i = 0, res; +-#ifdef X86_COMPILER2 +- if (debug > 0) { +- fprintf(stderr, "Jframe_iter: Entry sp = 0x%llx, fp = 0x%llx, pc = 0x%llx\n", gregs[R_SP], gregs[R_FP], gregs[R_PC]); +- } +-#endif /* X86_COMPILER2 */ +- +- memset(&jframe, 0, sizeof(Jframe_t)); +- memset(buf, 0, sizeof(buf)); +- res = Jlookup_by_regs(J, gregs, buf, sizeof(buf), &jframe); +- if (res != PS_OK) +- return (-1); +- +- +- res = func(cld, gregs, buf, (jframe.locinf)? jframe.bci : -1, +- jframe.line, NULL); +- if (res != 0) { +- update_gregs(gregs, jframe); +- return (res); +- } +- for (i = 1; i < jframe.vf_cnt; i++) { +- Jget_vframe(J, i, buf, sizeof(buf), &jframe); +- res = func(cld, gregs, buf, (jframe.locinf)? jframe.bci : -1, +- jframe.line, NULL); +- if (res != 0) { +- update_gregs(gregs, jframe); +- return (res); +- } +- } +- update_gregs(gregs, jframe); +- return (0); +-} +--- old/src/java.base/solaris/native/libjvm_db/libjvm_db.h 2020-05-20 18:10:26.438101703 -0700 ++++ /dev/null 2020-03-09 18:57:19.455001459 -0700 +@@ -1,69 +0,0 @@ +-/* +- * Copyright (c) 2003, 2018, Oracle and/or its affiliates. All rights reserved. +- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. +- * +- * This code is free software; you can redistribute it and/or modify it +- * under the terms of the GNU General Public License version 2 only, as +- * published by the Free Software Foundation. +- * +- * This code is distributed in the hope that it will be useful, but WITHOUT +- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +- * version 2 for more details (a copy is included in the LICENSE file that +- * accompanied this code). +- * +- * You should have received a copy of the GNU General Public License version +- * 2 along with this work; if not, write to the Free Software Foundation, +- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. +- * +- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA +- * or visit www.oracle.com if you need additional information or have any +- * questions. +- * +- */ +- +-#ifndef OS_SOLARIS_DTRACE_LIBJVM_DB_H +-#define OS_SOLARIS_DTRACE_LIBJVM_DB_H +- +-#include +-#include "jni.h" +- +-#ifdef __cplusplus +-extern "C" { +-#endif +- +-typedef struct jvm_agent jvm_agent_t; +- +-#define JVM_DB_VERSION 1 +- +-JNIEXPORT jvm_agent_t *Jagent_create(struct ps_prochandle *P, int vers); +- +-/* +- * Called from Jframe_iter() for each java frame. If it returns 0, then +- * Jframe_iter() proceeds to the next frame. Otherwise, the return value is +- * immediately returned to the caller of Jframe_iter(). +- * +- * Parameters: +- * 'cld' is client supplied data (to maintain iterator state, if any). +- * 'name' is java method name. +- * 'bci' is byte code index. it will be -1 if not available. +- * 'line' is java source line number. it will be 0 if not available. +- * 'handle' is an abstract client handle, reserved for future expansions +- */ +- +-typedef int java_stack_f(void *cld, const prgregset_t regs, const char* name, int bci, int line, void *handle); +- +-/* +- * Iterates over the java frames at the current location. Returns -1 if no java +- * frames were found, or if there was some unrecoverable error. Otherwise, +- * returns the last value returned from 'func'. +- */ +-JNIEXPORT int Jframe_iter(jvm_agent_t *agent, prgregset_t gregs, java_stack_f *func, void* cld); +- +-JNIEXPORT void Jagent_destroy(jvm_agent_t *J); +- +-#ifdef __cplusplus +-} /* extern "C" */ +-#endif /* __cplusplus */ +- +-#endif // OS_SOLARIS_DTRACE_LIBJVM_DB_H +--- old/src/java.base/solaris/native/libjvm_dtrace/jvm_dtrace.c 2020-05-20 18:10:27.182115987 -0700 ++++ /dev/null 2020-03-09 18:57:19.455001459 -0700 +@@ -1,562 +0,0 @@ +-/* +- * Copyright (c) 2006, 2015, Oracle and/or its affiliates. All rights reserved. +- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. +- * +- * This code is free software; you can redistribute it and/or modify it +- * under the terms of the GNU General Public License version 2 only, as +- * published by the Free Software Foundation. +- * +- * This code is distributed in the hope that it will be useful, but WITHOUT +- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +- * version 2 for more details (a copy is included in the LICENSE file that +- * accompanied this code). +- * +- * You should have received a copy of the GNU General Public License version +- * 2 along with this work; if not, write to the Free Software Foundation, +- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. +- * +- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA +- * or visit www.oracle.com if you need additional information or have any +- * questions. +- * +- */ +- +-#include +-#include +-#include +-#include +-#include +-#include +-#include +-#include +-#include +-#include +-#include +-#include +-#include +-#include +-#include "jvm_dtrace.h" +- +-// NOTE: These constants are used in JVM code as well. +-// KEEP JVM CODE IN SYNC if you are going to change these... +- +-#define DTRACE_ALLOC_PROBES 0x1 +-#define DTRACE_METHOD_PROBES 0x2 +-#define DTRACE_MONITOR_PROBES 0x4 +-#define DTRACE_ALL_PROBES -1 +- +-// generic error messages +-#define JVM_ERR_OUT_OF_MEMORY "out of memory (native heap)" +-#define JVM_ERR_INVALID_PARAM "invalid input parameter(s)" +-#define JVM_ERR_NULL_PARAM "input parameter is NULL" +- +-// error messages for attach +-#define JVM_ERR_CANT_OPEN_DOOR "cannot open door file" +-#define JVM_ERR_CANT_CREATE_ATTACH_FILE "cannot create attach file" +-#define JVM_ERR_DOOR_FILE_PERMISSION "door file is not secure" +-#define JVM_ERR_CANT_SIGNAL "cannot send SIGQUIT to target" +- +-// error messages for enable probe +-#define JVM_ERR_DOOR_CMD_SEND "door command send failed" +-#define JVM_ERR_DOOR_CANT_READ_STATUS "cannot read door command status" +-#define JVM_ERR_DOOR_CMD_STATUS "door command error status" +- +-// error message for detach +-#define JVM_ERR_CANT_CLOSE_DOOR "cannot close door file" +- +-#define RESTARTABLE(_cmd, _result) do { \ +- do { \ +- _result = _cmd; \ +- } while((_result == -1) && (errno == EINTR)); \ +-} while(0) +- +-struct _jvm_t { +- pid_t pid; +- int door_fd; +-}; +- +-static int libjvm_dtrace_debug; +-static void print_debug(const char* fmt,...) { +- if (libjvm_dtrace_debug) { +- va_list alist; +- va_start(alist, fmt); +- fputs("libjvm_dtrace DEBUG: ", stderr); +- vfprintf(stderr, fmt, alist); +- va_end(alist); +- } +-} +- +-/* Key for thread local error message */ +-static thread_key_t jvm_error_key; +- +-/* init function for this library */ +-static void init_jvm_dtrace() { +- /* check for env. var for debug mode */ +- libjvm_dtrace_debug = getenv("LIBJVM_DTRACE_DEBUG") != NULL; +- /* create key for thread local error message */ +- if (thr_keycreate(&jvm_error_key, NULL) != 0) { +- print_debug("can't create thread_key_t for jvm error key\n"); +- // exit(1); ? +- } +-} +- +-#pragma init(init_jvm_dtrace) +- +-/* set thread local error message */ +-static void set_jvm_error(const char* msg) { +- thr_setspecific(jvm_error_key, (void*)msg); +-} +- +-/* clear thread local error message */ +-static void clear_jvm_error() { +- thr_setspecific(jvm_error_key, NULL); +-} +- +-/* file handling functions that can handle interrupt */ +- +-static int file_open(const char* path, int flag) { +- int ret; +- RESTARTABLE(open(path, flag), ret); +- return ret; +-} +- +-static int file_close(int fd) { +- return close(fd); +-} +- +-static int file_read(int fd, char* buf, int len) { +- int ret; +- RESTARTABLE(read(fd, buf, len), ret); +- return ret; +-} +- +-/* send SIGQUIT signal to given process */ +-static int send_sigquit(pid_t pid) { +- int ret; +- RESTARTABLE(kill(pid, SIGQUIT), ret); +- return ret; +-} +- +-/* called to check permissions on attach file */ +-static int check_permission(const char* path) { +- struct stat64 sb; +- uid_t uid, gid; +- int res; +- +- /* +- * Check that the path is owned by the effective uid/gid of this +- * process. Also check that group/other access is not allowed. +- */ +- uid = geteuid(); +- gid = getegid(); +- +- res = stat64(path, &sb); +- if (res != 0) { +- print_debug("stat failed for %s\n", path); +- return -1; +- } +- +- if ((sb.st_uid != uid) || (sb.st_gid != gid) || +- ((sb.st_mode & (S_IRGRP|S_IWGRP|S_IROTH|S_IWOTH)) != 0)) { +- print_debug("well-known file %s is not secure\n", path); +- return -1; +- } +- return 0; +-} +- +-#define ATTACH_FILE_PATTERN "/tmp/.attach_pid%d" +- +-/* fill-in the name of attach file name in given buffer */ +-static void fill_attach_file_name(char* path, int len, pid_t pid) { +- memset(path, 0, len); +- sprintf(path, ATTACH_FILE_PATTERN, pid); +-} +- +-#define DOOR_FILE_PATTERN "/tmp/.java_pid%d" +- +-/* open door file for the given JVM */ +-static int open_door(pid_t pid) { +- char path[PATH_MAX + 1]; +- int fd; +- +- sprintf(path, DOOR_FILE_PATTERN, pid); +- fd = file_open(path, O_RDONLY); +- if (fd < 0) { +- set_jvm_error(JVM_ERR_CANT_OPEN_DOOR); +- print_debug("cannot open door file %s\n", path); +- return -1; +- } +- print_debug("opened door file %s\n", path); +- if (check_permission(path) != 0) { +- set_jvm_error(JVM_ERR_DOOR_FILE_PERMISSION); +- print_debug("check permission failed for %s\n", path); +- file_close(fd); +- fd = -1; +- } +- return fd; +-} +- +-/* create attach file for given process */ +-static int create_attach_file(pid_t pid) { +- char path[PATH_MAX + 1]; +- int fd; +- fill_attach_file_name(path, sizeof(path), pid); +- fd = file_open(path, O_CREAT | O_RDWR); +- if (fd < 0) { +- set_jvm_error(JVM_ERR_CANT_CREATE_ATTACH_FILE); +- print_debug("cannot create file %s\n", path); +- } else { +- print_debug("created attach file %s\n", path); +- } +- return fd; +-} +- +-/* delete attach file for given process */ +-static void delete_attach_file(pid_t pid) { +- char path[PATH_MAX + 1]; +- fill_attach_file_name(path, sizeof(path), pid); +- int res = unlink(path); +- if (res) { +- print_debug("cannot delete attach file %s\n", path); +- } else { +- print_debug("deleted attach file %s\n", path); +- } +-} +- +-/* attach to given JVM */ +-jvm_t* jvm_attach(pid_t pid) { +- jvm_t* jvm; +- int door_fd, attach_fd, i = 0; +- +- jvm = (jvm_t*) calloc(1, sizeof(jvm_t)); +- if (jvm == NULL) { +- set_jvm_error(JVM_ERR_OUT_OF_MEMORY); +- print_debug("calloc failed in %s at %d\n", __FILE__, __LINE__); +- return NULL; +- } +- jvm->pid = pid; +- attach_fd = -1; +- +- door_fd = open_door(pid); +- if (door_fd < 0) { +- print_debug("trying to create attach file\n"); +- if ((attach_fd = create_attach_file(pid)) < 0) { +- goto quit; +- } +- +- /* send QUIT signal to the target so that it will +- * check for the attach file. +- */ +- if (send_sigquit(pid) != 0) { +- set_jvm_error(JVM_ERR_CANT_SIGNAL); +- print_debug("sending SIGQUIT failed\n"); +- goto quit; +- } +- +- /* give the target VM time to start the attach mechanism */ +- do { +- int res; +- RESTARTABLE(poll(0, 0, 200), res); +- door_fd = open_door(pid); +- i++; +- } while (i <= 50 && door_fd == -1); +- if (door_fd < 0) { +- print_debug("Unable to open door to process %d\n", pid); +- goto quit; +- } +- } +- +-quit: +- if (attach_fd >= 0) { +- file_close(attach_fd); +- delete_attach_file(jvm->pid); +- } +- if (door_fd >= 0) { +- jvm->door_fd = door_fd; +- clear_jvm_error(); +- } else { +- free(jvm); +- jvm = NULL; +- } +- return jvm; +-} +- +-/* return the last thread local error message */ +-const char* jvm_get_last_error() { +- const char* res = NULL; +- thr_getspecific(jvm_error_key, (void**)&res); +- return res; +-} +- +-/* detach the givenb JVM */ +-int jvm_detach(jvm_t* jvm) { +- if (jvm) { +- int res = 0; +- if (jvm->door_fd != -1) { +- if (file_close(jvm->door_fd) != 0) { +- set_jvm_error(JVM_ERR_CANT_CLOSE_DOOR); +- res = -1; +- } else { +- clear_jvm_error(); +- } +- } +- free(jvm); +- return res; +- } else { +- set_jvm_error(JVM_ERR_NULL_PARAM); +- print_debug("jvm_t* is NULL\n"); +- return -1; +- } +-} +- +-/* +- * A simple table to translate some known errors into reasonable +- * error messages +- */ +-static struct { +- int err; +- const char* msg; +-} const error_messages[] = { +- { 100, "Bad request" }, +- { 101, "Protocol mismatch" }, +- { 102, "Resource failure" }, +- { 103, "Internal error" }, +- { 104, "Permission denied" }, +-}; +- +-/* +- * Lookup the given error code and return the appropriate +- * message. If not found return NULL. +- */ +-static const char* translate_error(int err) { +- int table_size = sizeof(error_messages) / sizeof(error_messages[0]); +- int i; +- +- for (i=0; i\0\0 +- */ +- if (cstr == NULL) { +- print_debug("command name is NULL\n"); +- goto quit; +- } +- size = strlen(PROTOCOL_VERSION) + strlen(cstr) + 2; +- buf = (char*)malloc(size); +- if (buf != NULL) { +- char* pos = buf; +- strcpy(buf, PROTOCOL_VERSION); +- pos += strlen(PROTOCOL_VERSION)+1; +- strcpy(pos, cstr); +- } else { +- set_jvm_error(JVM_ERR_OUT_OF_MEMORY); +- print_debug("malloc failed at %d in %s\n", __LINE__, __FILE__); +- goto quit; +- } +- +- /* +- * Next we iterate over the arguments and extend the buffer +- * to include them. +- */ +- for (i=0; idoor_fd, &door_args), rc); +- +- /* +- * door_call failed +- */ +- if (rc == -1) { +- print_debug("door_call failed\n"); +- } else { +- /* +- * door_call succeeded but the call didn't return the expected jint. +- */ +- if (door_args.data_size < sizeof(int)) { +- print_debug("Enqueue error - reason unknown as result is truncated!"); +- } else { +- int* res = (int*)(door_args.data_ptr); +- if (*res != 0) { +- const char* msg = translate_error(*res); +- if (msg == NULL) { +- print_debug("Unable to enqueue command to target VM: %d\n", *res); +- } else { +- print_debug("Unable to enqueue command to target VM: %s\n", msg); +- } +- } else { +- /* +- * The door call should return a file descriptor to one end of +- * a socket pair +- */ +- if ((door_args.desc_ptr != NULL) && +- (door_args.desc_num == 1) && +- (door_args.desc_ptr->d_attributes & DOOR_DESCRIPTOR)) { +- result = door_args.desc_ptr->d_data.d_desc.d_descriptor; +- } else { +- print_debug("Reply from enqueue missing descriptor!\n"); +- } +- } +- } +- } +- +-quit: +- if (buf) free(buf); +- return result; +-} +- +-/* read status code for a door command */ +-static int read_status(int fd) { +- char ch, buf[16]; +- int index = 0; +- +- while (1) { +- if (file_read(fd, &ch, sizeof(ch)) != sizeof(ch)) { +- set_jvm_error(JVM_ERR_DOOR_CANT_READ_STATUS); +- print_debug("door cmd status: read status failed\n"); +- return -1; +- } +- buf[index++] = ch; +- if (ch == '\n') { +- buf[index - 1] = '\0'; +- return atoi(buf); +- } +- if (index == sizeof(buf)) { +- set_jvm_error(JVM_ERR_DOOR_CANT_READ_STATUS); +- print_debug("door cmd status: read status overflow\n"); +- return -1; +- } +- } +-} +- +-static const char* ENABLE_DPROBES_CMD = "enabledprobes"; +- +-/* enable one or more DTrace probes for a given JVM */ +-int jvm_enable_dtprobes(jvm_t* jvm, int num_probe_types, const char** probe_types) { +- int fd, status = 0; +- char ch; +- const char* args[1]; +- char buf[16]; +- int probe_type = 0, index; +- int count = 0; +- +- if (jvm == NULL) { +- set_jvm_error(JVM_ERR_NULL_PARAM); +- print_debug("jvm_t* is NULL\n"); +- return -1; +- } +- +- if (num_probe_types == 0 || probe_types == NULL || +- probe_types[0] == NULL) { +- set_jvm_error(JVM_ERR_INVALID_PARAM); +- print_debug("invalid probe type argument(s)\n"); +- return -1; +- } +- +- for (index = 0; index < num_probe_types; index++) { +- const char* p = probe_types[index]; +- if (strcmp(p, JVM_DTPROBE_OBJECT_ALLOC) == 0) { +- probe_type |= DTRACE_ALLOC_PROBES; +- count++; +- } else if (strcmp(p, JVM_DTPROBE_METHOD_ENTRY) == 0 || +- strcmp(p, JVM_DTPROBE_METHOD_RETURN) == 0) { +- probe_type |= DTRACE_METHOD_PROBES; +- count++; +- } else if (strcmp(p, JVM_DTPROBE_MONITOR_ENTER) == 0 || +- strcmp(p, JVM_DTPROBE_MONITOR_ENTERED) == 0 || +- strcmp(p, JVM_DTPROBE_MONITOR_EXIT) == 0 || +- strcmp(p, JVM_DTPROBE_MONITOR_WAIT) == 0 || +- strcmp(p, JVM_DTPROBE_MONITOR_WAITED) == 0 || +- strcmp(p, JVM_DTPROBE_MONITOR_NOTIFY) == 0 || +- strcmp(p, JVM_DTPROBE_MONITOR_NOTIFYALL) == 0) { +- probe_type |= DTRACE_MONITOR_PROBES; +- count++; +- } else if (strcmp(p, JVM_DTPROBE_ALL) == 0) { +- probe_type |= DTRACE_ALL_PROBES; +- count++; +- } +- } +- +- if (count == 0) { +- return count; +- } +- sprintf(buf, "%d", probe_type); +- args[0] = buf; +- +- fd = enqueue_command(jvm, ENABLE_DPROBES_CMD, 1, args); +- if (fd < 0) { +- set_jvm_error(JVM_ERR_DOOR_CMD_SEND); +- return -1; +- } +- +- status = read_status(fd); +- // non-zero status is error +- if (status) { +- set_jvm_error(JVM_ERR_DOOR_CMD_STATUS); +- print_debug("%s command failed (status: %d) in target JVM\n", +- ENABLE_DPROBES_CMD, status); +- file_close(fd); +- return -1; +- } +- // read from stream until EOF +- while (file_read(fd, &ch, sizeof(ch)) == sizeof(ch)) { +- if (libjvm_dtrace_debug) { +- printf("%c", ch); +- } +- } +- +- file_close(fd); +- clear_jvm_error(); +- return count; +-} +--- old/src/java.base/solaris/native/libjvm_dtrace/jvm_dtrace.h 2020-05-20 18:10:27.938130502 -0700 ++++ /dev/null 2020-03-09 18:57:19.455001459 -0700 +@@ -1,86 +0,0 @@ +-/* +- * Copyright (c) 2006, 2018, Oracle and/or its affiliates. All rights reserved. +- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. +- * +- * This code is free software; you can redistribute it and/or modify it +- * under the terms of the GNU General Public License version 2 only, as +- * published by the Free Software Foundation. +- * +- * This code is distributed in the hope that it will be useful, but WITHOUT +- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +- * version 2 for more details (a copy is included in the LICENSE file that +- * accompanied this code). +- * +- * You should have received a copy of the GNU General Public License version +- * 2 along with this work; if not, write to the Free Software Foundation, +- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. +- * +- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA +- * or visit www.oracle.com if you need additional information or have any +- * questions. +- * +- */ +- +-#ifndef _JVM_DTRACE_H_ +-#define _JVM_DTRACE_H_ +- +-/* +- * Interface to dynamically turn on probes in Hotspot JVM. Currently, +- * this interface can be used to dynamically enable certain DTrace +- * probe points that are costly to have "always on". +- */ +- +-#ifdef __cplusplus +-extern "C" { +-#endif +- +-#include +-#include "jni.h" +- +-struct _jvm_t; +-typedef struct _jvm_t jvm_t; +- +- +-/* Attach to the given JVM process. Returns NULL on failure. +- jvm_get_last_error() returns last error message. */ +-JNIEXPORT jvm_t* jvm_attach(pid_t pid); +- +-/* Returns the last error message from this library or NULL if none. */ +-JNIEXPORT const char* jvm_get_last_error(); +- +-/* few well-known probe type constants for 'probe_types' param below */ +- +-#define JVM_DTPROBE_METHOD_ENTRY "method-entry" +-#define JVM_DTPROBE_METHOD_RETURN "method-return" +-#define JVM_DTPROBE_MONITOR_ENTER "monitor-contended-enter" +-#define JVM_DTPROBE_MONITOR_ENTERED "monitor-contended-entered" +-#define JVM_DTPROBE_MONITOR_EXIT "monitor-contended-exit" +-#define JVM_DTPROBE_MONITOR_WAIT "monitor-wait" +-#define JVM_DTPROBE_MONITOR_WAITED "monitor-waited" +-#define JVM_DTPROBE_MONITOR_NOTIFY "monitor-notify" +-#define JVM_DTPROBE_MONITOR_NOTIFYALL "monitor-notifyall" +-#define JVM_DTPROBE_OBJECT_ALLOC "object-alloc" +-#define JVM_DTPROBE_ALL "*" +- +-/* Enable the specified DTrace probes of given probe types on +- * the specified JVM. Returns >= 0 on success, -1 on failure. +- * On success, this returns number of probe_types enabled. +- * On failure, jvm_get_last_error() returns the last error message. +- */ +-JNIEXPORT int jvm_enable_dtprobes(jvm_t* jvm, int num_probe_types, const char** probe_types); +- +-/* Note: There is no jvm_disable_dtprobes function. Probes are automatically +- * disabled when there are no more clients requiring those probes. +- */ +- +-/* Detach the given JVM. Returns 0 on success, -1 on failure. +- * jvm_get_last_error() returns the last error message. +- */ +-JNIEXPORT int jvm_detach(jvm_t* jvm); +- +-#ifdef __cplusplus +-} +-#endif +- +-#endif /* _JVM_DTRACE_H_ */ +--- old/src/java.base/solaris/native/libnet/solaris_close.c 2020-05-20 18:10:28.690144940 -0700 ++++ /dev/null 2020-03-09 18:57:19.455001459 -0700 +@@ -1,107 +0,0 @@ +-/* +- * Copyright (c) 2014, 2019, Oracle and/or its affiliates. All rights reserved. +- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. +- * +- * This code is free software; you can redistribute it and/or modify it +- * under the terms of the GNU General Public License version 2 only, as +- * published by the Free Software Foundation. Oracle designates this +- * particular file as subject to the "Classpath" exception as provided +- * by Oracle in the LICENSE file that accompanied this code. +- * +- * This code is distributed in the hope that it will be useful, but WITHOUT +- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +- * version 2 for more details (a copy is included in the LICENSE file that +- * accompanied this code). +- * +- * You should have received a copy of the GNU General Public License version +- * 2 along with this work; if not, write to the Free Software Foundation, +- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. +- * +- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA +- * or visit www.oracle.com if you need additional information or have any +- * questions. +- */ +- +-#include +-#include +-#include +-#include +-#include "jvm.h" +-#include "net_util.h" +- +-/* Support for restartable system calls on Solaris. */ +- +-#define RESTARTABLE_RETURN_INT(_cmd) do { \ +- int _result; \ +- if (1) { \ +- do { \ +- _result = _cmd; \ +- } while((_result == -1) && (errno == EINTR)); \ +- return _result; \ +- } \ +-} while(0) +- +-int NET_Read(int s, void* buf, size_t len) { +- RESTARTABLE_RETURN_INT(recv(s, buf, len, 0)); +-} +- +-int NET_NonBlockingRead(int s, void* buf, size_t len) { +- RESTARTABLE_RETURN_INT(recv(s, buf, len, MSG_DONTWAIT)); +-} +- +-int NET_RecvFrom(int s, void *buf, int len, unsigned int flags, +- struct sockaddr *from, socklen_t *fromlen) { +- RESTARTABLE_RETURN_INT(recvfrom(s, buf, len, flags, from, fromlen)); +-} +- +-int NET_Send(int s, void *msg, int len, unsigned int flags) { +- RESTARTABLE_RETURN_INT(send(s, msg, len, flags)); +-} +- +-int NET_SendTo(int s, const void *msg, int len, unsigned int flags, +- const struct sockaddr *to, int tolen) { +- RESTARTABLE_RETURN_INT(sendto(s, msg, len, flags, to, tolen)); +-} +- +-int NET_Connect(int s, struct sockaddr *addr, int addrlen) { +- RESTARTABLE_RETURN_INT(connect(s, addr, addrlen)); +-} +- +-int NET_Accept(int s, struct sockaddr *addr, socklen_t *addrlen) { +- RESTARTABLE_RETURN_INT(accept(s, addr, addrlen)); +-} +- +-int NET_SocketClose(int fd) { +- return close(fd); +-} +- +-int NET_Dup2(int fd, int fd2) { +- return dup2(fd, fd2); +-} +- +-int NET_Poll(struct pollfd *ufds, unsigned int nfds, int timeout) { +- RESTARTABLE_RETURN_INT(poll(ufds, nfds, timeout)); +-} +- +-int NET_Timeout(JNIEnv *env, int s, long timeout, jlong nanoTimeStamp) { +- int result; +- jlong prevNanoTime = nanoTimeStamp; +- jlong nanoTimeout = (jlong) timeout * NET_NSEC_PER_MSEC; +- struct pollfd pfd; +- pfd.fd = s; +- pfd.events = POLLIN; +- +- for(;;) { +- result = poll(&pfd, 1, nanoTimeout / NET_NSEC_PER_MSEC); +- if (result < 0 && errno == EINTR) { +- jlong newNanoTime = JVM_NanoTime(env, 0); +- nanoTimeout -= newNanoTime - prevNanoTime; +- if (nanoTimeout < NET_NSEC_PER_MSEC) +- return 0; +- prevNanoTime = newNanoTime; +- } else { +- return result; +- } +- } +-} +--- old/src/java.base/solaris/native/libnio/ch/DevPollArrayWrapper.c 2020-05-20 18:10:29.450159532 -0700 ++++ /dev/null 2020-03-09 18:57:19.455001459 -0700 +@@ -1,112 +0,0 @@ +-/* +- * Copyright (c) 2001, 2018, Oracle and/or its affiliates. All rights reserved. +- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. +- * +- * This code is free software; you can redistribute it and/or modify it +- * under the terms of the GNU General Public License version 2 only, as +- * published by the Free Software Foundation. Oracle designates this +- * particular file as subject to the "Classpath" exception as provided +- * by Oracle in the LICENSE file that accompanied this code. +- * +- * This code is distributed in the hope that it will be useful, but WITHOUT +- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +- * version 2 for more details (a copy is included in the LICENSE file that +- * accompanied this code). +- * +- * You should have received a copy of the GNU General Public License version +- * 2 along with this work; if not, write to the Free Software Foundation, +- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. +- * +- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA +- * or visit www.oracle.com if you need additional information or have any +- * questions. +- */ +- +-#include +-#include +-#include +-#include +-#include +- +-#include "jni.h" +-#include "jni_util.h" +-#include "jvm.h" +-#include "jlong.h" +-#include "nio.h" +-#include "nio_util.h" +- +-#include "sun_nio_ch_DevPollArrayWrapper.h" +- +-JNIEXPORT jint JNICALL +-Java_sun_nio_ch_DevPollArrayWrapper_init(JNIEnv *env, jobject this) +-{ +- int wfd = open("/dev/poll", O_RDWR); +- if (wfd < 0) { +- JNU_ThrowIOExceptionWithLastError(env, "Error opening driver"); +- return -1; +- } +- return wfd; +-} +- +-JNIEXPORT void JNICALL +-Java_sun_nio_ch_DevPollArrayWrapper_register(JNIEnv *env, jobject this, +- jint wfd, jint fd, jint mask) +-{ +- struct pollfd a[1]; +- int n; +- +- a[0].fd = fd; +- a[0].events = mask; +- a[0].revents = 0; +- +- n = write(wfd, &a[0], sizeof(a)); +- if (n != sizeof(a)) { +- if (n < 0) { +- JNU_ThrowIOExceptionWithLastError(env, "Error writing pollfds"); +- } else { +- JNU_ThrowIOException(env, "Unexpected number of bytes written"); +- } +- } +-} +- +-JNIEXPORT void JNICALL +-Java_sun_nio_ch_DevPollArrayWrapper_registerMultiple(JNIEnv *env, jobject this, +- jint wfd, jlong address, +- jint len) +-{ +- unsigned char *pollBytes = (unsigned char *)jlong_to_ptr(address); +- unsigned char *pollEnd = pollBytes + sizeof(struct pollfd) * len; +- while (pollBytes < pollEnd) { +- int bytesWritten = write(wfd, pollBytes, (int)(pollEnd - pollBytes)); +- if (bytesWritten < 0) { +- JNU_ThrowIOExceptionWithLastError(env, "Error writing pollfds"); +- return; +- } +- pollBytes += bytesWritten; +- } +-} +- +-JNIEXPORT jint JNICALL +-Java_sun_nio_ch_DevPollArrayWrapper_poll0(JNIEnv *env, jobject this, +- jlong address, jint numfds, +- jlong timeout, jint wfd) +-{ +- struct dvpoll a; +- void *pfd = (void *) jlong_to_ptr(address); +- int result; +- +- a.dp_fds = pfd; +- a.dp_nfds = numfds; +- a.dp_timeout = (int)timeout; +- result = ioctl(wfd, DP_POLL, &a); +- if (result < 0) { +- if (errno == EINTR) { +- return IOS_INTERRUPTED; +- } else { +- JNU_ThrowIOExceptionWithLastError(env, "Error reading driver"); +- return IOS_THROWN; +- } +- } +- return result; +-} +--- old/src/java.base/solaris/native/libnio/ch/SolarisEventPort.c 2020-05-20 18:10:30.154173048 -0700 ++++ /dev/null 2020-03-09 18:57:19.455001459 -0700 +@@ -1,147 +0,0 @@ +-/* +- * Copyright (c) 2008, 2018, Oracle and/or its affiliates. All rights reserved. +- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. +- * +- * This code is free software; you can redistribute it and/or modify it +- * under the terms of the GNU General Public License version 2 only, as +- * published by the Free Software Foundation. Oracle designates this +- * particular file as subject to the "Classpath" exception as provided +- * by Oracle in the LICENSE file that accompanied this code. +- * +- * This code is distributed in the hope that it will be useful, but WITHOUT +- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +- * version 2 for more details (a copy is included in the LICENSE file that +- * accompanied this code). +- * +- * You should have received a copy of the GNU General Public License version +- * 2 along with this work; if not, write to the Free Software Foundation, +- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. +- * +- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA +- * or visit www.oracle.com if you need additional information or have any +- * questions. +- */ +- +-#include +-#include +-#include +-#include +- +-#include "jni.h" +-#include "jni_util.h" +-#include "jvm.h" +-#include "jlong.h" +-#include "nio.h" +-#include "nio_util.h" +- +-#include "sun_nio_ch_SolarisEventPort.h" +- +-JNIEXPORT jint JNICALL +-Java_sun_nio_ch_SolarisEventPort_port_1create +- (JNIEnv* env, jclass clazz) +-{ +- int port = port_create(); +- if (port == -1) { +- JNU_ThrowIOExceptionWithLastError(env, "port_create"); +- } +- return (jint)port; +-} +- +-JNIEXPORT void JNICALL +-Java_sun_nio_ch_SolarisEventPort_port_1close +- (JNIEnv* env, jclass clazz, jint port) +-{ +- int res = close(port); +- if (res < 0 && res != EINTR) { +- JNU_ThrowIOExceptionWithLastError(env, "close failed"); +- } +-} +- +-JNIEXPORT jboolean JNICALL +-Java_sun_nio_ch_SolarisEventPort_port_1associate +- (JNIEnv* env, jclass clazz, jint port, jint source, jlong objectAddress, jint events) +-{ +- uintptr_t object = (uintptr_t)jlong_to_ptr(objectAddress); +- if (port_associate((int)port, (int)source, object, (int)events, NULL) == 0) { +- return JNI_TRUE; +- } else { +- if (errno != EBADFD) +- JNU_ThrowIOExceptionWithLastError(env, "port_associate"); +- return JNI_FALSE; +- } +-} +- +-JNIEXPORT jboolean JNICALL +-Java_sun_nio_ch_SolarisEventPort_port_1dissociate +- (JNIEnv* env, jclass clazz, jint port, jint source, jlong objectAddress) +-{ +- uintptr_t object = (uintptr_t)jlong_to_ptr(objectAddress); +- +- if (port_dissociate((int)port, (int)source, object) == 0) { +- return JNI_TRUE; +- } else { +- if (errno != ENOENT) +- JNU_ThrowIOExceptionWithLastError(env, "port_dissociate"); +- return JNI_FALSE; +- } +-} +- +-JNIEXPORT void JNICALL +-Java_sun_nio_ch_SolarisEventPort_port_1send(JNIEnv* env, jclass clazz, +- jint port, jint events) +-{ +- if (port_send((int)port, (int)events, NULL) == -1) { +- JNU_ThrowIOExceptionWithLastError(env, "port_send"); +- } +-} +- +-JNIEXPORT jint JNICALL +-Java_sun_nio_ch_SolarisEventPort_port_1get(JNIEnv* env, jclass clazz, +- jint port, jlong eventAddress) +-{ +- int res; +- port_event_t* ev = (port_event_t*)jlong_to_ptr(eventAddress); +- +- res = port_get((int)port, ev, NULL); +- if (res == -1) { +- if (errno == EINTR) { +- return IOS_INTERRUPTED; +- } else { +- JNU_ThrowIOExceptionWithLastError(env, "port_get failed"); +- return IOS_THROWN; +- } +- } +- return res; +-} +- +-JNIEXPORT jint JNICALL +-Java_sun_nio_ch_SolarisEventPort_port_1getn(JNIEnv* env, jclass clazz, +- jint port, jlong arrayAddress, jint max, jlong timeout) +-{ +- int res; +- uint_t n = 1; +- port_event_t* list = (port_event_t*)jlong_to_ptr(arrayAddress); +- timespec_t ts; +- timespec_t* tsp; +- +- if (timeout >= 0L) { +- ts.tv_sec = timeout / 1000; +- ts.tv_nsec = 1000000 * (timeout % 1000); +- tsp = &ts; +- } else { +- tsp = NULL; +- } +- +- res = port_getn((int)port, list, (uint_t)max, &n, tsp); +- if (res == -1 && errno != ETIME) { +- if (errno == EINTR) { +- return IOS_INTERRUPTED; +- } else { +- JNU_ThrowIOExceptionWithLastError(env, "port_getn failed"); +- return IOS_THROWN; +- } +- } +- +- return (jint)n; +-} +--- old/src/java.base/solaris/native/libnio/fs/SolarisNativeDispatcher.c 2020-05-20 18:10:30.850186411 -0700 ++++ /dev/null 2020-03-09 18:57:19.455001459 -0700 +@@ -1,143 +0,0 @@ +-/* +- * Copyright (c) 2008, 2012, Oracle and/or its affiliates. All rights reserved. +- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. +- * +- * This code is free software; you can redistribute it and/or modify it +- * under the terms of the GNU General Public License version 2 only, as +- * published by the Free Software Foundation. Oracle designates this +- * particular file as subject to the "Classpath" exception as provided +- * by Oracle in the LICENSE file that accompanied this code. +- * +- * This code is distributed in the hope that it will be useful, but WITHOUT +- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +- * version 2 for more details (a copy is included in the LICENSE file that +- * accompanied this code). +- * +- * You should have received a copy of the GNU General Public License version +- * 2 along with this work; if not, write to the Free Software Foundation, +- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. +- * +- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA +- * or visit www.oracle.com if you need additional information or have any +- * questions. +- */ +- +-#include "jni.h" +-#include "jni_util.h" +-#include "jvm.h" +-#include "jlong.h" +- +-#include +-#include +-#include +-#include +-#include +- +-#include "jni.h" +- +-#include "sun_nio_fs_SolarisNativeDispatcher.h" +- +-static jfieldID entry_name; +-static jfieldID entry_dir; +-static jfieldID entry_fstype; +-static jfieldID entry_options; +-static jfieldID entry_dev; +- +-static void throwUnixException(JNIEnv* env, int errnum) { +- jobject x = JNU_NewObjectByName(env, "sun/nio/fs/UnixException", +- "(I)V", errnum); +- if (x != NULL) { +- (*env)->Throw(env, x); +- } +-} +- +-JNIEXPORT void JNICALL +-Java_sun_nio_fs_SolarisNativeDispatcher_init(JNIEnv *env, jclass clazz) { +- clazz = (*env)->FindClass(env, "sun/nio/fs/UnixMountEntry"); +- CHECK_NULL(clazz); +- entry_name = (*env)->GetFieldID(env, clazz, "name", "[B"); +- CHECK_NULL(entry_name); +- entry_dir = (*env)->GetFieldID(env, clazz, "dir", "[B"); +- CHECK_NULL(entry_dir); +- entry_fstype = (*env)->GetFieldID(env, clazz, "fstype", "[B"); +- CHECK_NULL(entry_fstype); +- entry_options = (*env)->GetFieldID(env, clazz, "opts", "[B"); +- CHECK_NULL(entry_options); +- entry_dev = (*env)->GetFieldID(env, clazz, "dev", "J"); +- CHECK_NULL(entry_dev); +-} +- +-JNIEXPORT jint JNICALL +-Java_sun_nio_fs_SolarisNativeDispatcher_facl(JNIEnv* env, jclass this, jint fd, +- jint cmd, jint nentries, jlong address) +-{ +- void* aclbufp = jlong_to_ptr(address); +- int n = -1; +- +- n = facl((int)fd, (int)cmd, (int)nentries, aclbufp); +- if (n == -1) { +- throwUnixException(env, errno); +- } +- return (jint)n; +-} +- +-JNIEXPORT jint JNICALL +-Java_sun_nio_fs_SolarisNativeDispatcher_getextmntent(JNIEnv* env, jclass this, +- jlong value, jobject entry) +-{ +- struct extmnttab ent; +- FILE* fp = jlong_to_ptr(value); +- jsize len; +- jbyteArray bytes; +- char* name; +- char* dir; +- char* fstype; +- char* options; +- dev_t dev; +- +- if (getextmntent(fp, &ent, 0)) +- return -1; +- name = ent.mnt_special; +- dir = ent.mnt_mountp; +- fstype = ent.mnt_fstype; +- options = ent.mnt_mntopts; +- dev = makedev(ent.mnt_major, ent.mnt_minor); +- if (dev == NODEV) { +- throwUnixException(env, errno); +- return -1; +- } +- +- len = strlen(name); +- bytes = (*env)->NewByteArray(env, len); +- if (bytes == NULL) +- return -1; +- (*env)->SetByteArrayRegion(env, bytes, 0, len, (jbyte*)name); +- (*env)->SetObjectField(env, entry, entry_name, bytes); +- +- len = strlen(dir); +- bytes = (*env)->NewByteArray(env, len); +- if (bytes == NULL) +- return -1; +- (*env)->SetByteArrayRegion(env, bytes, 0, len, (jbyte*)dir); +- (*env)->SetObjectField(env, entry, entry_dir, bytes); +- +- len = strlen(fstype); +- bytes = (*env)->NewByteArray(env, len); +- if (bytes == NULL) +- return -1; +- (*env)->SetByteArrayRegion(env, bytes, 0, len, (jbyte*)fstype); +- (*env)->SetObjectField(env, entry, entry_fstype, bytes); +- +- len = strlen(options); +- bytes = (*env)->NewByteArray(env, len); +- if (bytes == NULL) +- return -1; +- (*env)->SetByteArrayRegion(env, bytes, 0, len, (jbyte*)options); +- (*env)->SetObjectField(env, entry, entry_options, bytes); +- +- if (dev != 0) +- (*env)->SetLongField(env, entry, entry_dev, (jlong)dev); +- +- return 0; +-} +--- old/src/java.base/solaris/native/libnio/fs/SolarisWatchService.c 2020-05-20 18:10:31.586200541 -0700 ++++ /dev/null 2020-03-09 18:57:19.455001459 -0700 +@@ -1,104 +0,0 @@ +-/* +- * Copyright (c) 2008, 2009, Oracle and/or its affiliates. All rights reserved. +- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. +- * +- * This code is free software; you can redistribute it and/or modify it +- * under the terms of the GNU General Public License version 2 only, as +- * published by the Free Software Foundation. Oracle designates this +- * particular file as subject to the "Classpath" exception as provided +- * by Oracle in the LICENSE file that accompanied this code. +- * +- * This code is distributed in the hope that it will be useful, but WITHOUT +- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +- * version 2 for more details (a copy is included in the LICENSE file that +- * accompanied this code). +- * +- * You should have received a copy of the GNU General Public License version +- * 2 along with this work; if not, write to the Free Software Foundation, +- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. +- * +- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA +- * or visit www.oracle.com if you need additional information or have any +- * questions. +- */ +- +-#include "jni.h" +-#include "jni_util.h" +-#include "jvm.h" +-#include "jlong.h" +- +-#include +-#include +-#include +-#include // Solaris 10 +- +-#include "sun_nio_fs_SolarisWatchService.h" +- +-static void throwUnixException(JNIEnv* env, int errnum) { +- jobject x = JNU_NewObjectByName(env, "sun/nio/fs/UnixException", +- "(I)V", errnum); +- if (x != NULL) { +- (*env)->Throw(env, x); +- } +-} +- +-JNIEXPORT void JNICALL +-Java_sun_nio_fs_SolarisWatchService_init(JNIEnv *env, jclass clazz) +-{ +-} +- +-JNIEXPORT jint JNICALL +-Java_sun_nio_fs_SolarisWatchService_portCreate +- (JNIEnv* env, jclass clazz) +-{ +- int port = port_create(); +- if (port == -1) { +- throwUnixException(env, errno); +- } +- return (jint)port; +-} +- +-JNIEXPORT void JNICALL +-Java_sun_nio_fs_SolarisWatchService_portAssociate +- (JNIEnv* env, jclass clazz, jint port, jint source, jlong objectAddress, jint events) +-{ +- uintptr_t object = (uintptr_t)jlong_to_ptr(objectAddress); +- +- if (port_associate((int)port, (int)source, object, (int)events, NULL) == -1) { +- throwUnixException(env, errno); +- } +-} +- +-JNIEXPORT void JNICALL +-Java_sun_nio_fs_SolarisWatchService_portDissociate +- (JNIEnv* env, jclass clazz, jint port, jint source, jlong objectAddress) +-{ +- uintptr_t object = (uintptr_t)jlong_to_ptr(objectAddress); +- +- if (port_dissociate((int)port, (int)source, object) == -1) { +- throwUnixException(env, errno); +- } +-} +- +-JNIEXPORT void JNICALL +-Java_sun_nio_fs_SolarisWatchService_portSend(JNIEnv* env, jclass clazz, +- jint port, jint events) +-{ +- if (port_send((int)port, (int)events, NULL) == -1) { +- throwUnixException(env, errno); +- } +-} +- +-JNIEXPORT jint JNICALL +-Java_sun_nio_fs_SolarisWatchService_portGetn(JNIEnv* env, jclass clazz, +- jint port, jlong arrayAddress, jint max) +-{ +- uint_t n = 1; +- port_event_t* list = (port_event_t*)jlong_to_ptr(arrayAddress); +- +- if (port_getn((int)port, list, (uint_t)max, &n, NULL) == -1) { +- throwUnixException(env, errno); +- } +- return (jint)n; +-} +--- old/src/java.desktop/solaris/classes/sun/font/X11CNS11643.java 2020-05-20 18:10:32.298214211 -0700 ++++ /dev/null 2020-03-09 18:57:19.455001459 -0700 +@@ -1,178 +0,0 @@ +-/* +- * Copyright (c) 2001, 2008, Oracle and/or its affiliates. All rights reserved. +- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. +- * +- * This code is free software; you can redistribute it and/or modify it +- * under the terms of the GNU General Public License version 2 only, as +- * published by the Free Software Foundation. Oracle designates this +- * particular file as subject to the "Classpath" exception as provided +- * by Oracle in the LICENSE file that accompanied this code. +- * +- * This code is distributed in the hope that it will be useful, but WITHOUT +- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +- * version 2 for more details (a copy is included in the LICENSE file that +- * accompanied this code). +- * +- * You should have received a copy of the GNU General Public License version +- * 2 along with this work; if not, write to the Free Software Foundation, +- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. +- * +- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA +- * or visit www.oracle.com if you need additional information or have any +- * questions. +- */ +- +-package sun.font; +- +-import java.nio.CharBuffer; +-import java.nio.ByteBuffer; +-import java.nio.charset.*; +-import sun.nio.cs.*; +- +-public abstract class X11CNS11643 extends Charset { +- private final int plane; +- public X11CNS11643 (int plane, String name) { +- super(name, null); +- switch (plane) { +- case 1: +- this.plane = 0; // CS1 +- break; +- case 2: +- case 3: +- this.plane = plane; +- break; +- default: +- throw new IllegalArgumentException +- ("Only planes 1, 2, and 3 supported"); +- } +- } +- +- public CharsetEncoder newEncoder() { +- return new Encoder(this, plane); +- } +- +- public CharsetDecoder newDecoder() { +- return new Decoder(this, plane); +- } +- +- public boolean contains(Charset cs) { +- return cs instanceof X11CNS11643; +- } +- +- private class Encoder extends EUC_TW.Encoder { +- private int plane; +- public Encoder(Charset cs, int plane) { +- super(cs); +- this.plane = plane; +- } +- +- private byte[] bb = new byte[4]; +- public boolean canEncode(char c) { +- if (c <= 0x7F) { +- return false; +- } +- int nb = toEUC(c, bb); +- if (nb == -1) +- return false; +- int p = 0; +- if (nb == 4) +- p = (bb[1] & 0xff) - 0xa0; +- return (p == plane); +- } +- +- public boolean isLegalReplacement(byte[] repl) { +- return true; +- } +- +- protected CoderResult encodeLoop(CharBuffer src, ByteBuffer dst) { +- char[] sa = src.array(); +- int sp = src.arrayOffset() + src.position(); +- int sl = src.arrayOffset() + src.limit(); +- byte[] da = dst.array(); +- int dp = dst.arrayOffset() + dst.position(); +- int dl = dst.arrayOffset() + dst.limit(); +- +- try { +- while (sp < sl) { +- char c = sa[sp]; +- if ( c > '\u007f'&& c < '\uFFFE') { +- int nb = toEUC(c, bb); +- if (nb != -1) { +- int p = 0; +- if (nb == 4) +- p = (bb[1] & 0xff) - 0xa0; +- if (p == plane) { +- if (dl - dp < 2) +- return CoderResult.OVERFLOW; +- if (nb == 2) { +- da[dp++] = (byte)(bb[0] & 0x7f); +- da[dp++] = (byte)(bb[1] & 0x7f); +- } else { +- da[dp++] = (byte)(bb[2] & 0x7f); +- da[dp++] = (byte)(bb[3] & 0x7f); +- } +- sp++; +- continue; +- } +- } +- } +- return CoderResult.unmappableForLength(1); +- } +- return CoderResult.UNDERFLOW; +- } finally { +- src.position(sp - src.arrayOffset()); +- dst.position(dp - dst.arrayOffset()); +- } +- } +- } +- +- private class Decoder extends EUC_TW.Decoder { +- int plane; +- private String table; +- protected Decoder(Charset cs, int plane) { +- super(cs); +- if (plane == 0) +- this.plane = plane; +- else if (plane == 2 || plane == 3) +- this.plane = plane - 1; +- else +- throw new IllegalArgumentException +- ("Only planes 1, 2, and 3 supported"); +- } +- +- //we only work on array backed buffer. +- protected CoderResult decodeLoop(ByteBuffer src, CharBuffer dst) { +- byte[] sa = src.array(); +- int sp = src.arrayOffset() + src.position(); +- int sl = src.arrayOffset() + src.limit(); +- +- char[] da = dst.array(); +- int dp = dst.arrayOffset() + dst.position(); +- int dl = dst.arrayOffset() + dst.limit(); +- +- try { +- while (sp < sl) { +- if ( sl - sp < 2) { +- return CoderResult.UNDERFLOW; +- } +- int b1 = (sa[sp] & 0xff) | 0x80; +- int b2 = (sa[sp + 1] & 0xff) | 0x80; +- char[] cc = toUnicode(b1, b2, plane); +- // plane3 has non-bmp characters(added), x11cnsp3 +- // however does not support them +- if (cc == null || cc.length == 2) +- return CoderResult.unmappableForLength(2); +- if (dl - dp < 1) +- return CoderResult.OVERFLOW; +- da[dp++] = cc[0]; +- sp +=2; +- } +- return CoderResult.UNDERFLOW; +- } finally { +- src.position(sp - src.arrayOffset()); +- dst.position(dp - dst.arrayOffset()); +- } +- } +- } +-} +--- old/src/java.desktop/solaris/classes/sun/font/X11CNS11643P1.java 2020-05-20 18:10:32.990227497 -0700 ++++ /dev/null 2020-03-09 18:57:19.455001459 -0700 +@@ -1,33 +0,0 @@ +-/* +- * Copyright (c) 1996, 2005, Oracle and/or its affiliates. All rights reserved. +- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. +- * +- * This code is free software; you can redistribute it and/or modify it +- * under the terms of the GNU General Public License version 2 only, as +- * published by the Free Software Foundation. Oracle designates this +- * particular file as subject to the "Classpath" exception as provided +- * by Oracle in the LICENSE file that accompanied this code. +- * +- * This code is distributed in the hope that it will be useful, but WITHOUT +- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +- * version 2 for more details (a copy is included in the LICENSE file that +- * accompanied this code). +- * +- * You should have received a copy of the GNU General Public License version +- * 2 along with this work; if not, write to the Free Software Foundation, +- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. +- * +- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA +- * or visit www.oracle.com if you need additional information or have any +- * questions. +- */ +- +- +-package sun.font; +- +-public class X11CNS11643P1 extends X11CNS11643 { +- public X11CNS11643P1() { +- super(1, "X11CNS11643P1"); +- } +-} +--- old/src/java.desktop/solaris/classes/sun/font/X11CNS11643P2.java 2020-05-20 18:10:33.650240169 -0700 ++++ /dev/null 2020-03-09 18:57:19.455001459 -0700 +@@ -1,32 +0,0 @@ +-/* +- * Copyright (c) 1996, 2005, Oracle and/or its affiliates. All rights reserved. +- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. +- * +- * This code is free software; you can redistribute it and/or modify it +- * under the terms of the GNU General Public License version 2 only, as +- * published by the Free Software Foundation. Oracle designates this +- * particular file as subject to the "Classpath" exception as provided +- * by Oracle in the LICENSE file that accompanied this code. +- * +- * This code is distributed in the hope that it will be useful, but WITHOUT +- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +- * version 2 for more details (a copy is included in the LICENSE file that +- * accompanied this code). +- * +- * You should have received a copy of the GNU General Public License version +- * 2 along with this work; if not, write to the Free Software Foundation, +- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. +- * +- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA +- * or visit www.oracle.com if you need additional information or have any +- * questions. +- */ +- +-package sun.font; +- +-public class X11CNS11643P2 extends X11CNS11643 { +- public X11CNS11643P2() { +- super(2, "X11CNS11643P2"); +- } +-} +--- old/src/java.desktop/solaris/classes/sun/font/X11CNS11643P3.java 2020-05-20 18:10:34.342253455 -0700 ++++ /dev/null 2020-03-09 18:57:19.455001459 -0700 +@@ -1,32 +0,0 @@ +-/* +- * Copyright (c) 1997, 2005, Oracle and/or its affiliates. All rights reserved. +- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. +- * +- * This code is free software; you can redistribute it and/or modify it +- * under the terms of the GNU General Public License version 2 only, as +- * published by the Free Software Foundation. Oracle designates this +- * particular file as subject to the "Classpath" exception as provided +- * by Oracle in the LICENSE file that accompanied this code. +- * +- * This code is distributed in the hope that it will be useful, but WITHOUT +- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +- * version 2 for more details (a copy is included in the LICENSE file that +- * accompanied this code). +- * +- * You should have received a copy of the GNU General Public License version +- * 2 along with this work; if not, write to the Free Software Foundation, +- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. +- * +- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA +- * or visit www.oracle.com if you need additional information or have any +- * questions. +- */ +- +-package sun.font; +- +-public class X11CNS11643P3 extends X11CNS11643 { +- public X11CNS11643P3() { +- super(3, "X11CNS11643P3"); +- } +-} +--- old/src/java.desktop/solaris/native/libjsound/PLATFORM_API_SolarisOS_PCM.c 2020-05-20 18:10:35.046266971 -0700 ++++ /dev/null 2020-03-09 18:57:19.455001459 -0700 +@@ -1,627 +0,0 @@ +-/* +- * Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved. +- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. +- * +- * This code is free software; you can redistribute it and/or modify it +- * under the terms of the GNU General Public License version 2 only, as +- * published by the Free Software Foundation. Oracle designates this +- * particular file as subject to the "Classpath" exception as provided +- * by Oracle in the LICENSE file that accompanied this code. +- * +- * This code is distributed in the hope that it will be useful, but WITHOUT +- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +- * version 2 for more details (a copy is included in the LICENSE file that +- * accompanied this code). +- * +- * You should have received a copy of the GNU General Public License version +- * 2 along with this work; if not, write to the Free Software Foundation, +- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. +- * +- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA +- * or visit www.oracle.com if you need additional information or have any +- * questions. +- */ +- +-#define USE_ERROR +-#define USE_TRACE +- +-#include "PLATFORM_API_SolarisOS_Utils.h" +-#include "DirectAudio.h" +- +-#if USE_DAUDIO == TRUE +- +- +-// The default buffer time +-#define DEFAULT_PERIOD_TIME_MILLIS 50 +- +-///// implemented functions of DirectAudio.h +- +-INT32 DAUDIO_GetDirectAudioDeviceCount() { +- return (INT32) getAudioDeviceCount(); +-} +- +- +-INT32 DAUDIO_GetDirectAudioDeviceDescription(INT32 mixerIndex, +- DirectAudioDeviceDescription* description) { +- AudioDeviceDescription desc; +- +- if (getAudioDeviceDescriptionByIndex(mixerIndex, &desc, TRUE)) { +- description->maxSimulLines = desc.maxSimulLines; +- strncpy(description->name, desc.name, DAUDIO_STRING_LENGTH-1); +- description->name[DAUDIO_STRING_LENGTH-1] = 0; +- strncpy(description->vendor, desc.vendor, DAUDIO_STRING_LENGTH-1); +- description->vendor[DAUDIO_STRING_LENGTH-1] = 0; +- strncpy(description->version, desc.version, DAUDIO_STRING_LENGTH-1); +- description->version[DAUDIO_STRING_LENGTH-1] = 0; +- /*strncpy(description->description, desc.description, DAUDIO_STRING_LENGTH-1);*/ +- strncpy(description->description, "Solaris Mixer", DAUDIO_STRING_LENGTH-1); +- description->description[DAUDIO_STRING_LENGTH-1] = 0; +- return TRUE; +- } +- return FALSE; +- +-} +- +-#define MAX_SAMPLE_RATES 20 +- +-void DAUDIO_GetFormats(INT32 mixerIndex, INT32 deviceID, int isSource, void* creator) { +- int fd = -1; +- AudioDeviceDescription desc; +- am_sample_rates_t *sr; +- /* hardcoded bits and channels */ +- int bits[] = {8, 16}; +- int bitsCount = 2; +- int channels[] = {1, 2}; +- int channelsCount = 2; +- /* for querying sample rates */ +- int err; +- int ch, b; +- uint_t s; +- +- TRACE2("DAUDIO_GetFormats, mixer %d, isSource=%d\n", mixerIndex, isSource); +- if (getAudioDeviceDescriptionByIndex(mixerIndex, &desc, FALSE)) { +- fd = open(desc.pathctl, O_RDONLY); +- } +- if (fd < 0) { +- ERROR1("Couldn't open audio device ctl for device %d!\n", mixerIndex); +- return; +- } +- +- /* get sample rates */ +- sr = (am_sample_rates_t*) malloc(AUDIO_MIXER_SAMP_RATES_STRUCT_SIZE(MAX_SAMPLE_RATES)); +- if (sr == NULL) { +- ERROR1("DAUDIO_GetFormats: out of memory for mixer %d\n", (int) mixerIndex); +- close(fd); +- return; +- } +- +- sr->num_samp_rates = MAX_SAMPLE_RATES; +- sr->type = isSource?AUDIO_PLAY:AUDIO_RECORD; +- sr->samp_rates[0] = -2; +- err = ioctl(fd, AUDIO_MIXER_GET_SAMPLE_RATES, sr); +- if (err < 0) { +- ERROR1(" DAUDIO_GetFormats: AUDIO_MIXER_GET_SAMPLE_RATES failed for mixer %d!\n", +- (int)mixerIndex); +- ERROR2(" -> num_sample_rates=%d sample_rates[0] = %d\n", +- (int) sr->num_samp_rates, +- (int) sr->samp_rates[0]); +- /* Some Solaris 8 drivers fail for get sample rates! +- * Do as if we support all sample rates +- */ +- sr->flags = MIXER_SR_LIMITS; +- } +- if ((sr->flags & MIXER_SR_LIMITS) +- || (sr->num_samp_rates > MAX_SAMPLE_RATES)) { +-#ifdef USE_TRACE +- if ((sr->flags & MIXER_SR_LIMITS)) { +- TRACE1(" DAUDIO_GetFormats: floating sample rate allowed by mixer %d\n", +- (int)mixerIndex); +- } +- if (sr->num_samp_rates > MAX_SAMPLE_RATES) { +- TRACE2(" DAUDIO_GetFormats: more than %d formats. Use -1 for sample rates mixer %d\n", +- MAX_SAMPLE_RATES, (int)mixerIndex); +- } +-#endif +- /* +- * Fake it to have only one sample rate: -1 +- */ +- sr->num_samp_rates = 1; +- sr->samp_rates[0] = -1; +- } +- close(fd); +- +- for (ch = 0; ch < channelsCount; ch++) { +- for (b = 0; b < bitsCount; b++) { +- for (s = 0; s < sr->num_samp_rates; s++) { +- DAUDIO_AddAudioFormat(creator, +- bits[b], /* significant bits */ +- 0, /* frameSize: let it be calculated */ +- channels[ch], +- (float) ((int) sr->samp_rates[s]), +- DAUDIO_PCM, /* encoding - let's only do PCM */ +- (bits[b] > 8)?TRUE:TRUE, /* isSigned */ +-#ifdef _LITTLE_ENDIAN +- FALSE /* little endian */ +-#else +- (bits[b] > 8)?TRUE:FALSE /* big endian */ +-#endif +- ); +- } +- } +- } +- free(sr); +-} +- +- +-typedef struct { +- int fd; +- audio_info_t info; +- int bufferSizeInBytes; +- int frameSize; /* storage size in Bytes */ +- /* how many bytes were written or read */ +- INT32 transferedBytes; +- /* if transferedBytes exceed 32-bit boundary, +- * it will be reset and positionOffset will receive +- * the offset +- */ +- INT64 positionOffset; +-} SolPcmInfo; +- +- +-void* DAUDIO_Open(INT32 mixerIndex, INT32 deviceID, int isSource, +- int encoding, float sampleRate, int sampleSizeInBits, +- int frameSize, int channels, +- int isSigned, int isBigEndian, int bufferSizeInBytes) { +- int err = 0; +- int openMode; +- AudioDeviceDescription desc; +- SolPcmInfo* info; +- +- TRACE0("> DAUDIO_Open\n"); +- if (encoding != DAUDIO_PCM) { +- ERROR1(" DAUDIO_Open: invalid encoding %d\n", (int) encoding); +- return NULL; +- } +- if (channels <= 0) { +- ERROR1(" DAUDIO_Open: Invalid number of channels=%d!\n", channels); +- return NULL; +- } +- +- info = (SolPcmInfo*) malloc(sizeof(SolPcmInfo)); +- if (!info) { +- ERROR0("Out of memory\n"); +- return NULL; +- } +- memset(info, 0, sizeof(SolPcmInfo)); +- info->frameSize = frameSize; +- info->fd = -1; +- +- if (isSource) { +- openMode = O_WRONLY; +- } else { +- openMode = O_RDONLY; +- } +- +-#ifndef __linux__ +- /* blackdown does not use NONBLOCK */ +- openMode |= O_NONBLOCK; +-#endif +- +- if (getAudioDeviceDescriptionByIndex(mixerIndex, &desc, FALSE)) { +- info->fd = open(desc.path, openMode); +- } +- if (info->fd < 0) { +- ERROR1("Couldn't open audio device for mixer %d!\n", mixerIndex); +- free(info); +- return NULL; +- } +- /* set to multiple open */ +- if (ioctl(info->fd, AUDIO_MIXER_MULTIPLE_OPEN, NULL) >= 0) { +- TRACE1("DAUDIO_Open: %s set to multiple open\n", desc.path); +- } else { +- ERROR1("DAUDIO_Open: ioctl AUDIO_MIXER_MULTIPLE_OPEN failed on %s!\n", desc.path); +- } +- +- AUDIO_INITINFO(&(info->info)); +- /* need AUDIO_GETINFO ioctl to get this to work on solaris x86 */ +- err = ioctl(info->fd, AUDIO_GETINFO, &(info->info)); +- +- /* not valid to call AUDIO_SETINFO ioctl with all the fields from AUDIO_GETINFO. */ +- AUDIO_INITINFO(&(info->info)); +- +- if (isSource) { +- info->info.play.sample_rate = sampleRate; +- info->info.play.precision = sampleSizeInBits; +- info->info.play.channels = channels; +- info->info.play.encoding = AUDIO_ENCODING_LINEAR; +- info->info.play.buffer_size = bufferSizeInBytes; +- info->info.play.pause = 1; +- } else { +- info->info.record.sample_rate = sampleRate; +- info->info.record.precision = sampleSizeInBits; +- info->info.record.channels = channels; +- info->info.record.encoding = AUDIO_ENCODING_LINEAR; +- info->info.record.buffer_size = bufferSizeInBytes; +- info->info.record.pause = 1; +- } +- err = ioctl(info->fd, AUDIO_SETINFO, &(info->info)); +- if (err < 0) { +- ERROR0("DAUDIO_Open: could not set info!\n"); +- DAUDIO_Close((void*) info, isSource); +- return NULL; +- } +- DAUDIO_Flush((void*) info, isSource); +- +- err = ioctl(info->fd, AUDIO_GETINFO, &(info->info)); +- if (err >= 0) { +- if (isSource) { +- info->bufferSizeInBytes = info->info.play.buffer_size; +- } else { +- info->bufferSizeInBytes = info->info.record.buffer_size; +- } +- TRACE2("DAUDIO: buffersize in bytes: requested=%d, got %d\n", +- (int) bufferSizeInBytes, +- (int) info->bufferSizeInBytes); +- } else { +- ERROR0("DAUDIO_Open: cannot get info!\n"); +- DAUDIO_Close((void*) info, isSource); +- return NULL; +- } +- TRACE0("< DAUDIO_Open: Opened device successfully.\n"); +- return (void*) info; +-} +- +- +-int DAUDIO_Start(void* id, int isSource) { +- SolPcmInfo* info = (SolPcmInfo*) id; +- int err, modified; +- audio_info_t audioInfo; +- +- TRACE0("> DAUDIO_Start\n"); +- +- AUDIO_INITINFO(&audioInfo); +- err = ioctl(info->fd, AUDIO_GETINFO, &audioInfo); +- if (err >= 0) { +- // unpause +- modified = FALSE; +- if (isSource && audioInfo.play.pause) { +- audioInfo.play.pause = 0; +- modified = TRUE; +- } +- if (!isSource && audioInfo.record.pause) { +- audioInfo.record.pause = 0; +- modified = TRUE; +- } +- if (modified) { +- err = ioctl(info->fd, AUDIO_SETINFO, &audioInfo); +- } +- } +- +- TRACE1("< DAUDIO_Start %s\n", (err>=0)?"success":"error"); +- return (err >= 0)?TRUE:FALSE; +-} +- +-int DAUDIO_Stop(void* id, int isSource) { +- SolPcmInfo* info = (SolPcmInfo*) id; +- int err, modified; +- audio_info_t audioInfo; +- +- TRACE0("> DAUDIO_Stop\n"); +- +- AUDIO_INITINFO(&audioInfo); +- err = ioctl(info->fd, AUDIO_GETINFO, &audioInfo); +- if (err >= 0) { +- // pause +- modified = FALSE; +- if (isSource && !audioInfo.play.pause) { +- audioInfo.play.pause = 1; +- modified = TRUE; +- } +- if (!isSource && !audioInfo.record.pause) { +- audioInfo.record.pause = 1; +- modified = TRUE; +- } +- if (modified) { +- err = ioctl(info->fd, AUDIO_SETINFO, &audioInfo); +- } +- } +- +- TRACE1("< DAUDIO_Stop %s\n", (err>=0)?"success":"error"); +- return (err >= 0)?TRUE:FALSE; +-} +- +-void DAUDIO_Close(void* id, int isSource) { +- SolPcmInfo* info = (SolPcmInfo*) id; +- +- TRACE0("DAUDIO_Close\n"); +- if (info != NULL) { +- if (info->fd >= 0) { +- DAUDIO_Flush(id, isSource); +- close(info->fd); +- } +- free(info); +- } +-} +- +-#ifndef USE_TRACE +-/* close to 2^31 */ +-#define POSITION_MAX 2000000000 +-#else +-/* for testing */ +-#define POSITION_MAX 1000000 +-#endif +- +-void resetErrorFlagAndAdjustPosition(SolPcmInfo* info, int isSource, int count) { +- audio_info_t audioInfo; +- audio_prinfo_t* prinfo; +- int err; +- int offset = -1; +- int underrun = FALSE; +- int devBytes = 0; +- +- if (count > 0) { +- info->transferedBytes += count; +- +- if (isSource) { +- prinfo = &(audioInfo.play); +- } else { +- prinfo = &(audioInfo.record); +- } +- AUDIO_INITINFO(&audioInfo); +- err = ioctl(info->fd, AUDIO_GETINFO, &audioInfo); +- if (err >= 0) { +- underrun = prinfo->error; +- devBytes = prinfo->samples * info->frameSize; +- } +- AUDIO_INITINFO(&audioInfo); +- if (underrun) { +- /* if an underrun occurred, reset */ +- ERROR1("DAUDIO_Write/Read: Underrun/overflow: adjusting positionOffset by %d:\n", +- (devBytes - info->transferedBytes)); +- ERROR1(" devBytes from %d to 0, ", devBytes); +- ERROR2(" positionOffset from %d to %d ", +- (int) info->positionOffset, +- (int) (info->positionOffset + info->transferedBytes)); +- ERROR1(" transferedBytes from %d to 0\n", +- (int) info->transferedBytes); +- prinfo->samples = 0; +- info->positionOffset += info->transferedBytes; +- info->transferedBytes = 0; +- } +- else if (info->transferedBytes > POSITION_MAX) { +- /* we will reset transferedBytes and +- * the samples field in prinfo +- */ +- offset = devBytes; +- prinfo->samples = 0; +- } +- /* reset error flag */ +- prinfo->error = 0; +- +- err = ioctl(info->fd, AUDIO_SETINFO, &audioInfo); +- if (err >= 0) { +- if (offset > 0) { +- /* upon exit of AUDIO_SETINFO, the samples parameter +- * was set to the previous value. This is our +- * offset. +- */ +- TRACE1("Adjust samplePos: offset=%d, ", (int) offset); +- TRACE2("transferedBytes=%d -> %d, ", +- (int) info->transferedBytes, +- (int) (info->transferedBytes - offset)); +- TRACE2("positionOffset=%d -> %d\n", +- (int) (info->positionOffset), +- (int) (((int) info->positionOffset) + offset)); +- info->transferedBytes -= offset; +- info->positionOffset += offset; +- } +- } else { +- ERROR0("DAUDIO: resetErrorFlagAndAdjustPosition ioctl failed!\n"); +- } +- } +-} +- +-// returns -1 on error +-int DAUDIO_Write(void* id, char* data, int byteSize) { +- SolPcmInfo* info = (SolPcmInfo*) id; +- int ret = -1; +- +- TRACE1("> DAUDIO_Write %d bytes\n", byteSize); +- if (info!=NULL) { +- ret = write(info->fd, data, byteSize); +- resetErrorFlagAndAdjustPosition(info, TRUE, ret); +- /* sets ret to -1 if buffer full, no error! */ +- if (ret < 0) { +- ret = 0; +- } +- } +- TRACE1("< DAUDIO_Write: returning %d bytes.\n", ret); +- return ret; +-} +- +-// returns -1 on error +-int DAUDIO_Read(void* id, char* data, int byteSize) { +- SolPcmInfo* info = (SolPcmInfo*) id; +- int ret = -1; +- +- TRACE1("> DAUDIO_Read %d bytes\n", byteSize); +- if (info != NULL) { +- ret = read(info->fd, data, byteSize); +- resetErrorFlagAndAdjustPosition(info, TRUE, ret); +- /* sets ret to -1 if buffer full, no error! */ +- if (ret < 0) { +- ret = 0; +- } +- } +- TRACE1("< DAUDIO_Read: returning %d bytes.\n", ret); +- return ret; +-} +- +- +-int DAUDIO_GetBufferSize(void* id, int isSource) { +- SolPcmInfo* info = (SolPcmInfo*) id; +- if (info) { +- return info->bufferSizeInBytes; +- } +- return 0; +-} +- +-int DAUDIO_StillDraining(void* id, int isSource) { +- SolPcmInfo* info = (SolPcmInfo*) id; +- audio_info_t audioInfo; +- audio_prinfo_t* prinfo; +- int ret = FALSE; +- +- if (info!=NULL) { +- if (isSource) { +- prinfo = &(audioInfo.play); +- } else { +- prinfo = &(audioInfo.record); +- } +- /* check error flag */ +- AUDIO_INITINFO(&audioInfo); +- ioctl(info->fd, AUDIO_GETINFO, &audioInfo); +- ret = (prinfo->error != 0)?FALSE:TRUE; +- } +- return ret; +-} +- +- +-int getDevicePosition(SolPcmInfo* info, int isSource) { +- audio_info_t audioInfo; +- audio_prinfo_t* prinfo; +- int err; +- +- if (isSource) { +- prinfo = &(audioInfo.play); +- } else { +- prinfo = &(audioInfo.record); +- } +- AUDIO_INITINFO(&audioInfo); +- err = ioctl(info->fd, AUDIO_GETINFO, &audioInfo); +- if (err >= 0) { +- /*TRACE2("---> device paused: %d eof=%d\n", +- prinfo->pause, prinfo->eof); +- */ +- return (int) (prinfo->samples * info->frameSize); +- } +- ERROR0("DAUDIO: getDevicePosition: ioctl failed!\n"); +- return -1; +-} +- +-int DAUDIO_Flush(void* id, int isSource) { +- SolPcmInfo* info = (SolPcmInfo*) id; +- int err = -1; +- int pos; +- +- TRACE0("DAUDIO_Flush\n"); +- if (info) { +- if (isSource) { +- err = ioctl(info->fd, I_FLUSH, FLUSHW); +- } else { +- err = ioctl(info->fd, I_FLUSH, FLUSHR); +- } +- if (err >= 0) { +- /* resets the transferedBytes parameter to +- * the current samples count of the device +- */ +- pos = getDevicePosition(info, isSource); +- if (pos >= 0) { +- info->transferedBytes = pos; +- } +- } +- } +- if (err < 0) { +- ERROR0("ERROR in DAUDIO_Flush\n"); +- } +- return (err < 0)?FALSE:TRUE; +-} +- +-int DAUDIO_GetAvailable(void* id, int isSource) { +- SolPcmInfo* info = (SolPcmInfo*) id; +- int ret = 0; +- int pos; +- +- if (info) { +- /* unfortunately, the STREAMS architecture +- * seems to not have a method for querying +- * the available bytes to read/write! +- * estimate it... +- */ +- pos = getDevicePosition(info, isSource); +- if (pos >= 0) { +- if (isSource) { +- /* we usually have written more bytes +- * to the queue than the device position should be +- */ +- ret = (info->bufferSizeInBytes) - (info->transferedBytes - pos); +- } else { +- /* for record, the device stream should +- * be usually ahead of our read actions +- */ +- ret = pos - info->transferedBytes; +- } +- if (ret > info->bufferSizeInBytes) { +- ERROR2("DAUDIO_GetAvailable: available=%d, too big at bufferSize=%d!\n", +- (int) ret, (int) info->bufferSizeInBytes); +- ERROR2(" devicePos=%d, transferedBytes=%d\n", +- (int) pos, (int) info->transferedBytes); +- ret = info->bufferSizeInBytes; +- } +- else if (ret < 0) { +- ERROR1("DAUDIO_GetAvailable: available=%d, in theory not possible!\n", +- (int) ret); +- ERROR2(" devicePos=%d, transferedBytes=%d\n", +- (int) pos, (int) info->transferedBytes); +- ret = 0; +- } +- } +- } +- +- TRACE1("DAUDIO_GetAvailable returns %d bytes\n", ret); +- return ret; +-} +- +-INT64 DAUDIO_GetBytePosition(void* id, int isSource, INT64 javaBytePos) { +- SolPcmInfo* info = (SolPcmInfo*) id; +- int ret; +- int pos; +- INT64 result = javaBytePos; +- +- if (info) { +- pos = getDevicePosition(info, isSource); +- if (pos >= 0) { +- result = info->positionOffset + pos; +- } +- } +- +- //printf("getbyteposition: javaBytePos=%d , return=%d\n", (int) javaBytePos, (int) result); +- return result; +-} +- +- +-void DAUDIO_SetBytePosition(void* id, int isSource, INT64 javaBytePos) { +- SolPcmInfo* info = (SolPcmInfo*) id; +- int ret; +- int pos; +- +- if (info) { +- pos = getDevicePosition(info, isSource); +- if (pos >= 0) { +- info->positionOffset = javaBytePos - pos; +- } +- } +-} +- +-int DAUDIO_RequiresServicing(void* id, int isSource) { +- // never need servicing on Solaris +- return FALSE; +-} +- +-void DAUDIO_Service(void* id, int isSource) { +- // never need servicing on Solaris +-} +- +- +-#endif // USE_DAUDIO +--- old/src/java.desktop/solaris/native/libjsound/PLATFORM_API_SolarisOS_Ports.c 2020-05-20 18:10:35.750280487 -0700 ++++ /dev/null 2020-03-09 18:57:19.455001459 -0700 +@@ -1,600 +0,0 @@ +-/* +- * Copyright (c) 2002, 2016, Oracle and/or its affiliates. All rights reserved. +- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. +- * +- * This code is free software; you can redistribute it and/or modify it +- * under the terms of the GNU General Public License version 2 only, as +- * published by the Free Software Foundation. Oracle designates this +- * particular file as subject to the "Classpath" exception as provided +- * by Oracle in the LICENSE file that accompanied this code. +- * +- * This code is distributed in the hope that it will be useful, but WITHOUT +- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +- * version 2 for more details (a copy is included in the LICENSE file that +- * accompanied this code). +- * +- * You should have received a copy of the GNU General Public License version +- * 2 along with this work; if not, write to the Free Software Foundation, +- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. +- * +- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA +- * or visit www.oracle.com if you need additional information or have any +- * questions. +- */ +- +-#define USE_ERROR +-//#define USE_TRACE +- +-#include "Ports.h" +-#include "PLATFORM_API_SolarisOS_Utils.h" +- +-#if USE_PORTS == TRUE +- +-#define MONITOR_GAIN_STRING "Monitor Gain" +- +-#define ALL_TARGET_PORT_COUNT 6 +- +-// define the following to not use audio_prinfo_t.mod_ports +-#define SOLARIS7_COMPATIBLE +- +-// Solaris audio defines +-static int targetPorts[ALL_TARGET_PORT_COUNT] = { +- AUDIO_SPEAKER, +- AUDIO_HEADPHONE, +- AUDIO_LINE_OUT, +- AUDIO_AUX1_OUT, +- AUDIO_AUX2_OUT, +- AUDIO_SPDIF_OUT +-}; +- +-static char* targetPortNames[ALL_TARGET_PORT_COUNT] = { +- "Speaker", +- "Headphone", +- "Line Out", +- "AUX1 Out", +- "AUX2 Out", +- "SPDIF Out" +-}; +- +-// defined in Ports.h +-static int targetPortJavaSoundMapping[ALL_TARGET_PORT_COUNT] = { +- PORT_DST_SPEAKER, +- PORT_DST_HEADPHONE, +- PORT_DST_LINE_OUT, +- PORT_DST_UNKNOWN, +- PORT_DST_UNKNOWN, +- PORT_DST_UNKNOWN, +-}; +- +-#define ALL_SOURCE_PORT_COUNT 7 +- +-// Solaris audio defines +-static int sourcePorts[ALL_SOURCE_PORT_COUNT] = { +- AUDIO_MICROPHONE, +- AUDIO_LINE_IN, +- AUDIO_CD, +- AUDIO_AUX1_IN, +- AUDIO_AUX2_IN, +- AUDIO_SPDIF_IN, +- AUDIO_CODEC_LOOPB_IN +-}; +- +-static char* sourcePortNames[ALL_SOURCE_PORT_COUNT] = { +- "Microphone In", +- "Line In", +- "Compact Disc In", +- "AUX1 In", +- "AUX2 In", +- "SPDIF In", +- "Internal Loopback" +-}; +- +-// Ports.h defines +-static int sourcePortJavaSoundMapping[ALL_SOURCE_PORT_COUNT] = { +- PORT_SRC_MICROPHONE, +- PORT_SRC_LINE_IN, +- PORT_SRC_COMPACT_DISC, +- PORT_SRC_UNKNOWN, +- PORT_SRC_UNKNOWN, +- PORT_SRC_UNKNOWN, +- PORT_SRC_UNKNOWN +-}; +- +-struct tag_PortControlID; +- +-typedef struct tag_PortInfo { +- int fd; // file descriptor of the pseudo device +- audio_info_t audioInfo; +- // ports +- int targetPortCount; +- int sourcePortCount; +- // indexes to sourcePorts/targetPorts +- // contains first target ports, then source ports +- int ports[ALL_TARGET_PORT_COUNT + ALL_SOURCE_PORT_COUNT]; +- // controls +- int maxControlCount; // upper bound of number of controls +- int usedControlIDs; // number of items already filled in controlIDs +- struct tag_PortControlID* controlIDs; // the control IDs themselves +-} PortInfo; +- +-#define PORT_CONTROL_TYPE_PLAY 0x4000000 +-#define PORT_CONTROL_TYPE_RECORD 0x8000000 +-#define PORT_CONTROL_TYPE_SELECT_PORT 1 +-#define PORT_CONTROL_TYPE_GAIN 2 +-#define PORT_CONTROL_TYPE_BALANCE 3 +-#define PORT_CONTROL_TYPE_MONITOR_GAIN 10 +-#define PORT_CONTROL_TYPE_OUTPUT_MUTED 11 +-#define PORT_CONTROL_TYPE_PLAYRECORD_MASK PORT_CONTROL_TYPE_PLAY | PORT_CONTROL_TYPE_RECORD +-#define PORT_CONTROL_TYPE_MASK 0xFFFFFF +- +- +-typedef struct tag_PortControlID { +- PortInfo* portInfo; +- INT32 controlType; // PORT_CONTROL_TYPE_XX +- uint_t port; +-} PortControlID; +- +- +-///// implemented functions of Ports.h +- +-INT32 PORT_GetPortMixerCount() { +- return (INT32) getAudioDeviceCount(); +-} +- +- +-INT32 PORT_GetPortMixerDescription(INT32 mixerIndex, PortMixerDescription* description) { +- AudioDeviceDescription desc; +- +- if (getAudioDeviceDescriptionByIndex(mixerIndex, &desc, TRUE)) { +- strncpy(description->name, desc.name, PORT_STRING_LENGTH-1); +- description->name[PORT_STRING_LENGTH-1] = 0; +- strncpy(description->vendor, desc.vendor, PORT_STRING_LENGTH-1); +- description->vendor[PORT_STRING_LENGTH-1] = 0; +- strncpy(description->version, desc.version, PORT_STRING_LENGTH-1); +- description->version[PORT_STRING_LENGTH-1] = 0; +- /*strncpy(description->description, desc.description, PORT_STRING_LENGTH-1);*/ +- strncpy(description->description, "Solaris Ports", PORT_STRING_LENGTH-1); +- description->description[PORT_STRING_LENGTH-1] = 0; +- return TRUE; +- } +- return FALSE; +-} +- +- +-void* PORT_Open(INT32 mixerIndex) { +- PortInfo* info = NULL; +- int fd = -1; +- AudioDeviceDescription desc; +- int success = FALSE; +- +- TRACE0("PORT_Open\n"); +- if (getAudioDeviceDescriptionByIndex(mixerIndex, &desc, FALSE)) { +- fd = open(desc.pathctl, O_RDWR); +- } +- if (fd < 0) { +- ERROR1("Couldn't open audio device ctl for device %d!\n", mixerIndex); +- return NULL; +- } +- +- info = (PortInfo*) malloc(sizeof(PortInfo)); +- if (info != NULL) { +- memset(info, 0, sizeof(PortInfo)); +- info->fd = fd; +- success = TRUE; +- } +- if (!success) { +- if (fd >= 0) { +- close(fd); +- } +- PORT_Close((void*) info); +- info = NULL; +- } +- return info; +-} +- +-void PORT_Close(void* id) { +- TRACE0("PORT_Close\n"); +- if (id != NULL) { +- PortInfo* info = (PortInfo*) id; +- if (info->fd >= 0) { +- close(info->fd); +- info->fd = -1; +- } +- if (info->controlIDs) { +- free(info->controlIDs); +- info->controlIDs = NULL; +- } +- free(info); +- } +-} +- +- +- +-INT32 PORT_GetPortCount(void* id) { +- int ret = 0; +- PortInfo* info = (PortInfo*) id; +- if (info != NULL) { +- if (!info->targetPortCount && !info->sourcePortCount) { +- int i; +- AUDIO_INITINFO(&info->audioInfo); +- if (ioctl(info->fd, AUDIO_GETINFO, &info->audioInfo) >= 0) { +- for (i = 0; i < ALL_TARGET_PORT_COUNT; i++) { +- if (info->audioInfo.play.avail_ports & targetPorts[i]) { +- info->ports[info->targetPortCount] = i; +- info->targetPortCount++; +- } +-#ifdef SOLARIS7_COMPATIBLE +- TRACE3("Target %d %s: avail=%d\n", i, targetPortNames[i], +- info->audioInfo.play.avail_ports & targetPorts[i]); +-#else +- TRACE4("Target %d %s: avail=%d mod=%d\n", i, targetPortNames[i], +- info->audioInfo.play.avail_ports & targetPorts[i], +- info->audioInfo.play.mod_ports & targetPorts[i]); +-#endif +- } +- for (i = 0; i < ALL_SOURCE_PORT_COUNT; i++) { +- if (info->audioInfo.record.avail_ports & sourcePorts[i]) { +- info->ports[info->targetPortCount + info->sourcePortCount] = i; +- info->sourcePortCount++; +- } +-#ifdef SOLARIS7_COMPATIBLE +- TRACE3("Source %d %s: avail=%d\n", i, sourcePortNames[i], +- info->audioInfo.record.avail_ports & sourcePorts[i]); +-#else +- TRACE4("Source %d %s: avail=%d mod=%d\n", i, sourcePortNames[i], +- info->audioInfo.record.avail_ports & sourcePorts[i], +- info->audioInfo.record.mod_ports & sourcePorts[i]); +-#endif +- } +- } +- } +- ret = info->targetPortCount + info->sourcePortCount; +- } +- return ret; +-} +- +-int isSourcePort(PortInfo* info, INT32 portIndex) { +- return (portIndex >= info->targetPortCount); +-} +- +-INT32 PORT_GetPortType(void* id, INT32 portIndex) { +- PortInfo* info = (PortInfo*) id; +- if ((portIndex >= 0) && (portIndex < PORT_GetPortCount(id))) { +- if (isSourcePort(info, portIndex)) { +- return sourcePortJavaSoundMapping[info->ports[portIndex]]; +- } else { +- return targetPortJavaSoundMapping[info->ports[portIndex]]; +- } +- } +- return 0; +-} +- +-// pre-condition: portIndex must have been verified! +-char* getPortName(PortInfo* info, INT32 portIndex) { +- char* ret = NULL; +- +- if (isSourcePort(info, portIndex)) { +- ret = sourcePortNames[info->ports[portIndex]]; +- } else { +- ret = targetPortNames[info->ports[portIndex]]; +- } +- return ret; +-} +- +-INT32 PORT_GetPortName(void* id, INT32 portIndex, char* name, INT32 len) { +- PortInfo* info = (PortInfo*) id; +- char* n; +- +- if ((portIndex >= 0) && (portIndex < PORT_GetPortCount(id))) { +- n = getPortName(info, portIndex); +- if (n) { +- strncpy(name, n, len-1); +- name[len-1] = 0; +- return TRUE; +- } +- } +- return FALSE; +-} +- +-void createPortControl(PortInfo* info, PortControlCreator* creator, INT32 portIndex, +- INT32 type, void** controlObjects, int* controlCount) { +- PortControlID* controlID; +- void* newControl = NULL; +- int controlIndex; +- char* jsType = NULL; +- int isBoolean = FALSE; +- +- TRACE0(">createPortControl\n"); +- +- // fill the ControlID structure and add this control +- if (info->usedControlIDs >= info->maxControlCount) { +- ERROR1("not enough free controlIDs !! maxControlIDs = %d\n", info->maxControlCount); +- return; +- } +- controlID = &(info->controlIDs[info->usedControlIDs]); +- controlID->portInfo = info; +- controlID->controlType = type; +- controlIndex = info->ports[portIndex]; +- if (isSourcePort(info, portIndex)) { +- controlID->port = sourcePorts[controlIndex]; +- } else { +- controlID->port = targetPorts[controlIndex]; +- } +- switch (type & PORT_CONTROL_TYPE_MASK) { +- case PORT_CONTROL_TYPE_SELECT_PORT: +- jsType = CONTROL_TYPE_SELECT; isBoolean = TRUE; break; +- case PORT_CONTROL_TYPE_GAIN: +- jsType = CONTROL_TYPE_VOLUME; break; +- case PORT_CONTROL_TYPE_BALANCE: +- jsType = CONTROL_TYPE_BALANCE; break; +- case PORT_CONTROL_TYPE_MONITOR_GAIN: +- jsType = CONTROL_TYPE_VOLUME; break; +- case PORT_CONTROL_TYPE_OUTPUT_MUTED: +- jsType = CONTROL_TYPE_MUTE; isBoolean = TRUE; break; +- } +- if (isBoolean) { +- TRACE0(" PORT_CONTROL_TYPE_BOOLEAN\n"); +- newControl = (creator->newBooleanControl)(creator, controlID, jsType); +- } +- else if (jsType == CONTROL_TYPE_BALANCE) { +- TRACE0(" PORT_CONTROL_TYPE_BALANCE\n"); +- newControl = (creator->newFloatControl)(creator, controlID, jsType, +- -1.0f, 1.0f, 2.0f / 65.0f, ""); +- } else { +- TRACE0(" PORT_CONTROL_TYPE_FLOAT\n"); +- newControl = (creator->newFloatControl)(creator, controlID, jsType, +- 0.0f, 1.0f, 1.0f / 256.0f, ""); +- } +- if (newControl) { +- controlObjects[*controlCount] = newControl; +- (*controlCount)++; +- info->usedControlIDs++; +- } +- TRACE0("addCompoundControl %d controls\n", *controlCount); +- if (*controlCount) { +- // create compound control and add it to the vector +- compControl = (creator->newCompoundControl)(creator, name, controlObjects, *controlCount); +- if (compControl) { +- TRACE1(" addCompoundControl: calling addControl %p\n", compControl); +- (creator->addControl)(creator, compControl); +- } +- *controlCount = 0; +- } +- TRACE0("addAllControl\n"); +- // go through all controls and add them to the vector +- for (i = 0; i < *controlCount; i++) { +- (creator->addControl)(creator, controlObjects[i]); +- } +- *controlCount = 0; +- TRACE0("PORT_GetControls(id=%p, portIndex=%d). controlIDs=%p, maxControlCount=%d\n", +- id, portIndex, info->controlIDs, info->maxControlCount); +- if ((portIndex >= 0) && (portIndex < portCount)) { +- // if the memory isn't reserved for the control structures, allocate it +- if (!info->controlIDs) { +- int maxCount = 0; +- TRACE0("getControl: allocate mem\n"); +- // get a maximum number of controls: +- // each port has a select, balance, and volume control. +- maxCount = 3 * portCount; +- // then there is monitorGain and outputMuted +- maxCount += (2 * info->targetPortCount); +- info->maxControlCount = maxCount; +- info->controlIDs = (PortControlID*) malloc(sizeof(PortControlID) * maxCount); +- } +- if (!isSourcePort(info, portIndex)) { +- type = PORT_CONTROL_TYPE_PLAY; +- // add master mute control +- createPortControl(info, creator, portIndex, +- type | PORT_CONTROL_TYPE_OUTPUT_MUTED, +- controls, &controlCount); +- addAllControls(info, creator, controls, &controlCount); +-#ifdef SOLARIS7_COMPATIBLE +- selectable = info->audioInfo.play.avail_ports & targetPorts[info->ports[portIndex]]; +-#else +- selectable = info->audioInfo.play.mod_ports & targetPorts[info->ports[portIndex]]; +-#endif +- } else { +- type = PORT_CONTROL_TYPE_RECORD; +-#ifdef SOLARIS7_COMPATIBLE +- selectable = info->audioInfo.record.avail_ports & sourcePorts[info->ports[portIndex]]; +-#else +- selectable = info->audioInfo.record.mod_ports & sourcePorts[info->ports[portIndex]]; +-#endif +- } +- // add a mixer strip with volume, ... +- createPortControl(info, creator, portIndex, +- type | PORT_CONTROL_TYPE_GAIN, +- controls, &controlCount); +- // ... balance, ... +- createPortControl(info, creator, portIndex, +- type | PORT_CONTROL_TYPE_BALANCE, +- controls, &controlCount); +- // ... and select control (if not always on)... +- if (selectable) { +- createPortControl(info, creator, portIndex, +- type | PORT_CONTROL_TYPE_SELECT_PORT, +- controls, &controlCount); +- } +- // ... packaged in a compound control. +- addCompoundControl(info, creator, getPortName(info, portIndex), controls, &controlCount); +- +- if (type == PORT_CONTROL_TYPE_PLAY) { +- // add a single strip for source ports with monitor gain +- createPortControl(info, creator, portIndex, +- type | PORT_CONTROL_TYPE_MONITOR_GAIN, +- controls, &controlCount); +- // also in a compound control +- addCompoundControl(info, creator, MONITOR_GAIN_STRING, controls, &controlCount); +- } +- } +- TRACE0("< PORT_getControls\n"); +-} +- +-INT32 PORT_GetIntValue(void* controlIDV) { +- PortControlID* controlID = (PortControlID*) controlIDV; +- audio_info_t audioInfo; +- audio_prinfo_t* prinfo; +- +- AUDIO_INITINFO(&audioInfo); +- if (ioctl(controlID->portInfo->fd, AUDIO_GETINFO, &audioInfo) >= 0) { +- if (controlID->controlType & PORT_CONTROL_TYPE_PLAY) { +- prinfo = &(audioInfo.play); +- } else { +- prinfo = &(audioInfo.record); +- } +- switch (controlID->controlType & PORT_CONTROL_TYPE_MASK) { +- case PORT_CONTROL_TYPE_SELECT_PORT: +- return (prinfo->port & controlID->port)?TRUE:FALSE; +- case PORT_CONTROL_TYPE_OUTPUT_MUTED: +- return (audioInfo.output_muted)?TRUE:FALSE; +- default: +- ERROR1("PORT_GetIntValue: Wrong type %d !\n", controlID->controlType & PORT_CONTROL_TYPE_MASK); +- } +- } +- ERROR0("PORT_GetIntValue: Could not ioctl!\n"); +- return 0; +-} +- +-void PORT_SetIntValue(void* controlIDV, INT32 value) { +- PortControlID* controlID = (PortControlID*) controlIDV; +- audio_info_t audioInfo; +- audio_prinfo_t* prinfo; +- int setPort; +- +- if (controlID->controlType & PORT_CONTROL_TYPE_PLAY) { +- prinfo = &(audioInfo.play); +- } else { +- prinfo = &(audioInfo.record); +- } +- switch (controlID->controlType & PORT_CONTROL_TYPE_MASK) { +- case PORT_CONTROL_TYPE_SELECT_PORT: +- // first try to just add this port. if that fails, set ONLY to this port. +- AUDIO_INITINFO(&audioInfo); +- if (ioctl(controlID->portInfo->fd, AUDIO_GETINFO, &audioInfo) >= 0) { +- if (value) { +- setPort = (prinfo->port | controlID->port); +- } else { +- setPort = (prinfo->port - controlID->port); +- } +- AUDIO_INITINFO(&audioInfo); +- prinfo->port = setPort; +- if (ioctl(controlID->portInfo->fd, AUDIO_SETINFO, &audioInfo) < 0) { +- // didn't work. Either this line doesn't support to select several +- // ports at once (e.g. record), or a real error +- if (value) { +- // set to ONLY this port (and disable any other currently selected ports) +- AUDIO_INITINFO(&audioInfo); +- prinfo->port = controlID->port; +- if (ioctl(controlID->portInfo->fd, AUDIO_SETINFO, &audioInfo) < 0) { +- ERROR2("Error setting output select port %d to port %d!\n", controlID->port, controlID->port); +- } +- } else { +- // assume it's an error +- ERROR2("Error setting output select port %d to port %d!\n", controlID->port, setPort); +- } +- } +- break; +- case PORT_CONTROL_TYPE_OUTPUT_MUTED: +- AUDIO_INITINFO(&audioInfo); +- audioInfo.output_muted = (value?TRUE:FALSE); +- if (ioctl(controlID->portInfo->fd, AUDIO_SETINFO, &audioInfo) < 0) { +- ERROR2("Error setting output muted on port %d to %d!\n", controlID->port, value); +- } +- break; +- default: +- ERROR1("PORT_SetIntValue: Wrong type %d !\n", controlID->controlType & PORT_CONTROL_TYPE_MASK); +- } +- } +-} +- +-float PORT_GetFloatValue(void* controlIDV) { +- PortControlID* controlID = (PortControlID*) controlIDV; +- audio_info_t audioInfo; +- audio_prinfo_t* prinfo; +- +- AUDIO_INITINFO(&audioInfo); +- if (ioctl(controlID->portInfo->fd, AUDIO_GETINFO, &audioInfo) >= 0) { +- if (controlID->controlType & PORT_CONTROL_TYPE_PLAY) { +- prinfo = &(audioInfo.play); +- } else { +- prinfo = &(audioInfo.record); +- } +- switch (controlID->controlType & PORT_CONTROL_TYPE_MASK) { +- case PORT_CONTROL_TYPE_GAIN: +- return ((float) (prinfo->gain - AUDIO_MIN_GAIN)) +- / ((float) (AUDIO_MAX_GAIN - AUDIO_MIN_GAIN)); +- case PORT_CONTROL_TYPE_BALANCE: +- return ((float) ((prinfo->balance - AUDIO_LEFT_BALANCE - AUDIO_MID_BALANCE) << 1)) +- / ((float) (AUDIO_RIGHT_BALANCE - AUDIO_LEFT_BALANCE)); +- case PORT_CONTROL_TYPE_MONITOR_GAIN: +- return ((float) (audioInfo.monitor_gain - AUDIO_MIN_GAIN)) +- / ((float) (AUDIO_MAX_GAIN - AUDIO_MIN_GAIN)); +- default: +- ERROR1("PORT_GetFloatValue: Wrong type %d !\n", controlID->controlType & PORT_CONTROL_TYPE_MASK); +- } +- } +- ERROR0("PORT_GetFloatValue: Could not ioctl!\n"); +- return 0.0f; +-} +- +-void PORT_SetFloatValue(void* controlIDV, float value) { +- PortControlID* controlID = (PortControlID*) controlIDV; +- audio_info_t audioInfo; +- audio_prinfo_t* prinfo; +- +- AUDIO_INITINFO(&audioInfo); +- +- if (controlID->controlType & PORT_CONTROL_TYPE_PLAY) { +- prinfo = &(audioInfo.play); +- } else { +- prinfo = &(audioInfo.record); +- } +- switch (controlID->controlType & PORT_CONTROL_TYPE_MASK) { +- case PORT_CONTROL_TYPE_GAIN: +- prinfo->gain = AUDIO_MIN_GAIN +- + (int) ((value * ((float) (AUDIO_MAX_GAIN - AUDIO_MIN_GAIN))) + 0.5f); +- break; +- case PORT_CONTROL_TYPE_BALANCE: +- prinfo->balance = AUDIO_LEFT_BALANCE + AUDIO_MID_BALANCE +- + ((int) (value * ((float) ((AUDIO_RIGHT_BALANCE - AUDIO_LEFT_BALANCE) >> 1))) + 0.5f); +- break; +- case PORT_CONTROL_TYPE_MONITOR_GAIN: +- audioInfo.monitor_gain = AUDIO_MIN_GAIN +- + (int) ((value * ((float) (AUDIO_MAX_GAIN - AUDIO_MIN_GAIN))) + 0.5f); +- break; +- default: +- ERROR1("PORT_SetFloatValue: Wrong type %d !\n", controlID->controlType & PORT_CONTROL_TYPE_MASK); +- return; +- } +- if (ioctl(controlID->portInfo->fd, AUDIO_SETINFO, &audioInfo) < 0) { +- ERROR0("PORT_SetFloatValue: Could not ioctl!\n"); +- } +-} +- +-#endif // USE_PORTS +--- old/src/java.desktop/solaris/native/libjsound/PLATFORM_API_SolarisOS_Utils.c 2020-05-20 18:10:36.498294848 -0700 ++++ /dev/null 2020-03-09 18:57:19.455001459 -0700 +@@ -1,193 +0,0 @@ +-/* +- * Copyright (c) 2002, 2007, Oracle and/or its affiliates. All rights reserved. +- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. +- * +- * This code is free software; you can redistribute it and/or modify it +- * under the terms of the GNU General Public License version 2 only, as +- * published by the Free Software Foundation. Oracle designates this +- * particular file as subject to the "Classpath" exception as provided +- * by Oracle in the LICENSE file that accompanied this code. +- * +- * This code is distributed in the hope that it will be useful, but WITHOUT +- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +- * version 2 for more details (a copy is included in the LICENSE file that +- * accompanied this code). +- * +- * You should have received a copy of the GNU General Public License version +- * 2 along with this work; if not, write to the Free Software Foundation, +- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. +- * +- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA +- * or visit www.oracle.com if you need additional information or have any +- * questions. +- */ +- +-#define USE_ERROR +-#define USE_TRACE +- +-#include "PLATFORM_API_SolarisOS_Utils.h" +- +-#define MAX_AUDIO_DEVICES 20 +- +-// not thread safe... +-static AudioDevicePath globalADPaths[MAX_AUDIO_DEVICES]; +-static int globalADCount = -1; +-static int globalADCacheTime = -1; +-/* how many seconds do we cache devices */ +-#define AD_CACHE_TIME 30 +- +-// return seconds +-long getTimeInSeconds() { +- struct timeval tv; +- gettimeofday(&tv, NULL); +- return tv.tv_sec; +-} +- +- +-int getAudioDeviceCount() { +- int count = MAX_AUDIO_DEVICES; +- +- getAudioDevices(globalADPaths, &count); +- return count; +-} +- +-/* returns TRUE if the path exists at all */ +-int addAudioDevice(char* path, AudioDevicePath* adPath, int* count) { +- int i; +- int found = 0; +- int fileExists = 0; +- // not thread safe... +- static struct stat statBuf; +- +- // get stats on the file +- if (stat(path, &statBuf) == 0) { +- // file exists. +- fileExists = 1; +- // If it is not yet in the adPath array, add it to the array +- for (i = 0; i < *count; i++) { +- if (adPath[i].st_ino == statBuf.st_ino +- && adPath[i].st_dev == statBuf.st_dev) { +- found = 1; +- break; +- } +- } +- if (!found) { +- adPath[*count].st_ino = statBuf.st_ino; +- adPath[*count].st_dev = statBuf.st_dev; +- strncpy(adPath[*count].path, path, MAX_NAME_LENGTH); +- adPath[*count].path[MAX_NAME_LENGTH - 1] = 0; +- (*count)++; +- TRACE1("Added audio device %s\n", path); +- } +- } +- return fileExists; +-} +- +- +-void getAudioDevices(AudioDevicePath* adPath, int* count) { +- int maxCount = *count; +- char* audiodev; +- char devsound[15]; +- int i; +- long timeInSeconds = getTimeInSeconds(); +- +- if (globalADCount < 0 +- || (getTimeInSeconds() - globalADCacheTime) > AD_CACHE_TIME +- || (adPath != globalADPaths)) { +- *count = 0; +- // first device, if set, is AUDIODEV variable +- audiodev = getenv("AUDIODEV"); +- if (audiodev != NULL && audiodev[0] != 0) { +- addAudioDevice(audiodev, adPath, count); +- } +- // then try /dev/audio +- addAudioDevice("/dev/audio", adPath, count); +- // then go through all of the /dev/sound/? devices +- for (i = 0; i < 100; i++) { +- sprintf(devsound, "/dev/sound/%d", i); +- if (!addAudioDevice(devsound, adPath, count)) { +- break; +- } +- } +- if (adPath == globalADPaths) { +- /* commit cache */ +- globalADCount = *count; +- /* set cache time */ +- globalADCacheTime = timeInSeconds; +- } +- } else { +- /* return cache */ +- *count = globalADCount; +- } +- // that's it +-} +- +-int getAudioDeviceDescriptionByIndex(int index, AudioDeviceDescription* adDesc, int getNames) { +- int count = MAX_AUDIO_DEVICES; +- int ret = 0; +- +- getAudioDevices(globalADPaths, &count); +- if (index>=0 && index < count) { +- ret = getAudioDeviceDescription(globalADPaths[index].path, adDesc, getNames); +- } +- return ret; +-} +- +-int getAudioDeviceDescription(char* path, AudioDeviceDescription* adDesc, int getNames) { +- int fd; +- int mixerMode; +- int len; +- audio_info_t info; +- audio_device_t deviceInfo; +- +- strncpy(adDesc->path, path, MAX_NAME_LENGTH); +- adDesc->path[MAX_NAME_LENGTH] = 0; +- strcpy(adDesc->pathctl, adDesc->path); +- strcat(adDesc->pathctl, "ctl"); +- strcpy(adDesc->name, adDesc->path); +- adDesc->vendor[0] = 0; +- adDesc->version[0] = 0; +- adDesc->description[0] = 0; +- adDesc->maxSimulLines = 1; +- +- // try to open the pseudo device and get more information +- fd = open(adDesc->pathctl, O_WRONLY | O_NONBLOCK); +- if (fd >= 0) { +- close(fd); +- if (getNames) { +- fd = open(adDesc->pathctl, O_RDONLY); +- if (fd >= 0) { +- if (ioctl(fd, AUDIO_GETDEV, &deviceInfo) >= 0) { +- strncpy(adDesc->vendor, deviceInfo.name, MAX_AUDIO_DEV_LEN); +- adDesc->vendor[MAX_AUDIO_DEV_LEN] = 0; +- strncpy(adDesc->version, deviceInfo.version, MAX_AUDIO_DEV_LEN); +- adDesc->version[MAX_AUDIO_DEV_LEN] = 0; +- /* add config string to the dev name +- * creates a string like "/dev/audio (onboard1)" +- */ +- len = strlen(adDesc->name) + 1; +- if (MAX_NAME_LENGTH - len > 3) { +- strcat(adDesc->name, " ("); +- strncat(adDesc->name, deviceInfo.config, MAX_NAME_LENGTH - len); +- strcat(adDesc->name, ")"); +- } +- adDesc->name[MAX_NAME_LENGTH-1] = 0; +- } +- if (ioctl(fd, AUDIO_MIXERCTL_GET_MODE, &mixerMode) >= 0) { +- if (mixerMode == AM_MIXER_MODE) { +- TRACE1(" getAudioDeviceDescription: %s is in mixer mode\n", adDesc->path); +- adDesc->maxSimulLines = -1; +- } +- } else { +- ERROR1("ioctl AUDIO_MIXERCTL_GET_MODE failed on %s!\n", adDesc->path); +- } +- close(fd); +- } else { +- ERROR1("could not open %s!\n", adDesc->pathctl); +- } +- } +- return 1; +- } +- return 0; +-} +--- old/src/java.desktop/solaris/native/libjsound/PLATFORM_API_SolarisOS_Utils.h 2020-05-20 18:10:37.194308211 -0700 ++++ /dev/null 2020-03-09 18:57:19.455001459 -0700 +@@ -1,97 +0,0 @@ +-/* +- * Copyright (c) 2002, 2013, Oracle and/or its affiliates. All rights reserved. +- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. +- * +- * This code is free software; you can redistribute it and/or modify it +- * under the terms of the GNU General Public License version 2 only, as +- * published by the Free Software Foundation. Oracle designates this +- * particular file as subject to the "Classpath" exception as provided +- * by Oracle in the LICENSE file that accompanied this code. +- * +- * This code is distributed in the hope that it will be useful, but WITHOUT +- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +- * version 2 for more details (a copy is included in the LICENSE file that +- * accompanied this code). +- * +- * You should have received a copy of the GNU General Public License version +- * 2 along with this work; if not, write to the Free Software Foundation, +- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. +- * +- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA +- * or visit www.oracle.com if you need additional information or have any +- * questions. +- */ +- +-#include +-#include +-#include +-#include +-/* does not work on Solaris 2.7 */ +-#include +-#include +-#include +-#ifndef __linux__ +-#include +-#endif +-#include +-#include +-#include +- +-#ifndef PLATFORM_API_SOLARISOS_UTILS_H_INCLUDED +-#define PLATFORM_API_SOLARISOS_UTILS_H_INCLUDED +- +-/* defines for Solaris 2.7 +- #ifndef AUDIO_AUX1_OUT +- #define AUDIO_AUX1_OUT (0x08) // output to aux1 out +- #define AUDIO_AUX2_OUT (0x10) // output to aux2 out +- #define AUDIO_SPDIF_OUT (0x20) // output to SPDIF port +- #define AUDIO_AUX1_IN (0x08) // input from aux1 in +- #define AUDIO_AUX2_IN (0x10) // input from aux2 in +- #define AUDIO_SPDIF_IN (0x20) // input from SPDIF port +- #endif +-*/ +- +-/* input from Codec inter. loopback */ +-#ifndef AUDIO_CODEC_LOOPB_IN +-#define AUDIO_CODEC_LOOPB_IN (0x40) +-#endif +- +- +-#define MAX_NAME_LENGTH 300 +- +-typedef struct tag_AudioDevicePath { +- char path[MAX_NAME_LENGTH]; +- ino_t st_ino; // inode number to detect duplicate devices +- dev_t st_dev; // device ID to detect duplicate audio devices +-} AudioDevicePath; +- +-typedef struct tag_AudioDeviceDescription { +- INT32 maxSimulLines; +- char path[MAX_NAME_LENGTH+1]; +- char pathctl[MAX_NAME_LENGTH+4]; +- char name[MAX_NAME_LENGTH+1]; +- char vendor[MAX_NAME_LENGTH+1]; +- char version[MAX_NAME_LENGTH+1]; +- char description[MAX_NAME_LENGTH+1]; +-} AudioDeviceDescription; +- +-int getAudioDeviceCount(); +- +-/* +- * adPath is an array of AudioDevicePath structures +- * count contains initially the number of elements in adPath +- * and will be set to the returned number of paths. +- */ +-void getAudioDevices(AudioDevicePath* adPath, int* count); +- +-/* +- * fills adDesc from the audio device given in path +- * returns 0 if an error occurred +- * if getNames is 0, only path and pathctl are filled +- */ +-int getAudioDeviceDescription(char* path, AudioDeviceDescription* adDesc, int getNames); +-int getAudioDeviceDescriptionByIndex(int index, AudioDeviceDescription* adDesc, int getNames); +- +- +-#endif // PLATFORM_API_SOLARISOS_UTILS_H_INCLUDED +--- old/src/jdk.attach/solaris/classes/sun/tools/attach/AttachProviderImpl.java 2020-05-20 18:10:37.910321958 -0700 ++++ /dev/null 2020-03-09 18:57:19.455001459 -0700 +@@ -1,79 +0,0 @@ +-/* +- * Copyright (c) 2005, Oracle and/or its affiliates. All rights reserved. +- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. +- * +- * This code is free software; you can redistribute it and/or modify it +- * under the terms of the GNU General Public License version 2 only, as +- * published by the Free Software Foundation. Oracle designates this +- * particular file as subject to the "Classpath" exception as provided +- * by Oracle in the LICENSE file that accompanied this code. +- * +- * This code is distributed in the hope that it will be useful, but WITHOUT +- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +- * version 2 for more details (a copy is included in the LICENSE file that +- * accompanied this code). +- * +- * You should have received a copy of the GNU General Public License version +- * 2 along with this work; if not, write to the Free Software Foundation, +- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. +- * +- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA +- * or visit www.oracle.com if you need additional information or have any +- * questions. +- */ +-package sun.tools.attach; +- +-import com.sun.tools.attach.VirtualMachine; +-import com.sun.tools.attach.VirtualMachineDescriptor; +-import com.sun.tools.attach.AttachNotSupportedException; +-import java.io.IOException; +- +-/* +- * An AttachProvider implementation for Solaris that use the doors +- * interface to the VM. +- */ +-public class AttachProviderImpl extends HotSpotAttachProvider { +- +- public AttachProviderImpl() { +- } +- +- public String name() { +- return "sun"; +- } +- +- public String type() { +- return "doors"; +- } +- +- public VirtualMachine attachVirtualMachine(String vmid) +- throws AttachNotSupportedException, IOException +- { +- checkAttachPermission(); +- +- // AttachNotSupportedException will be thrown if the target VM can be determined +- // to be not attachable. +- testAttachable(vmid); +- +- return new VirtualMachineImpl(this, vmid); +- } +- +- public VirtualMachine attachVirtualMachine(VirtualMachineDescriptor vmd) +- throws AttachNotSupportedException, IOException +- { +- if (vmd.provider() != this) { +- throw new AttachNotSupportedException("provider mismatch"); +- } +- // To avoid re-checking if the VM if attachable, we check if the descriptor +- // is for a hotspot VM - these descriptors are created by the listVirtualMachines +- // implementation which only returns a list of attachable VMs. +- if (vmd instanceof HotSpotVirtualMachineDescriptor) { +- assert ((HotSpotVirtualMachineDescriptor)vmd).isAttachable(); +- checkAttachPermission(); +- return new VirtualMachineImpl(this, vmd.id()); +- } else { +- return attachVirtualMachine(vmd.id()); +- } +- } +- +-} +--- old/src/jdk.attach/solaris/classes/sun/tools/attach/VirtualMachineImpl.java 2020-05-20 18:10:38.606335320 -0700 ++++ /dev/null 2020-03-09 18:57:19.455001459 -0700 +@@ -1,272 +0,0 @@ +-/* +- * Copyright (c) 2005, 2019, Oracle and/or its affiliates. All rights reserved. +- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. +- * +- * This code is free software; you can redistribute it and/or modify it +- * under the terms of the GNU General Public License version 2 only, as +- * published by the Free Software Foundation. Oracle designates this +- * particular file as subject to the "Classpath" exception as provided +- * by Oracle in the LICENSE file that accompanied this code. +- * +- * This code is distributed in the hope that it will be useful, but WITHOUT +- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +- * version 2 for more details (a copy is included in the LICENSE file that +- * accompanied this code). +- * +- * You should have received a copy of the GNU General Public License version +- * 2 along with this work; if not, write to the Free Software Foundation, +- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. +- * +- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA +- * or visit www.oracle.com if you need additional information or have any +- * questions. +- */ +-package sun.tools.attach; +- +-import com.sun.tools.attach.AttachOperationFailedException; +-import com.sun.tools.attach.AgentLoadException; +-import com.sun.tools.attach.AttachNotSupportedException; +-import com.sun.tools.attach.spi.AttachProvider; +- +-import java.io.InputStream; +-import java.io.IOException; +-import java.io.File; +-import java.io.FileNotFoundException; +- +-/* +- * Solaris implementation of HotSpotVirtualMachine. +- */ +-public class VirtualMachineImpl extends HotSpotVirtualMachine { +- // "/tmp" is used as a global well-known location for the files +- // .java_pid. and .attach_pid. It is important that this +- // location is the same for all processes, otherwise the tools +- // will not be able to find all Hotspot processes. +- // Any changes to this needs to be synchronized with HotSpot. +- private static final String tmpdir = "/tmp"; +- +- // door descriptor; +- private int fd = -1; +- String socket_path; +- +- /** +- * Attaches to the target VM +- */ +- VirtualMachineImpl(AttachProvider provider, String vmid) +- throws AttachNotSupportedException, IOException +- { +- super(provider, vmid); +- // This provider only understands process-ids (pids). +- int pid; +- try { +- pid = Integer.parseInt(vmid); +- if (pid < 1) { +- throw new NumberFormatException(); +- } +- } catch (NumberFormatException x) { +- throw new AttachNotSupportedException("Invalid process identifier: " + vmid); +- } +- +- // Opens the door file to the target VM. If the file is not +- // found it might mean that the attach mechanism isn't started in the +- // target VM so we attempt to start it and retry. +- try { +- fd = openDoor(pid); +- } catch (FileNotFoundException fnf1) { +- File f = createAttachFile(pid); +- try { +- sigquit(pid); +- +- // give the target VM time to start the attach mechanism +- final int delay_step = 100; +- final long timeout = attachTimeout(); +- long time_spend = 0; +- long delay = 0; +- do { +- // Increase timeout on each attempt to reduce polling +- delay += delay_step; +- try { +- Thread.sleep(delay); +- } catch (InterruptedException x) { } +- try { +- fd = openDoor(pid); +- } catch (FileNotFoundException fnf2) { +- // pass +- } +- +- time_spend += delay; +- if (time_spend > timeout/2 && fd == -1) { +- // Send QUIT again to give target VM the last chance to react +- sigquit(pid); +- } +- } while (time_spend <= timeout && fd == -1); +- if (fd == -1) { +- throw new AttachNotSupportedException( +- String.format("Unable to open door %s: " + +- "target process %d doesn't respond within %dms " + +- "or HotSpot VM not loaded", socket_path, pid, time_spend)); +- } +- } finally { +- f.delete(); +- } +- } +- assert fd >= 0; +- } +- +- /** +- * Detach from the target VM +- */ +- public void detach() throws IOException { +- synchronized (this) { +- if (fd != -1) { +- close(fd); +- fd = -1; +- } +- } +- } +- +- /** +- * Execute the given command in the target VM. +- */ +- InputStream execute(String cmd, Object ... args) throws AgentLoadException, IOException { +- assert args.length <= 3; // includes null +- +- // first check that we are still attached +- int door; +- synchronized (this) { +- if (fd == -1) { +- throw new IOException("Detached from target VM"); +- } +- door = fd; +- } +- +- // enqueue the command via a door call +- int s = enqueue(door, cmd, args); +- assert s >= 0; // valid file descriptor +- +- // The door call returns a file descriptor (one end of a socket pair). +- // Create an input stream around it. +- SocketInputStream sis = new SocketInputStream(s); +- +- // Read the command completion status +- int completionStatus; +- try { +- completionStatus = readInt(sis); +- } catch (IOException ioe) { +- sis.close(); +- throw ioe; +- } +- +- // If non-0 it means an error but we need to special-case the +- // "load" command to ensure that the right exception is thrown. +- if (completionStatus != 0) { +- // read from the stream and use that as the error message +- String message = readErrorMessage(sis); +- sis.close(); +- if (cmd.equals("load")) { +- String msg = "Failed to load agent library"; +- if (!message.isEmpty()) +- msg += ": " + message; +- throw new AgentLoadException(msg); +- } else { +- if (message.isEmpty()) +- message = "Command failed in target VM"; +- throw new AttachOperationFailedException(message); +- } +- } +- +- // Return the input stream so that the command output can be read +- return sis; +- } +- +- // InputStream over a socket +- private class SocketInputStream extends InputStream { +- int s; +- +- public SocketInputStream(int s) { +- this.s = s; +- } +- +- public synchronized int read() throws IOException { +- byte b[] = new byte[1]; +- int n = this.read(b, 0, 1); +- if (n == 1) { +- return b[0] & 0xff; +- } else { +- return -1; +- } +- } +- +- public synchronized int read(byte[] bs, int off, int len) throws IOException { +- if ((off < 0) || (off > bs.length) || (len < 0) || +- ((off + len) > bs.length) || ((off + len) < 0)) { +- throw new IndexOutOfBoundsException(); +- } else if (len == 0) +- return 0; +- +- return VirtualMachineImpl.read(s, bs, off, len); +- } +- +- public synchronized void close() throws IOException { +- if (s != -1) { +- int toClose = s; +- s = -1; +- VirtualMachineImpl.close(toClose); +- } +- } +- } +- +- // The door is attached to .java_pid in the temporary directory. +- private int openDoor(int pid) throws IOException { +- socket_path = tmpdir + "/.java_pid" + pid; +- fd = open(socket_path); +- +- // Check that the file owner/permission to avoid attaching to +- // bogus process +- try { +- checkPermissions(socket_path); +- } catch (IOException ioe) { +- close(fd); +- throw ioe; +- } +- return fd; +- } +- +- // On Solaris a simple handshake is used to start the attach mechanism +- // if not already started. The client creates a .attach_pid file in the +- // target VM's working directory (or temporary directory), and the SIGQUIT +- // handler checks for the file. +- private File createAttachFile(int pid) throws IOException { +- String fn = ".attach_pid" + pid; +- String path = "/proc/" + pid + "/cwd/" + fn; +- File f = new File(path); +- try { +- f = f.getCanonicalFile(); +- f.createNewFile(); +- } catch (IOException x) { +- f = new File(tmpdir, fn); +- f.createNewFile(); +- } +- return f; +- } +- +- //-- native methods +- +- static native int open(String path) throws IOException; +- +- static native void close(int fd) throws IOException; +- +- static native int read(int fd, byte buf[], int off, int buflen) throws IOException; +- +- static native void checkPermissions(String path) throws IOException; +- +- static native void sigquit(int pid) throws IOException; +- +- // enqueue a command (and arguments) to the given door +- static native int enqueue(int fd, String cmd, Object ... args) +- throws IOException; +- +- static { +- System.loadLibrary("attach"); +- } +-} +--- old/src/jdk.attach/solaris/native/libattach/VirtualMachineImpl.c 2020-05-20 18:10:39.306348760 -0700 ++++ /dev/null 2020-03-09 18:57:19.455001459 -0700 +@@ -1,389 +0,0 @@ +-/* +- * Copyright (c) 2005, 2018, Oracle and/or its affiliates. All rights reserved. +- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. +- * +- * This code is free software; you can redistribute it and/or modify it +- * under the terms of the GNU General Public License version 2 only, as +- * published by the Free Software Foundation. Oracle designates this +- * particular file as subject to the "Classpath" exception as provided +- * by Oracle in the LICENSE file that accompanied this code. +- * +- * This code is distributed in the hope that it will be useful, but WITHOUT +- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +- * version 2 for more details (a copy is included in the LICENSE file that +- * accompanied this code). +- * +- * You should have received a copy of the GNU General Public License version +- * 2 along with this work; if not, write to the Free Software Foundation, +- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. +- * +- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA +- * or visit www.oracle.com if you need additional information or have any +- * questions. +- */ +- +-#include "jni_util.h" +- +-#include +-#include +-#include +-#include +-#include +-#include +-#include +-#include +-#include +-#include +- +-#include "sun_tools_attach_VirtualMachineImpl.h" +- +-#define ROOT_UID 0 +- +-#define RESTARTABLE(_cmd, _result) do { \ +- do { \ +- _result = _cmd; \ +- } while((_result == -1) && (errno == EINTR)); \ +-} while(0) +- +-/* +- * Declare library specific JNI_Onload entry if static build +- */ +-DEF_STATIC_JNI_OnLoad +- +-/* +- * Class: sun_tools_attach_VirtualMachineImpl +- * Method: open +- * Signature: (Ljava/lang/String;)I +- */ +-JNIEXPORT jint JNICALL Java_sun_tools_attach_VirtualMachineImpl_open +- (JNIEnv *env, jclass cls, jstring path) +-{ +- jboolean isCopy; +- const char* p = GetStringPlatformChars(env, path, &isCopy); +- if (p == NULL) { +- return 0; +- } else { +- int fd; +- int err = 0; +- +- fd = open(p, O_RDWR); +- if (fd == -1) { +- err = errno; +- } +- +- if (isCopy) { +- JNU_ReleaseStringPlatformChars(env, path, p); +- } +- +- if (fd == -1) { +- if (err == ENOENT) { +- JNU_ThrowByName(env, "java/io/FileNotFoundException", NULL); +- } else { +- char* msg = strdup(strerror(err)); +- JNU_ThrowIOException(env, msg); +- if (msg != NULL) { +- free(msg); +- } +- } +- } +- return fd; +- } +-} +- +-/* +- * Class: sun_tools_attach_VirtualMachineImpl +- * Method: checkPermissions +- * Signature: (Ljava/lang/String;)V +- */ +-JNIEXPORT void JNICALL Java_sun_tools_attach_VirtualMachineImpl_checkPermissions +- (JNIEnv *env, jclass cls, jstring path) +-{ +- jboolean isCopy; +- const char* p = GetStringPlatformChars(env, path, &isCopy); +- if (p != NULL) { +- struct stat64 sb; +- uid_t uid, gid; +- int res; +- +- memset(&sb, 0, sizeof(struct stat64)); +- +- /* +- * Check that the path is owned by the effective uid/gid of this +- * process. Also check that group/other access is not allowed. +- */ +- uid = geteuid(); +- gid = getegid(); +- +- res = stat64(p, &sb); +- if (res != 0) { +- /* save errno */ +- res = errno; +- } +- +- if (res == 0) { +- char msg[100]; +- jboolean isError = JNI_FALSE; +- if (sb.st_uid != uid && uid != ROOT_UID) { +- snprintf(msg, sizeof(msg), +- "file should be owned by the current user (which is %d) but is owned by %d", uid, sb.st_uid); +- isError = JNI_TRUE; +- } else if (sb.st_gid != gid && uid != ROOT_UID) { +- snprintf(msg, sizeof(msg), +- "file's group should be the current group (which is %d) but the group is %d", gid, sb.st_gid); +- isError = JNI_TRUE; +- } else if ((sb.st_mode & (S_IRGRP|S_IWGRP|S_IROTH|S_IWOTH)) != 0) { +- snprintf(msg, sizeof(msg), +- "file should only be readable and writable by the owner but has 0%03o access", sb.st_mode & 0777); +- isError = JNI_TRUE; +- } +- if (isError) { +- char buf[256]; +- snprintf(buf, sizeof(buf), "well-known file %s is not secure: %s", p, msg); +- JNU_ThrowIOException(env, buf); +- } +- } else { +- char* msg = strdup(strerror(res)); +- JNU_ThrowIOException(env, msg); +- if (msg != NULL) { +- free(msg); +- } +- } +- +- if (isCopy) { +- JNU_ReleaseStringPlatformChars(env, path, p); +- } +- } +-} +- +-/* +- * Class: sun_tools_attach_VirtualMachineImpl +- * Method: close +- * Signature: (I)V +- */ +-JNIEXPORT void JNICALL Java_sun_tools_attach_VirtualMachineImpl_close +- (JNIEnv *env, jclass cls, jint fd) +-{ +- int ret; +- RESTARTABLE(close(fd), ret); +-} +- +-/* +- * Class: sun_tools_attach_VirtualMachineImpl +- * Method: read +- * Signature: (I[BI)I +- */ +-JNIEXPORT jint JNICALL Java_sun_tools_attach_VirtualMachineImpl_read +- (JNIEnv *env, jclass cls, jint fd, jbyteArray ba, jint off, jint baLen) +-{ +- unsigned char buf[128]; +- size_t len = sizeof(buf); +- ssize_t n; +- +- size_t remaining = (size_t)(baLen - off); +- if (len > remaining) { +- len = remaining; +- } +- +- RESTARTABLE(read(fd, buf, len), n); +- if (n == -1) { +- JNU_ThrowIOExceptionWithLastError(env, "read"); +- } else { +- if (n == 0) { +- n = -1; // EOF +- } else { +- (*env)->SetByteArrayRegion(env, ba, off, (jint)n, (jbyte *)(buf)); +- } +- } +- return n; +-} +- +-/* +- * Class: sun_tools_attach_VirtualMachineImpl +- * Method: sigquit +- * Signature: (I)V +- */ +-JNIEXPORT void JNICALL Java_sun_tools_attach_VirtualMachineImpl_sigquit +- (JNIEnv *env, jclass cls, jint pid) +-{ +- if (kill((pid_t)pid, SIGQUIT) == -1) { +- JNU_ThrowIOExceptionWithLastError(env, "kill"); +- } +-} +- +-/* +- * A simple table to translate some known errors into reasonable +- * error messages +- */ +-static struct { +- jint err; +- const char* msg; +-} const error_messages[] = { +- { 100, "Bad request" }, +- { 101, "Protocol mismatch" }, +- { 102, "Resource failure" }, +- { 103, "Internal error" }, +- { 104, "Permission denied" }, +-}; +- +-/* +- * Lookup the given error code and return the appropriate +- * message. If not found return NULL. +- */ +-static const char* translate_error(jint err) { +- int table_size = sizeof(error_messages) / sizeof(error_messages[0]); +- int i; +- +- for (i = 0; i < table_size; i++) { +- if (err == error_messages[i].err) { +- return error_messages[i].msg; +- } +- } +- return NULL; +-} +- +-/* +- * Current protocol version +- */ +-static const char* PROTOCOL_VERSION = "1"; +- +-/* +- * Class: sun_tools_attach_VirtualMachineImpl +- * Method: enqueue +- * Signature: (JILjava/lang/String;[Ljava/lang/Object;)V +- */ +-JNIEXPORT jint JNICALL Java_sun_tools_attach_VirtualMachineImpl_enqueue +- (JNIEnv *env, jclass cls, jint fd, jstring cmd, jobjectArray args) +-{ +- jint arg_count, i; +- size_t size; +- jboolean isCopy; +- door_arg_t door_args; +- char res_buffer[128]; +- jint result = -1; +- int rc; +- const char* cstr; +- char* buf; +- +- /* +- * First we get the command string and create the start of the +- * argument string to send to the target VM: +- * \0\0 +- */ +- cstr = JNU_GetStringPlatformChars(env, cmd, &isCopy); +- if (cstr == NULL) { +- return -1; /* pending exception */ +- } +- size = strlen(PROTOCOL_VERSION) + strlen(cstr) + 2; +- buf = (char*)malloc(size); +- if (buf != NULL) { +- char* pos = buf; +- strcpy(buf, PROTOCOL_VERSION); +- pos += strlen(PROTOCOL_VERSION)+1; +- strcpy(pos, cstr); +- } +- if (isCopy) { +- JNU_ReleaseStringPlatformChars(env, cmd, cstr); +- } +- if (buf == NULL) { +- JNU_ThrowOutOfMemoryError(env, "malloc failed"); +- return -1; +- } +- +- /* +- * Next we iterate over the arguments and extend the buffer +- * to include them. +- */ +- arg_count = (*env)->GetArrayLength(env, args); +- +- for (i = 0; i < arg_count; i++) { +- jobject obj = (*env)->GetObjectArrayElement(env, args, i); +- if (obj != NULL) { +- cstr = JNU_GetStringPlatformChars(env, obj, &isCopy); +- if (cstr != NULL) { +- size_t len = strlen(cstr); +- char* newbuf = (char*)realloc(buf, size+len+1); +- if (newbuf != NULL) { +- buf = newbuf; +- strcpy(buf+size, cstr); +- size += len+1; +- } +- if (isCopy) { +- JNU_ReleaseStringPlatformChars(env, obj, cstr); +- } +- if (newbuf == NULL) { +- free(buf); +- JNU_ThrowOutOfMemoryError(env, "realloc failed"); +- return -1; +- } +- } +- } else { +- char* newbuf = (char*)realloc(buf, size + 1); +- if (newbuf == NULL) { +- free(buf); +- JNU_ThrowOutOfMemoryError(env, "realloc failed"); +- return -1; +- } +- buf = newbuf; +- buf[size++] = 0; +- } +- if ((*env)->ExceptionOccurred(env)) { +- free(buf); +- return -1; +- } +- } +- +- /* +- * The arguments to the door function are in 'buf' so we now +- * do the door call +- */ +- door_args.data_ptr = buf; +- door_args.data_size = size; +- door_args.desc_ptr = NULL; +- door_args.desc_num = 0; +- door_args.rbuf = (char*)&res_buffer; +- door_args.rsize = sizeof(res_buffer); +- +- RESTARTABLE(door_call(fd, &door_args), rc); +- +- /* +- * door_call failed +- */ +- if (rc == -1) { +- JNU_ThrowIOExceptionWithLastError(env, "door_call"); +- } else { +- /* +- * door_call succeeded but the call didn't return the expected jint. +- */ +- if (door_args.data_size < sizeof(jint)) { +- JNU_ThrowIOException(env, "Enqueue error - reason unknown as result is truncated!"); +- } else { +- jint* res = (jint*)(door_args.data_ptr); +- if (*res != JNI_OK) { +- const char* msg = translate_error(*res); +- char buf[255]; +- if (msg == NULL) { +- sprintf(buf, "Unable to enqueue command to target VM: %d", *res); +- } else { +- sprintf(buf, "Unable to enqueue command to target VM: %s", msg); +- } +- JNU_ThrowIOException(env, buf); +- } else { +- /* +- * The door call should return a file descriptor to one end of +- * a socket pair +- */ +- if ((door_args.desc_ptr != NULL) && +- (door_args.desc_num == 1) && +- (door_args.desc_ptr->d_attributes & DOOR_DESCRIPTOR)) { +- result = door_args.desc_ptr->d_data.d_desc.d_descriptor; +- } else { +- JNU_ThrowIOException(env, "Reply from enqueue missing descriptor!"); +- } +- } +- } +- } +- +- free(buf); +- return result; +-} +--- old/src/jdk.crypto.cryptoki/solaris/conf/security/sunpkcs11-solaris.cfg 2020-05-20 18:10:40.002362123 -0700 ++++ /dev/null 2020-03-09 18:57:19.455001459 -0700 +@@ -1,23 +0,0 @@ +-# +-# Configuration file to allow the SunPKCS11 provider to utilize +-# the Solaris Cryptographic Framework, if it is available +-# +- +-name = Solaris +- +-description = SunPKCS11 accessing Solaris Cryptographic Framework +- +-library = /usr/lib/$ISA/libpkcs11.so +- +-handleStartupErrors = ignoreAll +- +-# Use the X9.63 encoding for EC points (do not wrap in an ASN.1 OctetString). +-useEcX963Encoding = true +- +-attributes = compatibility +- +-disabledMechanisms = { +- CKM_DSA_KEY_PAIR_GEN +- SecureRandom +-} +- +--- old/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/HotSpotSolarisVtblAccess.java 2020-05-20 18:10:58.230712087 -0700 ++++ /dev/null 2020-03-09 18:57:19.455001459 -0700 +@@ -1,65 +0,0 @@ +-/* +- * Copyright (c) 2000, 2005, Oracle and/or its affiliates. All rights reserved. +- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. +- * +- * This code is free software; you can redistribute it and/or modify it +- * under the terms of the GNU General Public License version 2 only, as +- * published by the Free Software Foundation. +- * +- * This code is distributed in the hope that it will be useful, but WITHOUT +- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +- * version 2 for more details (a copy is included in the LICENSE file that +- * accompanied this code). +- * +- * You should have received a copy of the GNU General Public License version +- * 2 along with this work; if not, write to the Free Software Foundation, +- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. +- * +- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA +- * or visit www.oracle.com if you need additional information or have any +- * questions. +- * +- */ +- +-package sun.jvm.hotspot; +- +-import java.util.*; +-import sun.jvm.hotspot.debugger.*; +-import sun.jvm.hotspot.types.*; +-import sun.jvm.hotspot.types.basic.*; +- +-/** This class implements the compiler-specific access to the vtbl for +- a given C++ type. */ +-public class HotSpotSolarisVtblAccess extends BasicVtblAccess { +- +- public HotSpotSolarisVtblAccess(SymbolLookup symbolLookup, +- String[] jvmLibNames) { +- super(symbolLookup, jvmLibNames); +- } +- +- protected String vtblSymbolForType(Type type) { +- String demangledSymbol = type.getName() + "::__vtbl"; +- return mangle(demangledSymbol); +- } +- +- //-------------------------------------------------------------------------------- +- // Internals only below this point +- // +- +- private String mangle(String symbol) { +- String[] parts = symbol.split("::"); +- StringBuffer mangled = new StringBuffer("__1c"); +- for (int i = 0; i < parts.length; i++) { +- int len = parts[i].length(); +- if (len >= 26) { +- mangled.append((char)('a' + (len / 26))); +- len = len % 26; +- } +- mangled.append((char)('A' + len)); +- mangled.append(parts[i]); +- } +- mangled.append("_"); +- return mangled.toString(); +- } +-} +--- old/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/runtime/solaris_amd64/SolarisAMD64JavaThreadPDAccess.java 2020-05-20 18:11:11.186960833 -0700 ++++ /dev/null 2020-03-09 18:57:19.455001459 -0700 +@@ -1,140 +0,0 @@ +-/* +- * Copyright (c) 2004, 2020, Oracle and/or its affiliates. All rights reserved. +- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. +- * +- * This code is free software; you can redistribute it and/or modify it +- * under the terms of the GNU General Public License version 2 only, as +- * published by the Free Software Foundation. +- * +- * This code is distributed in the hope that it will be useful, but WITHOUT +- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +- * version 2 for more details (a copy is included in the LICENSE file that +- * accompanied this code). +- * +- * You should have received a copy of the GNU General Public License version +- * 2 along with this work; if not, write to the Free Software Foundation, +- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. +- * +- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA +- * or visit www.oracle.com if you need additional information or have any +- * questions. +- * +- */ +- +-package sun.jvm.hotspot.runtime.solaris_amd64; +- +-import java.io.*; +-import java.util.*; +-import sun.jvm.hotspot.debugger.*; +-import sun.jvm.hotspot.debugger.amd64.*; +-import sun.jvm.hotspot.runtime.*; +-import sun.jvm.hotspot.runtime.amd64.*; +-import sun.jvm.hotspot.runtime.x86.*; +-import sun.jvm.hotspot.types.*; +-import sun.jvm.hotspot.utilities.*; +-import sun.jvm.hotspot.utilities.Observable; +-import sun.jvm.hotspot.utilities.Observer; +- +-public class SolarisAMD64JavaThreadPDAccess implements JavaThreadPDAccess { +- private static AddressField lastJavaFPField; +- private static AddressField osThreadField; +- private static AddressField baseOfStackPointerField; +- +- // Field from OSThread +- private static CIntegerField osThreadThreadIDField; +- +- // This is currently unneeded but is being kept in case we change +- // the currentFrameGuess algorithm +- private static final long GUESS_SCAN_RANGE = 128 * 1024; +- +- +- static { +- VM.registerVMInitializedObserver(new Observer() { +- public void update(Observable o, Object data) { +- initialize(VM.getVM().getTypeDataBase()); +- } +- }); +- } +- +- private static synchronized void initialize(TypeDataBase db) { +- Type type = db.lookupType("JavaThread"); +- Type anchorType = db.lookupType("JavaFrameAnchor"); +- +- lastJavaFPField = anchorType.getAddressField("_last_Java_fp"); +- osThreadField = type.getAddressField("_osthread"); +- +- type = db.lookupType("OSThread"); +- osThreadThreadIDField = type.getCIntegerField("_thread_id"); +- } +- +- public Address getLastJavaFP(Address addr) { +- return lastJavaFPField.getValue(addr.addOffsetTo(sun.jvm.hotspot.runtime.JavaThread.getAnchorField().getOffset())); +- } +- +- public Address getLastJavaPC(Address addr) { +- return null; +- } +- +- public Address getBaseOfStackPointer(Address addr) { +- return null; +- } +- +- public Frame getLastFramePD(JavaThread thread, Address addr) { +- Address fp = thread.getLastJavaFP(); +- if (fp == null) { +- return null; // no information +- } +- Address pc = thread.getLastJavaPC(); +- if ( pc != null ) { +- return new X86Frame(thread.getLastJavaSP(), fp, pc); +- } else { +- return new X86Frame(thread.getLastJavaSP(), fp); +- } +- } +- +- public RegisterMap newRegisterMap(JavaThread thread, boolean updateMap) { +- return new X86RegisterMap(thread, updateMap); +- } +- +- public Frame getCurrentFrameGuess(JavaThread thread, Address addr) { +- ThreadProxy t = getThreadProxy(addr); +- AMD64ThreadContext context = (AMD64ThreadContext) t.getContext(); +- AMD64CurrentFrameGuess guesser = new AMD64CurrentFrameGuess(context, thread); +- if (!guesser.run(GUESS_SCAN_RANGE)) { +- return null; +- } +- if (guesser.getPC() == null) { +- return new X86Frame(guesser.getSP(), guesser.getFP()); +- } else { +- return new X86Frame(guesser.getSP(), guesser.getFP(), guesser.getPC()); +- } +- } +- +- +- public void printThreadIDOn(Address addr, PrintStream tty) { +- tty.print(getThreadProxy(addr)); +- } +- +- +- public void printInfoOn(Address threadAddr, PrintStream tty) { +- } +- +- public Address getLastSP(Address addr) { +- ThreadProxy t = getThreadProxy(addr); +- AMD64ThreadContext context = (AMD64ThreadContext) t.getContext(); +- return context.getRegisterAsAddress(AMD64ThreadContext.RSP); +- } +- +- public ThreadProxy getThreadProxy(Address addr) { +- // Fetch the OSThread (for now and for simplicity, not making a +- // separate "OSThread" class in this package) +- Address osThreadAddr = osThreadField.getValue(addr); +- // Get the address of the thread ID from the OSThread +- Address tidAddr = osThreadAddr.addOffsetTo(osThreadThreadIDField.getOffset()); +- +- JVMDebugger debugger = VM.getVM().getDebugger(); +- return debugger.getThreadForIdentifierAddress(tidAddr); +- } +- +-} +--- old/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/runtime/solaris_x86/SolarisX86JavaThreadPDAccess.java 2020-05-20 18:11:12.654989017 -0700 ++++ /dev/null 2020-03-09 18:57:19.455001459 -0700 +@@ -1,142 +0,0 @@ +-/* +- * Copyright (c) 2000, 2020, Oracle and/or its affiliates. All rights reserved. +- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. +- * +- * This code is free software; you can redistribute it and/or modify it +- * under the terms of the GNU General Public License version 2 only, as +- * published by the Free Software Foundation. +- * +- * This code is distributed in the hope that it will be useful, but WITHOUT +- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +- * version 2 for more details (a copy is included in the LICENSE file that +- * accompanied this code). +- * +- * You should have received a copy of the GNU General Public License version +- * 2 along with this work; if not, write to the Free Software Foundation, +- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. +- * +- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA +- * or visit www.oracle.com if you need additional information or have any +- * questions. +- * +- */ +- +-package sun.jvm.hotspot.runtime.solaris_x86; +- +-import java.io.*; +-import java.util.*; +-import sun.jvm.hotspot.debugger.*; +-import sun.jvm.hotspot.debugger.x86.*; +-import sun.jvm.hotspot.runtime.*; +-import sun.jvm.hotspot.runtime.x86.*; +-import sun.jvm.hotspot.types.*; +-import sun.jvm.hotspot.utilities.*; +-import sun.jvm.hotspot.utilities.Observable; +-import sun.jvm.hotspot.utilities.Observer; +- +-/** Placeholder for now to allow us to start the SA without support +- for stack traces */ +- +-public class SolarisX86JavaThreadPDAccess implements JavaThreadPDAccess { +- private static AddressField lastJavaFPField; +- private static AddressField osThreadField; +- private static AddressField baseOfStackPointerField; +- +- // Field from OSThread +- private static CIntegerField osThreadThreadIDField; +- +- // This is currently unneeded but is being kept in case we change +- // the currentFrameGuess algorithm +- private static final long GUESS_SCAN_RANGE = 128 * 1024; +- +- +- static { +- VM.registerVMInitializedObserver(new Observer() { +- public void update(Observable o, Object data) { +- initialize(VM.getVM().getTypeDataBase()); +- } +- }); +- } +- +- private static synchronized void initialize(TypeDataBase db) { +- Type type = db.lookupType("JavaThread"); +- Type anchorType = db.lookupType("JavaFrameAnchor"); +- +- lastJavaFPField = anchorType.getAddressField("_last_Java_fp"); +- osThreadField = type.getAddressField("_osthread"); +- +- type = db.lookupType("OSThread"); +- osThreadThreadIDField = type.getCIntegerField("_thread_id"); +- } +- +- public Address getLastJavaFP(Address addr) { +- return lastJavaFPField.getValue(addr.addOffsetTo(sun.jvm.hotspot.runtime.JavaThread.getAnchorField().getOffset())); +- } +- +- public Address getLastJavaPC(Address addr) { +- return null; +- } +- +- public Address getBaseOfStackPointer(Address addr) { +- return null; +- } +- +- public Frame getLastFramePD(JavaThread thread, Address addr) { +- Address fp = thread.getLastJavaFP(); +- if (fp == null) { +- return null; // no information +- } +- Address pc = thread.getLastJavaPC(); +- if ( pc != null ) { +- return new X86Frame(thread.getLastJavaSP(), fp, pc); +- } else { +- return new X86Frame(thread.getLastJavaSP(), fp); +- } +- } +- +- public RegisterMap newRegisterMap(JavaThread thread, boolean updateMap) { +- return new X86RegisterMap(thread, updateMap); +- } +- +- public Frame getCurrentFrameGuess(JavaThread thread, Address addr) { +- ThreadProxy t = getThreadProxy(addr); +- X86ThreadContext context = (X86ThreadContext) t.getContext(); +- X86CurrentFrameGuess guesser = new X86CurrentFrameGuess(context, thread); +- if (!guesser.run(GUESS_SCAN_RANGE)) { +- return null; +- } +- if (guesser.getPC() == null) { +- return new X86Frame(guesser.getSP(), guesser.getFP()); +- } else { +- return new X86Frame(guesser.getSP(), guesser.getFP(), guesser.getPC()); +- } +- } +- +- +- public void printThreadIDOn(Address addr, PrintStream tty) { +- tty.print(getThreadProxy(addr)); +- } +- +- +- public void printInfoOn(Address threadAddr, PrintStream tty) { +- } +- +- public Address getLastSP(Address addr) { +- ThreadProxy t = getThreadProxy(addr); +- X86ThreadContext context = (X86ThreadContext) t.getContext(); +- return context.getRegisterAsAddress(X86ThreadContext.ESP); +- } +- +- public ThreadProxy getThreadProxy(Address addr) { +- // Fetch the OSThread (for now and for simplicity, not making a +- // separate "OSThread" class in this package) +- Address osThreadAddr = osThreadField.getValue(addr); +- // Get the address of the thread ID from the OSThread +- Address tidAddr = osThreadAddr.addOffsetTo(osThreadThreadIDField.getOffset()); +- +- JVMDebugger debugger = VM.getVM().getDebugger(); +- return debugger.getThreadForIdentifierAddress(tidAddr); +- } +- +-} +--- old/src/jdk.management/solaris/native/libmanagement_ext/UnixOperatingSystem.c 2020-05-20 18:12:18.112245724 -0700 ++++ /dev/null 2020-03-09 18:57:19.455001459 -0700 +@@ -1,254 +0,0 @@ +-/* +- * Copyright (c) 2011, 2019, Oracle and/or its affiliates. All rights reserved. +- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. +- * +- * This code is free software; you can redistribute it and/or modify it +- * under the terms of the GNU General Public License version 2 only, as +- * published by the Free Software Foundation. Oracle designates this +- * particular file as subject to the "Classpath" exception as provided +- * by Oracle in the LICENSE file that accompanied this code. +- * +- * This code is distributed in the hope that it will be useful, but WITHOUT +- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +- * version 2 for more details (a copy is included in the LICENSE file that +- * accompanied this code). +- * +- * You should have received a copy of the GNU General Public License version +- * 2 along with this work; if not, write to the Free Software Foundation, +- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. +- * +- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA +- * or visit www.oracle.com if you need additional information or have any +- * questions. +- */ +- +-#include +-#include +-#include +-#include +-#include +-#include +-#include +-#include +-#include +-#include +-#include +-#include +-#include +-#include +-#include "jvm.h" +-#include "com_sun_management_internal_OperatingSystemImpl.h" +- +-typedef struct { +- kstat_t *kstat; +- uint64_t last_idle; +- uint64_t last_total; +- double last_ratio; +-} cpuload_t; +- +-static cpuload_t *cpu_loads = NULL; +-static unsigned int num_cpus; +-static kstat_ctl_t *kstat_ctrl = NULL; +- +-static void map_cpu_kstat_counters() { +- kstat_t *kstat; +- int i; +- +- // Get number of CPU(s) +- if ((num_cpus = sysconf(_SC_NPROCESSORS_ONLN)) == -1) { +- num_cpus = 1; +- } +- +- // Data structure for saving CPU load +- if ((cpu_loads = calloc(num_cpus,sizeof(cpuload_t))) == NULL) { +- return; +- } +- +- // Get kstat cpu_stat counters for every CPU +- // (loop over kstat to find our cpu_stat(s) +- i = 0; +- for (kstat = kstat_ctrl->kc_chain; kstat != NULL; kstat = kstat->ks_next) { +- if (strncmp(kstat->ks_module, "cpu_stat", 8) == 0) { +- +- if (kstat_read(kstat_ctrl, kstat, NULL) == -1) { +- // Failed to initialize kstat for this CPU so ignore it +- continue; +- } +- +- if (i == num_cpus) { +- // Found more cpu_stats than reported CPUs +- break; +- } +- +- cpu_loads[i++].kstat = kstat; +- } +- } +-} +- +-static int init_cpu_kstat_counters() { +- static int initialized = 0; +- +- // Concurrence in this method is prevented by the lock in +- // the calling method get_cpu_load(); +- if(!initialized) { +- if ((kstat_ctrl = kstat_open()) != NULL) { +- map_cpu_kstat_counters(); +- initialized = 1; +- } +- } +- return initialized ? 0 : -1; +-} +- +-static void update_cpu_kstat_counters() { +- if(kstat_chain_update(kstat_ctrl) != 0) { +- free(cpu_loads); +- map_cpu_kstat_counters(); +- } +-} +- +-int read_cpustat(cpuload_t *load, cpu_stat_t *cpu_stat) { +- if (load->kstat == NULL) { +- // no handle. +- return -1; +- } +- if (kstat_read(kstat_ctrl, load->kstat, cpu_stat) == -1) { +- // disabling for now, a kstat chain update is likely to happen next time +- load->kstat = NULL; +- return -1; +- } +- return 0; +-} +- +-double get_single_cpu_load(unsigned int n) { +- cpuload_t *load; +- cpu_stat_t cpu_stat; +- uint_t *usage; +- uint64_t c_idle; +- uint64_t c_total; +- uint64_t d_idle; +- uint64_t d_total; +- int i; +- +- if (n >= num_cpus) { +- return -1.0; +- } +- +- load = &cpu_loads[n]; +- if (read_cpustat(load, &cpu_stat) < 0) { +- return -1.0; +- } +- +- usage = cpu_stat.cpu_sysinfo.cpu; +- c_idle = usage[CPU_IDLE]; +- +- for (c_total = 0, i = 0; i < CPU_STATES; i++) { +- c_total += usage[i]; +- } +- +- // Calculate diff against previous snapshot +- d_idle = c_idle - load->last_idle; +- d_total = c_total - load->last_total; +- +- /** update if weve moved */ +- if (d_total > 0) { +- // Save current values for next time around +- load->last_idle = c_idle; +- load->last_total = c_total; +- load->last_ratio = (double) (d_total - d_idle) / d_total; +- } +- +- return load->last_ratio; +-} +- +-int get_info(const char *path, void *info, size_t s, off_t o) { +- int fd; +- int ret = 0; +- if ((fd = open(path, O_RDONLY)) < 0) { +- return -1; +- } +- if (pread(fd, info, s, o) != s) { +- ret = -1; +- } +- close(fd); +- return ret; +-} +- +-#define MIN(a, b) ((a < b) ? a : b) +- +-static pthread_mutex_t lock = PTHREAD_MUTEX_INITIALIZER; +- +-/** +- * Return the cpu load (0-1) for proc number 'which' (or average all if which == -1) +- */ +-double get_cpu_load(int which) { +- double load =.0; +- +- pthread_mutex_lock(&lock); +- if(init_cpu_kstat_counters()==0) { +- +- update_cpu_kstat_counters(); +- +- if (which == -1) { +- unsigned int i; +- double t; +- +- for (t = .0, i = 0; i < num_cpus; i++) { +- t += get_single_cpu_load(i); +- } +- +- // Cap total systemload to 1.0 +- load = MIN((t / num_cpus), 1.0); +- } else { +- load = MIN(get_single_cpu_load(which), 1.0); +- } +- } else { +- load = -1.0; +- } +- pthread_mutex_unlock(&lock); +- +- return load; +-} +- +-/** +- * Return the cpu load (0-1) for the current process (i.e the JVM) +- * or -1.0 if the get_info() call failed +- */ +-double get_process_load(void) { +- psinfo_t info; +- +- // Get the percentage of "recent cpu usage" from all the lwp:s in the JVM:s +- // process. This is returned as a value between 0.0 and 1.0 multiplied by 0x8000. +- if (get_info("/proc/self/psinfo",&info.pr_pctcpu, sizeof(info.pr_pctcpu), offsetof(psinfo_t, pr_pctcpu)) == 0) { +- return (double) info.pr_pctcpu / 0x8000; +- } +- return -1.0; +-} +- +-JNIEXPORT jdouble JNICALL +-Java_com_sun_management_internal_OperatingSystemImpl_getCpuLoad0 +-(JNIEnv *env, jobject dummy) +-{ +- return get_cpu_load(-1); +-} +- +-JNIEXPORT jdouble JNICALL +-Java_com_sun_management_internal_OperatingSystemImpl_getProcessCpuLoad0 +-(JNIEnv *env, jobject dummy) +-{ +- return get_process_load(); +-} +- +-JNIEXPORT jdouble JNICALL +-Java_com_sun_management_internal_OperatingSystemImpl_getSingleCpuLoad0 +-(JNIEnv *env, jobject mbean, jint cpu_number) +-{ +- return -1.0; +-} +- +-JNIEXPORT jint JNICALL +-Java_com_sun_management_internal_OperatingSystemImpl_getHostConfiguredCpuCount0 +-(JNIEnv *env, jobject mbean) +-{ +- return -1; +-} diff --git a/build/openjdk21/patches/omnios-headless.patch b/build/openjdk21/patches/omnios-headless.patch new file mode 100644 index 0000000000..a959f20e01 --- /dev/null +++ b/build/openjdk21/patches/omnios-headless.patch @@ -0,0 +1,15 @@ +diff -wpruN '--exclude=*.orig' a~/make/lib/Awt2dLibraries.gmk a/make/lib/Awt2dLibraries.gmk +--- a~/make/modules/java.desktop/lib/Awt2dLibraries.gmk 1970-01-01 00:00:00 ++++ a/make/modules/java.desktop/lib/Awt2dLibraries.gmk 1970-01-01 00:00:00 +@@ -788,11 +788,9 @@ else # OPENJDK_TARGET_OS not windows + JAWT_LIBS += -lawt_xawt + else + JAWT_LIBS += -lawt_headless +- ifeq ($(call isTargetOs, linux), true) + JAWT_CFLAGS += -DHEADLESS + endif + endif +- endif + + $(eval $(call SetupJdkLibrary, BUILD_LIBJAWT, \ + NAME := jawt, \ diff --git a/build/openjdk21/patches/patch-make_GenerateLinkOptData.gmk b/build/openjdk21/patches/patch-make_GenerateLinkOptData.gmk new file mode 100644 index 0000000000..a51eca5e94 --- /dev/null +++ b/build/openjdk21/patches/patch-make_GenerateLinkOptData.gmk @@ -0,0 +1,14 @@ +$NetBSD$ + +Ensure java libraries can be found during build. + +--- make/GenerateLinkOptData.gmk.orig 2019-01-08 09:40:28.000000000 +0000 ++++ make/GenerateLinkOptData.gmk +@@ -65,6 +65,7 @@ $(CLASSLIST_FILE): $(INTERIM_IMAGE_DIR)/ + $(call MakeDir, $(LINK_OPT_DIR)) + $(call LogInfo, Generating $(patsubst $(OUTPUTDIR)/%, %, $@)) + $(call LogInfo, Generating $(patsubst $(OUTPUTDIR)/%, %, $(JLI_TRACE_FILE))) ++ LD_LIBRARY_PATH=$(INTERIM_IMAGE_DIR)/lib:$(INTERIM_IMAGE_DIR)/lib/jli \ + $(FIXPATH) $(INTERIM_IMAGE_DIR)/bin/java -XX:DumpLoadedClassList=$@.raw \ + -Duser.language=en -Duser.country=US \ + -cp $(SUPPORT_OUTPUTDIR)/classlist.jar \ diff --git a/build/openjdk21/patches/patch-make_autoconf_flags-cflags.m4 b/build/openjdk21/patches/patch-make_autoconf_flags-cflags.m4 new file mode 100644 index 0000000000..76ec2e6257 --- /dev/null +++ b/build/openjdk21/patches/patch-make_autoconf_flags-cflags.m4 @@ -0,0 +1,46 @@ +$NetBSD$ + +Support for SunOS/gcc. + +--- make/autoconf/flags-cflags.m4.orig 2019-01-08 09:40:27.000000000 +0000 ++++ make/autoconf/flags-cflags.m4 +@@ -42,8 +42,15 @@ AC_DEFUN([FLAGS_SETUP_SHARED_LIBS], + # overridden using LD_LIBRARY_PATH. See JDK-8326891 for more information. + SET_EXECUTABLE_ORIGIN='-Wl,-rpath,\$$ORIGIN[$]1 -Wl,--disable-new-dtags' + SET_SHARED_LIBRARY_ORIGIN="-Wl,-z,origin $SET_EXECUTABLE_ORIGIN" ++ if test "x$OPENJDK_TARGET_OS" = xsolaris; then ++ SET_EXECUTABLE_ORIGIN='-Wl,-rpath,\$$ORIGIN[$]1' ++ SET_SHARED_LIBRARY_ORIGIN="-Wl,-z,origin $SET_EXECUTABLE_ORIGIN" ++ SET_SHARED_LIBRARY_NAME='-Wl,-h,[$]1' ++ SET_SHARED_LIBRARY_MAPFILE='-Wl,-M,[$]1' ++ else + SET_SHARED_LIBRARY_NAME='-Wl,-soname=[$]1' + SET_SHARED_LIBRARY_MAPFILE='-Wl,-version-script=[$]1' ++ fi + + elif test "x$TOOLCHAIN_TYPE" = xclang; then + if test "x$OPENJDK_TARGET_OS" = xmacosx; then +@@ -69,8 +76,13 @@ + if test "x$OPENJDK_TARGET_OS" = xlinux; then + SET_EXECUTABLE_ORIGIN="$SET_EXECUTABLE_ORIGIN -Wl,--disable-new-dtags" + fi +- SET_SHARED_LIBRARY_NAME='-Wl,-soname=[$]1' +- SET_SHARED_LIBRARY_MAPFILE='-Wl,-version-script=[$]1' ++ if test "x$OPENJDK_TARGET_OS" = xsolaris; then ++ SET_SHARED_LIBRARY_NAME='-Wl,-h,[$]1' ++ SET_SHARED_LIBRARY_MAPFILE='-Wl,-M,[$]1' ++ else ++ SET_SHARED_LIBRARY_NAME='-Wl,-soname=[$]1' ++ SET_SHARED_LIBRARY_MAPFILE='-Wl,-version-script=[$]1' ++ fi + + # arm specific settings + if test "x$OPENJDK_TARGET_CPU" = "xarm"; then +@@ -553,6 +565,7 @@ AC_DEFUN([FLAGS_SETUP_CFLAGS_HELPER], + + if test "x$TOOLCHAIN_TYPE" = xgcc; then + ALWAYS_DEFINES_JVM="-D_GNU_SOURCE -D_REENTRANT" ++ ALWAYS_DEFINES_JDK="-D_GNU_SOURCE -D_REENTRANT -D_LARGEFILE64_SOURCE" + elif test "x$TOOLCHAIN_TYPE" = xclang; then + ALWAYS_DEFINES_JVM="-D_GNU_SOURCE" + elif test "x$TOOLCHAIN_TYPE" = xxlc; then diff --git a/build/openjdk21/patches/patch-make_autoconf_jdk-options.m4 b/build/openjdk21/patches/patch-make_autoconf_jdk-options.m4 new file mode 100644 index 0000000000..13ac1d5c7c --- /dev/null +++ b/build/openjdk21/patches/patch-make_autoconf_jdk-options.m4 @@ -0,0 +1,15 @@ +$NetBSD$ + +Shell portability. + +--- make/autoconf/jdk-options.m4.orig 2019-01-08 09:40:28.000000000 +0000 ++++ make/autoconf/jdk-options.m4 +@@ -143,7 +143,7 @@ AC_DEFUN_ONCE([JDKOPT_SETUP_JDK_OPTIONS] + AC_ARG_WITH(cacerts-file, [AS_HELP_STRING([--with-cacerts-file], + [specify alternative cacerts file])]) + AC_MSG_CHECKING([for cacerts file]) +- if test "x$with_cacerts_file" == x; then ++ if test "x$with_cacerts_file" = x; then + AC_MSG_RESULT([default]) + else + CACERTS_FILE=$with_cacerts_file diff --git a/build/openjdk21/patches/patch-make_launcher_LauncherCommon.gmk b/build/openjdk21/patches/patch-make_launcher_LauncherCommon.gmk new file mode 100644 index 0000000000..403df21fdd --- /dev/null +++ b/build/openjdk21/patches/patch-make_launcher_LauncherCommon.gmk @@ -0,0 +1,16 @@ +$NetBSD$ + +Support for SunOS/gcc. + +--- make/common/modules/LauncherCommon.gmk.orig 2019-01-08 09:40:28.000000000 +0000 ++++ make/common/modules/LauncherCommon.gmk +@@ -36,7 +36,9 @@ endif + # Also provide an override for non-conformant libraries. + ifeq ($(TOOLCHAIN_TYPE), gcc) + LAUNCHER_CFLAGS += -fvisibility=hidden ++ ifneq ($(OPENJDK_TARGET_OS), solaris) + LDFLAGS_JDKEXE += -Wl,--exclude-libs,ALL ++ endif + else ifeq ($(TOOLCHAIN_TYPE), clang) + LAUNCHER_CFLAGS += -fvisibility=hidden + else ifeq ($(TOOLCHAIN_TYPE), xlc) diff --git a/build/openjdk21/patches/patch-make_lib_LibCommon.gmk b/build/openjdk21/patches/patch-make_lib_LibCommon.gmk new file mode 100644 index 0000000000..89e496d434 --- /dev/null +++ b/build/openjdk21/patches/patch-make_lib_LibCommon.gmk @@ -0,0 +1,16 @@ +$NetBSD$ + +Support SunOS/gcc. + +--- make/common/modules/LibCommon.gmk.orig 2019-01-08 09:40:28.000000000 +0000 ++++ make/common/modules/LibCommon.gmk +@@ -40,7 +40,9 @@ WIN_JAVA_LIB := $(SUPPORT_OUTPUTDIR)/nat + ifeq ($(TOOLCHAIN_TYPE), gcc) + CFLAGS_JDKLIB += -fvisibility=hidden + CXXFLAGS_JDKLIB += -fvisibility=hidden ++ ifneq ($(OPENJDK_TARGET_OS), solaris) + LDFLAGS_JDKLIB += -Wl,--exclude-libs,ALL ++ endif + else ifeq ($(TOOLCHAIN_TYPE), clang) + CFLAGS_JDKLIB += -fvisibility=hidden + CXXFLAGS_JDKLIB += -fvisibility=hidden diff --git a/build/openjdk21/patches/patch-src_hotspot_share_gc_g1_g1Analytics.cpp b/build/openjdk21/patches/patch-src_hotspot_share_gc_g1_g1Analytics.cpp new file mode 100644 index 0000000000..3fd9137800 --- /dev/null +++ b/build/openjdk21/patches/patch-src_hotspot_share_gc_g1_g1Analytics.cpp @@ -0,0 +1,14 @@ +$NetBSD$ + +Similar issue to https://bugs.openjdk.java.net/browse/JDK-8193056 + +--- src/hotspot/share/gc/g1/g1Analytics.cpp.orig 2019-01-08 12:44:56.000000000 +0000 ++++ src/hotspot/share/gc/g1/g1Analytics.cpp +@@ -23,6 +23,7 @@ + */ + + #include "precompiled.hpp" ++#include "memory/allocation.inline.hpp" + #include "gc/g1/g1Analytics.hpp" + #include "gc/g1/g1AnalyticsSequences.inline.hpp" + #include "gc/g1/g1Predictions.hpp" diff --git a/build/openjdk21/patches/restore_os_cpu_solaris_x86.patch b/build/openjdk21/patches/restore_os_cpu_solaris_x86.patch new file mode 100644 index 0000000000..1610fa84f0 --- /dev/null +++ b/build/openjdk21/patches/restore_os_cpu_solaris_x86.patch @@ -0,0 +1,1887 @@ +diff -urN /tmp/a/assembler_solaris_x86.cpp b/src/hotspot/os_cpu/solaris_x86/assembler_solaris_x86.cpp +--- /tmp/a/assembler_solaris_x86.cpp 1970-01-01 01:00:00.000000000 +0100 ++++ b/src/hotspot/os_cpu/solaris_x86/assembler_solaris_x86.cpp 2024-10-15 14:59:36.868225263 +0100 +@@ -0,0 +1,37 @@ ++/* ++ * Copyright (c) 1999, 2015, Oracle and/or its affiliates. All rights reserved. ++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. ++ * ++ * This code is free software; you can redistribute it and/or modify it ++ * under the terms of the GNU General Public License version 2 only, as ++ * published by the Free Software Foundation. ++ * ++ * This code is distributed in the hope that it will be useful, but WITHOUT ++ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or ++ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License ++ * version 2 for more details (a copy is included in the LICENSE file that ++ * accompanied this code). ++ * ++ * You should have received a copy of the GNU General Public License version ++ * 2 along with this work; if not, write to the Free Software Foundation, ++ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. ++ * ++ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA ++ * or visit www.oracle.com if you need additional information or have any ++ * questions. ++ * ++ */ ++ ++#include "precompiled.hpp" ++#include "asm/macroAssembler.inline.hpp" ++#include "runtime/os.hpp" ++ ++void MacroAssembler::int3() { ++ push(rax); ++ push(rdx); ++ push(rcx); ++ call(RuntimeAddress(CAST_FROM_FN_PTR(address, os::breakpoint))); ++ pop(rcx); ++ pop(rdx); ++ pop(rax); ++} +diff -urN /tmp/a/atomic_solaris_x86.hpp b/src/hotspot/os_cpu/solaris_x86/atomic_solaris_x86.hpp +--- /tmp/a/atomic_solaris_x86.hpp 1970-01-01 01:00:00.000000000 +0100 ++++ b/src/hotspot/os_cpu/solaris_x86/atomic_solaris_x86.hpp 2024-10-15 14:59:36.868356722 +0100 +@@ -0,0 +1,182 @@ ++/* ++ * Copyright (c) 1999, 2019, Oracle and/or its affiliates. All rights reserved. ++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. ++ * ++ * This code is free software; you can redistribute it and/or modify it ++ * under the terms of the GNU General Public License version 2 only, as ++ * published by the Free Software Foundation. ++ * ++ * This code is distributed in the hope that it will be useful, but WITHOUT ++ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or ++ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License ++ * version 2 for more details (a copy is included in the LICENSE file that ++ * accompanied this code). ++ * ++ * You should have received a copy of the GNU General Public License version ++ * 2 along with this work; if not, write to the Free Software Foundation, ++ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. ++ * ++ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA ++ * or visit www.oracle.com if you need additional information or have any ++ * questions. ++ * ++ */ ++ ++#ifndef OS_CPU_SOLARIS_X86_ATOMIC_SOLARIS_X86_HPP ++#define OS_CPU_SOLARIS_X86_ATOMIC_SOLARIS_X86_HPP ++ ++inline int32_t _Atomic_add(int32_t add_value, volatile int32_t* dest) { ++ int32_t rv = add_value; ++ __asm__ volatile ("lock xaddl %0,(%2)" ++ : "=r" (rv) ++ : "0" (rv), "r" (dest) ++ : "cc", "memory"); ++ return rv + add_value; ++} ++inline int64_t _Atomic_add_long(int64_t add_value, volatile int64_t* dest) { ++ int64_t rv = add_value; ++ __asm__ volatile ("lock xaddq %0,(%2)" ++ : "=r" (rv) ++ : "0" (rv), "r" (dest) ++ : "cc", "memory"); ++ return rv + add_value; ++} ++inline int32_t _Atomic_xchg(int32_t exchange_value, volatile int32_t* dest) { ++ __asm__ __volatile__ ("xchgl (%2),%0" ++ : "=r" (exchange_value) ++ : "0" (exchange_value), "r" (dest) ++ : "memory"); ++ return exchange_value; ++} ++inline int64_t _Atomic_xchg_long(int64_t exchange_value, volatile int64_t* dest) { ++ __asm__ __volatile__ ("xchgq (%2),%0" ++ : "=r" (exchange_value) ++ : "0" (exchange_value), "r" (dest) ++ : "memory"); ++ return exchange_value; ++} ++inline int8_t _Atomic_cmpxchg_byte(int8_t exchange_value, volatile int8_t* dest, int8_t compare_value) { ++ __asm__ volatile ("lock cmpxchgb %1,(%3)" ++ : "=a" (exchange_value) ++ : "q" (exchange_value), "a" (compare_value), "r" (dest) ++ : "cc", "memory"); ++ return exchange_value; ++} ++inline int32_t _Atomic_cmpxchg(int32_t exchange_value, volatile int32_t* dest, int32_t compare_value) { ++ __asm__ volatile ("lock cmpxchgl %1,(%3)" ++ : "=a" (exchange_value) ++ : "q" (exchange_value), "a" (compare_value), "r" (dest) ++ : "cc", "memory"); ++ return exchange_value; ++} ++inline int64_t _Atomic_cmpxchg_long(int64_t exchange_value, volatile int64_t* dest, int64_t compare_value) { ++ __asm__ volatile ("lock cmpxchgq %1,(%3)" ++ : "=a" (exchange_value) ++ : "q" (exchange_value), "a" (compare_value), "r" (dest) ++ : "cc", "memory"); ++ return exchange_value; ++} ++ ++template ++struct Atomic::PlatformAdd { ++ template ++ D add_then_fetch(D volatile* dest, I add_value, atomic_memory_order order) const; ++ ++ template ++ D fetch_then_add(D volatile* dest, I add_value, atomic_memory_order order) const { ++ return add_then_fetch(dest, add_value, order) - add_value; ++ } ++}; ++ ++// Not using add_using_helper; see comment for cmpxchg. ++template<> ++template ++inline D Atomic::PlatformAdd<4>::add_then_fetch(D volatile* dest, I add_value, ++ atomic_memory_order order) const { ++ STATIC_ASSERT(4 == sizeof(I)); ++ STATIC_ASSERT(4 == sizeof(D)); ++ return PrimitiveConversions::cast( ++ _Atomic_add(PrimitiveConversions::cast(add_value), ++ reinterpret_cast(dest))); ++} ++ ++// Not using add_using_helper; see comment for cmpxchg. ++template<> ++template ++inline D Atomic::PlatformAdd<8>::add_then_fetch(D volatile* dest, I add_value, ++ atomic_memory_order order) const { ++ STATIC_ASSERT(8 == sizeof(I)); ++ STATIC_ASSERT(8 == sizeof(D)); ++ return PrimitiveConversions::cast( ++ _Atomic_add_long(PrimitiveConversions::cast(add_value), ++ reinterpret_cast(dest))); ++} ++ ++template<> ++template ++inline T Atomic::PlatformXchg<4>::operator()(T volatile* dest, ++ T exchange_value, ++ atomic_memory_order order) const { ++ STATIC_ASSERT(4 == sizeof(T)); ++ return PrimitiveConversions::cast( ++ _Atomic_xchg(PrimitiveConversions::cast(exchange_value), ++ reinterpret_cast(dest))); ++} ++ ++template<> ++template ++inline T Atomic::PlatformXchg<8>::operator()(T volatile* dest, ++ T exchange_value, ++ atomic_memory_order order) const { ++ STATIC_ASSERT(8 == sizeof(T)); ++ return PrimitiveConversions::cast( ++ _Atomic_xchg_long(PrimitiveConversions::cast(exchange_value), ++ reinterpret_cast(dest))); ++} ++ ++// Not using cmpxchg_using_helper here, because some configurations of ++// Solaris compiler don't deal well with passing a "defined in .il" ++// function as an argument. We *should* switch to using gcc-style ++// inline assembly, but attempting to do so with Studio 12.4 ran into ++// segfaults. ++ ++template<> ++template ++inline T Atomic::PlatformCmpxchg<1>::operator()(T volatile* dest, ++ T compare_value, ++ T exchange_value, ++ atomic_memory_order order) const { ++ STATIC_ASSERT(1 == sizeof(T)); ++ return PrimitiveConversions::cast( ++ _Atomic_cmpxchg_byte(PrimitiveConversions::cast(exchange_value), ++ reinterpret_cast(dest), ++ PrimitiveConversions::cast(compare_value))); ++} ++ ++template<> ++template ++inline T Atomic::PlatformCmpxchg<4>::operator()(T volatile* dest, ++ T compare_value, ++ T exchange_value, ++ atomic_memory_order order) const { ++ STATIC_ASSERT(4 == sizeof(T)); ++ return PrimitiveConversions::cast( ++ _Atomic_cmpxchg(PrimitiveConversions::cast(exchange_value), ++ reinterpret_cast(dest), ++ PrimitiveConversions::cast(compare_value))); ++} ++ ++template<> ++template ++inline T Atomic::PlatformCmpxchg<8>::operator()(T volatile* dest, ++ T compare_value, ++ T exchange_value, ++ atomic_memory_order order) const { ++ STATIC_ASSERT(8 == sizeof(T)); ++ return PrimitiveConversions::cast( ++ _Atomic_cmpxchg_long(PrimitiveConversions::cast(exchange_value), ++ reinterpret_cast(dest), ++ PrimitiveConversions::cast(compare_value))); ++} ++ ++#endif // OS_CPU_SOLARIS_X86_ATOMIC_SOLARIS_X86_HPP +diff -urN /tmp/a/bytes_solaris_x86.hpp b/src/hotspot/os_cpu/solaris_x86/bytes_solaris_x86.hpp +--- /tmp/a/bytes_solaris_x86.hpp 1970-01-01 01:00:00.000000000 +0100 ++++ b/src/hotspot/os_cpu/solaris_x86/bytes_solaris_x86.hpp 2024-10-15 14:59:36.868451442 +0100 +@@ -0,0 +1,60 @@ ++/* ++ * Copyright (c) 1998, 2019, Oracle and/or its affiliates. All rights reserved. ++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. ++ * ++ * This code is free software; you can redistribute it and/or modify it ++ * under the terms of the GNU General Public License version 2 only, as ++ * published by the Free Software Foundation. ++ * ++ * This code is distributed in the hope that it will be useful, but WITHOUT ++ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or ++ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License ++ * version 2 for more details (a copy is included in the LICENSE file that ++ * accompanied this code). ++ * ++ * You should have received a copy of the GNU General Public License version ++ * 2 along with this work; if not, write to the Free Software Foundation, ++ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. ++ * ++ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA ++ * or visit www.oracle.com if you need additional information or have any ++ * questions. ++ * ++ */ ++ ++#ifndef OS_CPU_SOLARIS_X86_BYTES_SOLARIS_X86_HPP ++#define OS_CPU_SOLARIS_X86_BYTES_SOLARIS_X86_HPP ++ ++extern "C" { ++ inline u2 _raw_swap_u2(u2 x) { ++ unsigned short int __dest; ++ __asm__ ("rorw $8, %w0": "=r" (__dest): "0" (x): "cc"); ++ return __dest; ++ } ++ inline u4 _raw_swap_u4(u4 x) { ++ unsigned int __dest; ++ __asm__ ("bswap %0" : "=r" (__dest) : "0" (x)); ++ return __dest; ++ } ++ inline u8 _raw_swap_u8(u8 x) { ++ unsigned long __dest; ++ __asm__ ("bswap %q0" : "=r" (__dest) : "0" (x)); ++ return __dest; ++ } ++} ++ ++// Efficient swapping of data bytes from Java byte ++// ordering to native byte ordering and vice versa. ++inline u2 Bytes::swap_u2(u2 x) { ++ return _raw_swap_u2(x); ++} ++ ++inline u4 Bytes::swap_u4(u4 x) { ++ return _raw_swap_u4(x); ++} ++ ++inline u8 Bytes::swap_u8(u8 x) { ++ return _raw_swap_u8(x); ++} ++ ++#endif // OS_CPU_SOLARIS_X86_BYTES_SOLARIS_X86_HPP +diff -urN /tmp/a/copy_solaris_x86.hpp b/src/hotspot/os_cpu/solaris_x86/copy_solaris_x86.hpp +--- /tmp/a/copy_solaris_x86.hpp 1970-01-01 01:00:00.000000000 +0100 ++++ b/src/hotspot/os_cpu/solaris_x86/copy_solaris_x86.hpp 2024-10-15 14:59:36.868532464 +0100 +@@ -0,0 +1,30 @@ ++/* ++ * Copyright (c) 2003, 2019, Oracle and/or its affiliates. All rights reserved. ++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. ++ * ++ * This code is free software; you can redistribute it and/or modify it ++ * under the terms of the GNU General Public License version 2 only, as ++ * published by the Free Software Foundation. ++ * ++ * This code is distributed in the hope that it will be useful, but WITHOUT ++ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or ++ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License ++ * version 2 for more details (a copy is included in the LICENSE file that ++ * accompanied this code). ++ * ++ * You should have received a copy of the GNU General Public License version ++ * 2 along with this work; if not, write to the Free Software Foundation, ++ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. ++ * ++ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA ++ * or visit www.oracle.com if you need additional information or have any ++ * questions. ++ * ++ */ ++ ++#ifndef OS_CPU_SOLARIS_X86_COPY_SOLARIS_X86_HPP ++#define OS_CPU_SOLARIS_X86_COPY_SOLARIS_X86_HPP ++ ++// now in central copy_x86.hpp ++ ++#endif // OS_CPU_SOLARIS_X86_COPY_SOLARIS_X86_HPP +diff -urN /tmp/a/globals_solaris_x86.hpp b/src/hotspot/os_cpu/solaris_x86/globals_solaris_x86.hpp +--- /tmp/a/globals_solaris_x86.hpp 1970-01-01 01:00:00.000000000 +0100 ++++ b/src/hotspot/os_cpu/solaris_x86/globals_solaris_x86.hpp 2024-10-15 14:59:36.868622681 +0100 +@@ -0,0 +1,40 @@ ++/* ++ * Copyright (c) 2000, 2019, Oracle and/or its affiliates. All rights reserved. ++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. ++ * ++ * This code is free software; you can redistribute it and/or modify it ++ * under the terms of the GNU General Public License version 2 only, as ++ * published by the Free Software Foundation. ++ * ++ * This code is distributed in the hope that it will be useful, but WITHOUT ++ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or ++ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License ++ * version 2 for more details (a copy is included in the LICENSE file that ++ * accompanied this code). ++ * ++ * You should have received a copy of the GNU General Public License version ++ * 2 along with this work; if not, write to the Free Software Foundation, ++ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. ++ * ++ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA ++ * or visit www.oracle.com if you need additional information or have any ++ * questions. ++ * ++ */ ++ ++#ifndef OS_CPU_SOLARIS_X86_GLOBALS_SOLARIS_X86_HPP ++#define OS_CPU_SOLARIS_X86_GLOBALS_SOLARIS_X86_HPP ++ ++// Sets the default values for platform dependent flags used by the runtime system. ++// (see globals.hpp) ++ ++define_pd_global(bool, DontYieldALot, true); // Determined in the design center ++define_pd_global(intx, CompilerThreadStackSize, 1024); ++define_pd_global(intx, ThreadStackSize, 1024); // 0 => use system default ++define_pd_global(intx, VMThreadStackSize, 1024); ++define_pd_global(size_t, JVMInvokeMethodSlack, 8*K); ++ ++// Used on 64 bit platforms for UseCompressedOops base address ++define_pd_global(size_t, HeapBaseMinAddress, 2*G); ++ ++#endif // OS_CPU_SOLARIS_X86_GLOBALS_SOLARIS_X86_HPP +diff -urN /tmp/a/javaThread_solaris_x86.cpp b/src/hotspot/os_cpu/solaris_x86/javaThread_solaris_x86.cpp +--- /tmp/a/javaThread_solaris_x86.cpp 1970-01-01 01:00:00.000000000 +0100 ++++ b/src/hotspot/os_cpu/solaris_x86/javaThread_solaris_x86.cpp 2024-10-15 14:59:36.869548940 +0100 +@@ -0,0 +1,97 @@ ++/* ++ * Copyright (c) 2003, 2020, Oracle and/or its affiliates. All rights reserved. ++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. ++ * ++ * This code is free software; you can redistribute it and/or modify it ++ * under the terms of the GNU General Public License version 2 only, as ++ * published by the Free Software Foundation. ++ * ++ * This code is distributed in the hope that it will be useful, but WITHOUT ++ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or ++ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License ++ * version 2 for more details (a copy is included in the LICENSE file that ++ * accompanied this code). ++ * ++ * You should have received a copy of the GNU General Public License version ++ * 2 along with this work; if not, write to the Free Software Foundation, ++ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. ++ * ++ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA ++ * or visit www.oracle.com if you need additional information or have any ++ * questions. ++ * ++ */ ++ ++#include "precompiled.hpp" ++#include "runtime/frame.inline.hpp" ++#include "runtime/javaThread.hpp" ++ ++frame JavaThread::pd_last_frame() { ++ assert(has_last_Java_frame(), "must have last_Java_sp() when suspended"); ++ vmassert(_anchor.last_Java_pc() != NULL, "not walkable"); ++ return frame(_anchor.last_Java_sp(), _anchor.last_Java_fp(), _anchor.last_Java_pc()); ++} ++ ++// For Forte Analyzer AsyncGetCallTrace profiling support - thread is ++// currently interrupted by SIGPROF ++bool JavaThread::pd_get_top_frame_for_signal_handler(frame* fr_addr, ++ void* ucontext, bool isInJava) { ++ assert(Thread::current() == this, "caller must be current thread"); ++ return pd_get_top_frame(fr_addr, ucontext, isInJava); ++} ++ ++bool JavaThread::pd_get_top_frame_for_profiling(frame* fr_addr, ++ void* ucontext, bool isInJava) { ++ return pd_get_top_frame(fr_addr, ucontext, isInJava); ++} ++ ++bool JavaThread::pd_get_top_frame(frame* fr_addr, ++ void* ucontext, bool isInJava) { ++ assert(this->is_Java_thread(), "must be JavaThread"); ++ JavaThread* jt = (JavaThread *)this; ++ ++ // There is small window where last_Java_frame is not walkable or safe ++ if (jt->has_last_Java_frame() && jt->frame_anchor()->walkable()) { ++ *fr_addr = jt->pd_last_frame(); ++ return true; ++ } ++ ++ ucontext_t* uc = (ucontext_t*) ucontext; ++ ++ // We always want to use the initial frame we create from the ucontext as ++ // it certainly signals where we currently are. However that frame may not ++ // be safe for calling sender. In that case if we have a last_Java_frame ++ // then the forte walker will switch to that frame as the virtual sender ++ // for the frame we create here which is not sender safe. ++ ++ intptr_t* ret_fp; ++ intptr_t* ret_sp; ++ address addr = os::fetch_frame_from_context(uc, &ret_sp, &ret_fp); ++ ++ // Something would really have to be screwed up to get a NULL pc ++ ++ if (addr == NULL) { ++ // ucontext wasn't useful ++ return false; ++ } ++ ++ // If sp and fp are nonsense just leave them out ++ ++ if (!jt->is_in_full_stack((address)ret_sp)) { ++ ret_sp = NULL; ++ ret_fp = NULL; ++ } else { ++ // sp is reasonable is fp reasonable? ++ if (!jt->is_in_stack_range_incl((address)ret_fp, (address)ret_sp)) { ++ ret_fp = NULL; ++ } ++ } ++ ++ frame ret_frame(ret_sp, ret_fp, addr); ++ ++ *fr_addr = ret_frame; ++ return true; ++ ++} ++ ++void JavaThread::cache_global_variables() { } +diff -urN /tmp/a/javaThread_solaris_x86.hpp b/src/hotspot/os_cpu/solaris_x86/javaThread_solaris_x86.hpp +--- /tmp/a/javaThread_solaris_x86.hpp 1970-01-01 01:00:00.000000000 +0100 ++++ b/src/hotspot/os_cpu/solaris_x86/javaThread_solaris_x86.hpp 2024-10-15 14:59:36.869648787 +0100 +@@ -0,0 +1,59 @@ ++/* ++ * Copyright (c) 1999, 2019, Oracle and/or its affiliates. All rights reserved. ++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. ++ * ++ * This code is free software; you can redistribute it and/or modify it ++ * under the terms of the GNU General Public License version 2 only, as ++ * published by the Free Software Foundation. ++ * ++ * This code is distributed in the hope that it will be useful, but WITHOUT ++ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or ++ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License ++ * version 2 for more details (a copy is included in the LICENSE file that ++ * accompanied this code). ++ * ++ * You should have received a copy of the GNU General Public License version ++ * 2 along with this work; if not, write to the Free Software Foundation, ++ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. ++ * ++ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA ++ * or visit www.oracle.com if you need additional information or have any ++ * questions. ++ * ++ */ ++ ++#ifndef OS_CPU_SOLARIS_X86_JAVATHREAD_SOLARIS_X86_HPP ++#define OS_CPU_SOLARIS_X86_JAVATHREAD_SOLARIS_X86_HPP ++ ++ private: ++ void pd_initialize() { _anchor.clear(); } ++ ++ frame pd_last_frame(); ++ ++ public: ++ ++ void set_base_of_stack_pointer(intptr_t* base_sp) {} ++ ++ static ByteSize last_Java_fp_offset() { ++ return byte_offset_of(JavaThread, _anchor) + JavaFrameAnchor::last_Java_fp_offset(); ++ } ++ ++ intptr_t* base_of_stack_pointer() { return NULL; } ++ void record_base_of_stack_pointer() {} ++ ++ bool pd_get_top_frame_for_signal_handler(frame* fr_addr, void* ucontext, ++ bool isInJava); ++ bool pd_get_top_frame_for_profiling(frame* fr_addr, void* ucontext, ++ bool isInJava); ++private: ++ bool pd_get_top_frame(frame* fr_addr, void* ucontext, ++ bool isInJava); ++public: ++ ++ // These routines are only used on cpu architectures that ++ // have separate register stacks (Itanium). ++ static bool register_stack_overflow() { return false; } ++ static void enable_register_stack_guard() {} ++ static void disable_register_stack_guard() {} ++ ++#endif // OS_CPU_SOLARIS_X86_JAVATHREAD_SOLARIS_X86_HPP +diff -urN /tmp/a/orderAccess_solaris_x86.hpp b/src/hotspot/os_cpu/solaris_x86/orderAccess_solaris_x86.hpp +--- /tmp/a/orderAccess_solaris_x86.hpp 1970-01-01 01:00:00.000000000 +0100 ++++ b/src/hotspot/os_cpu/solaris_x86/orderAccess_solaris_x86.hpp 2024-10-15 14:59:36.868709514 +0100 +@@ -0,0 +1,58 @@ ++/* ++ * Copyright (c) 2003, 2019, Oracle and/or its affiliates. All rights reserved. ++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. ++ * ++ * This code is free software; you can redistribute it and/or modify it ++ * under the terms of the GNU General Public License version 2 only, as ++ * published by the Free Software Foundation. ++ * ++ * This code is distributed in the hope that it will be useful, but WITHOUT ++ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or ++ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License ++ * version 2 for more details (a copy is included in the LICENSE file that ++ * accompanied this code). ++ * ++ * You should have received a copy of the GNU General Public License version ++ * 2 along with this work; if not, write to the Free Software Foundation, ++ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. ++ * ++ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA ++ * or visit www.oracle.com if you need additional information or have any ++ * questions. ++ * ++ */ ++ ++#ifndef OS_CPU_SOLARIS_X86_ORDERACCESS_SOLARIS_X86_HPP ++#define OS_CPU_SOLARIS_X86_ORDERACCESS_SOLARIS_X86_HPP ++ ++// Included in orderAccess.hpp header file. ++ ++// Compiler version last used for testing: solaris studio 12u3 ++// Please update this information when this file changes ++ ++// Implementation of class OrderAccess. ++ ++// A compiler barrier, forcing the C++ compiler to invalidate all memory assumptions ++inline void compiler_barrier() { ++ __asm__ volatile ("" : : : "memory"); ++} ++ ++inline void OrderAccess::loadload() { compiler_barrier(); } ++inline void OrderAccess::storestore() { compiler_barrier(); } ++inline void OrderAccess::loadstore() { compiler_barrier(); } ++inline void OrderAccess::storeload() { fence(); } ++ ++inline void OrderAccess::acquire() { compiler_barrier(); } ++inline void OrderAccess::release() { compiler_barrier(); } ++ ++inline void OrderAccess::fence() { ++ __asm__ volatile ("lock; addl $0,0(%%rsp)" : : : "cc", "memory"); ++ compiler_barrier(); ++} ++ ++inline void OrderAccess::cross_modify_fence_impl() { ++ int idx = 0; ++ __asm__ volatile ("cpuid " : "+a" (idx) : : "ebx", "ecx", "edx", "memory"); ++} ++ ++#endif // OS_CPU_SOLARIS_X86_ORDERACCESS_SOLARIS_X86_HPP +diff -urN /tmp/a/os_solaris_x86.cpp b/src/hotspot/os_cpu/solaris_x86/os_solaris_x86.cpp +--- /tmp/a/os_solaris_x86.cpp 1970-01-01 01:00:00.000000000 +0100 ++++ b/src/hotspot/os_cpu/solaris_x86/os_solaris_x86.cpp 2024-10-15 14:59:36.911042968 +0100 +@@ -0,0 +1,610 @@ ++/* ++ * Copyright (c) 1999, 2020, Oracle and/or its affiliates. All rights reserved. ++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. ++ * ++ * This code is free software; you can redistribute it and/or modify it ++ * under the terms of the GNU General Public License version 2 only, as ++ * published by the Free Software Foundation. ++ * ++ * This code is distributed in the hope that it will be useful, but WITHOUT ++ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or ++ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License ++ * version 2 for more details (a copy is included in the LICENSE file that ++ * accompanied this code). ++ * ++ * You should have received a copy of the GNU General Public License version ++ * 2 along with this work; if not, write to the Free Software Foundation, ++ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. ++ * ++ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA ++ * or visit www.oracle.com if you need additional information or have any ++ * questions. ++ * ++ */ ++ ++// no precompiled headers ++#include "jvm.h" ++#include "asm/macroAssembler.hpp" ++#include "classfile/classLoader.hpp" ++#include "classfile/systemDictionary.hpp" ++#include "classfile/vmSymbols.hpp" ++#include "code/codeCache.hpp" ++#include "code/icBuffer.hpp" ++#include "code/vtableStubs.hpp" ++#include "interpreter/interpreter.hpp" ++#include "logging/log.hpp" ++#include "memory/allocation.inline.hpp" ++#include "os_solaris.hpp" ++#include "os_posix.hpp" ++#include "prims/jniFastGetField.hpp" ++#include "prims/jvm_misc.hpp" ++#include "runtime/arguments.hpp" ++#include "runtime/frame.inline.hpp" ++#include "runtime/interfaceSupport.inline.hpp" ++#include "runtime/java.hpp" ++#include "runtime/javaCalls.hpp" ++#include "runtime/mutexLocker.hpp" ++#include "runtime/osThread.hpp" ++#include "runtime/safepointMechanism.hpp" ++#include "runtime/sharedRuntime.hpp" ++#include "runtime/stubRoutines.hpp" ++#include "runtime/thread.inline.hpp" ++#include "runtime/timer.hpp" ++#include "signals_posix.hpp" ++#include "utilities/align.hpp" ++#include "utilities/events.hpp" ++#include "utilities/vmError.hpp" ++ ++// put OS-includes here ++# include ++# include ++# include ++# include ++# include ++# include ++# include ++# include ++# include ++# include ++# include ++# include ++# include ++# include ++# include ++# include ++# include ++# include ++# include ++# include ++# include ++# include ++ ++ ++#define MAX_PATH (2 * K) ++ ++// Minimum usable stack sizes required to get to user code. Space for ++// HotSpot guard pages is added later. ++#ifdef _LP64 ++// The adlc generated method 'State::MachNodeGenerator(int)' used by the C2 compiler ++// threads requires a large stack with the Solaris Studio C++ compiler version 5.13 ++// and product VM builds (debug builds require significantly less stack space). ++size_t os::_compiler_thread_min_stack_allowed = 325 * K; ++size_t os::_java_thread_min_stack_allowed = 48 * K; ++size_t os::_vm_internal_thread_min_stack_allowed = 224 * K; ++#else ++size_t os::_compiler_thread_min_stack_allowed = 32 * K; ++size_t os::_java_thread_min_stack_allowed = 32 * K; ++size_t os::_vm_internal_thread_min_stack_allowed = 64 * K; ++#endif // _LP64 ++ ++#ifdef AMD64 ++#define REG_SP REG_RSP ++#define REG_PC REG_RIP ++#define REG_FP REG_RBP ++#else ++#define REG_SP UESP ++#define REG_PC EIP ++#define REG_FP EBP ++// 4900493 counter to prevent runaway LDTR refresh attempt ++ ++static volatile int ldtr_refresh = 0; ++// the libthread instruction that faults because of the stale LDTR ++ ++static const unsigned char movlfs[] = { 0x8e, 0xe0 // movl %eax,%fs ++ }; ++#endif // AMD64 ++ ++char* os::non_memory_address_word() { ++ // Must never look like an address returned by reserve_memory, ++ // even in its subfields (as defined by the CPU immediate fields, ++ // if the CPU splits constants across multiple instructions). ++ return (char*) -1; ++} ++ ++// ++// Validate a ucontext retrieved from walking a uc_link of a ucontext. ++// There are issues with libthread giving out uc_links for different threads ++// on the same uc_link chain and bad or circular links. ++// ++bool os::Solaris::valid_ucontext(Thread* thread, const ucontext_t* valid, const ucontext_t* suspect) { ++ if (valid >= suspect || ++ valid->uc_stack.ss_flags != suspect->uc_stack.ss_flags || ++ valid->uc_stack.ss_sp != suspect->uc_stack.ss_sp || ++ valid->uc_stack.ss_size != suspect->uc_stack.ss_size) { ++ DEBUG_ONLY(tty->print_cr("valid_ucontext: failed test 1");) ++ return false; ++ } ++ ++ if (thread->is_Java_thread()) { ++ if (!thread->is_in_full_stack_checked((address)suspect)) { ++ DEBUG_ONLY(tty->print_cr("valid_ucontext: uc_link not in thread stack");) ++ return false; ++ } ++ if (!thread->is_in_full_stack_checked((address) suspect->uc_mcontext.gregs[REG_SP])) { ++ DEBUG_ONLY(tty->print_cr("valid_ucontext: stackpointer not in thread stack");) ++ return false; ++ } ++ } ++ return true; ++} ++ ++// We will only follow one level of uc_link since there are libthread ++// issues with ucontext linking and it is better to be safe and just ++// let caller retry later. ++const ucontext_t* os::Solaris::get_valid_uc_in_signal_handler(Thread *thread, ++ const ucontext_t *uc) { ++ ++ const ucontext_t *retuc = NULL; ++ ++ if (uc != NULL) { ++ if (uc->uc_link == NULL) { ++ // cannot validate without uc_link so accept current ucontext ++ retuc = uc; ++ } else if (os::Solaris::valid_ucontext(thread, uc, uc->uc_link)) { ++ // first ucontext is valid so try the next one ++ uc = uc->uc_link; ++ if (uc->uc_link == NULL) { ++ // cannot validate without uc_link so accept current ucontext ++ retuc = uc; ++ } else if (os::Solaris::valid_ucontext(thread, uc, uc->uc_link)) { ++ // the ucontext one level down is also valid so return it ++ retuc = uc; ++ } ++ } ++ } ++ return retuc; ++} ++ ++void os::Posix::ucontext_set_pc(ucontext_t* uc, address pc) { ++ uc->uc_mcontext.gregs [REG_PC] = (greg_t) pc; ++} ++ ++// Assumes ucontext is valid ++intptr_t* os::Solaris::ucontext_get_sp(const ucontext_t *uc) { ++ return (intptr_t*)uc->uc_mcontext.gregs[REG_SP]; ++} ++ ++// Assumes ucontext is valid ++intptr_t* os::Solaris::ucontext_get_fp(const ucontext_t *uc) { ++ return (intptr_t*)uc->uc_mcontext.gregs[REG_FP]; ++} ++ ++address os::Posix::ucontext_get_pc(const ucontext_t *uc) { ++ return (address) uc->uc_mcontext.gregs[REG_PC]; ++} ++ ++address os::fetch_frame_from_context(const void* ucVoid, ++ intptr_t** ret_sp, intptr_t** ret_fp) { ++ ++ address epc; ++ const ucontext_t *uc = (const ucontext_t*)ucVoid; ++ ++ if (uc != NULL) { ++ epc = os::Posix::ucontext_get_pc(uc); ++ if (ret_sp) *ret_sp = os::Solaris::ucontext_get_sp(uc); ++ if (ret_fp) *ret_fp = os::Solaris::ucontext_get_fp(uc); ++ } else { ++ epc = NULL; ++ if (ret_sp) *ret_sp = (intptr_t *)NULL; ++ if (ret_fp) *ret_fp = (intptr_t *)NULL; ++ } ++ ++ return epc; ++} ++ ++frame os::fetch_frame_from_context(const void* ucVoid) { ++ intptr_t* sp; ++ intptr_t* fp; ++ address epc = fetch_frame_from_context(ucVoid, &sp, &fp); ++ return frame(sp, fp, epc); ++} ++ ++frame os::fetch_compiled_frame_from_context(const void* ucVoid) { ++ const ucontext_t* uc = (const ucontext_t*)ucVoid; ++ frame fr = os::fetch_frame_from_context(uc); ++ // in compiled code, the stack banging is performed just after the return pc ++ // has been pushed on the stack ++ return frame(fr.sp() + 1, fr.fp(), (address)*(fr.sp())); ++} ++ ++frame os::get_sender_for_C_frame(frame* fr) { ++ return frame(fr->sender_sp(), fr->link(), fr->sender_pc()); ++} ++ ++extern "C" intptr_t *_get_current_sp() { ++ register intptr_t *rsp __asm__ ("rsp"); ++ return rsp; ++} ++ ++address os::current_stack_pointer() { ++ return (address)_get_current_sp(); ++} ++ ++extern "C" intptr_t *_get_current_fp() { ++ register intptr_t **rbp __asm__ ("rbp"); ++ return (intptr_t*) *rbp; ++} ++ ++frame os::current_frame() { ++ intptr_t* fp = _get_current_fp(); // it's inlined so want current fp ++ // fp is for os::current_frame. We want the fp for our caller. ++ frame myframe((intptr_t*)os::current_stack_pointer(), ++ (intptr_t*)fp, ++ CAST_FROM_FN_PTR(address, os::current_frame)); ++ frame caller_frame = os::get_sender_for_C_frame(&myframe); ++ ++ if (os::is_first_C_frame(&caller_frame)) { ++ // stack is not walkable ++ frame ret; // This will be a null useless frame ++ return ret; ++ } else { ++ // return frame for our caller's caller ++ return os::get_sender_for_C_frame(&caller_frame); ++ } ++} ++ ++ ++juint os::cpu_microcode_revision() { ++ juint result = 0; ++ // to implement this, look at the source for ucodeadm -v ++ return result; ++} ++ ++bool PosixSignals::pd_hotspot_signal_handler(int sig, siginfo_t* info, ++ ucontext_t* uc, JavaThread* thread) { ++ ++ if (info == NULL || info->si_code <= 0 || info->si_code == SI_NOINFO) { ++ // can't decode this kind of signal ++ info = NULL; ++ } else { ++ assert(sig == info->si_signo, "bad siginfo"); ++ } ++ ++ // decide if this trap can be handled by a stub ++ address stub = NULL; ++ ++ address pc = NULL; ++ ++ //%note os_trap_1 ++ if (info != NULL && uc != NULL && thread != NULL) { ++ // factor me: getPCfromContext ++ pc = (address) uc->uc_mcontext.gregs[REG_PC]; ++ ++ // Handle ALL stack overflow variations here ++ if (sig == SIGSEGV && info->si_code == SEGV_ACCERR) { ++ address addr = (address) info->si_addr; ++ if (thread->is_in_full_stack(addr)) { ++ // stack overflow ++ if (os::Posix::handle_stack_overflow(thread, addr, pc, uc, &stub)) { ++ return true; // continue ++ } ++ } ++ } ++ ++ if ((sig == SIGSEGV) && VM_Version::is_cpuinfo_segv_addr(pc)) { ++ // Verify that OS save/restore AVX registers. ++ stub = VM_Version::cpuinfo_cont_addr(); ++ } ++ ++ if (thread->thread_state() == _thread_in_vm || ++ thread->thread_state() == _thread_in_native) { ++ if (sig == SIGBUS && info->si_code == BUS_OBJERR && thread->doing_unsafe_access()) { ++ address next_pc = Assembler::locate_next_instruction(pc); ++ if (UnsafeCopyMemory::contains_pc(pc)) { ++ next_pc = UnsafeCopyMemory::page_error_continue_pc(pc); ++ } ++ stub = SharedRuntime::handle_unsafe_access(thread, next_pc); ++ } ++ } ++ ++ if (thread->thread_state() == _thread_in_Java) { ++ // Support Safepoint Polling ++ if ( sig == SIGSEGV && SafepointMechanism::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 ++ // here if the underlying file has been truncated. ++ // Do not crash the VM in such a case. ++ CodeBlob* cb = CodeCache::find_blob(pc); ++ if (cb != NULL) { ++ CompiledMethod* nm = cb->as_compiled_method_or_null(); ++ bool is_unsafe_arraycopy = thread->doing_unsafe_access() && UnsafeCopyMemory::contains_pc(pc); ++ if ((nm != NULL && nm->has_unsafe_access()) || is_unsafe_arraycopy) { ++ address next_pc = Assembler::locate_next_instruction(pc); ++ if (is_unsafe_arraycopy) { ++ next_pc = UnsafeCopyMemory::page_error_continue_pc(pc); ++ } ++ stub = SharedRuntime::handle_unsafe_access(thread, next_pc); ++ } ++ } ++ } ++ else ++ if (sig == SIGFPE && info->si_code == FPE_INTDIV) { ++ // integer divide by zero ++ stub = SharedRuntime::continuation_for_implicit_exception(thread, pc, SharedRuntime::IMPLICIT_DIVIDE_BY_ZERO); ++ } ++#ifndef AMD64 ++ else if (sig == SIGFPE && info->si_code == FPE_FLTDIV) { ++ // floating-point divide by zero ++ stub = SharedRuntime::continuation_for_implicit_exception(thread, pc, SharedRuntime::IMPLICIT_DIVIDE_BY_ZERO); ++ } ++ else if (sig == SIGFPE && info->si_code == FPE_FLTINV) { ++ // The encoding of D2I in i486.ad can cause an exception prior ++ // to the fist instruction if there was an invalid operation ++ // pending. We want to dismiss that exception. From the win_32 ++ // side it also seems that if it really was the fist causing ++ // the exception that we do the d2i by hand with different ++ // rounding. Seems kind of weird. QQQ TODO ++ // Note that we take the exception at the NEXT floating point instruction. ++ if (pc[0] == 0xDB) { ++ assert(pc[0] == 0xDB, "not a FIST opcode"); ++ assert(pc[1] == 0x14, "not a FIST opcode"); ++ assert(pc[2] == 0x24, "not a FIST opcode"); ++ return true; ++ } else { ++ assert(pc[-3] == 0xDB, "not an flt invalid opcode"); ++ assert(pc[-2] == 0x14, "not an flt invalid opcode"); ++ assert(pc[-1] == 0x24, "not an flt invalid opcode"); ++ } ++ } ++ else if (sig == SIGFPE ) { ++ tty->print_cr("caught SIGFPE, info 0x%x.", info->si_code); ++ } ++#endif // !AMD64 ++ ++ // QQQ It doesn't seem that we need to do this on x86 because we should be able ++ // to return properly from the handler without this extra stuff on the back side. ++ ++ else if (sig == SIGSEGV && info->si_code > 0 && ++ MacroAssembler::uses_implicit_null_check(info->si_addr)) { ++ // Determination of interpreter/vtable stub/compiled code null exception ++ stub = SharedRuntime::continuation_for_implicit_exception(thread, pc, SharedRuntime::IMPLICIT_NULL); ++ } ++ } ++ ++ // jni_fast_GetField can trap at certain pc's if a GC kicks in ++ // and the heap gets shrunk before the field access. ++ if ((sig == SIGSEGV) || (sig == SIGBUS)) { ++ address addr = JNI_FastGetField::find_slowcase_pc(pc); ++ if (addr != (address)-1) { ++ stub = addr; ++ } ++ } ++ } ++ ++ // Execution protection violation ++ // ++ // Preventative code for future versions of Solaris which may ++ // enable execution protection when running the 32-bit VM on AMD64. ++ // ++ // This should be kept as the last step in the triage. We don't ++ // have a dedicated trap number for a no-execute fault, so be ++ // conservative and allow other handlers the first shot. ++ // ++ // Note: We don't test that info->si_code == SEGV_ACCERR here. ++ // this si_code is so generic that it is almost meaningless; and ++ // the si_code for this condition may change in the future. ++ // Furthermore, a false-positive should be harmless. ++ if (UnguardOnExecutionViolation > 0 && ++ (sig == SIGSEGV || sig == SIGBUS) && ++ uc->uc_mcontext.gregs[TRAPNO] == T_PGFLT) { // page fault ++ int page_size = os::vm_page_size(); ++ address addr = (address) info->si_addr; ++ address pc = (address) uc->uc_mcontext.gregs[REG_PC]; ++ // Make sure the pc and the faulting address are sane. ++ // ++ // If an instruction spans a page boundary, and the page containing ++ // the beginning of the instruction is executable but the following ++ // page is not, the pc and the faulting address might be slightly ++ // different - we still want to unguard the 2nd page in this case. ++ // ++ // 15 bytes seems to be a (very) safe value for max instruction size. ++ bool pc_is_near_addr = ++ (pointer_delta((void*) addr, (void*) pc, sizeof(char)) < 15); ++ bool instr_spans_page_boundary = ++ (align_down((intptr_t) pc ^ (intptr_t) addr, ++ (intptr_t) page_size) > 0); ++ ++ if (pc == addr || (pc_is_near_addr && instr_spans_page_boundary)) { ++ static volatile address last_addr = ++ (address) os::non_memory_address_word(); ++ ++ // In conservative mode, don't unguard unless the address is in the VM ++ if (addr != last_addr && ++ (UnguardOnExecutionViolation > 1 || os::address_is_in_vm(addr))) { ++ ++ // Make memory rwx and retry ++ address page_start = align_down(addr, page_size); ++ bool res = os::protect_memory((char*) page_start, page_size, ++ os::MEM_PROT_RWX); ++ ++ log_debug(os)("Execution protection violation " ++ "at " INTPTR_FORMAT ++ ", unguarding " INTPTR_FORMAT ": %s, errno=%d", p2i(addr), ++ p2i(page_start), (res ? "success" : "failed"), errno); ++ stub = pc; ++ ++ // Set last_addr so if we fault again at the same address, we don't end ++ // up in an endless loop. ++ // ++ // There are two potential complications here. Two threads trapping at ++ // the same address at the same time could cause one of the threads to ++ // think it already unguarded, and abort the VM. Likely very rare. ++ // ++ // The other race involves two threads alternately trapping at ++ // different addresses and failing to unguard the page, resulting in ++ // an endless loop. This condition is probably even more unlikely than ++ // the first. ++ // ++ // Although both cases could be avoided by using locks or thread local ++ // last_addr, these solutions are unnecessary complication: this ++ // handler is a best-effort safety net, not a complete solution. It is ++ // disabled by default and should only be used as a workaround in case ++ // we missed any no-execute-unsafe VM code. ++ ++ last_addr = addr; ++ } ++ } ++ } ++ ++ if (stub != NULL) { ++ // save all thread context in case we need to restore it ++ ++ if (thread != NULL) thread->set_saved_exception_pc(pc); ++ // 12/02/99: On Sparc it appears that the full context is also saved ++ // but as yet, no one looks at or restores that saved context ++ os::Posix::ucontext_set_pc(uc, stub); ++ return true; ++ } ++ ++ return false; ++} ++ ++void os::print_context(outputStream *st, const void *context) { ++ if (context == NULL) return; ++ ++ const ucontext_t *uc = (const ucontext_t*)context; ++ st->print_cr("Registers:"); ++#ifdef AMD64 ++ st->print( "RAX=" INTPTR_FORMAT, uc->uc_mcontext.gregs[REG_RAX]); ++ st->print(", RBX=" INTPTR_FORMAT, uc->uc_mcontext.gregs[REG_RBX]); ++ st->print(", RCX=" INTPTR_FORMAT, uc->uc_mcontext.gregs[REG_RCX]); ++ st->print(", RDX=" INTPTR_FORMAT, uc->uc_mcontext.gregs[REG_RDX]); ++ st->cr(); ++ st->print( "RSP=" INTPTR_FORMAT, uc->uc_mcontext.gregs[REG_RSP]); ++ st->print(", RBP=" INTPTR_FORMAT, uc->uc_mcontext.gregs[REG_RBP]); ++ st->print(", RSI=" INTPTR_FORMAT, uc->uc_mcontext.gregs[REG_RSI]); ++ st->print(", RDI=" INTPTR_FORMAT, uc->uc_mcontext.gregs[REG_RDI]); ++ st->cr(); ++ st->print( "R8 =" INTPTR_FORMAT, uc->uc_mcontext.gregs[REG_R8]); ++ st->print(", R9 =" INTPTR_FORMAT, uc->uc_mcontext.gregs[REG_R9]); ++ st->print(", R10=" INTPTR_FORMAT, uc->uc_mcontext.gregs[REG_R10]); ++ st->print(", R11=" INTPTR_FORMAT, uc->uc_mcontext.gregs[REG_R11]); ++ st->cr(); ++ st->print( "R12=" INTPTR_FORMAT, uc->uc_mcontext.gregs[REG_R12]); ++ st->print(", R13=" INTPTR_FORMAT, uc->uc_mcontext.gregs[REG_R13]); ++ st->print(", R14=" INTPTR_FORMAT, uc->uc_mcontext.gregs[REG_R14]); ++ st->print(", R15=" INTPTR_FORMAT, uc->uc_mcontext.gregs[REG_R15]); ++ st->cr(); ++ st->print( "RIP=" INTPTR_FORMAT, uc->uc_mcontext.gregs[REG_RIP]); ++ st->print(", RFLAGS=" INTPTR_FORMAT, uc->uc_mcontext.gregs[REG_RFL]); ++#else ++ st->print( "EAX=" INTPTR_FORMAT, uc->uc_mcontext.gregs[EAX]); ++ st->print(", EBX=" INTPTR_FORMAT, uc->uc_mcontext.gregs[EBX]); ++ st->print(", ECX=" INTPTR_FORMAT, uc->uc_mcontext.gregs[ECX]); ++ st->print(", EDX=" INTPTR_FORMAT, uc->uc_mcontext.gregs[EDX]); ++ st->cr(); ++ st->print( "ESP=" INTPTR_FORMAT, uc->uc_mcontext.gregs[UESP]); ++ st->print(", EBP=" INTPTR_FORMAT, uc->uc_mcontext.gregs[EBP]); ++ st->print(", ESI=" INTPTR_FORMAT, uc->uc_mcontext.gregs[ESI]); ++ st->print(", EDI=" INTPTR_FORMAT, uc->uc_mcontext.gregs[EDI]); ++ st->cr(); ++ st->print( "EIP=" INTPTR_FORMAT, uc->uc_mcontext.gregs[EIP]); ++ st->print(", EFLAGS=" INTPTR_FORMAT, uc->uc_mcontext.gregs[EFL]); ++#endif // AMD64 ++ st->cr(); ++ st->cr(); ++} ++ ++void os::print_tos_pc(outputStream *st, const void *context) { ++ if (context == NULL) return; ++ ++ const ucontext_t* uc = (const ucontext_t*)context; ++ ++ intptr_t *sp = (intptr_t *)os::Solaris::ucontext_get_sp(uc); ++ st->print_cr("Top of Stack: (sp=" INTPTR_FORMAT ")", (intptr_t)sp); ++ print_hex_dump(st, (address)sp, (address)(sp + 8*sizeof(intptr_t)), sizeof(intptr_t)); ++ st->cr(); ++ ++ // Note: it may be unsafe to inspect memory near pc. For example, pc may ++ // point to garbage if entry point in an nmethod is corrupted. Leave ++ // this at the end, and hope for the best. ++ address pc = os::Posix::ucontext_get_pc(uc); ++ print_instructions(st, pc, sizeof(char)); ++ st->cr(); ++} ++ ++void os::print_register_info(outputStream *st, const void *context, int& continuation) { ++ const int register_count = AMD64_ONLY(16) NOT_AMD64(8); ++ int n = continuation; ++ assert(n >= 0 && n <= register_count, "Invalid continuation value"); ++ if (context == nullptr || n == register_count) { ++ return; ++ } ++ ++ const ucontext_t *uc = (const ucontext_t*)context; ++ while (n < register_count) { ++ // Update continuation with next index before printing location ++ continuation = n + 1; ++# define CASE_PRINT_REG(n, str, id) case n: st->print(str); print_location(st, uc->uc_mcontext.gregs[REG_##id]); ++ switch (n) { ++#ifdef AMD64 ++ CASE_PRINT_REG( 0, "RAX=", RAX); break; ++ CASE_PRINT_REG( 1, "RBX=", RBX); break; ++ CASE_PRINT_REG( 2, "RCX=", RCX); break; ++ CASE_PRINT_REG( 3, "RDX=", RDX); break; ++ CASE_PRINT_REG( 4, "RSP=", RSP); break; ++ CASE_PRINT_REG( 5, "RBP=", RBP); break; ++ CASE_PRINT_REG( 6, "RSI=", RSI); break; ++ CASE_PRINT_REG( 7, "RDI=", RDI); break; ++ CASE_PRINT_REG( 8, "R8 =", R8); break; ++ CASE_PRINT_REG( 9, "R9 =", R9); break; ++ CASE_PRINT_REG(10, "R10=", R10); break; ++ CASE_PRINT_REG(11, "R11=", R11); break; ++ CASE_PRINT_REG(12, "R12=", R12); break; ++ CASE_PRINT_REG(13, "R13=", R13); break; ++ CASE_PRINT_REG(14, "R14=", R14); break; ++ CASE_PRINT_REG(15, "R15=", R15); break; ++#else ++ CASE_PRINT_REG(0, "EAX=", EAX); break; ++ CASE_PRINT_REG(1, "EBX=", EBX); break; ++ CASE_PRINT_REG(2, "ECX=", ECX); break; ++ CASE_PRINT_REG(3, "EDX=", EDX); break; ++ CASE_PRINT_REG(4, "ESP=", ESP); break; ++ CASE_PRINT_REG(5, "EBP=", EBP); break; ++ CASE_PRINT_REG(6, "ESI=", ESI); break; ++ CASE_PRINT_REG(7, "EDI=", EDI); break; ++#endif // AMD64 ++ } ++# undef CASE_PRINT_REG ++ ++n; ++ } ++} ++ ++ ++void os::Solaris::init_thread_fpu_state(void) { ++ // Nothing to do ++} ++void os::setup_fpu() {} ++ ++#ifndef PRODUCT ++void os::verify_stack_alignment() { ++ assert(((intptr_t)os::current_stack_pointer() & (StackAlignmentInBytes-1)) == 0, "incorrect stack alignment"); ++} ++#endif ++ ++int os::extra_bang_size_in_bytes() { ++ // JDK-8050147 requires the full cache line bang for x86. ++ return VM_Version::L1_line_size(); ++} +diff -urN /tmp/a/os_solaris_x86.hpp b/src/hotspot/os_cpu/solaris_x86/os_solaris_x86.hpp +--- /tmp/a/os_solaris_x86.hpp 1970-01-01 01:00:00.000000000 +0100 ++++ b/src/hotspot/os_cpu/solaris_x86/os_solaris_x86.hpp 2024-10-15 14:59:36.898145900 +0100 +@@ -0,0 +1,57 @@ ++/* ++ * Copyright (c) 1999, 2019, Oracle and/or its affiliates. All rights reserved. ++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. ++ * ++ * This code is free software; you can redistribute it and/or modify it ++ * under the terms of the GNU General Public License version 2 only, as ++ * published by the Free Software Foundation. ++ * ++ * This code is distributed in the hope that it will be useful, but WITHOUT ++ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or ++ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License ++ * version 2 for more details (a copy is included in the LICENSE file that ++ * accompanied this code). ++ * ++ * You should have received a copy of the GNU General Public License version ++ * 2 along with this work; if not, write to the Free Software Foundation, ++ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. ++ * ++ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA ++ * or visit www.oracle.com if you need additional information or have any ++ * questions. ++ * ++ */ ++ ++#ifndef OS_CPU_SOLARIS_X86_OS_SOLARIS_X86_HPP ++#define OS_CPU_SOLARIS_X86_OS_SOLARIS_X86_HPP ++ ++ // ++ // NOTE: we are back in class os here, not Solaris ++ // ++#ifdef AMD64 ++ static void setup_fpu() {} ++#else ++ static int32_t (*atomic_xchg_func) (int32_t, volatile int32_t*); ++ static int32_t (*atomic_cmpxchg_func) (int32_t, volatile int32_t*, int32_t); ++ static int64_t (*atomic_cmpxchg_long_func)(int64_t, volatile int64_t*, int64_t); ++ static int32_t (*atomic_add_func) (int32_t, volatile int32_t*); ++ ++ static int32_t atomic_xchg_bootstrap (int32_t, volatile int32_t*); ++ static int32_t atomic_cmpxchg_bootstrap (int32_t, volatile int32_t*, int32_t); ++ static int64_t atomic_cmpxchg_long_bootstrap(int64_t, volatile int64_t*, int64_t); ++ static int32_t atomic_add_bootstrap (int32_t, volatile int32_t*); ++ ++ static void setup_fpu(); ++#endif // AMD64 ++ ++ static juint cpu_microcode_revision(); ++ ++ static jlong rdtsc(); ++ ++ static bool is_allocatable(size_t bytes); ++ ++ // Used to register dynamic code cache area with the OS ++ // Note: Currently only used in 64 bit Windows implementations ++ static bool register_code_area(char *low, char *high) { return true; } ++ ++#endif // OS_CPU_SOLARIS_X86_OS_SOLARIS_X86_HPP +diff -urN /tmp/a/os_solaris_x86.inline.hpp b/src/hotspot/os_cpu/solaris_x86/os_solaris_x86.inline.hpp +--- /tmp/a/os_solaris_x86.inline.hpp 1970-01-01 01:00:00.000000000 +0100 ++++ b/src/hotspot/os_cpu/solaris_x86/os_solaris_x86.inline.hpp 2024-10-15 14:59:36.869168535 +0100 +@@ -0,0 +1,39 @@ ++/* ++ * Copyright (c) 2011, 2019, Oracle and/or its affiliates. All rights reserved. ++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. ++ * ++ * This code is free software; you can redistribute it and/or modify it ++ * under the terms of the GNU General Public License version 2 only, as ++ * published by the Free Software Foundation. ++ * ++ * This code is distributed in the hope that it will be useful, but WITHOUT ++ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or ++ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License ++ * version 2 for more details (a copy is included in the LICENSE file that ++ * accompanied this code). ++ * ++ * You should have received a copy of the GNU General Public License version ++ * 2 along with this work; if not, write to the Free Software Foundation, ++ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. ++ * ++ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA ++ * or visit www.oracle.com if you need additional information or have any ++ * questions. ++ * ++ */ ++ ++#ifndef OS_CPU_SOLARIS_X86_OS_SOLARIS_X86_INLINE_HPP ++#define OS_CPU_SOLARIS_X86_OS_SOLARIS_X86_INLINE_HPP ++ ++#include "runtime/os.hpp" ++ ++// See http://www.technovelty.org/code/c/reading-rdtsc.htl for details ++inline jlong os::rdtsc() { ++ uint64_t res; ++ uint32_t ts1, ts2; ++ __asm__ __volatile__ ("rdtsc" : "=a" (ts1), "=d" (ts2)); ++ res = ((uint64_t)ts1 | (uint64_t)ts2 << 32); ++ return (jlong)res; ++} ++ ++#endif // OS_CPU_SOLARIS_X86_OS_SOLARIS_X86_INLINE_HPP +diff -urN /tmp/a/prefetch_solaris_x86.inline.hpp b/src/hotspot/os_cpu/solaris_x86/prefetch_solaris_x86.inline.hpp +--- /tmp/a/prefetch_solaris_x86.inline.hpp 1970-01-01 01:00:00.000000000 +0100 ++++ b/src/hotspot/os_cpu/solaris_x86/prefetch_solaris_x86.inline.hpp 2024-10-15 14:59:36.869266764 +0100 +@@ -0,0 +1,42 @@ ++/* ++ * Copyright (c) 2003, 2019, Oracle and/or its affiliates. All rights reserved. ++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. ++ * ++ * This code is free software; you can redistribute it and/or modify it ++ * under the terms of the GNU General Public License version 2 only, as ++ * published by the Free Software Foundation. ++ * ++ * This code is distributed in the hope that it will be useful, but WITHOUT ++ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or ++ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License ++ * version 2 for more details (a copy is included in the LICENSE file that ++ * accompanied this code). ++ * ++ * You should have received a copy of the GNU General Public License version ++ * 2 along with this work; if not, write to the Free Software Foundation, ++ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. ++ * ++ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA ++ * or visit www.oracle.com if you need additional information or have any ++ * questions. ++ * ++ */ ++ ++#ifndef OS_CPU_SOLARIS_X86_PREFETCH_SOLARIS_X86_INLINE_HPP ++#define OS_CPU_SOLARIS_X86_PREFETCH_SOLARIS_X86_INLINE_HPP ++ ++#include "runtime/prefetch.hpp" ++ ++inline void Prefetch::read (const void *loc, intx interval) { ++#ifdef AMD64 ++ __asm__ ("prefetcht0 (%0,%1,1)" : : "r" (loc), "r" (interval)); ++#endif // AMD64 ++} ++ ++inline void Prefetch::write(void *loc, intx interval) { ++#ifdef AMD64 ++ __asm__ ("prefetcht0 (%0,%1,1)" : : "r" (loc), "r" (interval)); ++#endif // AMD64 ++} ++ ++#endif // OS_CPU_SOLARIS_X86_PREFETCH_SOLARIS_X86_INLINE_HPP +diff -urN /tmp/a/safefetch_solaris_x86_64.S b/src/hotspot/os_cpu/solaris_x86/safefetch_solaris_x86_64.S +--- /tmp/a/safefetch_solaris_x86_64.S 1970-01-01 01:00:00.000000000 +0100 ++++ b/src/hotspot/os_cpu/solaris_x86/safefetch_solaris_x86_64.S 2024-10-15 14:59:36.915486184 +0100 +@@ -0,0 +1,58 @@ ++# ++# Copyright (c) 2022 SAP SE. All rights reserved. ++# Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved. ++# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. ++# ++# This code is free software; you can redistribute it and/or modify it ++# under the terms of the GNU General Public License version 2 only, as ++# published by the Free Software Foundation. ++# ++# This code is distributed in the hope that it will be useful, but WITHOUT ++# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or ++# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License ++# version 2 for more details (a copy is included in the LICENSE file that ++# accompanied this code). ++# ++# You should have received a copy of the GNU General Public License version ++# 2 along with this work; if not, write to the Free Software Foundation, ++# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. ++# ++# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA ++# or visit www.oracle.com if you need additional information or have any ++# questions. ++# ++ .globl SafeFetch32_impl ++ .globl SafeFetchN_impl ++ .globl _SafeFetch32_fault ++ .globl _SafeFetchN_fault ++ .globl _SafeFetch32_continuation ++ .globl _SafeFetchN_continuation ++ ++ .text ++ ++ ++ # Support for int SafeFetch32(int* address, int defaultval); ++ # ++ # %rdi : address ++ # %esi : defaultval ++ .type SafeFetch32_impl,@function ++SafeFetch32_impl: ++_SafeFetch32_fault: ++ movl (%rdi), %eax # load target value, may fault ++ ret ++_SafeFetch32_continuation: ++ movl %esi, %eax # return default ++ ret ++ ++ # Support for intptr_t SafeFetchN(intptr_t* address, intptr_t defaultval); ++ # ++ # %rdi : address ++ # %rsi : defaultval ++ .type SafeFetchN_impl,@function ++SafeFetchN_impl: ++_SafeFetchN_fault: ++ movq (%rdi), %rax # load target value, may fault ++ ret ++_SafeFetchN_continuation: ++ movq %rsi, %rax # return default ++ ret +diff -urN /tmp/a/solaris_x86_64.S b/src/hotspot/os_cpu/solaris_x86/solaris_x86_64.S +--- /tmp/a/solaris_x86_64.S 1970-01-01 01:00:00.000000000 +0100 ++++ b/src/hotspot/os_cpu/solaris_x86/solaris_x86_64.S 2024-10-15 14:59:36.869441513 +0100 +@@ -0,0 +1,386 @@ ++# ++# Copyright (c) 2004, 2013, Oracle and/or its affiliates. All rights reserved. ++# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. ++# ++# This code is free software; you can redistribute it and/or modify it ++# under the terms of the GNU General Public License version 2 only, as ++# published by the Free Software Foundation. ++# ++# This code is distributed in the hope that it will be useful, but WITHOUT ++# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or ++# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License ++# version 2 for more details (a copy is included in the LICENSE file that ++# accompanied this code). ++# ++# You should have received a copy of the GNU General Public License version ++# 2 along with this work; if not, write to the Free Software Foundation, ++# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. ++# ++# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA ++# or visit www.oracle.com if you need additional information or have any ++# questions. ++# ++ ++ .globl fs_load ++ .globl fs_thread ++ ++ ## NOTE WELL! The _Copy functions are called directly ++ ## from server-compiler-generated code via CallLeafNoFP, ++ ## which means that they *must* either not use floating ++ ## point or use it in the same manner as does the server ++ ## compiler. ++ ++ .globl _Copy_arrayof_conjoint_bytes ++ .globl _Copy_conjoint_jshorts_atomic ++ .globl _Copy_arrayof_conjoint_jshorts ++ .globl _Copy_conjoint_jints_atomic ++ .globl _Copy_arrayof_conjoint_jints ++ .globl _Copy_conjoint_jlongs_atomic ++ .globl _Copy_arrayof_conjoint_jlongs ++ ++ .section .text,"ax" ++ ++ # Fast thread accessors, used by threadLS_solaris_amd64.cpp ++ .align 16 ++fs_load: ++ movq %fs:(%rdi),%rax ++ ret ++ ++ .align 16 ++fs_thread: ++ movq %fs:0x0,%rax ++ ret ++ ++ .globl SpinPause ++ .align 16 ++SpinPause: ++ rep ++ nop ++ movq $1, %rax ++ ret ++ ++ ++ # Support for void Copy::arrayof_conjoint_bytes(void* from, ++ # void* to, ++ # size_t count) ++ # rdi - from ++ # rsi - to ++ # rdx - count, treated as ssize_t ++ # ++ .align 16 ++_Copy_arrayof_conjoint_bytes: ++ movq %rdx,%r8 # byte count ++ shrq $3,%rdx # qword count ++ cmpq %rdi,%rsi ++ leaq -1(%rdi,%r8,1),%rax # from + bcount*1 - 1 ++ jbe acb_CopyRight ++ cmpq %rax,%rsi ++ jbe acb_CopyLeft ++acb_CopyRight: ++ leaq -8(%rdi,%rdx,8),%rax # from + qcount*8 - 8 ++ leaq -8(%rsi,%rdx,8),%rcx # to + qcount*8 - 8 ++ negq %rdx ++ jmp 7f ++ .align 16 ++1: movq 8(%rax,%rdx,8),%rsi ++ movq %rsi,8(%rcx,%rdx,8) ++ addq $1,%rdx ++ jnz 1b ++2: testq $4,%r8 # check for trailing dword ++ jz 3f ++ movl 8(%rax),%esi # copy trailing dword ++ movl %esi,8(%rcx) ++ addq $4,%rax ++ addq $4,%rcx # original %rsi is trashed, so we ++ # can't use it as a base register ++3: testq $2,%r8 # check for trailing word ++ jz 4f ++ movw 8(%rax),%si # copy trailing word ++ movw %si,8(%rcx) ++ addq $2,%rcx ++4: testq $1,%r8 # check for trailing byte ++ jz 5f ++ movb -1(%rdi,%r8,1),%al # copy trailing byte ++ movb %al,8(%rcx) ++5: ret ++ .align 16 ++6: movq -24(%rax,%rdx,8),%rsi ++ movq %rsi,-24(%rcx,%rdx,8) ++ movq -16(%rax,%rdx,8),%rsi ++ movq %rsi,-16(%rcx,%rdx,8) ++ movq -8(%rax,%rdx,8),%rsi ++ movq %rsi,-8(%rcx,%rdx,8) ++ movq (%rax,%rdx,8),%rsi ++ movq %rsi,(%rcx,%rdx,8) ++7: addq $4,%rdx ++ jle 6b ++ subq $4,%rdx ++ jl 1b ++ jmp 2b ++acb_CopyLeft: ++ testq $1,%r8 # check for trailing byte ++ jz 1f ++ movb -1(%rdi,%r8,1),%cl # copy trailing byte ++ movb %cl,-1(%rsi,%r8,1) ++ subq $1,%r8 # adjust for possible trailing word ++1: testq $2,%r8 # check for trailing word ++ jz 2f ++ movw -2(%rdi,%r8,1),%cx # copy trailing word ++ movw %cx,-2(%rsi,%r8,1) ++2: testq $4,%r8 # check for trailing dword ++ jz 5f ++ movl (%rdi,%rdx,8),%ecx # copy trailing dword ++ movl %ecx,(%rsi,%rdx,8) ++ jmp 5f ++ .align 16 ++3: movq -8(%rdi,%rdx,8),%rcx ++ movq %rcx,-8(%rsi,%rdx,8) ++ subq $1,%rdx ++ jnz 3b ++ ret ++ .align 16 ++4: movq 24(%rdi,%rdx,8),%rcx ++ movq %rcx,24(%rsi,%rdx,8) ++ movq 16(%rdi,%rdx,8),%rcx ++ movq %rcx,16(%rsi,%rdx,8) ++ movq 8(%rdi,%rdx,8),%rcx ++ movq %rcx,8(%rsi,%rdx,8) ++ movq (%rdi,%rdx,8),%rcx ++ movq %rcx,(%rsi,%rdx,8) ++5: subq $4,%rdx ++ jge 4b ++ addq $4,%rdx ++ jg 3b ++ ret ++ ++ # Support for void Copy::arrayof_conjoint_jshorts(void* from, ++ # void* to, ++ # size_t count) ++ # Equivalent to ++ # conjoint_jshorts_atomic ++ # ++ # If 'from' and/or 'to' are aligned on 4- or 2-byte boundaries, we ++ # let the hardware handle it. The tow or four words within dwords ++ # or qwords that span cache line boundaries will still be loaded ++ # and stored atomically. ++ # ++ # rdi - from ++ # rsi - to ++ # rdx - count, treated as ssize_t ++ # ++ .align 16 ++_Copy_arrayof_conjoint_jshorts: ++_Copy_conjoint_jshorts_atomic: ++ movq %rdx,%r8 # word count ++ shrq $2,%rdx # qword count ++ cmpq %rdi,%rsi ++ leaq -2(%rdi,%r8,2),%rax # from + wcount*2 - 2 ++ jbe acs_CopyRight ++ cmpq %rax,%rsi ++ jbe acs_CopyLeft ++acs_CopyRight: ++ leaq -8(%rdi,%rdx,8),%rax # from + qcount*8 - 8 ++ leaq -8(%rsi,%rdx,8),%rcx # to + qcount*8 - 8 ++ negq %rdx ++ jmp 6f ++1: movq 8(%rax,%rdx,8),%rsi ++ movq %rsi,8(%rcx,%rdx,8) ++ addq $1,%rdx ++ jnz 1b ++2: testq $2,%r8 # check for trailing dword ++ jz 3f ++ movl 8(%rax),%esi # copy trailing dword ++ movl %esi,8(%rcx) ++ addq $4,%rcx # original %rsi is trashed, so we ++ # can't use it as a base register ++3: testq $1,%r8 # check for trailing word ++ jz 4f ++ movw -2(%rdi,%r8,2),%si # copy trailing word ++ movw %si,8(%rcx) ++4: ret ++ .align 16 ++5: movq -24(%rax,%rdx,8),%rsi ++ movq %rsi,-24(%rcx,%rdx,8) ++ movq -16(%rax,%rdx,8),%rsi ++ movq %rsi,-16(%rcx,%rdx,8) ++ movq -8(%rax,%rdx,8),%rsi ++ movq %rsi,-8(%rcx,%rdx,8) ++ movq (%rax,%rdx,8),%rsi ++ movq %rsi,(%rcx,%rdx,8) ++6: addq $4,%rdx ++ jle 5b ++ subq $4,%rdx ++ jl 1b ++ jmp 2b ++acs_CopyLeft: ++ testq $1,%r8 # check for trailing word ++ jz 1f ++ movw -2(%rdi,%r8,2),%cx # copy trailing word ++ movw %cx,-2(%rsi,%r8,2) ++1: testq $2,%r8 # check for trailing dword ++ jz 4f ++ movl (%rdi,%rdx,8),%ecx # copy trailing dword ++ movl %ecx,(%rsi,%rdx,8) ++ jmp 4f ++2: movq -8(%rdi,%rdx,8),%rcx ++ movq %rcx,-8(%rsi,%rdx,8) ++ subq $1,%rdx ++ jnz 2b ++ ret ++ .align 16 ++3: movq 24(%rdi,%rdx,8),%rcx ++ movq %rcx,24(%rsi,%rdx,8) ++ movq 16(%rdi,%rdx,8),%rcx ++ movq %rcx,16(%rsi,%rdx,8) ++ movq 8(%rdi,%rdx,8),%rcx ++ movq %rcx,8(%rsi,%rdx,8) ++ movq (%rdi,%rdx,8),%rcx ++ movq %rcx,(%rsi,%rdx,8) ++4: subq $4,%rdx ++ jge 3b ++ addq $4,%rdx ++ jg 2b ++ ret ++ ++ # Support for void Copy::arrayof_conjoint_jints(jint* from, ++ # jint* to, ++ # size_t count) ++ # Equivalent to ++ # conjoint_jints_atomic ++ # ++ # If 'from' and/or 'to' are aligned on 4-byte boundaries, we let ++ # the hardware handle it. The two dwords within qwords that span ++ # cache line boundaries will still be loaded and stored atomically. ++ # ++ # rdi - from ++ # rsi - to ++ # rdx - count, treated as ssize_t ++ # ++ .align 16 ++_Copy_arrayof_conjoint_jints: ++_Copy_conjoint_jints_atomic: ++ movq %rdx,%r8 # dword count ++ shrq %rdx # qword count ++ cmpq %rdi,%rsi ++ leaq -4(%rdi,%r8,4),%rax # from + dcount*4 - 4 ++ jbe aci_CopyRight ++ cmpq %rax,%rsi ++ jbe aci_CopyLeft ++aci_CopyRight: ++ leaq -8(%rdi,%rdx,8),%rax # from + qcount*8 - 8 ++ leaq -8(%rsi,%rdx,8),%rcx # to + qcount*8 - 8 ++ negq %rdx ++ jmp 5f ++ .align 16 ++1: movq 8(%rax,%rdx,8),%rsi ++ movq %rsi,8(%rcx,%rdx,8) ++ addq $1,%rdx ++ jnz 1b ++2: testq $1,%r8 # check for trailing dword ++ jz 3f ++ movl 8(%rax),%esi # copy trailing dword ++ movl %esi,8(%rcx) ++3: ret ++ .align 16 ++4: movq -24(%rax,%rdx,8),%rsi ++ movq %rsi,-24(%rcx,%rdx,8) ++ movq -16(%rax,%rdx,8),%rsi ++ movq %rsi,-16(%rcx,%rdx,8) ++ movq -8(%rax,%rdx,8),%rsi ++ movq %rsi,-8(%rcx,%rdx,8) ++ movq (%rax,%rdx,8),%rsi ++ movq %rsi,(%rcx,%rdx,8) ++5: addq $4,%rdx ++ jle 4b ++ subq $4,%rdx ++ jl 1b ++ jmp 2b ++aci_CopyLeft: ++ testq $1,%r8 # check for trailing dword ++ jz 3f ++ movl -4(%rdi,%r8,4),%ecx # copy trailing dword ++ movl %ecx,-4(%rsi,%r8,4) ++ jmp 3f ++1: movq -8(%rdi,%rdx,8),%rcx ++ movq %rcx,-8(%rsi,%rdx,8) ++ subq $1,%rdx ++ jnz 1b ++ ret ++ .align 16 ++2: movq 24(%rdi,%rdx,8),%rcx ++ movq %rcx,24(%rsi,%rdx,8) ++ movq 16(%rdi,%rdx,8),%rcx ++ movq %rcx,16(%rsi,%rdx,8) ++ movq 8(%rdi,%rdx,8),%rcx ++ movq %rcx,8(%rsi,%rdx,8) ++ movq (%rdi,%rdx,8),%rcx ++ movq %rcx,(%rsi,%rdx,8) ++3: subq $4,%rdx ++ jge 2b ++ addq $4,%rdx ++ jg 1b ++ ret ++ ++ # Support for void Copy::arrayof_conjoint_jlongs(jlong* from, ++ # jlong* to, ++ # size_t count) ++ # Equivalent to ++ # conjoint_jlongs_atomic ++ # arrayof_conjoint_oops ++ # conjoint_oops_atomic ++ # ++ # rdi - from ++ # rsi - to ++ # rdx - count, treated as ssize_t ++ # ++ .align 16 ++_Copy_arrayof_conjoint_jlongs: ++_Copy_conjoint_jlongs_atomic: ++ cmpq %rdi,%rsi ++ leaq -8(%rdi,%rdx,8),%rax # from + count*8 - 8 ++ jbe acl_CopyRight ++ cmpq %rax,%rsi ++ jbe acl_CopyLeft ++acl_CopyRight: ++ leaq -8(%rsi,%rdx,8),%rcx # to + count*8 - 8 ++ negq %rdx ++ jmp 3f ++1: movq 8(%rax,%rdx,8),%rsi ++ movq %rsi,8(%rcx,%rdx,8) ++ addq $1,%rdx ++ jnz 1b ++ ret ++ .align 16 ++2: movq -24(%rax,%rdx,8),%rsi ++ movq %rsi,-24(%rcx,%rdx,8) ++ movq -16(%rax,%rdx,8),%rsi ++ movq %rsi,-16(%rcx,%rdx,8) ++ movq -8(%rax,%rdx,8),%rsi ++ movq %rsi,-8(%rcx,%rdx,8) ++ movq (%rax,%rdx,8),%rsi ++ movq %rsi,(%rcx,%rdx,8) ++3: addq $4,%rdx ++ jle 2b ++ subq $4,%rdx ++ jl 1b ++ ret ++4: movq -8(%rdi,%rdx,8),%rcx ++ movq %rcx,-8(%rsi,%rdx,8) ++ subq $1,%rdx ++ jnz 4b ++ ret ++ .align 16 ++5: movq 24(%rdi,%rdx,8),%rcx ++ movq %rcx,24(%rsi,%rdx,8) ++ movq 16(%rdi,%rdx,8),%rcx ++ movq %rcx,16(%rsi,%rdx,8) ++ movq 8(%rdi,%rdx,8),%rcx ++ movq %rcx,8(%rsi,%rdx,8) ++ movq (%rdi,%rdx,8),%rcx ++ movq %rcx,(%rsi,%rdx,8) ++acl_CopyLeft: ++ subq $4,%rdx ++ jge 5b ++ addq $4,%rdx ++ jg 4b ++ ret +diff -urN /tmp/a/vmStructs_solaris_x86.hpp b/src/hotspot/os_cpu/solaris_x86/vmStructs_solaris_x86.hpp +--- /tmp/a/vmStructs_solaris_x86.hpp 1970-01-01 01:00:00.000000000 +0100 ++++ b/src/hotspot/os_cpu/solaris_x86/vmStructs_solaris_x86.hpp 2024-10-15 14:59:36.869736563 +0100 +@@ -0,0 +1,40 @@ ++/* ++ * Copyright (c) 2000, 2019, Oracle and/or its affiliates. All rights reserved. ++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. ++ * ++ * This code is free software; you can redistribute it and/or modify it ++ * under the terms of the GNU General Public License version 2 only, as ++ * published by the Free Software Foundation. ++ * ++ * This code is distributed in the hope that it will be useful, but WITHOUT ++ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or ++ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License ++ * version 2 for more details (a copy is included in the LICENSE file that ++ * accompanied this code). ++ * ++ * You should have received a copy of the GNU General Public License version ++ * 2 along with this work; if not, write to the Free Software Foundation, ++ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. ++ * ++ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA ++ * or visit www.oracle.com if you need additional information or have any ++ * questions. ++ * ++ */ ++ ++#ifndef OS_CPU_SOLARIS_X86_VMSTRUCTS_SOLARIS_X86_HPP ++#define OS_CPU_SOLARIS_X86_VMSTRUCTS_SOLARIS_X86_HPP ++ ++// These are the OS and CPU-specific fields, types and integer ++// constants required by the Serviceability Agent. This file is ++// referenced by vmStructs.cpp. ++ ++#define VM_STRUCTS_OS_CPU(nonstatic_field, static_field, unchecked_nonstatic_field, volatile_nonstatic_field, nonproduct_nonstatic_field, c2_nonstatic_field, unchecked_c1_static_field, unchecked_c2_static_field) ++ ++#define VM_TYPES_OS_CPU(declare_type, declare_toplevel_type, declare_oop_type, declare_integer_type, declare_unsigned_integer_type, declare_c1_toplevel_type, declare_c2_type, declare_c2_toplevel_type) ++ ++#define VM_INT_CONSTANTS_OS_CPU(declare_constant, declare_preprocessor_constant, declare_c1_constant, declare_c2_constant, declare_c2_preprocessor_constant) ++ ++#define VM_LONG_CONSTANTS_OS_CPU(declare_constant, declare_preprocessor_constant, declare_c1_constant, declare_c2_constant, declare_c2_preprocessor_constant) ++ ++#endif // OS_CPU_SOLARIS_X86_VMSTRUCTS_SOLARIS_X86_HPP +diff -urN /tmp/a/vm_version_solaris_x86.cpp b/src/hotspot/os_cpu/solaris_x86/vm_version_solaris_x86.cpp +--- /tmp/a/vm_version_solaris_x86.cpp 1970-01-01 01:00:00.000000000 +0100 ++++ b/src/hotspot/os_cpu/solaris_x86/vm_version_solaris_x86.cpp 2024-10-15 14:59:36.869816605 +0100 +@@ -0,0 +1,28 @@ ++/* ++ * Copyright (c) 2006, 2019, Oracle and/or its affiliates. All rights reserved. ++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. ++ * ++ * This code is free software; you can redistribute it and/or modify it ++ * under the terms of the GNU General Public License version 2 only, as ++ * published by the Free Software Foundation. ++ * ++ * This code is distributed in the hope that it will be useful, but WITHOUT ++ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or ++ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License ++ * version 2 for more details (a copy is included in the LICENSE file that ++ * accompanied this code). ++ * ++ * You should have received a copy of the GNU General Public License version ++ * 2 along with this work; if not, write to the Free Software Foundation, ++ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. ++ * ++ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA ++ * or visit www.oracle.com if you need additional information or have any ++ * questions. ++ * ++ */ ++ ++#include "precompiled.hpp" ++#include "runtime/os.hpp" ++#include "runtime/vm_version.hpp" ++ diff --git a/build/openjdk21/patches/restore_os_solaris.patch b/build/openjdk21/patches/restore_os_solaris.patch new file mode 100644 index 0000000000..dae8aa9064 --- /dev/null +++ b/build/openjdk21/patches/restore_os_solaris.patch @@ -0,0 +1,5846 @@ +diff -urN /tmp/a/attachListener_solaris.cpp b/src/hotspot/os/solaris/attachListener_solaris.cpp +--- /tmp/a/attachListener_solaris.cpp 1970-01-01 01:00:00.000000000 +0100 ++++ b/src/hotspot/os/solaris/attachListener_solaris.cpp 2024-10-15 14:59:36.865690786 +0100 +@@ -0,0 +1,749 @@ ++/* ++ * Copyright (c) 2005, 2019, Oracle and/or its affiliates. All rights reserved. ++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. ++ * ++ * This code is free software; you can redistribute it and/or modify it ++ * under the terms of the GNU General Public License version 2 only, as ++ * published by the Free Software Foundation. ++ * ++ * This code is distributed in the hope that it will be useful, but WITHOUT ++ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or ++ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License ++ * version 2 for more details (a copy is included in the LICENSE file that ++ * accompanied this code). ++ * ++ * You should have received a copy of the GNU General Public License version ++ * 2 along with this work; if not, write to the Free Software Foundation, ++ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. ++ * ++ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA ++ * or visit www.oracle.com if you need additional information or have any ++ * questions. ++ * ++ */ ++ ++#include "precompiled.hpp" ++#include "logging/log.hpp" ++#include "runtime/interfaceSupport.inline.hpp" ++#include "runtime/os.inline.hpp" ++#include "services/attachListener.hpp" ++#include "services/dtraceAttacher.hpp" ++#include "utilities/vmError.hpp" ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++// stropts.h uses STR in stream ioctl defines ++#undef STR ++#include ++#undef STR ++#define STR(a) #a ++ ++// The attach mechanism on Solaris is implemented using the Doors IPC ++// mechanism. The first tool to attempt to attach causes the attach ++// listener thread to startup. This thread creates a door that is ++// associated with a function that enqueues an operation to the attach ++// listener. The door is attached to a file in the file system so that ++// client (tools) can locate it. To enqueue an operation to the VM the ++// client calls through the door which invokes the enqueue function in ++// this process. The credentials of the client are checked and if the ++// effective uid matches this process then the operation is enqueued. ++// When an operation completes the attach listener is required to send the ++// operation result and any result data to the client. In this implementation ++// the result is returned via a UNIX domain socket. A pair of connected ++// sockets (socketpair) is created in the enqueue function and the file ++// descriptor for one of the sockets is returned to the client as the ++// return from the door call. The other end is retained in this process. ++// When the operation completes the result is sent to the client and ++// the socket is closed. ++ ++// forward reference ++class SolarisAttachOperation; ++ ++class SolarisAttachListener: AllStatic { ++ private: ++ ++ // the path to which we attach the door file descriptor ++ static char _door_path[PATH_MAX+1]; ++ static volatile bool _has_door_path; ++ ++ // door descriptor returned by door_create ++ static int _door_descriptor; ++ ++ static bool _atexit_registered; ++ ++ // mutex to protect operation list ++ static pthread_mutex_t _mutex; ++ ++ // semaphore to wakeup listener thread ++ static sema_t _wakeup; ++ ++ static pthread_mutex_t* mutex() { return &_mutex; } ++ static sema_t* wakeup() { return &_wakeup; } ++ ++ // enqueued operation list ++ static SolarisAttachOperation* _head; ++ static SolarisAttachOperation* _tail; ++ ++ static SolarisAttachOperation* head() { return _head; } ++ static void set_head(SolarisAttachOperation* head) { _head = head; } ++ ++ static SolarisAttachOperation* tail() { return _tail; } ++ static void set_tail(SolarisAttachOperation* tail) { _tail = tail; } ++ ++ // create the door ++ static int create_door(); ++ ++ public: ++ enum { ++ ATTACH_PROTOCOL_VER = 1 // protocol version ++ }; ++ enum { ++ ATTACH_ERROR_BADREQUEST = 100, // error code returned by ++ ATTACH_ERROR_BADVERSION = 101, // the door call ++ ATTACH_ERROR_RESOURCE = 102, ++ ATTACH_ERROR_INTERNAL = 103, ++ ATTACH_ERROR_DENIED = 104 ++ }; ++ ++ static void set_door_path(char* path) { ++ if (path == NULL) { ++ _door_path[0] = '\0'; ++ _has_door_path = false; ++ } else { ++ strncpy(_door_path, path, PATH_MAX); ++ _door_path[PATH_MAX] = '\0'; // ensure it's nul terminated ++ _has_door_path = true; ++ } ++ } ++ ++ static void set_door_descriptor(int dd) { _door_descriptor = dd; } ++ ++ // initialize the listener ++ static int init(); ++ ++ static bool has_door_path() { return _has_door_path; } ++ static char* door_path() { return _door_path; } ++ static int door_descriptor() { return _door_descriptor; } ++ ++ // enqueue an operation ++ static void enqueue(SolarisAttachOperation* op); ++ ++ // dequeue an operation ++ static SolarisAttachOperation* dequeue(); ++}; ++ ++ ++// SolarisAttachOperation is an AttachOperation that additionally encapsulates ++// a socket connection to the requesting client/tool. SolarisAttachOperation ++// can additionally be held in a linked list. ++ ++class SolarisAttachOperation: public AttachOperation { ++ private: ++ friend class SolarisAttachListener; ++ ++ // connection to client ++ int _socket; ++ ++ // linked list support ++ SolarisAttachOperation* _next; ++ ++ SolarisAttachOperation* next() { return _next; } ++ void set_next(SolarisAttachOperation* next) { _next = next; } ++ ++ public: ++ void complete(jint res, bufferedStream* st); ++ ++ int socket() const { return _socket; } ++ void set_socket(int s) { _socket = s; } ++ ++ SolarisAttachOperation(char* name) : AttachOperation(name) { ++ set_socket(-1); ++ set_next(NULL); ++ } ++}; ++ ++// statics ++char SolarisAttachListener::_door_path[PATH_MAX+1]; ++volatile bool SolarisAttachListener::_has_door_path; ++int SolarisAttachListener::_door_descriptor = -1; ++bool SolarisAttachListener::_atexit_registered = false; ++pthread_mutex_t SolarisAttachListener::_mutex; ++sema_t SolarisAttachListener::_wakeup; ++SolarisAttachOperation* SolarisAttachListener::_head = NULL; ++SolarisAttachOperation* SolarisAttachListener::_tail = NULL; ++ ++// Supporting class to help split a buffer into individual components ++class ArgumentIterator : public StackObj { ++ private: ++ char* _pos; ++ char* _end; ++ public: ++ ArgumentIterator(char* arg_buffer, size_t arg_size) { ++ _pos = arg_buffer; ++ _end = _pos + arg_size - 1; ++ } ++ char* next() { ++ if (*_pos == '\0') { ++ // advance the iterator if possible (null arguments) ++ if (_pos < _end) { ++ _pos += 1; ++ } ++ return NULL; ++ } ++ char* res = _pos; ++ char* next_pos = strchr(_pos, '\0'); ++ if (next_pos < _end) { ++ next_pos++; ++ } ++ _pos = next_pos; ++ return res; ++ } ++}; ++ ++// Calls from the door function to check that the client credentials ++// match this process. Returns 0 if credentials okay, otherwise -1. ++static int check_credentials() { ++ ucred_t *cred_info = NULL; ++ int ret = -1; // deny by default ++ ++ // get client credentials ++ if (door_ucred(&cred_info) == -1) { ++ return -1; // unable to get them, deny ++ } ++ ++ // get euid/egid from ucred_free ++ uid_t ucred_euid = ucred_geteuid(cred_info); ++ gid_t ucred_egid = ucred_getegid(cred_info); ++ ++ // check that the effective uid/gid matches ++ if (os::Posix::matches_effective_uid_and_gid_or_root(ucred_euid, ucred_egid)) { ++ ret = 0; // allow ++ } ++ ++ ucred_free(cred_info); ++ return ret; ++} ++ ++ ++// Parses the argument buffer to create an AttachOperation that we should ++// enqueue to the attach listener. ++// The buffer is expected to be formatted as follows: ++// 00000 ++// where is the version number (must be "1"), is the command ++// name ("load, "datadump", ...) and is an argument. ++// ++static SolarisAttachOperation* create_operation(char* argp, size_t arg_size, int* err) { ++ // assume bad request until parsed ++ *err = SolarisAttachListener::ATTACH_ERROR_BADREQUEST; ++ ++ if (arg_size < 2 || argp[arg_size-1] != '\0') { ++ return NULL; // no ver or not null terminated ++ } ++ ++ // Use supporting class to iterate over the buffer ++ ArgumentIterator args(argp, arg_size); ++ ++ // First check the protocol version ++ char* ver = args.next(); ++ if (ver == NULL) { ++ return NULL; ++ } ++ if (atoi(ver) != SolarisAttachListener::ATTACH_PROTOCOL_VER) { ++ *err = SolarisAttachListener::ATTACH_ERROR_BADVERSION; ++ return NULL; ++ } ++ ++ // Get command name and create the operation ++ char* name = args.next(); ++ if (name == NULL || strlen(name) > AttachOperation::name_length_max) { ++ return NULL; ++ } ++ SolarisAttachOperation* op = new SolarisAttachOperation(name); ++ ++ // Iterate over the arguments ++ for (int i=0; iset_arg(i, NULL); ++ } else { ++ if (strlen(arg) > AttachOperation::arg_length_max) { ++ delete op; ++ return NULL; ++ } ++ op->set_arg(i, arg); ++ } ++ } ++ ++ // return operation ++ *err = 0; ++ return op; ++} ++ ++// This is door function which the client executes via a door_call. ++extern "C" { ++ static void enqueue_proc(void* cookie, char* argp, size_t arg_size, ++ door_desc_t* dt, uint_t n_desc) ++ { ++ int return_fd = -1; ++ SolarisAttachOperation* op = NULL; ++ ++ // wait up to 10 seconds for listener to be up and running ++ jint res = 0; ++ int sleep_count = 0; ++ while (!AttachListener::is_initialized()) { ++ sleep(1); // 1 second ++ sleep_count++; ++ if (sleep_count > 10) { // try for 10 seconds ++ debug_only(warning("door_call when not enabled")); ++ res = (jint)SolarisAttachListener::ATTACH_ERROR_INTERNAL; ++ break; ++ } ++ } ++ ++ // check client credentials ++ if (res == 0) { ++ if (check_credentials() != 0) { ++ res = (jint)SolarisAttachListener::ATTACH_ERROR_DENIED; ++ } ++ } ++ ++ // if we are stopped at ShowMessageBoxOnError then maybe we can ++ // load a diagnostic library ++ if (res == 0 && VMError::is_error_reported()) { ++ if (ShowMessageBoxOnError) { ++ // TBD - support loading of diagnostic library here ++ } ++ ++ // can't enqueue operation after fatal error ++ res = (jint)SolarisAttachListener::ATTACH_ERROR_RESOURCE; ++ } ++ ++ // create the operation ++ if (res == 0) { ++ int err; ++ op = create_operation(argp, arg_size, &err); ++ res = (op == NULL) ? (jint)err : 0; ++ } ++ ++ // create a pair of connected sockets. Store the file descriptor ++ // for one end in the operation and enqueue the operation. The ++ // file descriptor for the other end will be returned to the client. ++ if (res == 0) { ++ int s[2]; ++ if (socketpair(PF_UNIX, SOCK_STREAM, 0, s) < 0) { ++ delete op; ++ res = (jint)SolarisAttachListener::ATTACH_ERROR_RESOURCE; ++ } else { ++ op->set_socket(s[0]); ++ return_fd = s[1]; ++ SolarisAttachListener::enqueue(op); ++ } ++ } ++ ++ // Return 0 (success) + file descriptor, or non-0 (error) ++ if (res == 0) { ++ door_desc_t desc; ++ // DOOR_RELEASE flag makes sure fd is closed after passing it to ++ // the client. See door_return(3DOOR) man page. ++ desc.d_attributes = DOOR_DESCRIPTOR | DOOR_RELEASE; ++ desc.d_data.d_desc.d_descriptor = return_fd; ++ door_return((char*)&res, sizeof(res), &desc, 1); ++ } else { ++ door_return((char*)&res, sizeof(res), NULL, 0); ++ } ++ } ++} ++ ++// atexit hook to detach the door and remove the file ++extern "C" { ++ static void listener_cleanup() { ++ int dd = SolarisAttachListener::door_descriptor(); ++ if (dd >= 0) { ++ SolarisAttachListener::set_door_descriptor(-1); ++ ::close(dd); ++ } ++ if (SolarisAttachListener::has_door_path()) { ++ char* path = SolarisAttachListener::door_path(); ++ ::fdetach(path); ++ ::unlink(path); ++ SolarisAttachListener::set_door_path(NULL); ++ } ++ } ++} ++ ++// Create the door ++int SolarisAttachListener::create_door() { ++ char door_path[PATH_MAX+1]; ++ char initial_path[PATH_MAX+1]; ++ int fd, res; ++ ++ // register exit function ++ if (!_atexit_registered) { ++ _atexit_registered = true; ++ ::atexit(listener_cleanup); ++ } ++ ++ // create the door descriptor ++ int dd = ::door_create(enqueue_proc, NULL, 0); ++ if (dd < 0) { ++ return -1; ++ } ++ ++ // create initial file to attach door descriptor ++ snprintf(door_path, sizeof(door_path), "%s/.java_pid%d", ++ os::get_temp_directory(), os::current_process_id()); ++ snprintf(initial_path, sizeof(initial_path), "%s.tmp", door_path); ++ RESTARTABLE(::creat(initial_path, S_IRUSR | S_IWUSR), fd); ++ if (fd == -1) { ++ log_debug(attach)("attempt to create door file %s failed (%d)", initial_path, errno); ++ ::door_revoke(dd); ++ return -1; ++ } ++ assert(fd >= 0, "bad file descriptor"); ++ ::close(fd); ++ ++ // attach the door descriptor to the file ++ if ((res = ::fattach(dd, initial_path)) == -1) { ++ // if busy then detach and try again ++ if (errno == EBUSY) { ++ ::fdetach(initial_path); ++ res = ::fattach(dd, initial_path); ++ } ++ if (res == -1) { ++ log_debug(attach)("unable to create door - fattach failed (%d)", errno); ++ ::door_revoke(dd); ++ dd = -1; ++ } ++ } ++ ++ // rename file so that clients can attach ++ if (dd >= 0) { ++ if (::rename(initial_path, door_path) == -1) { ++ ::close(dd); ++ ::fdetach(initial_path); ++ log_debug(attach)("unable to create door - rename %s to %s failed (%d)", initial_path, door_path, errno); ++ dd = -1; ++ } ++ } ++ if (dd >= 0) { ++ set_door_descriptor(dd); ++ set_door_path(door_path); ++ log_trace(attach)("door file %s created successfully", door_path); ++ } else { ++ // unable to create door, attach it to file, or rename file into place ++ ::unlink(initial_path); ++ return -1; ++ } ++ ++ return 0; ++} ++ ++// Initialization - create the door, locks, and other initialization ++int SolarisAttachListener::init() { ++ if (create_door()) { ++ return -1; ++ } ++ ++ int status = pthread_mutex_init(&_mutex, NULL); ++ assert_status(status==0, status, "mutex_init"); ++ ++ status = ::sema_init(&_wakeup, 0, NULL, NULL); ++ assert_status(status==0, status, "sema_init"); ++ ++ set_head(NULL); ++ set_tail(NULL); ++ ++ return 0; ++} ++ ++// Dequeue an operation ++SolarisAttachOperation* SolarisAttachListener::dequeue() { ++ for (;;) { ++ int res; ++ ++ // wait for somebody to enqueue something ++ while ((res = ::sema_wait(wakeup())) == EINTR) ++ ; ++ if (res) { ++ warning("sema_wait failed: %s", os::strerror(res)); ++ return NULL; ++ } ++ ++ // lock the list ++ res = pthread_mutex_lock(mutex()); ++ assert(res == 0, "mutex_lock failed"); ++ ++ // remove the head of the list ++ SolarisAttachOperation* op = head(); ++ if (op != NULL) { ++ set_head(op->next()); ++ if (head() == NULL) { ++ set_tail(NULL); ++ } ++ } ++ ++ // unlock ++ pthread_mutex_unlock(mutex()); ++ ++ // if we got an operation when return it. ++ if (op != NULL) { ++ return op; ++ } ++ } ++} ++ ++// Enqueue an operation ++void SolarisAttachListener::enqueue(SolarisAttachOperation* op) { ++ // lock list ++ int res = pthread_mutex_lock(mutex()); ++ assert(res == 0, "mutex_lock failed"); ++ ++ // enqueue at tail ++ op->set_next(NULL); ++ if (head() == NULL) { ++ set_head(op); ++ } else { ++ tail()->set_next(op); ++ } ++ set_tail(op); ++ ++ // wakeup the attach listener ++ RESTARTABLE(::sema_post(wakeup()), res); ++ assert(res == 0, "sema_post failed"); ++ ++ // unlock ++ pthread_mutex_unlock(mutex()); ++} ++ ++ ++// support function - writes the (entire) buffer to a socket ++static int write_fully(int s, char* buf, int len) { ++ do { ++ int n = ::write(s, buf, len); ++ if (n == -1) { ++ if (errno != EINTR) return -1; ++ } else { ++ buf += n; ++ len -= n; ++ } ++ } ++ while (len > 0); ++ return 0; ++} ++ ++// Complete an operation by sending the operation result and any result ++// output to the client. At this time the socket is in blocking mode so ++// potentially we can block if there is a lot of data and the client is ++// non-responsive. For most operations this is a non-issue because the ++// default send buffer is sufficient to buffer everything. In the future ++// if there are operations that involves a very big reply then it the ++// socket could be made non-blocking and a timeout could be used. ++ ++void SolarisAttachOperation::complete(jint res, bufferedStream* st) { ++ if (this->socket() >= 0) { ++ JavaThread* thread = JavaThread::current(); ++ ThreadBlockInVM tbivm(thread); ++ ++ // write operation result ++ char msg[32]; ++ sprintf(msg, "%d\n", res); ++ int rc = write_fully(this->socket(), msg, strlen(msg)); ++ ++ // write any result data ++ if (rc == 0) { ++ write_fully(this->socket(), (char*) st->base(), st->size()); ++ ::shutdown(this->socket(), 2); ++ } ++ ++ // close socket and we're done ++ ::close(this->socket()); ++ } ++ delete this; ++} ++ ++ ++// AttachListener functions ++ ++AttachOperation* AttachListener::dequeue() { ++ JavaThread* thread = JavaThread::current(); ++ ThreadBlockInVM tbivm(thread); ++ ++ AttachOperation* op = SolarisAttachListener::dequeue(); ++ ++ return op; ++} ++ ++ ++// Performs initialization at vm startup ++// For Solaris we remove any stale .java_pid file which could cause ++// an attaching process to think we are ready to receive a door_call ++// before we are properly initialized ++ ++void AttachListener::vm_start() { ++ char fn[PATH_MAX+1]; ++ struct stat64 st; ++ int ret; ++ ++ int n = snprintf(fn, sizeof(fn), "%s/.java_pid%d", ++ os::get_temp_directory(), os::current_process_id()); ++ assert(n < sizeof(fn), "java_pid file name buffer overflow"); ++ ++ RESTARTABLE(::stat64(fn, &st), ret); ++ if (ret == 0) { ++ ret = ::unlink(fn); ++ if (ret == -1) { ++ log_debug(attach)("Failed to remove stale attach pid file at %s", fn); ++ } ++ } ++} ++ ++int AttachListener::pd_init() { ++ JavaThread* thread = JavaThread::current(); ++ ThreadBlockInVM tbivm(thread); ++ ++ int ret_code = SolarisAttachListener::init(); ++ ++ return ret_code; ++} ++ ++// Attach Listener is started lazily except in the case when ++// +ReduseSignalUsage is used ++bool AttachListener::init_at_startup() { ++ if (ReduceSignalUsage) { ++ return true; ++ } else { ++ return false; ++ } ++} ++ ++bool AttachListener::check_socket_file() { ++ int ret; ++ struct stat64 st; ++ ret = stat64(SolarisAttachListener::door_path(), &st); ++ if (ret == -1) { // need to restart attach listener. ++ log_debug(attach)("Door file %s does not exist - Restart Attach Listener", ++ SolarisAttachListener::door_path()); ++ ++ listener_cleanup(); ++ ++ // wait to terminate current attach listener instance... ++ while (AttachListener::transit_state(AL_INITIALIZING, ++ AL_NOT_INITIALIZED) != AL_NOT_INITIALIZED) { ++ os::naked_yield(); ++ } ++ return is_init_trigger(); ++ } ++ return false; ++} ++ ++// If the file .attach_pid exists in the working directory ++// or /tmp then this is the trigger to start the attach mechanism ++bool AttachListener::is_init_trigger() { ++ if (init_at_startup() || is_initialized()) { ++ return false; // initialized at startup or already initialized ++ } ++ char fn[PATH_MAX + 1]; ++ int ret; ++ struct stat64 st; ++ sprintf(fn, ".attach_pid%d", os::current_process_id()); ++ RESTARTABLE(::stat64(fn, &st), ret); ++ if (ret == -1) { ++ log_trace(attach)("Failed to find attach file: %s, trying alternate", fn); ++ snprintf(fn, sizeof(fn), "%s/.attach_pid%d", ++ os::get_temp_directory(), os::current_process_id()); ++ RESTARTABLE(::stat64(fn, &st), ret); ++ if (ret == -1) { ++ log_debug(attach)("Failed to find attach file: %s", fn); ++ } ++ } ++ if (ret == 0) { ++ // simple check to avoid starting the attach mechanism when ++ // a bogus non-root user creates the file ++ if (os::Posix::matches_effective_uid_or_root(st.st_uid)) { ++ init(); ++ log_trace(attach)("Attach triggered by %s", fn); ++ return true; ++ } else { ++ log_debug(attach)("File %s has wrong user id %d (vs %d). Attach is not triggered", fn, st.st_uid, geteuid()); ++ } ++ } ++ return false; ++} ++ ++// if VM aborts then detach/cleanup ++void AttachListener::abort() { ++ listener_cleanup(); ++} ++ ++void AttachListener::pd_data_dump() { ++ os::signal_notify(SIGQUIT); ++} ++ ++static jint enable_dprobes(AttachOperation* op, outputStream* out) { ++ const char* probe = op->arg(0); ++ if (probe == NULL || probe[0] == '\0') { ++ out->print_cr("No probe specified"); ++ return JNI_ERR; ++ } else { ++ char *end; ++ long val = strtol(probe, &end, 10); ++ if (end == probe || val < 0 || val > INT_MAX) { ++ out->print_cr("invalid probe type"); ++ return JNI_ERR; ++ } else { ++ int probe_typess = (int) val; ++ DTrace::enable_dprobes(probe_typess); ++ return JNI_OK; ++ } ++ } ++} ++ ++// platform specific operations table ++static AttachOperationFunctionInfo funcs[] = { ++ { "enabledprobes", enable_dprobes }, ++ { NULL, NULL } ++}; ++ ++AttachOperationFunctionInfo* AttachListener::pd_find_operation(const char* name) { ++ int i; ++ for (i = 0; funcs[i].name != NULL; i++) { ++ if (strcmp(funcs[i].name, name) == 0) { ++ return &funcs[i]; ++ } ++ } ++ return NULL; ++} ++ ++// Solaris specific global flag set. ++jint AttachListener::pd_set_flag(AttachOperation* op, outputStream* out) { ++ const char* name = op->arg(0); ++ assert(name != NULL, "flag name should not be null"); ++ bool flag = true; ++ const char* arg1; ++ if ((arg1 = op->arg(1)) != NULL) { ++ char *end; ++ flag = (strtol(arg1, &end, 10) != 0); ++ if (arg1 == end) { ++ out->print_cr("flag value has to be an integer"); ++ return JNI_ERR; ++ } ++ } ++ ++ if (strcmp(name, "DTraceMonitorProbes") == 0) { ++ DTrace::set_monitor_dprobes(flag); ++ return JNI_OK; ++ } ++ ++ out->print_cr("flag '%s' cannot be changed", name); ++ return JNI_ERR; ++} ++ ++void AttachListener::pd_detachall() { ++ DTrace::detach_all_clients(); ++} +diff -urN /tmp/a/c1_globals_solaris.hpp b/src/hotspot/os/solaris/c1_globals_solaris.hpp +--- /tmp/a/c1_globals_solaris.hpp 1970-01-01 01:00:00.000000000 +0100 ++++ b/src/hotspot/os/solaris/c1_globals_solaris.hpp 2024-10-15 14:59:36.865791389 +0100 +@@ -0,0 +1,36 @@ ++/* ++ * Copyright (c) 2000, 2019, Oracle and/or its affiliates. All rights reserved. ++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. ++ * ++ * This code is free software; you can redistribute it and/or modify it ++ * under the terms of the GNU General Public License version 2 only, as ++ * published by the Free Software Foundation. ++ * ++ * This code is distributed in the hope that it will be useful, but WITHOUT ++ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or ++ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License ++ * version 2 for more details (a copy is included in the LICENSE file that ++ * accompanied this code). ++ * ++ * You should have received a copy of the GNU General Public License version ++ * 2 along with this work; if not, write to the Free Software Foundation, ++ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. ++ * ++ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA ++ * or visit www.oracle.com if you need additional information or have any ++ * questions. ++ * ++ */ ++ ++#ifndef OS_SOLARIS_C1_GLOBALS_SOLARIS_HPP ++#define OS_SOLARIS_C1_GLOBALS_SOLARIS_HPP ++ ++#include "utilities/globalDefinitions.hpp" ++#include "utilities/macros.hpp" ++ ++// ++// Sets the default values for operating system dependent flags used by the ++// client compiler. (see c1_globals.hpp) ++// ++ ++#endif // OS_SOLARIS_C1_GLOBALS_SOLARIS_HPP +diff -urN /tmp/a/c2_globals_solaris.hpp b/src/hotspot/os/solaris/c2_globals_solaris.hpp +--- /tmp/a/c2_globals_solaris.hpp 1970-01-01 01:00:00.000000000 +0100 ++++ b/src/hotspot/os/solaris/c2_globals_solaris.hpp 2024-10-15 14:59:36.865879080 +0100 +@@ -0,0 +1,36 @@ ++/* ++ * Copyright (c) 2000, 2019, Oracle and/or its affiliates. All rights reserved. ++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. ++ * ++ * This code is free software; you can redistribute it and/or modify it ++ * under the terms of the GNU General Public License version 2 only, as ++ * published by the Free Software Foundation. ++ * ++ * This code is distributed in the hope that it will be useful, but WITHOUT ++ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or ++ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License ++ * version 2 for more details (a copy is included in the LICENSE file that ++ * accompanied this code). ++ * ++ * You should have received a copy of the GNU General Public License version ++ * 2 along with this work; if not, write to the Free Software Foundation, ++ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. ++ * ++ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA ++ * or visit www.oracle.com if you need additional information or have any ++ * questions. ++ * ++ */ ++ ++#ifndef OS_SOLARIS_C2_GLOBALS_SOLARIS_HPP ++#define OS_SOLARIS_C2_GLOBALS_SOLARIS_HPP ++ ++#include "utilities/globalDefinitions.hpp" ++#include "utilities/macros.hpp" ++ ++// ++// Sets the default values for operating system dependent flags used by the ++// server compiler. (see c2_globals.hpp) ++// ++ ++#endif // OS_SOLARIS_C2_GLOBALS_SOLARIS_HPP +diff -urN /tmp/a/decoder_solaris.cpp b/src/hotspot/os/solaris/decoder_solaris.cpp +--- /tmp/a/decoder_solaris.cpp 1970-01-01 01:00:00.000000000 +0100 ++++ b/src/hotspot/os/solaris/decoder_solaris.cpp 2024-10-15 14:59:36.892630480 +0100 +@@ -0,0 +1,45 @@ ++/* ++ * Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved. ++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. ++ * ++ * This code is free software; you can redistribute it and/or modify it ++ * under the terms of the GNU General Public License version 2 only, as ++ * published by the Free Software Foundation. ++ * ++ * This code is distributed in the hope that it will be useful, but WITHOUT ++ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or ++ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License ++ * version 2 for more details (a copy is included in the LICENSE file that ++ * accompanied this code). ++ * ++ * You should have received a copy of the GNU General Public License version ++ * 2 along with this work; if not, write to the Free Software Foundation, ++ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. ++ * ++ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA ++ * or visit www.oracle.com if you need additional information or have any ++ * questions. ++ * ++ */ ++ ++#include "jvm.h" ++#include "utilities/decoder_elf.hpp" ++ ++#include ++ ++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; ++} ++ +diff -urN /tmp/a/dtrace/jhelper.d b/src/hotspot/os/solaris/dtrace/jhelper.d +--- /tmp/a/dtrace/jhelper.d 1970-01-01 01:00:00.000000000 +0100 ++++ b/src/hotspot/os/solaris/dtrace/jhelper.d 2024-10-15 14:59:36.866184620 +0100 +@@ -0,0 +1,540 @@ ++/* ++ * Copyright (c) 2003, 2018, Oracle and/or its affiliates. All rights reserved. ++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. ++ * ++ * This code is free software; you can redistribute it and/or modify it ++ * under the terms of the GNU General Public License version 2 only, as ++ * published by the Free Software Foundation. ++ * ++ * This code is distributed in the hope that it will be useful, but WITHOUT ++ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or ++ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License ++ * version 2 for more details (a copy is included in the LICENSE file that ++ * accompanied this code). ++ * ++ * You should have received a copy of the GNU General Public License version ++ * 2 along with this work; if not, write to the Free Software Foundation, ++ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. ++ * ++ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA ++ * or visit www.oracle.com if you need additional information or have any ++ * questions. ++ * ++ */ ++ ++/* This file is auto-generated */ ++#include "JvmOffsetsIndex.h" ++ ++#define DEBUG ++ ++#ifdef DEBUG ++#define MARK_LINE this->line = __LINE__ ++#else ++#define MARK_LINE ++#endif ++ ++#ifdef _LP64 ++#define STACK_BIAS 0x7ff ++#define pointer uint64_t ++#else ++#define STACK_BIAS 0 ++#define pointer uint32_t ++#endif ++ ++extern pointer __JvmOffsets; ++ ++/* GrowableArray* */ ++extern pointer __1cJCodeCacheG_heaps_; ++ ++extern pointer __1cIUniverseO_collectedHeap_; ++ ++extern pointer __1cHnmethodG__vtbl_; ++extern pointer __1cGMethodG__vtbl_; ++extern pointer __1cKBufferBlobG__vtbl_; ++ ++#define copyin_ptr(ADDR) *(pointer*) copyin((pointer) (ADDR), sizeof(pointer)) ++#define copyin_uchar(ADDR) *(uchar_t*) copyin((pointer) (ADDR), sizeof(uchar_t)) ++#define copyin_uint16(ADDR) *(uint16_t*) copyin((pointer) (ADDR), sizeof(uint16_t)) ++#define copyin_uint32(ADDR) *(uint32_t*) copyin((pointer) (ADDR), sizeof(uint32_t)) ++#define copyin_int32(ADDR) *(int32_t*) copyin((pointer) (ADDR), sizeof(int32_t)) ++#define copyin_uint8(ADDR) *(uint8_t*) copyin((pointer) (ADDR), sizeof(uint8_t)) ++ ++#define copyin_offset(JVM_CONST) JVM_CONST = \ ++ copyin_int32(JvmOffsetsPtr + IDX_##JVM_CONST * sizeof(int32_t)) ++ ++int init_done; ++ ++dtrace:helper:ustack: ++{ ++ MARK_LINE; ++ this->done = 0; ++ /* ++ * TBD: ++ * Here we initialize init_done, otherwise jhelper does not work. ++ * Therefore, copyin_offset() statements work multiple times now. ++ * There is a hope we could avoid it in the future, and so, ++ * this initialization can be removed. ++ */ ++ init_done = 0; ++ this->error = (char *) NULL; ++ this->result = (char *) NULL; ++ this->isMethod = 0; ++ this->codecache = 0; ++ this->klass = (pointer) NULL; ++ this->vtbl = (pointer) NULL; ++ this->suffix = '\0'; ++} ++ ++dtrace:helper:ustack: ++{ ++ MARK_LINE; ++ /* Initialization of JvmOffsets constants */ ++ JvmOffsetsPtr = (pointer) &``__JvmOffsets; ++} ++ ++dtrace:helper:ustack: ++/!init_done && !this->done/ ++{ ++ MARK_LINE; ++ ++ copyin_offset(POINTER_SIZE); ++ copyin_offset(COMPILER); ++ copyin_offset(OFFSET_CollectedHeap_reserved); ++ copyin_offset(OFFSET_MemRegion_start); ++ copyin_offset(OFFSET_MemRegion_word_size); ++ copyin_offset(SIZE_HeapWord); ++ ++ copyin_offset(OFFSET_interpreter_frame_method); ++ copyin_offset(OFFSET_Klass_name); ++ copyin_offset(OFFSET_ConstantPool_pool_holder); ++ ++ copyin_offset(OFFSET_HeapBlockHeader_used); ++ copyin_offset(OFFSET_oopDesc_metadata); ++ ++ copyin_offset(OFFSET_Symbol_length); ++ copyin_offset(OFFSET_Symbol_body); ++ ++ copyin_offset(OFFSET_Method_constMethod); ++ copyin_offset(OFFSET_ConstMethod_constants); ++ copyin_offset(OFFSET_ConstMethod_name_index); ++ copyin_offset(OFFSET_ConstMethod_signature_index); ++ ++ copyin_offset(OFFSET_CodeHeap_memory); ++ copyin_offset(OFFSET_CodeHeap_segmap); ++ copyin_offset(OFFSET_CodeHeap_log2_segment_size); ++ ++ copyin_offset(OFFSET_GrowableArray_CodeHeap_data); ++ copyin_offset(OFFSET_GrowableArray_CodeHeap_len); ++ ++ copyin_offset(OFFSET_VirtualSpace_low); ++ copyin_offset(OFFSET_VirtualSpace_high); ++ ++ copyin_offset(OFFSET_CodeBlob_name); ++ ++ copyin_offset(OFFSET_nmethod_method); ++ copyin_offset(SIZE_HeapBlockHeader); ++ copyin_offset(SIZE_oopDesc); ++ copyin_offset(SIZE_ConstantPool); ++ ++ copyin_offset(OFFSET_NarrowPtrStruct_base); ++ copyin_offset(OFFSET_NarrowPtrStruct_shift); ++ ++ /* ++ * The PC to translate is in arg0. ++ */ ++ this->pc = arg0; ++ ++#if defined(__i386) || defined(__amd64) ++ this->methodPtr = copyin_ptr(arg1 + OFFSET_interpreter_frame_method); ++#else ++#error "Don't know architecture" ++#endif ++ ++ /* Read address of GrowableArray */ ++ // this->code_heaps_address = copyin_ptr(&``__1cJCodeCacheG_heaps_); ++ this->code_heaps_address = * ( uint64_t * ) copyin ( ( uint64_t ) ( &``__1cJCodeCacheG_heaps_ ) , sizeof ( uint64_t ) ); ++ ++ /* Read address of _data array field in GrowableArray */ ++ this->code_heaps_array_address = copyin_ptr(this->code_heaps_address + OFFSET_GrowableArray_CodeHeap_data); ++ this->number_of_heaps = copyin_uint32(this->code_heaps_address + OFFSET_GrowableArray_CodeHeap_len); ++ ++ this->Method_vtbl = (pointer) &``__1cGMethodG__vtbl_; ++ ++ /* ++ * Get Java heap bounds ++ */ ++ // this->Universe_collectedHeap = copyin_ptr(&``__1cIUniverseO_collectedHeap_); ++ this->Universe_collectedHeap = * ( uint64_t * ) copyin ( ( uint64_t ) ( &``__1cIUniverseO_collectedHeap_ ) , sizeof ( uint64_t ) ); ++ ++ this->heap_start = copyin_ptr(this->Universe_collectedHeap + ++ OFFSET_CollectedHeap_reserved + ++ OFFSET_MemRegion_start); ++ this->heap_size = SIZE_HeapWord * ++ copyin_ptr(this->Universe_collectedHeap + ++ OFFSET_CollectedHeap_reserved + ++ OFFSET_MemRegion_word_size ++ ); ++ this->heap_end = this->heap_start + this->heap_size; ++} ++ ++/* ++ * IMPORTANT: At the moment the ustack helper supports up to 5 code heaps in ++ * the code cache. If more code heaps are added the following probes have to ++ * be extended. This is done by simply adding a probe to get the heap bounds ++ * and another probe to set the code heap address of the newly created heap. ++ */ ++ ++/* ++ * ----- BEGIN: Get bounds of code heaps ----- ++ */ ++dtrace:helper:ustack: ++/init_done < 1 && this->number_of_heaps >= 1 && !this->done/ ++{ ++ MARK_LINE; ++ /* CodeHeap 1 */ ++ init_done = 1; ++ this->code_heap1_address = copyin_ptr(this->code_heaps_array_address); ++ this->code_heap1_low = copyin_ptr(this->code_heap1_address + ++ OFFSET_CodeHeap_memory + OFFSET_VirtualSpace_low); ++ this->code_heap1_high = copyin_ptr(this->code_heap1_address + ++ OFFSET_CodeHeap_memory + OFFSET_VirtualSpace_high); ++} ++ ++dtrace:helper:ustack: ++/init_done < 2 && this->number_of_heaps >= 2 && !this->done/ ++{ ++ MARK_LINE; ++ /* CodeHeap 2 */ ++ init_done = 2; ++ this->code_heaps_array_address = this->code_heaps_array_address + POINTER_SIZE; ++ this->code_heap2_address = copyin_ptr(this->code_heaps_array_address); ++ this->code_heap2_low = copyin_ptr(this->code_heap2_address + ++ OFFSET_CodeHeap_memory + OFFSET_VirtualSpace_low); ++ this->code_heap2_high = copyin_ptr(this->code_heap2_address + ++ OFFSET_CodeHeap_memory + OFFSET_VirtualSpace_high); ++} ++ ++dtrace:helper:ustack: ++/init_done < 3 && this->number_of_heaps >= 3 && !this->done/ ++{ ++ /* CodeHeap 3 */ ++ init_done = 3; ++ this->code_heaps_array_address = this->code_heaps_array_address + POINTER_SIZE; ++ this->code_heap3_address = copyin_ptr(this->code_heaps_array_address); ++ this->code_heap3_low = copyin_ptr(this->code_heap3_address + ++ OFFSET_CodeHeap_memory + OFFSET_VirtualSpace_low); ++ this->code_heap3_high = copyin_ptr(this->code_heap3_address + ++ OFFSET_CodeHeap_memory + OFFSET_VirtualSpace_high); ++} ++ ++dtrace:helper:ustack: ++/init_done < 4 && this->number_of_heaps >= 4 && !this->done/ ++{ ++ /* CodeHeap 4 */ ++ init_done = 4; ++ this->code_heaps_array_address = this->code_heaps_array_address + POINTER_SIZE; ++ this->code_heap4_address = copyin_ptr(this->code_heaps_array_address); ++ this->code_heap4_low = copyin_ptr(this->code_heap4_address + ++ OFFSET_CodeHeap_memory + OFFSET_VirtualSpace_low); ++ this->code_heap4_high = copyin_ptr(this->code_heap4_address + ++ OFFSET_CodeHeap_memory + OFFSET_VirtualSpace_high); ++} ++ ++dtrace:helper:ustack: ++/init_done < 5 && this->number_of_heaps >= 5 && !this->done/ ++{ ++ /* CodeHeap 5 */ ++ init_done = 5; ++ this->code_heaps_array_address = this->code_heaps_array_address + POINTER_SIZE; ++ this->code_heap5_address = copyin_ptr(this->code_heaps_array_address); ++ this->code_heap5_low = copyin_ptr(this->code_heap5_address + ++ OFFSET_CodeHeap_memory + OFFSET_VirtualSpace_low); ++ this->code_heap5_high = copyin_ptr(this->code_heap5_address + ++ OFFSET_CodeHeap_memory + OFFSET_VirtualSpace_high); ++} ++/* ++ * ----- END: Get bounds of code heaps ----- ++ */ ++ ++/* ++ * ----- BEGIN: Get address of the code heap pc points to ----- ++ */ ++dtrace:helper:ustack: ++/!this->done && this->number_of_heaps >= 1 && this->code_heap1_low <= this->pc && this->pc < this->code_heap1_high/ ++{ ++ MARK_LINE; ++ this->codecache = 1; ++ this->code_heap_address = this->code_heap1_address; ++} ++ ++dtrace:helper:ustack: ++/!this->done && this->number_of_heaps >= 2 && this->code_heap2_low <= this->pc && this->pc < this->code_heap2_high/ ++{ ++ MARK_LINE; ++ this->codecache = 1; ++ this->code_heap_address = this->code_heap2_address; ++} ++ ++dtrace:helper:ustack: ++/!this->done && this->number_of_heaps >= 3 && this->code_heap3_low <= this->pc && this->pc < this->code_heap3_high/ ++{ ++ MARK_LINE; ++ this->codecache = 1; ++ this->code_heap_address = this->code_heap3_address; ++} ++ ++dtrace:helper:ustack: ++/!this->done && this->number_of_heaps >= 4 && this->code_heap4_low <= this->pc && this->pc < this->code_heap4_high/ ++{ ++ MARK_LINE; ++ this->codecache = 1; ++ this->code_heap_address = this->code_heap4_address; ++} ++ ++dtrace:helper:ustack: ++/!this->done && this->number_of_heaps >= 5 && this->code_heap5_low <= this->pc && this->pc < this->code_heap5_high/ ++{ ++ MARK_LINE; ++ this->codecache = 1; ++ this->code_heap_address = this->code_heap5_address; ++} ++/* ++ * ----- END: Get address of the code heap pc points to ----- ++ */ ++ ++dtrace:helper:ustack: ++/!this->done && this->codecache/ ++{ ++ MARK_LINE; ++ /* ++ * Get code heap configuration ++ */ ++ this->code_heap_low = copyin_ptr(this->code_heap_address + ++ OFFSET_CodeHeap_memory + OFFSET_VirtualSpace_low); ++ this->code_heap_segmap_low = copyin_ptr(this->code_heap_address + ++ OFFSET_CodeHeap_segmap + OFFSET_VirtualSpace_low); ++ this->code_heap_log2_segment_size = copyin_uint32( ++ this->code_heap_address + OFFSET_CodeHeap_log2_segment_size); ++ ++ /* ++ * Find start ++ */ ++ this->segment = (this->pc - this->code_heap_low) >> ++ this->code_heap_log2_segment_size; ++ this->block = this->code_heap_segmap_low; ++ this->tag = copyin_uchar(this->block + this->segment); ++} ++ ++dtrace:helper:ustack: ++/!this->done && this->codecache && this->tag > 0/ ++{ ++ MARK_LINE; ++ this->tag = copyin_uchar(this->block + this->segment); ++ this->segment = this->segment - this->tag; ++} ++ ++dtrace:helper:ustack: ++/!this->done && this->codecache && this->tag > 0/ ++{ ++ MARK_LINE; ++ this->tag = copyin_uchar(this->block + this->segment); ++ this->segment = this->segment - this->tag; ++} ++ ++dtrace:helper:ustack: ++/!this->done && this->codecache && this->tag > 0/ ++{ ++ MARK_LINE; ++ this->tag = copyin_uchar(this->block + this->segment); ++ this->segment = this->segment - this->tag; ++} ++ ++dtrace:helper:ustack: ++/!this->done && this->codecache && this->tag > 0/ ++{ ++ MARK_LINE; ++ this->tag = copyin_uchar(this->block + this->segment); ++ this->segment = this->segment - this->tag; ++} ++ ++dtrace:helper:ustack: ++/!this->done && this->codecache && this->tag > 0/ ++{ ++ MARK_LINE; ++ this->tag = copyin_uchar(this->block + this->segment); ++ this->segment = this->segment - this->tag; ++} ++ ++dtrace:helper:ustack: ++/!this->done && this->codecache && this->tag > 0/ ++{ ++ MARK_LINE; ++ this->error = ""; ++ this->done = 1; ++} ++ ++dtrace:helper:ustack: ++/!this->done && this->codecache/ ++{ ++ MARK_LINE; ++ this->block = this->code_heap_low + ++ (this->segment << this->code_heap_log2_segment_size); ++ this->used = copyin_uint32(this->block + OFFSET_HeapBlockHeader_used); ++} ++ ++dtrace:helper:ustack: ++/!this->done && this->codecache && !this->used/ ++{ ++ MARK_LINE; ++ this->error = ""; ++ this->done = 1; ++} ++ ++dtrace:helper:ustack: ++/!this->done && this->codecache/ ++{ ++ MARK_LINE; ++ this->start = this->block + SIZE_HeapBlockHeader; ++ this->vtbl = copyin_ptr(this->start); ++ ++ this->nmethod_vtbl = (pointer) &``__1cHnmethodG__vtbl_; ++ this->BufferBlob_vtbl = (pointer) &``__1cKBufferBlobG__vtbl_; ++} ++ ++dtrace:helper:ustack: ++/!this->done && this->vtbl == this->nmethod_vtbl/ ++{ ++ MARK_LINE; ++ this->methodPtr = copyin_ptr(this->start + OFFSET_nmethod_method); ++ this->suffix = '*'; ++ this->isMethod = 1; ++} ++ ++dtrace:helper:ustack: ++/!this->done && this->vtbl == this->BufferBlob_vtbl/ ++{ ++ MARK_LINE; ++ this->name = copyin_ptr(this->start + OFFSET_CodeBlob_name); ++} ++ ++ ++dtrace:helper:ustack: ++/!this->done && this->vtbl == this->BufferBlob_vtbl && this->methodPtr != 0/ ++{ ++ MARK_LINE; ++ this->klass = copyin_ptr(this->methodPtr); ++ this->isMethod = this->klass == this->Method_vtbl; ++ this->done = !this->isMethod; ++} ++ ++dtrace:helper:ustack: ++/!this->done && !this->isMethod/ ++{ ++ MARK_LINE; ++ this->name = copyin_ptr(this->start + OFFSET_CodeBlob_name); ++ this->result = this->name != 0 ? copyinstr(this->name) : ""; ++ this->done = 1; ++} ++ ++dtrace:helper:ustack: ++/!this->done && this->isMethod/ ++{ ++ MARK_LINE; ++ this->constMethod = copyin_ptr(this->methodPtr + ++ OFFSET_Method_constMethod); ++ ++ this->nameIndex = copyin_uint16(this->constMethod + ++ OFFSET_ConstMethod_name_index); ++ ++ this->signatureIndex = copyin_uint16(this->constMethod + ++ OFFSET_ConstMethod_signature_index); ++ ++ this->constantPool = copyin_ptr(this->constMethod + ++ OFFSET_ConstMethod_constants); ++ ++ this->nameSymbol = copyin_ptr(this->constantPool + ++ this->nameIndex * sizeof (pointer) + SIZE_ConstantPool); ++ /* The symbol is a CPSlot and has lower bit set to indicate metadata */ ++ this->nameSymbol &= (~1); /* remove metadata lsb */ ++ ++ this->nameSymbolLength = copyin_uint16(this->nameSymbol + ++ OFFSET_Symbol_length); ++ ++ this->signatureSymbol = copyin_ptr(this->constantPool + ++ this->signatureIndex * sizeof (pointer) + SIZE_ConstantPool); ++ this->signatureSymbol &= (~1); /* remove metadata lsb */ ++ ++ this->signatureSymbolLength = copyin_uint16(this->signatureSymbol + ++ OFFSET_Symbol_length); ++ ++ this->klassPtr = copyin_ptr(this->constantPool + ++ OFFSET_ConstantPool_pool_holder); ++ ++ this->klassSymbol = copyin_ptr(this->klassPtr + ++ OFFSET_Klass_name); ++ ++ this->klassSymbolLength = copyin_uint16(this->klassSymbol + ++ OFFSET_Symbol_length); ++ ++ /* ++ * Enough for three strings, plus the '.', plus the trailing '\0'. ++ */ ++ this->result = (char *) alloca(this->klassSymbolLength + ++ this->nameSymbolLength + ++ this->signatureSymbolLength + 2 + 1); ++ ++ copyinto(this->klassSymbol + OFFSET_Symbol_body, ++ this->klassSymbolLength, this->result); ++ ++ /* ++ * Add the '.' between the class and the name. ++ */ ++ this->result[this->klassSymbolLength] = '.'; ++ ++ copyinto(this->nameSymbol + OFFSET_Symbol_body, ++ this->nameSymbolLength, ++ this->result + this->klassSymbolLength + 1); ++ ++ copyinto(this->signatureSymbol + OFFSET_Symbol_body, ++ this->signatureSymbolLength, ++ this->result + this->klassSymbolLength + ++ this->nameSymbolLength + 1); ++ ++ /* ++ * Now we need to add a trailing '\0' and possibly a tag character. ++ */ ++ this->result[this->klassSymbolLength + 1 + ++ this->nameSymbolLength + ++ this->signatureSymbolLength] = this->suffix; ++ this->result[this->klassSymbolLength + 2 + ++ this->nameSymbolLength + ++ this->signatureSymbolLength] = '\0'; ++ ++ this->done = 1; ++} ++ ++dtrace:helper:ustack: ++/this->done && this->error == (char *) NULL/ ++{ ++ this->result; ++} ++ ++dtrace:helper:ustack: ++/this->done && this->error != (char *) NULL/ ++{ ++ this->error; ++} ++ ++dtrace:helper:ustack: ++/!this->done && this->codecache/ ++{ ++ this->done = 1; ++ "error"; ++} ++ ++ ++dtrace:helper:ustack: ++/!this->done/ ++{ ++ NULL; ++} +diff -urN /tmp/a/globals_solaris.hpp b/src/hotspot/os/solaris/globals_solaris.hpp +--- /tmp/a/globals_solaris.hpp 1970-01-01 01:00:00.000000000 +0100 ++++ b/src/hotspot/os/solaris/globals_solaris.hpp 2024-10-15 14:59:36.866277900 +0100 +@@ -0,0 +1,49 @@ ++/* ++ * Copyright (c) 2005, 2020, Oracle and/or its affiliates. All rights reserved. ++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. ++ * ++ * This code is free software; you can redistribute it and/or modify it ++ * under the terms of the GNU General Public License version 2 only, as ++ * published by the Free Software Foundation. ++ * ++ * This code is distributed in the hope that it will be useful, but WITHOUT ++ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or ++ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License ++ * version 2 for more details (a copy is included in the LICENSE file that ++ * accompanied this code). ++ * ++ * You should have received a copy of the GNU General Public License version ++ * 2 along with this work; if not, write to the Free Software Foundation, ++ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. ++ * ++ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA ++ * or visit www.oracle.com if you need additional information or have any ++ * questions. ++ * ++ */ ++ ++#ifndef OS_SOLARIS_GLOBALS_SOLARIS_HPP ++#define OS_SOLARIS_GLOBALS_SOLARIS_HPP ++ ++// ++// Defines Solaris specific flags. They are not available on other platforms. ++// ++#define RUNTIME_OS_FLAGS(develop, \ ++ develop_pd, \ ++ product, \ ++ product_pd, \ ++ notproduct, \ ++ range, \ ++ constraint) ++ ++// ++// Defines Solaris-specific default values. The flags are available on all ++// platforms, but they may have different default values on other platforms. ++// ++define_pd_global(size_t, PreTouchParallelChunkSize, 1 * G); ++define_pd_global(bool, UseLargePages, true); ++define_pd_global(bool, UseLargePagesIndividualAllocation, false); ++define_pd_global(bool, UseOSErrorReporting, false); ++define_pd_global(bool, UseThreadPriorities, false); ++ ++#endif // OS_SOLARIS_GLOBALS_SOLARIS_HPP +diff -urN /tmp/a/osThread_solaris.cpp b/src/hotspot/os/solaris/osThread_solaris.cpp +--- /tmp/a/osThread_solaris.cpp 1970-01-01 01:00:00.000000000 +0100 ++++ b/src/hotspot/os/solaris/osThread_solaris.cpp 2024-10-15 14:59:36.866366994 +0100 +@@ -0,0 +1,47 @@ ++/* ++ * Copyright (c) 1998, 2014, Oracle and/or its affiliates. All rights reserved. ++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. ++ * ++ * This code is free software; you can redistribute it and/or modify it ++ * under the terms of the GNU General Public License version 2 only, as ++ * published by the Free Software Foundation. ++ * ++ * This code is distributed in the hope that it will be useful, but WITHOUT ++ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or ++ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License ++ * version 2 for more details (a copy is included in the LICENSE file that ++ * accompanied this code). ++ * ++ * You should have received a copy of the GNU General Public License version ++ * 2 along with this work; if not, write to the Free Software Foundation, ++ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. ++ * ++ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA ++ * or visit www.oracle.com if you need additional information or have any ++ * questions. ++ * ++ */ ++ ++// no precompiled headers ++#include "runtime/handles.inline.hpp" ++#include "runtime/mutexLocker.hpp" ++#include "runtime/os.hpp" ++#include "runtime/osThread.hpp" ++#include "runtime/safepoint.hpp" ++#include "runtime/vmThread.hpp" ++ ++#include ++ ++ // *************************************************************** ++ // Platform dependent initialization and cleanup ++ // *************************************************************** ++ ++void OSThread::pd_initialize() { ++ _thread_id = 0; ++ sigemptyset(&_caller_sigmask); ++ ++ _vm_created_thread = false; ++} ++ ++void OSThread::pd_destroy() { ++} +diff -urN /tmp/a/osThread_solaris.hpp b/src/hotspot/os/solaris/osThread_solaris.hpp +--- /tmp/a/osThread_solaris.hpp 1970-01-01 01:00:00.000000000 +0100 ++++ b/src/hotspot/os/solaris/osThread_solaris.hpp 2024-10-15 14:59:36.866470811 +0100 +@@ -0,0 +1,93 @@ ++/* ++ * Copyright (c) 1997, 2019, Oracle and/or its affiliates. All rights reserved. ++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. ++ * ++ * This code is free software; you can redistribute it and/or modify it ++ * under the terms of the GNU General Public License version 2 only, as ++ * published by the Free Software Foundation. ++ * ++ * This code is distributed in the hope that it will be useful, but WITHOUT ++ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or ++ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License ++ * version 2 for more details (a copy is included in the LICENSE file that ++ * accompanied this code). ++ * ++ * You should have received a copy of the GNU General Public License version ++ * 2 along with this work; if not, write to the Free Software Foundation, ++ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. ++ * ++ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA ++ * or visit www.oracle.com if you need additional information or have any ++ * questions. ++ * ++ */ ++ ++#ifndef OS_SOLARIS_OSTHREAD_SOLARIS_HPP ++#define OS_SOLARIS_OSTHREAD_SOLARIS_HPP ++ ++// This is embedded via include into the class OSThread ++ public: ++ typedef thread_t thread_id_t; ++ ++ private: ++ uint _lwp_id; // lwp ID, only used with bound threads ++ int _native_priority; // Saved native priority when starting ++ // a bound thread ++ sigset_t _caller_sigmask; // Caller's signal mask ++ bool _vm_created_thread; // true if the VM created this thread, ++ // false if primary thread or attached thread ++ public: ++ uint lwp_id() const { return _lwp_id; } ++ int native_priority() const { return _native_priority; } ++ ++ // Set and get state of _vm_created_thread flag ++ void set_vm_created() { _vm_created_thread = true; } ++ bool is_vm_created() { return _vm_created_thread; } ++ ++ // Methods to save/restore caller's signal mask ++ sigset_t caller_sigmask() const { return _caller_sigmask; } ++ void set_caller_sigmask(sigset_t sigmask) { _caller_sigmask = sigmask; } ++ ++#ifndef PRODUCT ++ // Used for debugging, return a unique integer for each thread. ++ int thread_identifier() const { return _thread_id; } ++#endif ++#ifdef ASSERT ++ // On solaris reposition can fail in two ways: ++ // 1: a mismatched pc, because signal is delivered too late, target thread ++ // is resumed. ++ // 2: on a timeout where signal is lost, target thread is resumed. ++ bool valid_reposition_failure() { ++ // only 1 and 2 can happen and we can handle both of them ++ return true; ++ } ++#endif ++ void set_lwp_id(uint id) { _lwp_id = id; } ++ void set_native_priority(int prio) { _native_priority = prio; } ++ ++ public: ++ pthread_t pthread_id() const { ++ // Here: same as OSThread::thread_id() ++ return _thread_id; ++ } ++ SuspendResume sr; ++ ++ private: ++ void* _siginfo; ++ ucontext_t* _ucontext; ++ ++ public: ++ void set_siginfo(void* ptr) { _siginfo = ptr; } ++ ucontext_t* ucontext() const { return _ucontext; } ++ void set_ucontext(ucontext_t* ptr) { _ucontext = ptr; } ++ ++ // *************************************************************** ++ // Platform dependent initialization and cleanup ++ // *************************************************************** ++ ++private: ++ ++ void pd_initialize(); ++ void pd_destroy(); ++ ++#endif // OS_SOLARIS_OSTHREAD_SOLARIS_HPP +diff -urN /tmp/a/os_perf_solaris.cpp b/src/hotspot/os/solaris/os_perf_solaris.cpp +--- /tmp/a/os_perf_solaris.cpp 1970-01-01 01:00:00.000000000 +0100 ++++ b/src/hotspot/os/solaris/os_perf_solaris.cpp 2024-10-15 14:59:36.866740494 +0100 +@@ -0,0 +1,808 @@ ++/* ++ * Copyright (c) 2012, 2019, Oracle and/or its affiliates. All rights reserved. ++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. ++ * ++ * This code is free software; you can redistribute it and/or modify it ++ * under the terms of the GNU General Public License version 2 only, as ++ * published by the Free Software Foundation. ++ * ++ * This code is distributed in the hope that it will be useful, but WITHOUT ++ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or ++ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License ++ * version 2 for more details (a copy is included in the LICENSE file that ++ * accompanied this code). ++ * ++ * You should have received a copy of the GNU General Public License version ++ * 2 along with this work; if not, write to the Free Software Foundation, ++ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. ++ * ++ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA ++ * or visit www.oracle.com if you need additional information or have any ++ * questions. ++ * ++ */ ++ ++#include "precompiled.hpp" ++#include "jvm.h" ++#include "memory/allocation.inline.hpp" ++#include "runtime/os.hpp" ++#include "runtime/os_perf.hpp" ++#include "runtime/vm_version.hpp" ++#include "os_solaris.inline.hpp" ++#include "utilities/globalDefinitions.hpp" ++#include "utilities/macros.hpp" ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++static const double NANOS_PER_SEC = 1000000000.0; ++ ++struct CPUPerfTicks { ++ kstat_t* kstat; ++ uint64_t last_idle; ++ uint64_t last_total; ++ double last_ratio; ++}; ++ ++struct CPUPerfCounters { ++ int nProcs; ++ CPUPerfTicks* jvmTicks; ++ kstat_ctl_t* kstat_ctrl; ++}; ++ ++static int get_info(const char* path, void* info, size_t s, off_t o) { ++ assert(path != NULL, "path is NULL!"); ++ assert(info != NULL, "info is NULL!"); ++ ++ int fd = -1; ++ ++ if ((fd = os::open(path, O_RDONLY, 0)) < 0) { ++ return OS_ERR; ++ } ++ if (pread(fd, info, s, o) != s) { ++ close(fd); ++ return OS_ERR; ++ } ++ close(fd); ++ return OS_OK; ++} ++ ++static int get_psinfo2(void* info, size_t s, off_t o) { ++ return get_info("/proc/self/psinfo", info, s, o); ++} ++ ++static int get_psinfo(psinfo_t* info) { ++ return get_psinfo2(info, sizeof(*info), 0); ++} ++ ++static int read_cpustat(kstat_ctl_t* kstat_ctrl, CPUPerfTicks* load, cpu_stat_t* cpu_stat) { ++ assert(kstat_ctrl != NULL, "kstat_ctrl pointer is NULL!"); ++ assert(load != NULL, "load pointer is NULL!"); ++ assert(cpu_stat != NULL, "cpu_stat pointer is NULL!"); ++ ++ if (load->kstat == NULL) { ++ // no handle. ++ return OS_ERR; ++ } ++ if (kstat_read(kstat_ctrl, load->kstat, cpu_stat) == OS_ERR) { ++ // disable handle for this CPU ++ load->kstat = NULL; ++ return OS_ERR; ++ } ++ return OS_OK; ++} ++ ++static double get_cpu_load(int which_logical_cpu, CPUPerfCounters* counters) { ++ assert(counters != NULL, "counters pointer is NULL!"); ++ ++ cpu_stat_t cpu_stat = {0}; ++ ++ if (which_logical_cpu >= counters->nProcs) { ++ return .0; ++ } ++ ++ CPUPerfTicks load = counters->jvmTicks[which_logical_cpu]; ++ if (read_cpustat(counters->kstat_ctrl, &load, &cpu_stat) != OS_OK) { ++ return .0; ++ } ++ ++ uint_t* usage = cpu_stat.cpu_sysinfo.cpu; ++ if (usage == NULL) { ++ return .0; ++ } ++ ++ uint64_t c_idle = usage[CPU_IDLE]; ++ uint64_t c_total = 0; ++ ++ for (int i = 0; i < CPU_STATES; i++) { ++ c_total += usage[i]; ++ } ++ ++ // Calculate diff against previous snapshot ++ uint64_t d_idle = c_idle - load.last_idle; ++ uint64_t d_total = c_total - load.last_total; ++ ++ /** update if weve moved */ ++ if (d_total > 0) { ++ // Save current values for next time around ++ load.last_idle = c_idle; ++ load.last_total = c_total; ++ load.last_ratio = (double) (d_total - d_idle) / d_total; ++ } ++ ++ return load.last_ratio; ++} ++ ++static int get_boot_time(uint64_t* time) { ++ assert(time != NULL, "time pointer is NULL!"); ++ setutxent(); ++ for(;;) { ++ struct utmpx* u; ++ if ((u = getutxent()) == NULL) { ++ break; ++ } ++ if (u->ut_type == BOOT_TIME) { ++ *time = u->ut_xtime; ++ endutxent(); ++ return OS_OK; ++ } ++ } ++ endutxent(); ++ return OS_ERR; ++} ++ ++static int get_noof_context_switches(CPUPerfCounters* counters, uint64_t* switches) { ++ assert(switches != NULL, "switches pointer is NULL!"); ++ assert(counters != NULL, "counter pointer is NULL!"); ++ *switches = 0; ++ uint64_t s = 0; ++ ++ // Collect data from all CPUs ++ for (int i = 0; i < counters->nProcs; i++) { ++ cpu_stat_t cpu_stat = {0}; ++ CPUPerfTicks load = counters->jvmTicks[i]; ++ ++ if (read_cpustat(counters->kstat_ctrl, &load, &cpu_stat) == OS_OK) { ++ s += cpu_stat.cpu_sysinfo.pswitch; ++ } else { ++ //fail fast... ++ return OS_ERR; ++ } ++ } ++ *switches = s; ++ return OS_OK; ++} ++ ++static int perf_context_switch_rate(CPUPerfCounters* counters, double* rate) { ++ assert(counters != NULL, "counters is NULL!"); ++ assert(rate != NULL, "rate pointer is NULL!"); ++ static pthread_mutex_t contextSwitchLock = PTHREAD_MUTEX_INITIALIZER; ++ static uint64_t lastTime = 0; ++ static uint64_t lastSwitches = 0; ++ static double lastRate = 0.0; ++ ++ uint64_t lt = 0; ++ int res = 0; ++ ++ if (lastTime == 0) { ++ uint64_t tmp; ++ if (get_boot_time(&tmp) < 0) { ++ return OS_ERR; ++ } ++ lt = tmp * 1000; ++ } ++ ++ res = OS_OK; ++ ++ pthread_mutex_lock(&contextSwitchLock); ++ { ++ ++ uint64_t sw = 0; ++ clock_t t, d; ++ ++ if (lastTime == 0) { ++ lastTime = lt; ++ } ++ ++ t = clock(); ++ d = t - lastTime; ++ ++ if (d == 0) { ++ *rate = lastRate; ++ } else if (get_noof_context_switches(counters, &sw)== OS_OK) { ++ *rate = ((double)(sw - lastSwitches) / d) * 1000; ++ lastRate = *rate; ++ lastSwitches = sw; ++ lastTime = t; ++ } else { ++ *rate = 0.0; ++ res = OS_ERR; ++ } ++ if (*rate < 0.0) { ++ *rate = 0.0; ++ lastRate = 0.0; ++ } ++ } ++ pthread_mutex_unlock(&contextSwitchLock); ++ return res; ++ } ++ ++ ++ ++class CPUPerformanceInterface::CPUPerformance : public CHeapObj { ++ friend class CPUPerformanceInterface; ++ private: ++ CPUPerfCounters _counters; ++ int cpu_load(int which_logical_cpu, double* cpu_load); ++ int context_switch_rate(double* rate); ++ int cpu_load_total_process(double* cpu_load); ++ int cpu_loads_process(double* pjvmUserLoad, double* pjvmKernelLoad, double* psystemTotalLoad); ++ ++ CPUPerformance(); ++ ~CPUPerformance(); ++ bool initialize(); ++}; ++ ++CPUPerformanceInterface::CPUPerformance::CPUPerformance() { ++ _counters.nProcs = 0; ++ _counters.jvmTicks = NULL; ++ _counters.kstat_ctrl = NULL; ++} ++ ++bool CPUPerformanceInterface::CPUPerformance::initialize() { ++ // initialize kstat control structure, ++ _counters.kstat_ctrl = kstat_open(); ++ assert(_counters.kstat_ctrl != NULL, "error initializing kstat control structure!"); ++ ++ if (NULL == _counters.kstat_ctrl) { ++ return false; ++ } ++ ++ // Get number of CPU(s) ++ if ((_counters.nProcs = sysconf(_SC_NPROCESSORS_ONLN)) == OS_ERR) { ++ // ignore error? ++ _counters.nProcs = 1; ++ } ++ ++ assert(_counters.nProcs > 0, "no CPUs detected in sysconf call!"); ++ if (_counters.nProcs == 0) { ++ return false; ++ } ++ ++ // Data structure(s) for saving CPU load (one per CPU) ++ size_t array_entry_count = _counters.nProcs; ++ _counters.jvmTicks = NEW_C_HEAP_ARRAY(CPUPerfTicks, array_entry_count, mtInternal); ++ memset(_counters.jvmTicks, 0, array_entry_count * sizeof(*_counters.jvmTicks)); ++ ++ // Get kstat cpu_stat counters for every CPU ++ // loop over kstat to find our cpu_stat(s) ++ int i = 0; ++ for (kstat_t* kstat = _counters.kstat_ctrl->kc_chain; kstat != NULL; kstat = kstat->ks_next) { ++ if (strncmp(kstat->ks_module, "cpu_stat", 8) == 0) { ++ if (kstat_read(_counters.kstat_ctrl, kstat, NULL) == OS_ERR) { ++ continue; ++ } ++ if (i == _counters.nProcs) { ++ // more cpu_stats than reported CPUs ++ break; ++ } ++ _counters.jvmTicks[i++].kstat = kstat; ++ } ++ } ++ return true; ++} ++ ++CPUPerformanceInterface::CPUPerformance::~CPUPerformance() { ++ FREE_C_HEAP_ARRAY(char, _counters.jvmTicks); ++ if (_counters.kstat_ctrl != NULL) { ++ kstat_close(_counters.kstat_ctrl); ++ } ++} ++ ++int CPUPerformanceInterface::CPUPerformance::cpu_load(int which_logical_cpu, double* cpu_load) { ++ assert(cpu_load != NULL, "cpu_load pointer is NULL!"); ++ double t = .0; ++ if (-1 == which_logical_cpu) { ++ for (int i = 0; i < _counters.nProcs; i++) { ++ t += get_cpu_load(i, &_counters); ++ } ++ // Cap total systemload to 1.0 ++ t = MIN2((t / _counters.nProcs), 1.0); ++ } else { ++ t = MIN2(get_cpu_load(which_logical_cpu, &_counters), 1.0); ++ } ++ ++ *cpu_load = t; ++ return OS_OK; ++} ++ ++int CPUPerformanceInterface::CPUPerformance::cpu_load_total_process(double* cpu_load) { ++ assert(cpu_load != NULL, "cpu_load pointer is NULL!"); ++ ++ psinfo_t info; ++ ++ // Get the percentage of "recent cpu usage" from all the lwp:s in the JVM:s ++ // process. This is returned as a value between 0.0 and 1.0 multiplied by 0x8000. ++ if (get_psinfo2(&info.pr_pctcpu, sizeof(info.pr_pctcpu), offsetof(psinfo_t, pr_pctcpu)) != 0) { ++ *cpu_load = 0.0; ++ return OS_ERR; ++ } ++ *cpu_load = (double) info.pr_pctcpu / 0x8000; ++ return OS_OK; ++} ++ ++int CPUPerformanceInterface::CPUPerformance::cpu_loads_process(double* pjvmUserLoad, double* pjvmKernelLoad, double* psystemTotalLoad) { ++ assert(pjvmUserLoad != NULL, "pjvmUserLoad not inited"); ++ assert(pjvmKernelLoad != NULL, "pjvmKernelLoad not inited"); ++ assert(psystemTotalLoad != NULL, "psystemTotalLoad not inited"); ++ ++ static uint64_t lastTime; ++ static uint64_t lastUser, lastKernel; ++ static double lastUserRes, lastKernelRes; ++ ++ pstatus_t pss; ++ psinfo_t info; ++ ++ *pjvmKernelLoad = *pjvmUserLoad = *psystemTotalLoad = 0; ++ if (get_info("/proc/self/status", &pss.pr_utime, sizeof(timestruc_t)*2, offsetof(pstatus_t, pr_utime)) != 0) { ++ return OS_ERR; ++ } ++ ++ if (get_psinfo(&info) != 0) { ++ return OS_ERR; ++ } ++ ++ // get the total time in user, kernel and total time ++ // check ratios for 'lately' and multiply the 'recent load'. ++ uint64_t time = (info.pr_time.tv_sec * NANOS_PER_SEC) + info.pr_time.tv_nsec; ++ uint64_t user = (pss.pr_utime.tv_sec * NANOS_PER_SEC) + pss.pr_utime.tv_nsec; ++ uint64_t kernel = (pss.pr_stime.tv_sec * NANOS_PER_SEC) + pss.pr_stime.tv_nsec; ++ uint64_t diff = time - lastTime; ++ double load = (double) info.pr_pctcpu / 0x8000; ++ ++ if (diff > 0) { ++ lastUserRes = (load * (user - lastUser)) / diff; ++ lastKernelRes = (load * (kernel - lastKernel)) / diff; ++ ++ // BUG9182835 - patch for clamping these values to sane ones. ++ lastUserRes = MIN2(1, lastUserRes); ++ lastUserRes = MAX2(0, lastUserRes); ++ lastKernelRes = MIN2(1, lastKernelRes); ++ lastKernelRes = MAX2(0, lastKernelRes); ++ } ++ ++ double t = .0; ++ cpu_load(-1, &t); ++ // clamp at user+system and 1.0 ++ if (lastUserRes + lastKernelRes > t) { ++ t = MIN2(lastUserRes + lastKernelRes, 1.0); ++ } ++ ++ *pjvmUserLoad = lastUserRes; ++ *pjvmKernelLoad = lastKernelRes; ++ *psystemTotalLoad = t; ++ ++ lastTime = time; ++ lastUser = user; ++ lastKernel = kernel; ++ ++ return OS_OK; ++} ++ ++int CPUPerformanceInterface::CPUPerformance::context_switch_rate(double* rate) { ++ return perf_context_switch_rate(&_counters, rate); ++} ++ ++CPUPerformanceInterface::CPUPerformanceInterface() { ++ _impl = NULL; ++} ++ ++bool CPUPerformanceInterface::initialize() { ++ _impl = new CPUPerformanceInterface::CPUPerformance(); ++ return _impl->initialize(); ++} ++ ++CPUPerformanceInterface::~CPUPerformanceInterface(void) { ++ if (_impl != NULL) { ++ delete _impl; ++ } ++} ++ ++int CPUPerformanceInterface::cpu_load(int which_logical_cpu, double* cpu_load) const { ++ return _impl->cpu_load(which_logical_cpu, cpu_load); ++} ++ ++int CPUPerformanceInterface::cpu_load_total_process(double* cpu_load) const { ++ return _impl->cpu_load_total_process(cpu_load); ++} ++ ++int CPUPerformanceInterface::cpu_loads_process(double* pjvmUserLoad, double* pjvmKernelLoad, double* psystemTotalLoad) const { ++ return _impl->cpu_loads_process(pjvmUserLoad, pjvmKernelLoad, psystemTotalLoad); ++} ++ ++int CPUPerformanceInterface::context_switch_rate(double* rate) const { ++ return _impl->context_switch_rate(rate); ++} ++ ++class SystemProcessInterface::SystemProcesses : public CHeapObj { ++ friend class SystemProcessInterface; ++ private: ++ class ProcessIterator : public CHeapObj { ++ friend class SystemProcessInterface::SystemProcesses; ++ private: ++ DIR* _dir; ++ struct dirent* _entry; ++ bool _valid; ++ ++ ProcessIterator(); ++ ~ProcessIterator(); ++ bool initialize(); ++ ++ bool is_valid() const { return _valid; } ++ bool is_valid_entry(struct dirent* const entry) const; ++ bool is_dir(const char* const name) const; ++ char* allocate_string(const char* const str) const; ++ int current(SystemProcess* const process_info); ++ int next_process(); ++ }; ++ ++ ProcessIterator* _iterator; ++ SystemProcesses(); ++ bool initialize(); ++ ~SystemProcesses(); ++ ++ //information about system processes ++ int system_processes(SystemProcess** system_processes, int* no_of_sys_processes) const; ++}; ++ ++bool SystemProcessInterface::SystemProcesses::ProcessIterator::is_dir(const char* name) const { ++ struct stat64 mystat; ++ int ret_val = 0; ++ ++ ret_val = ::stat64(name, &mystat); ++ ++ if (ret_val < 0) { ++ return false; ++ } ++ ret_val = S_ISDIR(mystat.st_mode); ++ return ret_val > 0; ++} ++ ++// if it has a numeric name, is a directory and has a 'psinfo' file in it ++bool SystemProcessInterface::SystemProcesses::ProcessIterator::is_valid_entry(struct dirent* entry) const { ++ // ignore the "." and ".." directories ++ if ((strcmp(entry->d_name, ".") == 0) || ++ (strcmp(entry->d_name, "..") == 0)) { ++ return false; ++ } ++ ++ char buffer[PATH_MAX] = {0}; ++ uint64_t size = 0; ++ bool result = false; ++ FILE *fp = NULL; ++ ++ if (atoi(entry->d_name) != 0) { ++ jio_snprintf(buffer, PATH_MAX, "/proc/%s", entry->d_name); ++ ++ if (is_dir(buffer)) { ++ memset(buffer, 0, PATH_MAX); ++ jio_snprintf(buffer, PATH_MAX, "/proc/%s/psinfo", entry->d_name); ++ if ((fp = fopen(buffer, "r")) != NULL) { ++ int nread = 0; ++ psinfo_t psinfo_data; ++ if ((nread = fread(&psinfo_data, 1, sizeof(psinfo_t), fp)) != -1) { ++ // only considering system process owned by root ++ if (psinfo_data.pr_uid == 0) { ++ result = true; ++ } ++ } ++ } ++ } ++ } ++ ++ if (fp != NULL) { ++ fclose(fp); ++ } ++ ++ return result; ++} ++ ++char* SystemProcessInterface::SystemProcesses::ProcessIterator::allocate_string(const char* str) const { ++ if (str != NULL) { ++ return os::strdup_check_oom(str, mtInternal); ++ } ++ return NULL; ++} ++ ++int SystemProcessInterface::SystemProcesses::ProcessIterator::current(SystemProcess* process_info) { ++ if (!is_valid()) { ++ return OS_ERR; ++ } ++ ++ char psinfo_path[PATH_MAX] = {0}; ++ jio_snprintf(psinfo_path, PATH_MAX, "/proc/%s/psinfo", _entry->d_name); ++ ++ FILE *fp = NULL; ++ if ((fp = fopen(psinfo_path, "r")) == NULL) { ++ return OS_ERR; ++ } ++ ++ int nread = 0; ++ psinfo_t psinfo_data; ++ if ((nread = fread(&psinfo_data, 1, sizeof(psinfo_t), fp)) == -1) { ++ fclose(fp); ++ return OS_ERR; ++ } ++ ++ char *exe_path = NULL; ++ if ((psinfo_data.pr_fname != NULL) && ++ (psinfo_data.pr_psargs != NULL)) { ++ char *path_substring = strstr(psinfo_data.pr_psargs, psinfo_data.pr_fname); ++ if (path_substring != NULL) { ++ int len = path_substring - psinfo_data.pr_psargs; ++ exe_path = NEW_C_HEAP_ARRAY(char, len+1, mtInternal); ++ jio_snprintf(exe_path, len, "%s", psinfo_data.pr_psargs); ++ exe_path[len] = '\0'; ++ } ++ } ++ ++ process_info->set_pid(atoi(_entry->d_name)); ++ process_info->set_name(allocate_string(psinfo_data.pr_fname)); ++ process_info->set_path(allocate_string(exe_path)); ++ process_info->set_command_line(allocate_string(psinfo_data.pr_psargs)); ++ ++ if (exe_path != NULL) { ++ FREE_C_HEAP_ARRAY(char, exe_path); ++ } ++ ++ if (fp != NULL) { ++ fclose(fp); ++ } ++ ++ return OS_OK; ++} ++ ++int SystemProcessInterface::SystemProcesses::ProcessIterator::next_process() { ++ if (!is_valid()) { ++ return OS_ERR; ++ } ++ ++ do { ++ _entry = os::readdir(_dir); ++ if (_entry == NULL) { ++ // Error or reached end. Could use errno to distinguish those cases. ++ _valid = false; ++ return OS_ERR; ++ } ++ } while(!is_valid_entry(_entry)); ++ ++ _valid = true; ++ return OS_OK; ++} ++ ++SystemProcessInterface::SystemProcesses::ProcessIterator::ProcessIterator() { ++ _dir = NULL; ++ _entry = NULL; ++ _valid = false; ++} ++ ++bool SystemProcessInterface::SystemProcesses::ProcessIterator::initialize() { ++ _dir = os::opendir("/proc"); ++ _entry = NULL; ++ _valid = true; ++ next_process(); ++ ++ return true; ++} ++ ++SystemProcessInterface::SystemProcesses::ProcessIterator::~ProcessIterator() { ++ if (_dir != NULL) { ++ os::closedir(_dir); ++ } ++} ++ ++SystemProcessInterface::SystemProcesses::SystemProcesses() { ++ _iterator = NULL; ++} ++ ++bool SystemProcessInterface::SystemProcesses::initialize() { ++ _iterator = new SystemProcessInterface::SystemProcesses::ProcessIterator(); ++ return _iterator->initialize(); ++} ++ ++SystemProcessInterface::SystemProcesses::~SystemProcesses() { ++ if (_iterator != NULL) { ++ delete _iterator; ++ } ++} ++ ++int SystemProcessInterface::SystemProcesses::system_processes(SystemProcess** system_processes, int* no_of_sys_processes) const { ++ assert(system_processes != NULL, "system_processes pointer is NULL!"); ++ assert(no_of_sys_processes != NULL, "system_processes counter pointer is NULL!"); ++ assert(_iterator != NULL, "iterator is NULL!"); ++ ++ // initialize pointers ++ *no_of_sys_processes = 0; ++ *system_processes = NULL; ++ ++ while (_iterator->is_valid()) { ++ SystemProcess* tmp = new SystemProcess(); ++ _iterator->current(tmp); ++ ++ //if already existing head ++ if (*system_processes != NULL) { ++ //move "first to second" ++ tmp->set_next(*system_processes); ++ } ++ // new head ++ *system_processes = tmp; ++ // increment ++ (*no_of_sys_processes)++; ++ // step forward ++ _iterator->next_process(); ++ } ++ return OS_OK; ++} ++ ++int SystemProcessInterface::system_processes(SystemProcess** system_procs, int* no_of_sys_processes) const { ++ return _impl->system_processes(system_procs, no_of_sys_processes); ++} ++ ++SystemProcessInterface::SystemProcessInterface() { ++ _impl = NULL; ++} ++ ++bool SystemProcessInterface::initialize() { ++ _impl = new SystemProcessInterface::SystemProcesses(); ++ return _impl->initialize(); ++ ++} ++ ++SystemProcessInterface::~SystemProcessInterface() { ++ if (_impl != NULL) { ++ delete _impl; ++ } ++} ++ ++CPUInformationInterface::CPUInformationInterface() { ++ _cpu_info = NULL; ++} ++ ++bool CPUInformationInterface::initialize() { ++ _cpu_info = new CPUInformation(); ++ VM_Version::initialize_cpu_information(); ++ _cpu_info->set_number_of_hardware_threads(VM_Version::number_of_threads()); ++ _cpu_info->set_number_of_cores(VM_Version::number_of_cores()); ++ _cpu_info->set_number_of_sockets(VM_Version::number_of_sockets()); ++ _cpu_info->set_cpu_name(VM_Version::cpu_name()); ++ _cpu_info->set_cpu_description(VM_Version::cpu_description()); ++ return true; ++} ++ ++CPUInformationInterface::~CPUInformationInterface() { ++ if (_cpu_info != NULL) { ++ if (_cpu_info->cpu_name() != NULL) { ++ const char* cpu_name = _cpu_info->cpu_name(); ++ FREE_C_HEAP_ARRAY(char, cpu_name); ++ _cpu_info->set_cpu_name(NULL); ++ } ++ if (_cpu_info->cpu_description() != NULL) { ++ const char* cpu_desc = _cpu_info->cpu_description(); ++ FREE_C_HEAP_ARRAY(char, cpu_desc); ++ _cpu_info->set_cpu_description(NULL); ++ } ++ delete _cpu_info; ++ } ++} ++ ++int CPUInformationInterface::cpu_information(CPUInformation& cpu_info) { ++ if (_cpu_info == NULL) { ++ return OS_ERR; ++ } ++ ++ cpu_info = *_cpu_info; // shallow copy assignment ++ return OS_OK; ++} ++ ++class NetworkPerformanceInterface::NetworkPerformance : public CHeapObj { ++ friend class NetworkPerformanceInterface; ++ private: ++ NetworkPerformance(); ++ NONCOPYABLE(NetworkPerformance); ++ bool initialize(); ++ ~NetworkPerformance(); ++ int network_utilization(NetworkInterface** network_interfaces) const; ++}; ++ ++NetworkPerformanceInterface::NetworkPerformance::NetworkPerformance() { ++ ++} ++ ++bool NetworkPerformanceInterface::NetworkPerformance::initialize() { ++ return true; ++} ++ ++NetworkPerformanceInterface::NetworkPerformance::~NetworkPerformance() { ++ ++} ++ ++int NetworkPerformanceInterface::NetworkPerformance::network_utilization(NetworkInterface** network_interfaces) const ++{ ++ kstat_ctl_t* ctl = kstat_open(); ++ if (ctl == NULL) { ++ return OS_ERR; ++ } ++ ++ NetworkInterface* ret = NULL; ++ for (kstat_t* k = ctl->kc_chain; k != NULL; k = k->ks_next) { ++ if (strcmp(k->ks_class, "net") != 0) { ++ continue; ++ } ++ if (strcmp(k->ks_module, "link") != 0) { ++ continue; ++ } ++ ++ if (kstat_read(ctl, k, NULL) == -1) { ++ return OS_ERR; ++ } ++ ++ uint64_t bytes_in = UINT64_MAX; ++ uint64_t bytes_out = UINT64_MAX; ++ for (unsigned int i = 0; i < k->ks_ndata; ++i) { ++ kstat_named_t* data = &reinterpret_cast(k->ks_data)[i]; ++ if (strcmp(data->name, "rbytes64") == 0) { ++ bytes_in = data->value.ui64; ++ } ++ else if (strcmp(data->name, "obytes64") == 0) { ++ bytes_out = data->value.ui64; ++ } ++ } ++ ++ if ((bytes_in != UINT64_MAX) && (bytes_out != UINT64_MAX)) { ++ NetworkInterface* cur = new NetworkInterface(k->ks_name, bytes_in, bytes_out, ret); ++ ret = cur; ++ } ++ } ++ ++ kstat_close(ctl); ++ *network_interfaces = ret; ++ ++ return OS_OK; ++} ++ ++NetworkPerformanceInterface::NetworkPerformanceInterface() { ++ _impl = NULL; ++} ++ ++NetworkPerformanceInterface::~NetworkPerformanceInterface() { ++ if (_impl != NULL) { ++ delete _impl; ++ } ++} ++ ++bool NetworkPerformanceInterface::initialize() { ++ _impl = new NetworkPerformanceInterface::NetworkPerformance(); ++ return _impl->initialize(); ++} ++ ++int NetworkPerformanceInterface::network_utilization(NetworkInterface** network_interfaces) const { ++ return _impl->network_utilization(network_interfaces); ++} +diff -urN /tmp/a/os_solaris.cpp b/src/hotspot/os/solaris/os_solaris.cpp +--- /tmp/a/os_solaris.cpp 1970-01-01 01:00:00.000000000 +0100 ++++ b/src/hotspot/os/solaris/os_solaris.cpp 2024-10-15 14:59:36.867779471 +0100 +@@ -0,0 +1,3077 @@ ++/* ++ * Copyright (c) 1997, 2020, Oracle and/or its affiliates. All rights reserved. ++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. ++ * ++ * This code is free software; you can redistribute it and/or modify it ++ * under the terms of the GNU General Public License version 2 only, as ++ * published by the Free Software Foundation. ++ * ++ * This code is distributed in the hope that it will be useful, but WITHOUT ++ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or ++ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License ++ * version 2 for more details (a copy is included in the LICENSE file that ++ * accompanied this code). ++ * ++ * You should have received a copy of the GNU General Public License version ++ * 2 along with this work; if not, write to the Free Software Foundation, ++ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. ++ * ++ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA ++ * or visit www.oracle.com if you need additional information or have any ++ * questions. ++ * ++ */ ++ ++// no precompiled headers ++#include "jvm.h" ++#include "classfile/classLoader.hpp" ++#include "classfile/systemDictionary.hpp" ++#include "classfile/vmSymbols.hpp" ++#include "code/icBuffer.hpp" ++#include "code/vtableStubs.hpp" ++#include "compiler/compileBroker.hpp" ++#include "compiler/disassembler.hpp" ++#include "interpreter/interpreter.hpp" ++#include "jvmtifiles/jvmti.h" ++#include "logging/log.hpp" ++#include "logging/logStream.hpp" ++#include "memory/allocation.inline.hpp" ++#include "memory/universe.hpp" ++#include "oops/oop.inline.hpp" ++#include "os_solaris.inline.hpp" ++#include "prims/jniFastGetField.hpp" ++#include "prims/jvm_misc.hpp" ++#include "runtime/arguments.hpp" ++#include "runtime/atomic.hpp" ++#include "runtime/globals.hpp" ++#include "runtime/globals_extension.hpp" ++#include "runtime/interfaceSupport.inline.hpp" ++#include "runtime/java.hpp" ++#include "runtime/javaCalls.hpp" ++#include "runtime/javaThread.hpp" ++#include "runtime/mutexLocker.hpp" ++#include "runtime/objectMonitor.hpp" ++#include "runtime/osInfo.hpp" ++#include "runtime/orderAccess.hpp" ++#include "runtime/osThread.hpp" ++#include "runtime/park.hpp" ++#include "runtime/perfMemory.hpp" ++#include "runtime/sharedRuntime.hpp" ++#include "runtime/statSampler.hpp" ++#include "runtime/stubRoutines.hpp" ++#include "runtime/threadCritical.hpp" ++#include "runtime/threads.hpp" ++#include "runtime/timer.hpp" ++#include "runtime/vm_version.hpp" ++#include "semaphore_posix.hpp" ++#include "services/attachListener.hpp" ++#include "services/memTracker.hpp" ++#include "services/runtimeService.hpp" ++#include "signals_posix.hpp" ++#include "utilities/align.hpp" ++#include "utilities/decoder.hpp" ++#include "utilities/defaultStream.hpp" ++#include "utilities/events.hpp" ++#include "utilities/growableArray.hpp" ++#include "utilities/macros.hpp" ++#include "utilities/vmError.hpp" ++ ++// put OS-includes here ++# include ++# include ++# include ++# include ++# include ++# include ++# include ++# include ++# include ++# include ++# include ++# include ++# include ++# include // for elf Sym structure used by dladdr1 ++# include ++# include ++# include ++# include ++# include ++# include ++# include ++# include ++# include ++# include ++# include ++# include ++# include ++# include ++# include ++# include ++# include ++# include ++# include ++# include ++# include ++# include ++# include ++# include ++ ++# include ++ ++#define MAX_PATH (2 * K) ++ ++// for timer info max values which include all bits ++#define ALL_64_BITS CONST64(0xFFFFFFFFFFFFFFFF) ++ ++// Here are some liblgrp types from sys/lgrp_user.h to be able to ++// compile on older systems without this header file. ++ ++#ifndef MADV_ACCESS_LWP ++ #define MADV_ACCESS_LWP 7 /* next LWP to access heavily */ ++#endif ++#ifndef MADV_ACCESS_MANY ++ #define MADV_ACCESS_MANY 8 /* many processes to access heavily */ ++#endif ++ ++#ifndef LGRP_RSRC_CPU ++ #define LGRP_RSRC_CPU 0 /* CPU resources */ ++#endif ++#ifndef LGRP_RSRC_MEM ++ #define LGRP_RSRC_MEM 1 /* memory resources */ ++#endif ++ ++// guarded in sys/mman.h ++extern "C" { ++extern int getpagesizes(size_t[], int); ++} ++ ++// Values for ThreadPriorityPolicy == 1 ++int prio_policy1[CriticalPriority+1] = { ++ -99999, 0, 16, 32, 48, 64, ++ 80, 96, 112, 124, 127, 127 }; ++ ++// System parameters used internally ++static clock_t clock_tics_per_sec = 100; ++ ++// For diagnostics to print a message once. see run_periodic_checks ++static bool check_addr0_done = false; ++ ++address os::Solaris::handler_start; // start pc of thr_sighndlrinfo ++address os::Solaris::handler_end; // end pc of thr_sighndlrinfo ++ ++address os::Solaris::_main_stack_base = NULL; // 4352906 workaround ++ ++os::Solaris::pthread_setname_np_func_t os::Solaris::_pthread_setname_np = NULL; ++ ++// "default" initializers for missing libc APIs ++extern "C" { ++ int memcntl(void *, size_t, int, void *, int, int); ++ int meminfo(const uint64_t *, int, const uint_t *, int, uint64_t *, uint_t *); ++} ++ ++static inline size_t adjust_stack_size(address base, size_t size) { ++ if ((ssize_t)size < 0) { ++ // 4759953: Compensate for ridiculous stack size. ++ size = max_intx; ++ } ++ if (size > (size_t)base) { ++ // 4812466: Make sure size doesn't allow the stack to wrap the address space. ++ size = (size_t)base; ++ } ++ return size; ++} ++ ++static inline stack_t get_stack_info() { ++ stack_t st; ++ int retval = thr_stksegment(&st); ++ st.ss_size = adjust_stack_size((address)st.ss_sp, st.ss_size); ++ assert(retval == 0, "incorrect return value from thr_stksegment"); ++ assert((address)&st < (address)st.ss_sp, "Invalid stack base returned"); ++ assert((address)&st > (address)st.ss_sp-st.ss_size, "Invalid stack size returned"); ++ return st; ++} ++ ++bool os::is_primordial_thread(void) { ++ int r = thr_main(); ++ guarantee(r == 0 || r == 1, "CR6501650 or CR6493689"); ++ return r == 1; ++} ++ ++address os::current_stack_base() { ++ bool _is_primordial_thread = is_primordial_thread(); ++ ++ // Workaround 4352906, avoid calls to thr_stksegment by ++ // thr_main after the first one (it looks like we trash ++ // some data, causing the value for ss_sp to be incorrect). ++ if (!_is_primordial_thread || os::Solaris::_main_stack_base == NULL) { ++ stack_t st = get_stack_info(); ++ if (_is_primordial_thread) { ++ // cache initial value of stack base ++ os::Solaris::_main_stack_base = (address)st.ss_sp; ++ } ++ return (address)st.ss_sp; ++ } else { ++ guarantee(os::Solaris::_main_stack_base != NULL, "Attempt to use null cached stack base"); ++ return os::Solaris::_main_stack_base; ++ } ++} ++ ++size_t os::current_stack_size() { ++ size_t size; ++ ++ if (!is_primordial_thread()) { ++ size = get_stack_info().ss_size; ++ } else { ++ struct rlimit limits; ++ getrlimit(RLIMIT_STACK, &limits); ++ size = adjust_stack_size(os::Solaris::_main_stack_base, (size_t)limits.rlim_cur); ++ } ++ // base may not be page aligned ++ address base = current_stack_base(); ++ address bottom = align_up(base - size, os::vm_page_size());; ++ return (size_t)(base - bottom); ++} ++ ++jint os::Solaris::_os_thread_limit = 0; ++volatile jint os::Solaris::_os_thread_count = 0; ++ ++julong os::available_memory() { ++ return Solaris::available_memory(); ++} ++ ++julong os::free_memory() { ++ return Solaris::available_memory(); ++} ++ ++julong os::Solaris::available_memory() { ++ return (julong)sysconf(_SC_AVPHYS_PAGES) * os::vm_page_size(); ++} ++ ++julong os::Solaris::_physical_memory = 0; ++ ++julong os::physical_memory() { ++ return Solaris::physical_memory(); ++} ++ ++static hrtime_t first_hrtime = 0; ++static const hrtime_t hrtime_hz = 1000*1000*1000; ++static volatile hrtime_t max_hrtime = 0; ++ ++ ++void os::Solaris::initialize_system_info() { ++ set_processor_count(sysconf(_SC_NPROCESSORS_CONF)); ++ _physical_memory = (julong)sysconf(_SC_PHYS_PAGES) * ++ (julong)sysconf(_SC_PAGESIZE); ++} ++ ++uint os::processor_id() { ++ const processorid_t id = ::getcpuid(); ++ assert(id >= 0 && id < _processor_count, "Invalid processor id"); ++ return (uint)id; ++} ++ ++int os::active_processor_count() { ++ // User has overridden the number of active processors ++ if (ActiveProcessorCount > 0) { ++ log_trace(os)("active_processor_count: " ++ "active processor count set by user : %d", ++ ActiveProcessorCount); ++ return ActiveProcessorCount; ++ } ++ ++ int online_cpus = sysconf(_SC_NPROCESSORS_ONLN); ++ pid_t pid = getpid(); ++ psetid_t pset = PS_NONE; ++ // Are we running in a processor set or is there any processor set around? ++ if (pset_bind(PS_QUERY, P_PID, pid, &pset) == 0) { ++ uint_t pset_cpus; ++ // Query the number of cpus available to us. ++ if (pset_info(pset, NULL, &pset_cpus, NULL) == 0) { ++ assert(pset_cpus > 0 && pset_cpus <= online_cpus, "sanity check"); ++ return pset_cpus; ++ } ++ } ++ // Otherwise return number of online cpus ++ return online_cpus; ++} ++ ++void os::set_native_thread_name(const char *name) { ++ if (Solaris::_pthread_setname_np != NULL) { ++ // Only the first 31 bytes of 'name' are processed by pthread_setname_np ++ // but we explicitly copy into a size-limited buffer to avoid any ++ // possible overflow. ++ char buf[32]; ++ snprintf(buf, sizeof(buf), "%s", name); ++ buf[sizeof(buf) - 1] = '\0'; ++ Solaris::_pthread_setname_np(pthread_self(), buf); ++ } ++} ++ ++void os::init_system_properties_values() { ++ // The next steps are taken in the product version: ++ // ++ // Obtain the JAVA_HOME value from the location of libjvm.so. ++ // This library should be located at: ++ // /jre/lib//{client|server}/libjvm.so. ++ // ++ // If "/jre/lib/" appears at the right place in the path, then we ++ // assume libjvm.so is installed in a JDK and we use this path. ++ // ++ // Otherwise exit with message: "Could not create the Java virtual machine." ++ // ++ // The following extra steps are taken in the debugging version: ++ // ++ // If "/jre/lib/" does NOT appear at the right place in the path ++ // instead of exit check for $JAVA_HOME environment variable. ++ // ++ // If it is defined and we are able to locate $JAVA_HOME/jre/lib/, ++ // then we append a fake suffix "hotspot/libjvm.so" to this path so ++ // it looks like libjvm.so is installed there ++ // /jre/lib//hotspot/libjvm.so. ++ // ++ // Otherwise exit. ++ // ++ // Important note: if the location of libjvm.so changes this ++ // code needs to be changed accordingly. ++ ++// Base path of extensions installed on the system. ++#define SYS_EXT_DIR "/usr/jdk/packages" ++#define EXTENSIONS_DIR "/lib/ext" ++ ++ // Buffer that fits several sprintfs. ++ // Note that the space for the colon and the trailing null are provided ++ // by the nulls included by the sizeof operator. ++ const size_t bufsize = ++ MAX3((size_t)MAXPATHLEN, // For dll_dir & friends. ++ sizeof(SYS_EXT_DIR) + sizeof("/lib/"), // invariant ld_library_path ++ (size_t)MAXPATHLEN + sizeof(EXTENSIONS_DIR) + sizeof(SYS_EXT_DIR) + sizeof(EXTENSIONS_DIR)); // extensions dir ++ char *buf = NEW_C_HEAP_ARRAY(char, bufsize, mtInternal); ++ ++ // sysclasspath, java_home, dll_dir ++ { ++ char *pslash; ++ os::jvm_path(buf, bufsize); ++ ++ // Found the full path to libjvm.so. ++ // Now cut the path to /jre if we can. ++ *(strrchr(buf, '/')) = '\0'; // Get rid of /libjvm.so. ++ pslash = strrchr(buf, '/'); ++ if (pslash != NULL) { ++ *pslash = '\0'; // Get rid of /{client|server|hotspot}. ++ } ++ Arguments::set_dll_dir(buf); ++ ++ if (pslash != NULL) { ++ pslash = strrchr(buf, '/'); ++ if (pslash != NULL) { ++ *pslash = '\0'; // Get rid of /lib. ++ } ++ } ++ Arguments::set_java_home(buf); ++ if (!set_boot_path('/', ':')) { ++ vm_exit_during_initialization("Failed setting boot class path.", NULL); ++ } ++ } ++ ++ // Where to look for native libraries. ++ { ++ // Use dlinfo() to determine the correct java.library.path. ++ // ++ // If we're launched by the Java launcher, and the user ++ // does not set java.library.path explicitly on the commandline, ++ // the Java launcher sets LD_LIBRARY_PATH for us and unsets ++ // LD_LIBRARY_PATH_32 and LD_LIBRARY_PATH_64. In this case ++ // dlinfo returns LD_LIBRARY_PATH + crle settings (including ++ // /usr/lib), which is exactly what we want. ++ // ++ // If the user does set java.library.path, it completely ++ // overwrites this setting, and always has. ++ // ++ // If we're not launched by the Java launcher, we may ++ // get here with any/all of the LD_LIBRARY_PATH[_32|64] ++ // settings. Again, dlinfo does exactly what we want. ++ ++ Dl_serinfo info_sz, *info = &info_sz; ++ Dl_serpath *path; ++ char *library_path; ++ char *common_path = buf; ++ ++ // Determine search path count and required buffer size. ++ if (dlinfo(RTLD_SELF, RTLD_DI_SERINFOSIZE, (void *)info) == -1) { ++ FREE_C_HEAP_ARRAY(char, buf); ++ vm_exit_during_initialization("dlinfo SERINFOSIZE request", dlerror()); ++ } ++ ++ // Allocate new buffer and initialize. ++ info = (Dl_serinfo*)NEW_C_HEAP_ARRAY(char, info_sz.dls_size, mtInternal); ++ info->dls_size = info_sz.dls_size; ++ info->dls_cnt = info_sz.dls_cnt; ++ ++ // Obtain search path information. ++ if (dlinfo(RTLD_SELF, RTLD_DI_SERINFO, (void *)info) == -1) { ++ FREE_C_HEAP_ARRAY(char, buf); ++ FREE_C_HEAP_ARRAY(char, info); ++ vm_exit_during_initialization("dlinfo SERINFO request", dlerror()); ++ } ++ ++ path = &info->dls_serpath[0]; ++ ++ // Note: Due to a legacy implementation, most of the library path ++ // is set in the launcher. This was to accommodate linking restrictions ++ // on legacy Solaris implementations (which are no longer supported). ++ // Eventually, all the library path setting will be done here. ++ // ++ // However, to prevent the proliferation of improperly built native ++ // libraries, the new path component /usr/jdk/packages is added here. ++ ++ // Construct the invariant part of ld_library_path. ++ sprintf(common_path, SYS_EXT_DIR "/lib"); ++ ++ // Struct size is more than sufficient for the path components obtained ++ // through the dlinfo() call, so only add additional space for the path ++ // components explicitly added here. ++ size_t library_path_size = info->dls_size + strlen(common_path); ++ library_path = NEW_C_HEAP_ARRAY(char, library_path_size, mtInternal); ++ library_path[0] = '\0'; ++ ++ // Construct the desired Java library path from the linker's library ++ // search path. ++ // ++ // For compatibility, it is optimal that we insert the additional path ++ // components specific to the Java VM after those components specified ++ // in LD_LIBRARY_PATH (if any) but before those added by the ld.so ++ // infrastructure. ++ if (info->dls_cnt == 0) { // Not sure this can happen, but allow for it. ++ strcpy(library_path, common_path); ++ } else { ++ int inserted = 0; ++ uint_t i; ++ for (i = 0; i < info->dls_cnt; i++, path++) { ++ uint_t flags = path->dls_flags & LA_SER_MASK; ++ if (((flags & LA_SER_LIBPATH) == 0) && !inserted) { ++ strcat(library_path, common_path); ++ strcat(library_path, os::path_separator()); ++ inserted = 1; ++ } ++ strcat(library_path, path->dls_name); ++ strcat(library_path, os::path_separator()); ++ } ++ // Eliminate trailing path separator. ++ library_path[strlen(library_path)-1] = '\0'; ++ } ++ ++ // happens before argument parsing - can't use a trace flag ++ // tty->print_raw("init_system_properties_values: native lib path: "); ++ // tty->print_raw_cr(library_path); ++ ++ // Callee copies into its own buffer. ++ Arguments::set_library_path(library_path); ++ ++ FREE_C_HEAP_ARRAY(char, library_path); ++ FREE_C_HEAP_ARRAY(char, info); ++ } ++ ++ // Extensions directories. ++ sprintf(buf, "%s" EXTENSIONS_DIR ":" SYS_EXT_DIR EXTENSIONS_DIR, Arguments::get_java_home()); ++ Arguments::set_ext_dirs(buf); ++ ++ FREE_C_HEAP_ARRAY(char, buf); ++ ++#undef SYS_EXT_DIR ++#undef EXTENSIONS_DIR ++} ++ ++static thread_t main_thread; ++ ++// Thread start routine for all newly created threads ++extern "C" void* thread_native_entry(void* thread_addr) { ++ ++ Thread* thread = (Thread*)thread_addr; ++ ++ thread->record_stack_base_and_size(); ++ ++ // Try to randomize the cache line index of hot stack frames. ++ // This helps when threads of the same stack traces evict each other's ++ // cache lines. The threads can be either from the same JVM instance, or ++ // from different JVM instances. The benefit is especially true for ++ // processors with hyperthreading technology. ++ static int counter = 0; ++ int pid = os::current_process_id(); ++ alloca(((pid ^ counter++) & 7) * 128); ++ ++ int prio; ++ ++ thread->initialize_thread_current(); ++ ++ OSThread* osthr = thread->osthread(); ++ ++ osthr->set_lwp_id(_lwp_self()); // Store lwp in case we are bound ++ ++ log_info(os, thread)("Thread is alive (tid: " UINTX_FORMAT ").", ++ os::current_thread_id()); ++ ++ if (UseNUMA) { ++ int lgrp_id = os::numa_get_group_id(); ++ if (lgrp_id != -1) { ++ thread->set_lgrp_id(lgrp_id); ++ } ++ } ++ ++ // Our priority was set when we were created, and stored in the ++ // osthread, but couldn't be passed through to our LWP until now. ++ // So read back the priority and set it again. ++ ++ if (osthr->thread_id() != -1) { ++ if (UseThreadPriorities) { ++ int prio = osthr->native_priority(); ++ os::set_native_priority(thread, prio); ++ } ++ } ++ ++ assert(osthr->get_state() == RUNNABLE, "invalid os thread state"); ++ ++ // initialize signal mask for this thread ++ PosixSignals::hotspot_sigmask(thread); ++ ++ os::Solaris::init_thread_fpu_state(); ++ ++ thread->call_run(); ++ ++ // Note: at this point the thread object may already have deleted itself. ++ // Do not dereference it from here on out. ++ ++ // One less thread is executing ++ // When the VMThread gets here, the main thread may have already exited ++ // which frees the CodeHeap containing the Atomic::dec code ++ if (thread != VMThread::vm_thread() && VMThread::vm_thread() != NULL) { ++ Atomic::dec(&os::Solaris::_os_thread_count); ++ } ++ ++ log_info(os, thread)("Thread finished (tid: " UINTX_FORMAT ").", os::current_thread_id()); ++ ++ thr_exit(NULL); ++ ShouldNotReachHere(); ++ ++ return NULL; ++} ++ ++static OSThread* create_os_thread(Thread* thread, thread_t thread_id) { ++ // Allocate the OSThread object ++ OSThread* osthread = new OSThread(); ++ if (osthread == NULL) return NULL; ++ ++ // Store info on the Solaris thread into the OSThread ++ osthread->set_thread_id(thread_id); ++ osthread->set_lwp_id(_lwp_self()); ++ ++ if (UseNUMA) { ++ int lgrp_id = os::numa_get_group_id(); ++ if (lgrp_id != -1) { ++ thread->set_lgrp_id(lgrp_id); ++ } ++ } ++ ++ // Initial thread state is INITIALIZED, not SUSPENDED ++ osthread->set_state(INITIALIZED); ++ ++ return osthread; ++} ++ ++bool os::create_attached_thread(JavaThread* thread) { ++#ifdef ASSERT ++ thread->verify_not_published(); ++#endif ++ OSThread* osthread = create_os_thread(thread, thr_self()); ++ if (osthread == NULL) { ++ return false; ++ } ++ ++ // Initial thread state is RUNNABLE ++ osthread->set_state(RUNNABLE); ++ thread->set_osthread(osthread); ++ ++ if (os::is_primordial_thread()) { ++ os::Solaris::correct_stack_boundaries_for_primordial_thread(thread); ++ } ++ ++ // initialize signal mask for this thread ++ // and save the caller's signal mask ++ PosixSignals::hotspot_sigmask(thread); ++ ++ log_info(os, thread)("Thread attached (tid: " UINTX_FORMAT ").", ++ os::current_thread_id()); ++ ++ return true; ++} ++ ++bool os::create_main_thread(JavaThread* thread) { ++#ifdef ASSERT ++ thread->verify_not_published(); ++#endif ++ if (_starting_thread == NULL) { ++ _starting_thread = create_os_thread(thread, main_thread); ++ if (_starting_thread == NULL) { ++ return false; ++ } ++ } ++ ++ // The primodial thread is runnable from the start ++ _starting_thread->set_state(RUNNABLE); ++ ++ thread->set_osthread(_starting_thread); ++ ++ // initialize signal mask for this thread ++ // and save the caller's signal mask ++ PosixSignals::hotspot_sigmask(thread); ++ ++ return true; ++} ++ ++// Helper function to trace thread attributes, similar to os::Posix::describe_pthread_attr() ++static char* describe_thr_create_attributes(char* buf, size_t buflen, ++ size_t stacksize, long flags) { ++ stringStream ss(buf, buflen); ++ ss.print("stacksize: " SIZE_FORMAT "k, ", stacksize / 1024); ++ ss.print("flags: "); ++ #define PRINT_FLAG(f) if (flags & f) ss.print( #f " "); ++ #define ALL(X) \ ++ X(THR_SUSPENDED) \ ++ X(THR_DETACHED) \ ++ X(THR_BOUND) \ ++ X(THR_NEW_LWP) \ ++ X(THR_DAEMON) ++ ALL(PRINT_FLAG) ++ #undef ALL ++ #undef PRINT_FLAG ++ return buf; ++} ++ ++// return default stack size for thr_type ++size_t os::Posix::default_stack_size(os::ThreadType thr_type) { ++ // default stack size when not specified by caller is 1M (2M for LP64) ++ size_t s = (BytesPerWord >> 2) * K * K; ++ return s; ++} ++ ++bool os::create_thread(Thread* thread, ThreadType thr_type, ++ size_t req_stack_size) { ++ // Allocate the OSThread object ++ OSThread* osthread = new OSThread(); ++ if (osthread == NULL) { ++ return false; ++ } ++ ++ // calculate stack size if it's not specified by caller ++ size_t stack_size = os::Posix::get_initial_stack_size(thr_type, req_stack_size); ++ ++ // Initial state is ALLOCATED but not INITIALIZED ++ osthread->set_state(ALLOCATED); ++ ++ if (os::Solaris::_os_thread_count > os::Solaris::_os_thread_limit) { ++ // We got lots of threads. Check if we still have some address space left. ++ // Need to be at least 5Mb of unreserved address space. We do check by ++ // trying to reserve some. ++ const size_t VirtualMemoryBangSize = 20*K*K; ++ char* mem = os::reserve_memory(VirtualMemoryBangSize); ++ if (mem == NULL) { ++ delete osthread; ++ return false; ++ } else { ++ // Release the memory again ++ os::release_memory(mem, VirtualMemoryBangSize); ++ } ++ } ++ ++ // Setup osthread because the child thread may need it. ++ thread->set_osthread(osthread); ++ ++ // Create the Solaris thread ++ thread_t tid = 0; ++ long flags = THR_DETACHED | THR_SUSPENDED; ++ int status; ++ ++ // Mark that we don't have an lwp or thread id yet. ++ // In case we attempt to set the priority before the thread starts. ++ osthread->set_lwp_id(-1); ++ osthread->set_thread_id(-1); ++ ++ status = thr_create(NULL, stack_size, thread_native_entry, thread, flags, &tid); ++ ++ char buf[64]; ++ if (status == 0) { ++ log_info(os, thread)("Thread \"%s\" started (tid: " UINTX_FORMAT ", attributes: %s). ", ++ thread->name(), (uintx) tid, describe_thr_create_attributes(buf, sizeof(buf), stack_size, flags)); ++ } else { ++ log_warning(os, thread)("Failed to start thread \"%s\" - thr_create failed (%s) for attributes: %s.", ++ thread->name(), os::errno_name(status), describe_thr_create_attributes(buf, sizeof(buf), stack_size, flags)); ++ // Log some OS information which might explain why creating the thread failed. ++ log_info(os, thread)("Number of threads approx. running in the VM: %d", Threads::number_of_threads()); ++ LogStream st(Log(os, thread)::info()); ++ os::Posix::print_rlimit_info(&st); ++ os::print_memory_info(&st); ++ } ++ ++ if (status != 0) { ++ thread->set_osthread(NULL); ++ // Need to clean up stuff we've allocated so far ++ delete osthread; ++ return false; ++ } ++ ++ Atomic::inc(&os::Solaris::_os_thread_count); ++ ++ // Store info on the Solaris thread into the OSThread ++ osthread->set_thread_id(tid); ++ ++ // Remember that we created this thread so we can set priority on it ++ osthread->set_vm_created(); ++ ++ // Most thread types will set an explicit priority before starting the thread, ++ // but for those that don't we need a valid value to read back in thread_native_entry. ++ osthread->set_native_priority(NormPriority); ++ ++ // Initial thread state is INITIALIZED, not SUSPENDED ++ osthread->set_state(INITIALIZED); ++ ++ // The thread is returned suspended (in state INITIALIZED), and is started higher up in the call chain ++ return true; ++} ++ ++// CR 7190089: on Solaris, primordial thread's stack needs adjusting. ++// Without the adjustment, stack size is incorrect if stack is set to unlimited (ulimit -s unlimited). ++void os::Solaris::correct_stack_boundaries_for_primordial_thread(Thread* thr) { ++ assert(is_primordial_thread(), "Call only for primordial thread"); ++ ++ JavaThread* jt = (JavaThread *)thr; ++ assert(jt != NULL, "Sanity check"); ++ size_t stack_size; ++ address base = jt->stack_base(); ++ if (Arguments::created_by_java_launcher()) { ++ // Use 2MB to allow for Solaris 7 64 bit mode. ++ stack_size = JavaThread::stack_size_at_create() == 0 ++ ? 2048*K : JavaThread::stack_size_at_create(); ++ ++ // There are rare cases when we may have already used more than ++ // the basic stack size allotment before this method is invoked. ++ // Attempt to allow for a normally sized java_stack. ++ size_t current_stack_offset = (size_t)(base - (address)&stack_size); ++ stack_size += ReservedSpace::page_align_size_down(current_stack_offset); ++ } else { ++ // 6269555: If we were not created by a Java launcher, i.e. if we are ++ // running embedded in a native application, treat the primordial thread ++ // as much like a native attached thread as possible. This means using ++ // the current stack size from thr_stksegment(), unless it is too large ++ // to reliably setup guard pages. A reasonable max size is 8MB. ++ size_t current_size = os::current_stack_size(); ++ // This should never happen, but just in case.... ++ if (current_size == 0) current_size = 2 * K * K; ++ stack_size = current_size > (8 * K * K) ? (8 * K * K) : current_size; ++ } ++ address bottom = align_up(base - stack_size, os::vm_page_size());; ++ stack_size = (size_t)(base - bottom); ++ ++ assert(stack_size > 0, "Stack size calculation problem"); ++ ++ if (stack_size > jt->stack_size()) { ++#ifndef PRODUCT ++ struct rlimit limits; ++ getrlimit(RLIMIT_STACK, &limits); ++ size_t size = adjust_stack_size(base, (size_t)limits.rlim_cur); ++ assert(size >= jt->stack_size(), "Stack size problem in main thread"); ++#endif ++ tty->print_cr("Stack size of " SIZE_FORMAT " Kb exceeds current limit of " SIZE_FORMAT " Kb.\n" ++ "(Stack sizes are rounded up to a multiple of the system page size.)\n" ++ "See limit(1) to increase the stack size limit.", ++ stack_size / K, jt->stack_size() / K); ++ vm_exit(1); ++ } ++ assert(jt->stack_size() >= stack_size, ++ "Attempt to map more stack than was allocated"); ++ jt->set_stack_size(stack_size); ++ ++} ++ ++ ++ ++// Free Solaris resources related to the OSThread ++void os::free_thread(OSThread* osthread) { ++ assert(osthread != NULL, "os::free_thread but osthread not set"); ++ ++ // We are told to free resources of the argument thread, ++ // but we can only really operate on the current thread. ++ assert(Thread::current()->osthread() == osthread, ++ "os::free_thread but not current thread"); ++ ++ // Restore caller's signal mask ++ sigset_t sigmask = osthread->caller_sigmask(); ++ pthread_sigmask(SIG_SETMASK, &sigmask, NULL); ++ ++ delete osthread; ++} ++ ++void os::pd_start_thread(Thread* thread) { ++ int status = thr_continue(thread->osthread()->thread_id()); ++ assert_status(status == 0, status, "thr_continue failed"); ++} ++ ++ ++intx os::current_thread_id() { ++ return (intx)thr_self(); ++} ++ ++static pid_t _initial_pid = 0; ++ ++int os::current_process_id() { ++ return (int)(_initial_pid ? _initial_pid : getpid()); ++} ++ ++// gethrtime() should be monotonic according to the documentation, ++// but some virtualized platforms are known to break this guarantee. ++// getTimeNanos() must be guaranteed not to move backwards, so we ++// are forced to add a check here. ++inline hrtime_t getTimeNanos() { ++ const hrtime_t now = gethrtime(); ++ const hrtime_t prev = max_hrtime; ++ if (now <= prev) { ++ return prev; // same or retrograde time; ++ } ++ const hrtime_t obsv = Atomic::cmpxchg(&max_hrtime, prev, now); ++ assert(obsv >= prev, "invariant"); // Monotonicity ++ // If the CAS succeeded then we're done and return "now". ++ // If the CAS failed and the observed value "obsv" is >= now then ++ // we should return "obsv". If the CAS failed and now > obsv > prv then ++ // some other thread raced this thread and installed a new value, in which case ++ // we could either (a) retry the entire operation, (b) retry trying to install now ++ // or (c) just return obsv. We use (c). No loop is required although in some cases ++ // we might discard a higher "now" value in deference to a slightly lower but freshly ++ // installed obsv value. That's entirely benign -- it admits no new orderings compared ++ // to (a) or (b) -- and greatly reduces coherence traffic. ++ // We might also condition (c) on the magnitude of the delta between obsv and now. ++ // Avoiding excessive CAS operations to hot RW locations is critical. ++ // See https://blogs.oracle.com/dave/entry/cas_and_cache_trivia_invalidate ++ return (prev == obsv) ? now : obsv; ++} ++ ++double os::elapsedVTime() { ++ return (double)gethrvtime() / (double)hrtime_hz; ++} ++ ++// DLL functions ++ ++// This must be hard coded because it's the system's temporary ++// directory not the java application's temp directory, ala java.io.tmpdir. ++const char* os::get_temp_directory() { return "/tmp"; } ++ ++// check if addr is inside libjvm.so ++bool os::address_is_in_vm(address addr) { ++ static address libjvm_base_addr; ++ Dl_info dlinfo; ++ ++ if (libjvm_base_addr == NULL) { ++ if (dladdr(CAST_FROM_FN_PTR(void *, os::address_is_in_vm), &dlinfo) != 0) { ++ libjvm_base_addr = (address)dlinfo.dli_fbase; ++ } ++ assert(libjvm_base_addr !=NULL, "Cannot obtain base address for libjvm"); ++ } ++ ++ if (dladdr((void *)addr, &dlinfo) != 0) { ++ if (libjvm_base_addr == (address)dlinfo.dli_fbase) return true; ++ } ++ ++ return false; ++} ++ ++void os::prepare_native_symbols() { ++} ++ ++typedef int (*dladdr1_func_type)(void *, Dl_info *, void **, int); ++static dladdr1_func_type dladdr1_func = NULL; ++ ++bool os::dll_address_to_function_name(address addr, char *buf, ++ int buflen, int * offset, ++ bool demangle) { ++ // buf is not optional, but offset is optional ++ assert(buf != NULL, "sanity check"); ++ ++ Dl_info dlinfo; ++ ++ // dladdr1_func was initialized in os::init() ++ if (dladdr1_func != NULL) { ++ // yes, we have dladdr1 ++ ++ // Support for dladdr1 is checked at runtime; it may be ++ // available even if the vm is built on a machine that does ++ // not have dladdr1 support. Make sure there is a value for ++ // RTLD_DL_SYMENT. ++#ifndef RTLD_DL_SYMENT ++ #define RTLD_DL_SYMENT 1 ++#endif ++#ifdef _LP64 ++ Elf64_Sym * info; ++#else ++ Elf32_Sym * info; ++#endif ++ if (dladdr1_func((void *)addr, &dlinfo, (void **)&info, ++ RTLD_DL_SYMENT) != 0) { ++ // see if we have a matching symbol that covers our address ++ if (dlinfo.dli_saddr != NULL && ++ (char *)dlinfo.dli_saddr + info->st_size > (char *)addr) { ++ if (dlinfo.dli_sname != NULL) { ++ if (!(demangle && Decoder::demangle(dlinfo.dli_sname, buf, buflen))) { ++ jio_snprintf(buf, buflen, "%s", dlinfo.dli_sname); ++ } ++ if (offset != NULL) *offset = addr - (address)dlinfo.dli_saddr; ++ return true; ++ } ++ } ++ // no matching symbol so try for just file info ++ if (dlinfo.dli_fname != NULL && dlinfo.dli_fbase != NULL) { ++ if (Decoder::decode((address)(addr - (address)dlinfo.dli_fbase), ++ buf, buflen, offset, dlinfo.dli_fname, demangle)) { ++ return true; ++ } ++ } ++ } ++ buf[0] = '\0'; ++ if (offset != NULL) *offset = -1; ++ return false; ++ } ++ ++ // no, only dladdr is available ++ if (dladdr((void *)addr, &dlinfo) != 0) { ++ // see if we have a matching symbol ++ if (dlinfo.dli_saddr != NULL && dlinfo.dli_sname != NULL) { ++ if (!(demangle && Decoder::demangle(dlinfo.dli_sname, buf, buflen))) { ++ jio_snprintf(buf, buflen, dlinfo.dli_sname); ++ } ++ if (offset != NULL) *offset = addr - (address)dlinfo.dli_saddr; ++ return true; ++ } ++ // no matching symbol so try for just file info ++ if (dlinfo.dli_fname != NULL && dlinfo.dli_fbase != NULL) { ++ if (Decoder::decode((address)(addr - (address)dlinfo.dli_fbase), ++ buf, buflen, offset, dlinfo.dli_fname, demangle)) { ++ return true; ++ } ++ } ++ } ++ buf[0] = '\0'; ++ if (offset != NULL) *offset = -1; ++ return false; ++} ++ ++bool os::dll_address_to_library_name(address addr, char* buf, ++ int buflen, int* offset) { ++ // buf is not optional, but offset is optional ++ assert(buf != NULL, "sanity check"); ++ ++ Dl_info dlinfo; ++ ++ if (dladdr((void*)addr, &dlinfo) != 0) { ++ if (dlinfo.dli_fname != NULL) { ++ jio_snprintf(buf, buflen, "%s", dlinfo.dli_fname); ++ } ++ if (dlinfo.dli_fbase != NULL && offset != NULL) { ++ *offset = addr - (address)dlinfo.dli_fbase; ++ } ++ return true; ++ } ++ ++ buf[0] = '\0'; ++ if (offset) *offset = -1; ++ return false; ++} ++ ++int os::get_loaded_modules_info(os::LoadedModulesCallbackFunc callback, void *param) { ++ Dl_info dli; ++ // Sanity check? ++ if (dladdr(CAST_FROM_FN_PTR(void *, os::get_loaded_modules_info), &dli) == 0 || ++ dli.dli_fname == NULL) { ++ return 1; ++ } ++ ++ void * handle = dlopen(dli.dli_fname, RTLD_LAZY); ++ if (handle == NULL) { ++ return 1; ++ } ++ ++ Link_map *map; ++ dlinfo(handle, RTLD_DI_LINKMAP, &map); ++ if (map == NULL) { ++ dlclose(handle); ++ return 1; ++ } ++ ++ while (map->l_prev != NULL) { ++ map = map->l_prev; ++ } ++ ++ while (map != NULL) { ++ // Iterate through all map entries and call callback with fields of interest ++ if(callback(map->l_name, (address)map->l_addr, (address)0, param)) { ++ dlclose(handle); ++ return 1; ++ } ++ map = map->l_next; ++ } ++ ++ dlclose(handle); ++ return 0; ++} ++ ++int _print_dll_info_cb(const char * name, address base_address, address top_address, void * param) { ++ outputStream * out = (outputStream *) param; ++ out->print_cr(INTPTR_FORMAT " \t%s", (intptr_t)base_address, name); ++ return 0; ++} ++ ++void os::print_dll_info(outputStream * st) { ++ st->print_cr("Dynamic libraries:"); st->flush(); ++ if (get_loaded_modules_info(_print_dll_info_cb, (void *)st)) { ++ st->print_cr("Error: Cannot print dynamic libraries."); ++ } ++} ++ ++static void change_endianness(Elf32_Half& val) { ++ unsigned char *ptr = (unsigned char *)&val; ++ unsigned char swp = ptr[0]; ++ ptr[0] = ptr[1]; ++ ptr[1] = swp; ++} ++ ++// Loads .dll/.so and ++// in case of error it checks if .dll/.so was built for the ++// same architecture as Hotspot is running on ++ ++void * os::dll_load(const char *filename, char *ebuf, int ebuflen) { ++ log_info(os)("attempting shared library load of %s", filename); ++ ++ void * result= ::dlopen(filename, RTLD_LAZY); ++ if (result != NULL) { ++ // Successful loading ++ Events::log(NULL, "Loaded shared library %s", filename); ++ log_info(os)("shared library load of %s was successful", filename); ++ return result; ++ } ++ ++ Elf32_Ehdr elf_head; ++ const char* error_report = ::dlerror(); ++ if (error_report == NULL) { ++ error_report = "dlerror returned no error description"; ++ } ++ if (ebuf != NULL && ebuflen > 0) { ++ ::strncpy(ebuf, error_report, ebuflen-1); ++ ebuf[ebuflen-1]='\0'; ++ } ++ ++ Events::log(NULL, "Loading shared library %s failed, %s", filename, error_report); ++ log_info(os)("shared library load of %s failed, %s", filename, error_report); ++ ++ int diag_msg_max_length=ebuflen-strlen(ebuf); ++ char* diag_msg_buf=ebuf+strlen(ebuf); ++ ++ if (diag_msg_max_length==0) { ++ // No more space in ebuf for additional diagnostics message ++ return NULL; ++ } ++ ++ ++ int file_descriptor= ::open(filename, O_RDONLY | O_NONBLOCK); ++ ++ if (file_descriptor < 0) { ++ // Can't open library, report dlerror() message ++ return NULL; ++ } ++ ++ bool failed_to_read_elf_head= ++ (sizeof(elf_head)!= ++ (::read(file_descriptor, &elf_head,sizeof(elf_head)))); ++ ++ ::close(file_descriptor); ++ if (failed_to_read_elf_head) { ++ // file i/o error - report dlerror() msg ++ return NULL; ++ } ++ ++ if (elf_head.e_ident[EI_DATA] != LITTLE_ENDIAN_ONLY(ELFDATA2LSB) BIG_ENDIAN_ONLY(ELFDATA2MSB)) { ++ // handle invalid/out of range endianness values ++ if (elf_head.e_ident[EI_DATA] == 0 || elf_head.e_ident[EI_DATA] > 2) { ++ return NULL; ++ } ++ change_endianness(elf_head.e_machine); ++ } ++ ++ typedef struct { ++ Elf32_Half code; // Actual value as defined in elf.h ++ Elf32_Half compat_class; // Compatibility of archs at VM's sense ++ unsigned char elf_class; // 32 or 64 bit ++ unsigned char endianess; // MSB or LSB ++ char* name; // String representation ++ } arch_t; ++ ++ static const arch_t arch_array[]={ ++ {EM_386, EM_386, ELFCLASS32, ELFDATA2LSB, (char*)"IA 32"}, ++ {EM_486, EM_386, ELFCLASS32, ELFDATA2LSB, (char*)"IA 32"}, ++ {EM_IA_64, EM_IA_64, ELFCLASS64, ELFDATA2LSB, (char*)"IA 64"}, ++ {EM_X86_64, EM_X86_64, ELFCLASS64, ELFDATA2LSB, (char*)"AMD 64"}, ++ {EM_SPARC, EM_SPARC, ELFCLASS32, ELFDATA2MSB, (char*)"Sparc 32"}, ++ {EM_SPARC32PLUS, EM_SPARC, ELFCLASS32, ELFDATA2MSB, (char*)"Sparc 32"}, ++ {EM_SPARCV9, EM_SPARCV9, ELFCLASS64, ELFDATA2MSB, (char*)"Sparc v9 64"}, ++ {EM_PPC, EM_PPC, ELFCLASS32, ELFDATA2MSB, (char*)"Power PC 32"}, ++ {EM_PPC64, EM_PPC64, ELFCLASS64, ELFDATA2MSB, (char*)"Power PC 64"}, ++ {EM_ARM, EM_ARM, ELFCLASS32, ELFDATA2LSB, (char*)"ARM"}, ++ // we only support 64 bit z architecture ++ {EM_S390, EM_S390, ELFCLASS64, ELFDATA2MSB, (char*)"IBM System/390"}, ++ {EM_AARCH64, EM_AARCH64, ELFCLASS64, ELFDATA2LSB, (char*)"AARCH64"} ++ }; ++ ++#if (defined IA32) ++ static Elf32_Half running_arch_code=EM_386; ++#elif (defined AMD64) ++ static Elf32_Half running_arch_code=EM_X86_64; ++#elif (defined IA64) ++ static Elf32_Half running_arch_code=EM_IA_64; ++#elif (defined __sparc) && (defined _LP64) ++ static Elf32_Half running_arch_code=EM_SPARCV9; ++#elif (defined __sparc) && (!defined _LP64) ++ static Elf32_Half running_arch_code=EM_SPARC; ++#elif (defined __powerpc64__) ++ static Elf32_Half running_arch_code=EM_PPC64; ++#elif (defined __powerpc__) ++ static Elf32_Half running_arch_code=EM_PPC; ++#elif (defined ARM) ++ static Elf32_Half running_arch_code=EM_ARM; ++#else ++ #error Method os::dll_load requires that one of following is defined:\ ++ IA32, AMD64, IA64, __sparc, __powerpc__, ARM, ARM ++#endif ++ ++ // Identify compatibility class for VM's architecture and library's architecture ++ // Obtain string descriptions for architectures ++ ++ arch_t lib_arch={elf_head.e_machine,0,elf_head.e_ident[EI_CLASS], elf_head.e_ident[EI_DATA], NULL}; ++ int running_arch_index=-1; ++ ++ for (unsigned int i=0; i < ARRAY_SIZE(arch_array); i++) { ++ if (running_arch_code == arch_array[i].code) { ++ running_arch_index = i; ++ } ++ if (lib_arch.code == arch_array[i].code) { ++ lib_arch.compat_class = arch_array[i].compat_class; ++ lib_arch.name = arch_array[i].name; ++ } ++ } ++ ++ assert(running_arch_index != -1, ++ "Didn't find running architecture code (running_arch_code) in arch_array"); ++ if (running_arch_index == -1) { ++ // Even though running architecture detection failed ++ // we may still continue with reporting dlerror() message ++ return NULL; ++ } ++ ++ if (lib_arch.compat_class != arch_array[running_arch_index].compat_class) { ++ if (lib_arch.name != NULL) { ++ ::snprintf(diag_msg_buf, diag_msg_max_length-1, ++ " (Possible cause: can't load %s .so on a %s platform)", ++ lib_arch.name, arch_array[running_arch_index].name); ++ } else { ++ ::snprintf(diag_msg_buf, diag_msg_max_length-1, ++ " (Possible cause: can't load this .so (machine code=0x%x) on a %s platform)", ++ lib_arch.code, arch_array[running_arch_index].name); ++ } ++ return NULL; ++ } ++ ++ if (lib_arch.endianess != arch_array[running_arch_index].endianess) { ++ ::snprintf(diag_msg_buf, diag_msg_max_length-1," (Possible cause: endianness mismatch)"); ++ return NULL; ++ } ++ ++ // ELF file class/capacity : 0 - invalid, 1 - 32bit, 2 - 64bit ++ if (lib_arch.elf_class > 2 || lib_arch.elf_class < 1) { ++ ::snprintf(diag_msg_buf, diag_msg_max_length-1, " (Possible cause: invalid ELF file class)"); ++ return NULL; ++ } ++ ++ if (lib_arch.elf_class != arch_array[running_arch_index].elf_class) { ++ ::snprintf(diag_msg_buf, diag_msg_max_length-1, ++ " (Possible cause: architecture word width mismatch, can't load %d-bit .so on a %d-bit platform)", ++ (int) lib_arch.elf_class * 32, arch_array[running_arch_index].elf_class * 32); ++ return NULL; ++ } ++ ++ return NULL; ++} ++ ++static inline time_t get_mtime(const char* filename) { ++ struct stat st; ++ int ret = os::stat(filename, &st); ++ assert(ret == 0, "failed to stat() file '%s': %s", filename, os::strerror(errno)); ++ return st.st_mtime; ++} ++ ++int os::compare_file_modified_times(const char* file1, const char* file2) { ++ time_t t1 = get_mtime(file1); ++ time_t t2 = get_mtime(file2); ++ return t1 - t2; ++} ++ ++static bool _print_ascii_file(const char* filename, outputStream* st) { ++ int fd = ::open(filename, O_RDONLY); ++ if (fd == -1) { ++ return false; ++ } ++ ++ char buf[32]; ++ int bytes; ++ while ((bytes = ::read(fd, buf, sizeof(buf))) > 0) { ++ st->print_raw(buf, bytes); ++ } ++ ++ ::close(fd); ++ ++ return true; ++} ++ ++void os::print_os_info_brief(outputStream* st) { ++ os::Solaris::print_distro_info(st); ++ ++ os::Posix::print_uname_info(st); ++ ++ os::Solaris::print_libversion_info(st); ++} ++ ++void os::print_os_info(outputStream* st) { ++ st->print("OS:"); ++ ++ os::Solaris::print_distro_info(st); ++ ++ os::Posix::print_uname_info(st); ++ ++ os::Posix::print_uptime_info(st); ++ ++ os::Solaris::print_libversion_info(st); ++ ++ os::Posix::print_rlimit_info(st); ++ ++ os::Posix::print_load_average(st); ++} ++ ++void os::Solaris::print_distro_info(outputStream* st) { ++ if (!_print_ascii_file("/etc/release", st)) { ++ st->print("Solaris"); ++ } ++ st->cr(); ++} ++ ++void os::get_summary_os_info(char* buf, size_t buflen) { ++ strncpy(buf, "Solaris", buflen); // default to plain solaris ++ FILE* fp = fopen("/etc/release", "r"); ++ if (fp != NULL) { ++ char tmp[256]; ++ // Only get the first line and chop out everything but the os name. ++ if (fgets(tmp, sizeof(tmp), fp)) { ++ char* ptr = tmp; ++ // skip past whitespace characters ++ while (*ptr != '\0' && (*ptr == ' ' || *ptr == '\t' || *ptr == '\n')) ptr++; ++ if (*ptr != '\0') { ++ char* nl = strchr(ptr, '\n'); ++ if (nl != NULL) *nl = '\0'; ++ strncpy(buf, ptr, buflen); ++ } ++ } ++ fclose(fp); ++ } ++} ++ ++void os::Solaris::print_libversion_info(outputStream* st) { ++ st->print(" (T2 libthread)"); ++ st->cr(); ++} ++ ++static bool check_addr0(outputStream* st) { ++ jboolean status = false; ++ const int read_chunk = 200; ++ int ret = 0; ++ int nmap = 0; ++ int fd = ::open("/proc/self/map",O_RDONLY); ++ if (fd >= 0) { ++ prmap_t *p = NULL; ++ char *mbuff = (char *) calloc(read_chunk, sizeof(prmap_t)); ++ if (NULL == mbuff) { ++ ::close(fd); ++ return status; ++ } ++ while ((ret = ::read(fd, mbuff, read_chunk*sizeof(prmap_t))) > 0) { ++ //check if read() has not read partial data ++ if( 0 != ret % sizeof(prmap_t)){ ++ break; ++ } ++ nmap = ret / sizeof(prmap_t); ++ p = (prmap_t *)mbuff; ++ for(int i = 0; i < nmap; i++){ ++ if (p->pr_vaddr == 0x0) { ++ st->print("Warning: Address: " PTR_FORMAT ", Size: " SIZE_FORMAT "K, ",p->pr_vaddr, p->pr_size/1024); ++ st->print("Mapped file: %s, ", p->pr_mapname[0] == '\0' ? "None" : p->pr_mapname); ++ st->print("Access: "); ++ st->print("%s",(p->pr_mflags & MA_READ) ? "r" : "-"); ++ st->print("%s",(p->pr_mflags & MA_WRITE) ? "w" : "-"); ++ st->print("%s",(p->pr_mflags & MA_EXEC) ? "x" : "-"); ++ st->cr(); ++ status = true; ++ } ++ p++; ++ } ++ } ++ free(mbuff); ++ ::close(fd); ++ } ++ return status; ++} ++ ++void os::get_summary_cpu_info(char* buf, size_t buflen) { ++ // Get MHz with system call. We don't seem to already have this. ++ processor_info_t stats; ++ processorid_t id = getcpuid(); ++ int clock = 0; ++ if (processor_info(id, &stats) != -1) { ++ clock = stats.pi_clock; // pi_processor_type isn't more informative than below ++ } ++ snprintf(buf, buflen, "64 bit %d MHz", clock); ++} ++ ++void os::pd_print_cpu_info(outputStream* st, char* buf, size_t buflen) { ++ // Nothing to do for now. ++} ++ ++void os::print_memory_info(outputStream* st) { ++ st->print("Memory:"); ++ st->print(" " SIZE_FORMAT "k page", os::vm_page_size()>>10); ++ st->print(", physical " UINT64_FORMAT "k", os::physical_memory()>>10); ++ st->print("(" UINT64_FORMAT "k free)", os::available_memory() >> 10); ++ st->cr(); ++ (void) check_addr0(st); ++} ++ ++static int Maxsignum = 0; ++ ++static char saved_jvm_path[MAXPATHLEN] = { 0 }; ++ ++// Find the full path to the current module, libjvm.so ++void os::jvm_path(char *buf, jint buflen) { ++ // Error checking. ++ if (buflen < MAXPATHLEN) { ++ assert(false, "must use a large-enough buffer"); ++ buf[0] = '\0'; ++ return; ++ } ++ // Lazy resolve the path to current module. ++ if (saved_jvm_path[0] != 0) { ++ strcpy(buf, saved_jvm_path); ++ return; ++ } ++ ++ Dl_info dlinfo; ++ int ret = dladdr(CAST_FROM_FN_PTR(void *, os::jvm_path), &dlinfo); ++ assert(ret != 0, "cannot locate libjvm"); ++ if (ret != 0 && dlinfo.dli_fname != NULL) { ++ if (os::Posix::realpath((char *)dlinfo.dli_fname, buf, buflen) == NULL) { ++ return; ++ } ++ } else { ++ buf[0] = '\0'; ++ return; ++ } ++ ++ if (Arguments::sun_java_launcher_is_altjvm()) { ++ // Support for the java launcher's '-XXaltjvm=' option. Typical ++ // value for buf is "/jre/lib///libjvm.so". ++ // If "/jre/lib/" appears at the right place in the string, then ++ // assume we are installed in a JDK and we're done. Otherwise, check ++ // for a JAVA_HOME environment variable and fix up the path so it ++ // looks like libjvm.so is installed there (append a fake suffix ++ // hotspot/libjvm.so). ++ const char *p = buf + strlen(buf) - 1; ++ for (int count = 0; p > buf && count < 5; ++count) { ++ for (--p; p > buf && *p != '/'; --p) ++ /* empty */ ; ++ } ++ ++ if (strncmp(p, "/jre/lib/", 9) != 0) { ++ // Look for JAVA_HOME in the environment. ++ char* java_home_var = ::getenv("JAVA_HOME"); ++ if (java_home_var != NULL && java_home_var[0] != 0) { ++ char* jrelib_p; ++ int len; ++ ++ // Check the current module name "libjvm.so". ++ p = strrchr(buf, '/'); ++ assert(strstr(p, "/libjvm") == p, "invalid library name"); ++ ++ if (os::Posix::realpath(java_home_var, buf, buflen) == NULL) { ++ return; ++ } ++ // determine if this is a legacy image or modules image ++ // modules image doesn't have "jre" subdirectory ++ len = strlen(buf); ++ assert(len < buflen, "Ran out of buffer space"); ++ jrelib_p = buf + len; ++ snprintf(jrelib_p, buflen-len, "/jre/lib"); ++ if (0 != access(buf, F_OK)) { ++ snprintf(jrelib_p, buflen-len, "/lib"); ++ } ++ ++ if (0 == access(buf, F_OK)) { ++ // Use current module name "libjvm.so" ++ len = strlen(buf); ++ snprintf(buf + len, buflen-len, "/hotspot/libjvm.so"); ++ } else { ++ // Go back to path of .so ++ if (os::Posix::realpath((char *)dlinfo.dli_fname, buf, buflen) == NULL) { ++ return; ++ } ++ } ++ } ++ } ++ } ++ ++ strncpy(saved_jvm_path, buf, MAXPATHLEN); ++ saved_jvm_path[MAXPATHLEN - 1] = '\0'; ++} ++ ++//////////////////////////////////////////////////////////////////////////////// ++// Virtual Memory ++ ++static bool recoverable_mmap_error(int err) { ++ // See if the error is one we can let the caller handle. This ++ // list of errno values comes from the Solaris mmap(2) man page. ++ switch (err) { ++ case EBADF: ++ case EINVAL: ++ case ENOTSUP: ++ // let the caller deal with these errors ++ return true; ++ ++ default: ++ // Any remaining errors on this OS can cause our reserved mapping ++ // to be lost. That can cause confusion where different data ++ // structures think they have the same memory mapped. The worst ++ // scenario is if both the VM and a library think they have the ++ // same memory mapped. ++ return false; ++ } ++} ++ ++static void warn_fail_commit_memory(char* addr, size_t bytes, bool exec, ++ int err) { ++ warning("INFO: os::commit_memory(" PTR_FORMAT ", " SIZE_FORMAT ++ ", %d) failed; error='%s' (errno=%d)", p2i(addr), bytes, exec, ++ os::strerror(err), err); ++} ++ ++static void warn_fail_commit_memory(char* addr, size_t bytes, ++ size_t alignment_hint, bool exec, ++ int err) { ++ warning("INFO: os::commit_memory(" PTR_FORMAT ", " SIZE_FORMAT ++ ", " SIZE_FORMAT ", %d) failed; error='%s' (errno=%d)", p2i(addr), ++ bytes, alignment_hint, exec, os::strerror(err), err); ++} ++ ++int os::Solaris::commit_memory_impl(char* addr, size_t bytes, bool exec) { ++ int prot = exec ? PROT_READ|PROT_WRITE|PROT_EXEC : PROT_READ|PROT_WRITE; ++ size_t size = bytes; ++ char *res = Solaris::mmap_chunk(addr, size, MAP_PRIVATE|MAP_FIXED, prot); ++ if (res != NULL) { ++ if (UseNUMAInterleaving) { ++ numa_make_global(addr, bytes); ++ } ++ return 0; ++ } ++ ++ int err = errno; // save errno from mmap() call in mmap_chunk() ++ ++ if (!recoverable_mmap_error(err)) { ++ warn_fail_commit_memory(addr, bytes, exec, err); ++ vm_exit_out_of_memory(bytes, OOM_MMAP_ERROR, "committing reserved memory."); ++ } ++ ++ return err; ++} ++ ++bool os::pd_commit_memory(char* addr, size_t bytes, bool exec) { ++ return Solaris::commit_memory_impl(addr, bytes, exec) == 0; ++} ++ ++void os::pd_commit_memory_or_exit(char* addr, size_t bytes, bool exec, ++ const char* mesg) { ++ assert(mesg != NULL, "mesg must be specified"); ++ int err = os::Solaris::commit_memory_impl(addr, bytes, exec); ++ if (err != 0) { ++ // the caller wants all commit errors to exit with the specified mesg: ++ warn_fail_commit_memory(addr, bytes, exec, err); ++ vm_exit_out_of_memory(bytes, OOM_MMAP_ERROR, "%s", mesg); ++ } ++} ++ ++size_t os::Solaris::page_size_for_alignment(size_t alignment) { ++ assert(is_aligned(alignment, (size_t) os::vm_page_size()), ++ SIZE_FORMAT " is not aligned to " SIZE_FORMAT, ++ alignment, (size_t) os::vm_page_size()); ++ ++ int page_sizes_max = 9; ++ size_t _illumos_page_sizes[page_sizes_max]; ++ int n = getpagesizes(_illumos_page_sizes, page_sizes_max); ++ for (int i = 0; _illumos_page_sizes[i] != 0; i++) { ++ if (is_aligned(alignment, _illumos_page_sizes[i])) { ++ return _illumos_page_sizes[i]; ++ } ++ } ++ ++ return (size_t) os::vm_page_size(); ++} ++ ++int os::Solaris::commit_memory_impl(char* addr, size_t bytes, ++ size_t alignment_hint, bool exec) { ++ int err = Solaris::commit_memory_impl(addr, bytes, exec); ++ if (err == 0 && UseLargePages && alignment_hint > 0) { ++ assert(is_aligned(bytes, alignment_hint), ++ SIZE_FORMAT " is not aligned to " SIZE_FORMAT, bytes, alignment_hint); ++ ++ // The syscall memcntl requires an exact page size (see man memcntl for details). ++ size_t page_size = page_size_for_alignment(alignment_hint); ++ if (page_size > (size_t) os::vm_page_size()) { ++ (void)Solaris::setup_large_pages(addr, bytes, page_size); ++ } ++ } ++ return err; ++} ++ ++bool os::pd_commit_memory(char* addr, size_t bytes, size_t alignment_hint, ++ bool exec) { ++ return Solaris::commit_memory_impl(addr, bytes, alignment_hint, exec) == 0; ++} ++ ++void os::pd_commit_memory_or_exit(char* addr, size_t bytes, ++ size_t alignment_hint, bool exec, ++ const char* mesg) { ++ assert(mesg != NULL, "mesg must be specified"); ++ int err = os::Solaris::commit_memory_impl(addr, bytes, alignment_hint, exec); ++ if (err != 0) { ++ // the caller wants all commit errors to exit with the specified mesg: ++ warn_fail_commit_memory(addr, bytes, alignment_hint, exec, err); ++ vm_exit_out_of_memory(bytes, OOM_MMAP_ERROR, "%s", mesg); ++ } ++} ++ ++// Uncommit the pages in a specified region. ++void os::pd_free_memory(char* addr, size_t bytes, size_t alignment_hint) { ++ if (posix_madvise(addr, bytes, MADV_FREE) < 0) { ++ debug_only(warning("MADV_FREE failed.")); ++ return; ++ } ++} ++ ++size_t os::pd_pretouch_memory(void* first, void* last, size_t page_size) { ++ return page_size; ++} ++ ++bool os::pd_create_stack_guard_pages(char* addr, size_t size) { ++ return os::commit_memory(addr, size, !ExecMem); ++} ++ ++bool os::remove_stack_guard_pages(char* addr, size_t size) { ++ return os::uncommit_memory(addr, size); ++} ++ ++// Change the page size in a given range. ++void os::pd_realign_memory(char *addr, size_t bytes, size_t alignment_hint) { ++ assert((intptr_t)addr % alignment_hint == 0, "Address should be aligned."); ++ assert((intptr_t)(addr + bytes) % alignment_hint == 0, "End should be aligned."); ++ if (UseLargePages) { ++ size_t page_size = Solaris::page_size_for_alignment(alignment_hint); ++ if (page_size > (size_t) os::vm_page_size()) { ++ Solaris::setup_large_pages(addr, bytes, page_size); ++ } ++ } ++} ++ ++// Tell the OS to make the range local to the first-touching LWP ++void os::numa_make_local(char *addr, size_t bytes, int lgrp_hint) { ++ assert((intptr_t)addr % os::vm_page_size() == 0, "Address should be page-aligned."); ++ if (posix_madvise(addr, bytes, MADV_ACCESS_LWP) < 0) { ++ debug_only(warning("MADV_ACCESS_LWP failed.")); ++ } ++} ++ ++// Tell the OS that this range would be accessed from different LWPs. ++void os::numa_make_global(char *addr, size_t bytes) { ++ assert((intptr_t)addr % os::vm_page_size() == 0, "Address should be page-aligned."); ++ if (posix_madvise(addr, bytes, MADV_ACCESS_MANY) < 0) { ++ debug_only(warning("MADV_ACCESS_MANY failed.")); ++ } ++} ++ ++// Get the number of the locality groups. ++size_t os::numa_get_groups_num() { ++ size_t n = Solaris::lgrp_nlgrps(Solaris::lgrp_cookie()); ++ return n != -1 ? n : 1; ++} ++ ++// Get a list of leaf locality groups. A leaf lgroup is group that ++// doesn't have any children. Typical leaf group is a CPU or a CPU/memory ++// board. An LWP is assigned to one of these groups upon creation. ++size_t os::numa_get_leaf_groups(int *ids, size_t size) { ++ if ((ids[0] = Solaris::lgrp_root(Solaris::lgrp_cookie())) == -1) { ++ ids[0] = 0; ++ return 1; ++ } ++ int result_size = 0, top = 1, bottom = 0, cur = 0; ++ for (unsigned int k = 0; k < size; k++) { ++ int r = Solaris::lgrp_children(Solaris::lgrp_cookie(), ids[cur], ++ (Solaris::lgrp_id_t*)&ids[top], size - top); ++ if (r == -1) { ++ ids[0] = 0; ++ return 1; ++ } ++ if (!r) { ++ // That's a leaf node. ++ assert(bottom <= cur, "Sanity check"); ++ // Check if the node has memory ++ if (Solaris::lgrp_resources(Solaris::lgrp_cookie(), ids[cur], ++ NULL, 0, LGRP_RSRC_MEM) > 0) { ++ ids[bottom++] = ids[cur]; ++ } ++ } ++ top += r; ++ cur++; ++ } ++ if (bottom == 0) { ++ // Handle a situation, when the OS reports no memory available. ++ // Assume UMA architecture. ++ ids[0] = 0; ++ return 1; ++ } ++ return bottom; ++} ++ ++// Detect the topology change. Typically happens during CPU plugging-unplugging. ++bool os::numa_topology_changed() { ++ int is_stale = Solaris::lgrp_cookie_stale(Solaris::lgrp_cookie()); ++ if (is_stale != -1 && is_stale) { ++ Solaris::lgrp_fini(Solaris::lgrp_cookie()); ++ Solaris::lgrp_cookie_t c = Solaris::lgrp_init(Solaris::LGRP_VIEW_CALLER); ++ assert(c != 0, "Failure to initialize LGRP API"); ++ Solaris::set_lgrp_cookie(c); ++ return true; ++ } ++ return false; ++} ++ ++// Get the group id of the current LWP. ++int os::numa_get_group_id() { ++ int lgrp_id = Solaris::lgrp_home(P_LWPID, P_MYID); ++ if (lgrp_id == -1) { ++ return 0; ++ } ++ const int size = os::numa_get_groups_num(); ++ int *ids = (int*)alloca(size * sizeof(int)); ++ ++ // Get the ids of all lgroups with memory; r is the count. ++ int r = Solaris::lgrp_resources(Solaris::lgrp_cookie(), lgrp_id, ++ (Solaris::lgrp_id_t*)ids, size, LGRP_RSRC_MEM); ++ if (r <= 0) { ++ return 0; ++ } ++ return ids[os::random() % r]; ++} ++ ++int os::numa_get_group_id_for_address(const void* address) { ++ return 0; ++} ++ ++bool os::numa_get_group_ids_for_range(const void** addresses, int* lgrp_ids, size_t count) { ++ return false; ++} ++ ++// Scan the pages from start to end until a page different than ++// the one described in the info parameter is encountered. ++char *os::scan_pages(char *start, char* end, page_info* page_expected, ++ page_info* page_found) { ++ const uint_t info_types[] = { MEMINFO_VLGRP, MEMINFO_VPAGESIZE }; ++ const size_t types = sizeof(info_types) / sizeof(info_types[0]); ++ uint64_t addrs[MAX_MEMINFO_CNT], outdata[types * MAX_MEMINFO_CNT + 1]; ++ uint_t validity[MAX_MEMINFO_CNT]; ++ ++ size_t page_size = MAX2((size_t)os::vm_page_size(), page_expected->size); ++ uint64_t p = (uint64_t)start; ++ while (p < (uint64_t)end) { ++ addrs[0] = p; ++ size_t addrs_count = 1; ++ while (addrs_count < MAX_MEMINFO_CNT && addrs[addrs_count - 1] + page_size < (uint64_t)end) { ++ addrs[addrs_count] = addrs[addrs_count - 1] + page_size; ++ addrs_count++; ++ } ++ ++ if (meminfo(addrs, addrs_count, info_types, types, outdata, validity) < 0) { ++ return NULL; ++ } ++ ++ size_t i = 0; ++ for (; i < addrs_count; i++) { ++ if ((validity[i] & 1) != 0) { ++ if ((validity[i] & 4) != 0) { ++ if (outdata[types * i + 1] != page_expected->size) { ++ break; ++ } ++ } else if (page_expected->size != 0) { ++ break; ++ } ++ ++ if ((validity[i] & 2) != 0 && page_expected->lgrp_id > 0) { ++ if (outdata[types * i] != page_expected->lgrp_id) { ++ break; ++ } ++ } ++ } else { ++ return NULL; ++ } ++ } ++ ++ if (i < addrs_count) { ++ if ((validity[i] & 2) != 0) { ++ page_found->lgrp_id = outdata[types * i]; ++ } else { ++ page_found->lgrp_id = -1; ++ } ++ if ((validity[i] & 4) != 0) { ++ page_found->size = outdata[types * i + 1]; ++ } else { ++ page_found->size = 0; ++ } ++ return (char*)addrs[i]; ++ } ++ ++ p = addrs[addrs_count - 1] + page_size; ++ } ++ return end; ++} ++ ++bool os::pd_uncommit_memory(char* addr, size_t bytes, bool exec) { ++ size_t size = bytes; ++ // Map uncommitted pages PROT_NONE so we fail early if we touch an ++ // uncommitted page. Otherwise, the read/write might succeed if we ++ // have enough swap space to back the physical page. ++ return ++ NULL != Solaris::mmap_chunk(addr, size, ++ MAP_PRIVATE|MAP_FIXED|MAP_NORESERVE, ++ PROT_NONE); ++} ++ ++char* os::Solaris::mmap_chunk(char *addr, size_t size, int flags, int prot) { ++ char *b = (char *)mmap(addr, size, prot, flags, os::Solaris::_dev_zero_fd, 0); ++ ++ if (b == MAP_FAILED) { ++ return NULL; ++ } ++ return b; ++} ++ ++char* os::Solaris::anon_mmap(char* requested_addr, size_t bytes) { ++ char* addr = requested_addr; ++ int flags = MAP_PRIVATE | MAP_NORESERVE; ++ ++ // Map uncommitted pages PROT_NONE so we fail early if we touch an ++ // uncommitted page. Otherwise, the read/write might succeed if we ++ // have enough swap space to back the physical page. ++ return mmap_chunk(addr, bytes, flags, PROT_NONE); ++} ++ ++char* os::pd_reserve_memory(size_t bytes, bool exec) { ++ char* addr = Solaris::anon_mmap(NULL, bytes); ++ ++ return addr; ++} ++ ++char* os::pd_attempt_map_memory_to_file_at(char* requested_addr, size_t bytes, int file_desc) { ++ assert(file_desc >= 0, "file_desc is not valid"); ++ char* result = pd_attempt_reserve_memory_at(requested_addr, bytes, !ExecMem); ++ if (result != NULL) { ++ if (replace_existing_mapping_with_file_mapping(result, bytes, file_desc) == NULL) { ++ vm_exit_during_initialization(err_msg("Error in mapping Java heap at the given filesystem directory")); ++ } ++ } ++ return result; ++} ++ ++// Reserve memory at an arbitrary address, only if that area is ++// available (and not reserved for something else). ++ ++char* os::pd_attempt_reserve_memory_at(char* requested_addr, size_t bytes, bool exec) { ++ // Assert only that the size is a multiple of the page size, since ++ // that's all that mmap requires, and since that's all we really know ++ // about at this low abstraction level. If we need higher alignment, ++ // we can either pass an alignment to this method or verify alignment ++ // in one of the methods further up the call chain. See bug 5044738. ++ assert(bytes % os::vm_page_size() == 0, "reserving unexpected size block"); ++ ++ // Since snv_84, Solaris attempts to honor the address hint - see 5003415. ++ char* addr = Solaris::anon_mmap(requested_addr, bytes); ++ ++ volatile int err = errno; ++ if (addr == requested_addr) { ++ return addr; ++ } ++ ++ if (addr != NULL) { ++ pd_unmap_memory(addr, bytes); ++ } ++ ++ return NULL; ++} ++ ++bool os::pd_release_memory(char* addr, size_t bytes) { ++ size_t size = bytes; ++ return munmap(addr, size) == 0; ++} ++ ++static bool solaris_mprotect(char* addr, size_t bytes, int prot) { ++ assert(addr == (char*)align_down((uintptr_t)addr, os::vm_page_size()), ++ "addr must be page aligned"); ++ Events::log(NULL, "Protecting memory [" INTPTR_FORMAT "," INTPTR_FORMAT "] with protection modes %x", p2i(addr), p2i(addr+bytes), prot); ++ int retVal = mprotect(addr, bytes, prot); ++ return retVal == 0; ++} ++ ++// Protect memory (Used to pass readonly pages through ++// JNI GetArrayElements with empty arrays.) ++// Also, used for serialization page and for compressed oops null pointer ++// checking. ++bool os::protect_memory(char* addr, size_t bytes, ProtType prot, ++ bool is_committed) { ++ unsigned int p = 0; ++ switch (prot) { ++ case MEM_PROT_NONE: p = PROT_NONE; break; ++ case MEM_PROT_READ: p = PROT_READ; break; ++ case MEM_PROT_RW: p = PROT_READ|PROT_WRITE; break; ++ case MEM_PROT_RWX: p = PROT_READ|PROT_WRITE|PROT_EXEC; break; ++ default: ++ ShouldNotReachHere(); ++ } ++ // is_committed is unused. ++ return solaris_mprotect(addr, bytes, p); ++} ++ ++// guard_memory and unguard_memory only happens within stack guard pages. ++// Since ISM pertains only to the heap, guard and unguard memory should not ++/// happen with an ISM region. ++bool os::guard_memory(char* addr, size_t bytes) { ++ return solaris_mprotect(addr, bytes, PROT_NONE); ++} ++ ++bool os::unguard_memory(char* addr, size_t bytes) { ++ return solaris_mprotect(addr, bytes, PROT_READ|PROT_WRITE); ++} ++ ++// Large page support ++static size_t _large_page_size = 0; ++ ++bool os::Solaris::mpss_sanity_check(bool warn, size_t* page_size) { ++ // Find the page sizes supported by the system ++ int page_sizes_max = 9; ++ size_t _illumos_page_sizes[page_sizes_max]; ++ int n = getpagesizes(_illumos_page_sizes, page_sizes_max); ++ assert(n > 0, "illumos bug?"); ++ ++ if (n == 1) return false; // Only one page size available. ++ ++ // Skip sizes larger than 4M (or LargePageSizeInBytes if it was set) ++ const size_t size_limit = ++ FLAG_IS_DEFAULT(LargePageSizeInBytes) ? 4 * M : LargePageSizeInBytes; ++ int beg; ++ for (beg = 0; beg < n; ++beg) { ++ if (_illumos_page_sizes[beg] <= size_limit) { ++ _page_sizes.add(_illumos_page_sizes[beg]); ++ if (_illumos_page_sizes[beg] > *page_size) { ++ *page_size = _illumos_page_sizes[beg]; ++ } ++ } ++ } ++ // make sure we add the default ++ _page_sizes.add(os::vm_page_size()); ++ return true; ++} ++ ++void os::large_page_init() { ++ if (UseLargePages) { ++ // print a warning if any large page related flag is specified on command line ++ bool warn_on_failure = !FLAG_IS_DEFAULT(UseLargePages) || ++ !FLAG_IS_DEFAULT(LargePageSizeInBytes); ++ ++ UseLargePages = Solaris::mpss_sanity_check(warn_on_failure, &_large_page_size); ++ } ++} ++ ++bool os::Solaris::is_valid_page_size(size_t bytes) { ++ return _page_sizes.contains(bytes); ++} ++ ++bool os::Solaris::setup_large_pages(caddr_t start, size_t bytes, size_t align) { ++ assert(is_valid_page_size(align), SIZE_FORMAT " is not a valid page size", align); ++ assert(is_aligned((void*) start, align), ++ PTR_FORMAT " is not aligned to " SIZE_FORMAT, p2i((void*) start), align); ++ assert(is_aligned(bytes, align), ++ SIZE_FORMAT " is not aligned to " SIZE_FORMAT, bytes, align); ++ ++ // Signal to OS that we want large pages for addresses ++ // from addr, addr + bytes ++ struct memcntl_mha mpss_struct; ++ mpss_struct.mha_cmd = MHA_MAPSIZE_VA; ++ mpss_struct.mha_pagesize = align; ++ mpss_struct.mha_flags = 0; ++ // Upon successful completion, memcntl() returns 0 ++ if (memcntl(start, bytes, MC_HAT_ADVISE, (caddr_t) &mpss_struct, 0, 0)) { ++ debug_only(warning("Attempt to use MPSS failed.")); ++ return false; ++ } ++ return true; ++} ++ ++char* os::pd_reserve_memory_special(size_t size, size_t alignment, size_t page_size, char* addr, bool exec) { ++ fatal("os::reserve_memory_special should not be called on Solaris."); ++ return NULL; ++} ++ ++bool os::pd_release_memory_special(char* base, size_t bytes) { ++ fatal("os::release_memory_special should not be called on Solaris."); ++ return false; ++} ++ ++size_t os::large_page_size() { ++ return _large_page_size; ++} ++ ++// MPSS allows application to commit large page memory on demand; with ISM ++// the entire memory region must be allocated as shared memory. ++bool os::can_commit_large_page_memory() { ++ return true; ++} ++ ++bool os::can_execute_large_page_memory() { ++ return true; ++} ++ ++// Interface for setting lwp priorities. We are using T2 libthread, ++// which forces the use of bound threads, so all of our threads will ++// be assigned to real lwp's. Using the thr_setprio function is ++// meaningless in this mode so we must adjust the real lwp's priority. ++// The routines below implement the getting and setting of lwp priorities. ++// ++// Note: There are three priority scales used on Solaris. Java priorities ++// which range from 1 to 10, libthread "thr_setprio" scale which range ++// from 0 to 127, and the current scheduling class of the process we ++// are running in. This is typically from -60 to +60. ++// The setting of the lwp priorities is done after a call to thr_setprio ++// so Java priorities are mapped to libthread priorities and we map from ++// the latter to lwp priorities. We don't keep priorities stored in ++// Java priorities since some of our worker threads want to set priorities ++// higher than all Java threads. ++// ++// For related information: ++// (1) man -s 2 priocntl ++// (2) man -s 4 priocntl ++// (3) man dispadmin ++// = librt.so ++// = libthread/common/rtsched.c - thrp_setlwpprio(). ++// = ps -cL ... to validate priority. ++// = sched_get_priority_min and _max ++// pthread_create ++// sched_setparam ++// pthread_setschedparam ++// ++// Assumptions: ++// + We assume that all threads in the process belong to the same ++// scheduling class. IE. a homogeneous process. ++// + Must be root or in IA group to change change "interactive" attribute. ++// Priocntl() will fail silently. The only indication of failure is when ++// we read-back the value and notice that it hasn't changed. ++// + Interactive threads enter the runq at the head, non-interactive at the tail. ++// + For RT, change timeslice as well. Invariant: ++// constant "priority integral" ++// Konst == TimeSlice * (60-Priority) ++// Given a priority, compute appropriate timeslice. ++// + Higher numerical values have higher priority. ++ ++// sched class attributes ++typedef struct { ++ int schedPolicy; // classID ++ int maxPrio; ++ int minPrio; ++} SchedInfo; ++ ++ ++static SchedInfo tsLimits, iaLimits, rtLimits, fxLimits; ++ ++#ifdef ASSERT ++static int ReadBackValidate = 1; ++#endif ++static int myClass = 0; ++static int myMin = 0; ++static int myMax = 0; ++static int myCur = 0; ++static bool priocntl_enable = false; ++ ++static const int criticalPrio = FXCriticalPriority; ++static int java_MaxPriority_to_os_priority = 0; // Saved mapping ++ ++ ++// lwp_priocntl_init ++// ++// Try to determine the priority scale for our process. ++// ++// Return errno or 0 if OK. ++// ++static int lwp_priocntl_init() { ++ int rslt; ++ pcinfo_t ClassInfo; ++ pcparms_t ParmInfo; ++ int i; ++ ++ if (!UseThreadPriorities) return 0; ++ ++ // If ThreadPriorityPolicy is 1, switch tables ++ if (ThreadPriorityPolicy == 1) { ++ for (i = 0; i < CriticalPriority+1; i++) ++ os::java_to_os_priority[i] = prio_policy1[i]; ++ } ++ if (UseCriticalJavaThreadPriority) { ++ // MaxPriority always maps to the FX scheduling class and criticalPrio. ++ // See set_native_priority() and set_lwp_class_and_priority(). ++ // Save original MaxPriority mapping in case attempt to ++ // use critical priority fails. ++ java_MaxPriority_to_os_priority = os::java_to_os_priority[MaxPriority]; ++ // Set negative to distinguish from other priorities ++ os::java_to_os_priority[MaxPriority] = -criticalPrio; ++ } ++ ++ // Get IDs for a set of well-known scheduling classes. ++ // TODO-FIXME: GETCLINFO returns the current # of classes in the ++ // the system. We should have a loop that iterates over the ++ // classID values, which are known to be "small" integers. ++ ++ strcpy(ClassInfo.pc_clname, "TS"); ++ ClassInfo.pc_cid = -1; ++ rslt = priocntl(P_ALL, 0, PC_GETCID, (caddr_t)&ClassInfo); ++ if (rslt < 0) return errno; ++ assert(ClassInfo.pc_cid != -1, "cid for TS class is -1"); ++ tsLimits.schedPolicy = ClassInfo.pc_cid; ++ tsLimits.maxPrio = ((tsinfo_t*)ClassInfo.pc_clinfo)->ts_maxupri; ++ tsLimits.minPrio = -tsLimits.maxPrio; ++ ++ strcpy(ClassInfo.pc_clname, "IA"); ++ ClassInfo.pc_cid = -1; ++ rslt = priocntl(P_ALL, 0, PC_GETCID, (caddr_t)&ClassInfo); ++ if (rslt < 0) return errno; ++ assert(ClassInfo.pc_cid != -1, "cid for IA class is -1"); ++ iaLimits.schedPolicy = ClassInfo.pc_cid; ++ iaLimits.maxPrio = ((iainfo_t*)ClassInfo.pc_clinfo)->ia_maxupri; ++ iaLimits.minPrio = -iaLimits.maxPrio; ++ ++ strcpy(ClassInfo.pc_clname, "RT"); ++ ClassInfo.pc_cid = -1; ++ rslt = priocntl(P_ALL, 0, PC_GETCID, (caddr_t)&ClassInfo); ++ if (rslt < 0) return errno; ++ assert(ClassInfo.pc_cid != -1, "cid for RT class is -1"); ++ rtLimits.schedPolicy = ClassInfo.pc_cid; ++ rtLimits.maxPrio = ((rtinfo_t*)ClassInfo.pc_clinfo)->rt_maxpri; ++ rtLimits.minPrio = 0; ++ ++ strcpy(ClassInfo.pc_clname, "FX"); ++ ClassInfo.pc_cid = -1; ++ rslt = priocntl(P_ALL, 0, PC_GETCID, (caddr_t)&ClassInfo); ++ if (rslt < 0) return errno; ++ assert(ClassInfo.pc_cid != -1, "cid for FX class is -1"); ++ fxLimits.schedPolicy = ClassInfo.pc_cid; ++ fxLimits.maxPrio = ((fxinfo_t*)ClassInfo.pc_clinfo)->fx_maxupri; ++ fxLimits.minPrio = 0; ++ ++ // Query our "current" scheduling class. ++ // This will normally be IA, TS or, rarely, FX or RT. ++ memset(&ParmInfo, 0, sizeof(ParmInfo)); ++ ParmInfo.pc_cid = PC_CLNULL; ++ rslt = priocntl(P_PID, P_MYID, PC_GETPARMS, (caddr_t)&ParmInfo); ++ if (rslt < 0) return errno; ++ myClass = ParmInfo.pc_cid; ++ ++ // We now know our scheduling classId, get specific information ++ // about the class. ++ ClassInfo.pc_cid = myClass; ++ ClassInfo.pc_clname[0] = 0; ++ rslt = priocntl((idtype)0, 0, PC_GETCLINFO, (caddr_t)&ClassInfo); ++ if (rslt < 0) return errno; ++ ++ memset(&ParmInfo, 0, sizeof(pcparms_t)); ++ ParmInfo.pc_cid = PC_CLNULL; ++ rslt = priocntl(P_PID, P_MYID, PC_GETPARMS, (caddr_t)&ParmInfo); ++ if (rslt < 0) return errno; ++ ++ if (ParmInfo.pc_cid == rtLimits.schedPolicy) { ++ myMin = rtLimits.minPrio; ++ myMax = rtLimits.maxPrio; ++ } else if (ParmInfo.pc_cid == iaLimits.schedPolicy) { ++ iaparms_t *iaInfo = (iaparms_t*)ParmInfo.pc_clparms; ++ myMin = iaLimits.minPrio; ++ myMax = iaLimits.maxPrio; ++ myMax = MIN2(myMax, (int)iaInfo->ia_uprilim); // clamp - restrict ++ } else if (ParmInfo.pc_cid == tsLimits.schedPolicy) { ++ tsparms_t *tsInfo = (tsparms_t*)ParmInfo.pc_clparms; ++ myMin = tsLimits.minPrio; ++ myMax = tsLimits.maxPrio; ++ myMax = MIN2(myMax, (int)tsInfo->ts_uprilim); // clamp - restrict ++ } else if (ParmInfo.pc_cid == fxLimits.schedPolicy) { ++ fxparms_t *fxInfo = (fxparms_t*)ParmInfo.pc_clparms; ++ myMin = fxLimits.minPrio; ++ myMax = fxLimits.maxPrio; ++ myMax = MIN2(myMax, (int)fxInfo->fx_uprilim); // clamp - restrict ++ } else { ++ return EINVAL; // no clue, punt ++ } ++ ++ priocntl_enable = true; // Enable changing priorities ++ return 0; ++} ++ ++#define IAPRI(x) ((iaparms_t *)((x).pc_clparms)) ++#define RTPRI(x) ((rtparms_t *)((x).pc_clparms)) ++#define TSPRI(x) ((tsparms_t *)((x).pc_clparms)) ++#define FXPRI(x) ((fxparms_t *)((x).pc_clparms)) ++ ++ ++// scale_to_lwp_priority ++// ++// Convert from the libthread "thr_setprio" scale to our current ++// lwp scheduling class scale. ++// ++static int scale_to_lwp_priority(int rMin, int rMax, int x) { ++ int v; ++ ++ if (x == 127) return rMax; // avoid round-down ++ v = (((x*(rMax-rMin)))/128)+rMin; ++ return v; ++} ++ ++ ++// set_lwp_class_and_priority ++int set_lwp_class_and_priority(int ThreadID, int lwpid, ++ int newPrio, int new_class, bool scale) { ++ int rslt; ++ int Actual, Expected, prv; ++ pcparms_t ParmInfo; // for GET-SET ++#ifdef ASSERT ++ pcparms_t ReadBack; // for readback ++#endif ++ ++ // Set priority via PC_GETPARMS, update, PC_SETPARMS ++ // Query current values. ++ // TODO: accelerate this by eliminating the PC_GETPARMS call. ++ // Cache "pcparms_t" in global ParmCache. ++ // TODO: elide set-to-same-value ++ ++ // If something went wrong on init, don't change priorities. ++ if (!priocntl_enable) { ++ return EINVAL; ++ } ++ ++ // If lwp hasn't started yet, just return ++ // the _start routine will call us again. ++ if (lwpid <= 0) { ++ return 0; ++ } ++ ++ memset(&ParmInfo, 0, sizeof(pcparms_t)); ++ ParmInfo.pc_cid = PC_CLNULL; ++ rslt = priocntl(P_LWPID, lwpid, PC_GETPARMS, (caddr_t)&ParmInfo); ++ if (rslt < 0) return errno; ++ ++ int cur_class = ParmInfo.pc_cid; ++ ParmInfo.pc_cid = (id_t)new_class; ++ ++ if (new_class == rtLimits.schedPolicy) { ++ rtparms_t *rtInfo = (rtparms_t*)ParmInfo.pc_clparms; ++ rtInfo->rt_pri = scale ? scale_to_lwp_priority(rtLimits.minPrio, ++ rtLimits.maxPrio, newPrio) ++ : newPrio; ++ rtInfo->rt_tqsecs = RT_NOCHANGE; ++ rtInfo->rt_tqnsecs = RT_NOCHANGE; ++ } else if (new_class == iaLimits.schedPolicy) { ++ iaparms_t* iaInfo = (iaparms_t*)ParmInfo.pc_clparms; ++ int maxClamped = MIN2(iaLimits.maxPrio, ++ cur_class == new_class ++ ? (int)iaInfo->ia_uprilim : iaLimits.maxPrio); ++ iaInfo->ia_upri = scale ? scale_to_lwp_priority(iaLimits.minPrio, ++ maxClamped, newPrio) ++ : newPrio; ++ iaInfo->ia_uprilim = cur_class == new_class ++ ? IA_NOCHANGE : (pri_t)iaLimits.maxPrio; ++ iaInfo->ia_mode = IA_NOCHANGE; ++ } else if (new_class == tsLimits.schedPolicy) { ++ tsparms_t* tsInfo = (tsparms_t*)ParmInfo.pc_clparms; ++ int maxClamped = MIN2(tsLimits.maxPrio, ++ cur_class == new_class ++ ? (int)tsInfo->ts_uprilim : tsLimits.maxPrio); ++ tsInfo->ts_upri = scale ? scale_to_lwp_priority(tsLimits.minPrio, ++ maxClamped, newPrio) ++ : newPrio; ++ tsInfo->ts_uprilim = cur_class == new_class ++ ? TS_NOCHANGE : (pri_t)tsLimits.maxPrio; ++ } else if (new_class == fxLimits.schedPolicy) { ++ fxparms_t* fxInfo = (fxparms_t*)ParmInfo.pc_clparms; ++ int maxClamped = MIN2(fxLimits.maxPrio, ++ cur_class == new_class ++ ? (int)fxInfo->fx_uprilim : fxLimits.maxPrio); ++ fxInfo->fx_upri = scale ? scale_to_lwp_priority(fxLimits.minPrio, ++ maxClamped, newPrio) ++ : newPrio; ++ fxInfo->fx_uprilim = cur_class == new_class ++ ? FX_NOCHANGE : (pri_t)fxLimits.maxPrio; ++ fxInfo->fx_tqsecs = FX_NOCHANGE; ++ fxInfo->fx_tqnsecs = FX_NOCHANGE; ++ } else { ++ return EINVAL; // no clue, punt ++ } ++ ++ rslt = priocntl(P_LWPID, lwpid, PC_SETPARMS, (caddr_t)&ParmInfo); ++ if (rslt < 0) return errno; ++ ++#ifdef ASSERT ++ // Sanity check: read back what we just attempted to set. ++ // In theory it could have changed in the interim ... ++ // ++ // The priocntl system call is tricky. ++ // Sometimes it'll validate the priority value argument and ++ // return EINVAL if unhappy. At other times it fails silently. ++ // Readbacks are prudent. ++ ++ if (!ReadBackValidate) return 0; ++ ++ memset(&ReadBack, 0, sizeof(pcparms_t)); ++ ReadBack.pc_cid = PC_CLNULL; ++ rslt = priocntl(P_LWPID, lwpid, PC_GETPARMS, (caddr_t)&ReadBack); ++ assert(rslt >= 0, "priocntl failed"); ++ Actual = Expected = 0xBAD; ++ assert(ParmInfo.pc_cid == ReadBack.pc_cid, "cid's don't match"); ++ if (ParmInfo.pc_cid == rtLimits.schedPolicy) { ++ Actual = RTPRI(ReadBack)->rt_pri; ++ Expected = RTPRI(ParmInfo)->rt_pri; ++ } else if (ParmInfo.pc_cid == iaLimits.schedPolicy) { ++ Actual = IAPRI(ReadBack)->ia_upri; ++ Expected = IAPRI(ParmInfo)->ia_upri; ++ } else if (ParmInfo.pc_cid == tsLimits.schedPolicy) { ++ Actual = TSPRI(ReadBack)->ts_upri; ++ Expected = TSPRI(ParmInfo)->ts_upri; ++ } else if (ParmInfo.pc_cid == fxLimits.schedPolicy) { ++ Actual = FXPRI(ReadBack)->fx_upri; ++ Expected = FXPRI(ParmInfo)->fx_upri; ++ } ++#endif ++ ++ return 0; ++} ++ ++// Solaris only gives access to 128 real priorities at a time, ++// so we expand Java's ten to fill this range. This would be better ++// if we dynamically adjusted relative priorities. ++// ++// The ThreadPriorityPolicy option allows us to select 2 different ++// priority scales. ++// ++// ThreadPriorityPolicy=0 ++// Since the Solaris' default priority is MaximumPriority, we do not ++// set a priority lower than Max unless a priority lower than ++// NormPriority is requested. ++// ++// ThreadPriorityPolicy=1 ++// This mode causes the priority table to get filled with ++// linear values. NormPriority gets mapped to 50% of the ++// Maximum priority and so on. This will cause VM threads ++// to get unfair treatment against other Solaris processes ++// which do not explicitly alter their thread priorities. ++ ++int os::java_to_os_priority[CriticalPriority + 1] = { ++ -99999, // 0 Entry should never be used ++ ++ 0, // 1 MinPriority ++ 32, // 2 ++ 64, // 3 ++ ++ 96, // 4 ++ 127, // 5 NormPriority ++ 127, // 6 ++ ++ 127, // 7 ++ 127, // 8 ++ 127, // 9 NearMaxPriority ++ ++ 127, // 10 MaxPriority ++ ++ -criticalPrio // 11 CriticalPriority ++}; ++ ++OSReturn os::set_native_priority(Thread* thread, int newpri) { ++ OSThread* osthread = thread->osthread(); ++ ++ // Save requested priority in case the thread hasn't been started ++ osthread->set_native_priority(newpri); ++ ++ // Check for critical priority request ++ bool fxcritical = false; ++ if (newpri == -criticalPrio) { ++ fxcritical = true; ++ newpri = criticalPrio; ++ } ++ ++ assert(newpri >= MinimumPriority && newpri <= MaximumPriority, "bad priority mapping"); ++ if (!UseThreadPriorities) return OS_OK; ++ ++ int status = 0; ++ ++ if (!fxcritical) { ++ // Use thr_setprio only if we have a priority that thr_setprio understands ++ status = thr_setprio(thread->osthread()->thread_id(), newpri); ++ } ++ ++ int lwp_status = ++ set_lwp_class_and_priority(osthread->thread_id(), ++ osthread->lwp_id(), ++ newpri, ++ fxcritical ? fxLimits.schedPolicy : myClass, ++ !fxcritical); ++ if (lwp_status != 0 && fxcritical) { ++ // Try again, this time without changing the scheduling class ++ newpri = java_MaxPriority_to_os_priority; ++ lwp_status = set_lwp_class_and_priority(osthread->thread_id(), ++ osthread->lwp_id(), ++ newpri, myClass, false); ++ } ++ status |= lwp_status; ++ return (status == 0) ? OS_OK : OS_ERR; ++} ++ ++ ++OSReturn os::get_native_priority(const Thread* const thread, ++ int *priority_ptr) { ++ int p; ++ if (!UseThreadPriorities) { ++ *priority_ptr = NormalPriority; ++ return OS_OK; ++ } ++ int status = thr_getprio(thread->osthread()->thread_id(), &p); ++ if (status != 0) { ++ return OS_ERR; ++ } ++ *priority_ptr = p; ++ return OS_OK; ++} ++ ++//////////////////////////////////////////////////////////////////////////////// ++ ++// This does not do anything on Solaris. This is basically a hook for being ++// able to use structured exception handling (thread-local exception filters) on, e.g., Win32. ++void os::os_exception_wrapper(java_call_t f, JavaValue* value, ++ const methodHandle& method, JavaCallArguments* args, ++ JavaThread* thread) { ++ f(value, method, args, thread); ++} ++ ++void report_error(const char* file_name, int line_no, const char* title, ++ const char* format, ...); ++ ++// (Static) wrappers for the liblgrp API ++os::Solaris::lgrp_home_func_t os::Solaris::_lgrp_home; ++os::Solaris::lgrp_init_func_t os::Solaris::_lgrp_init; ++os::Solaris::lgrp_fini_func_t os::Solaris::_lgrp_fini; ++os::Solaris::lgrp_root_func_t os::Solaris::_lgrp_root; ++os::Solaris::lgrp_children_func_t os::Solaris::_lgrp_children; ++os::Solaris::lgrp_resources_func_t os::Solaris::_lgrp_resources; ++os::Solaris::lgrp_nlgrps_func_t os::Solaris::_lgrp_nlgrps; ++os::Solaris::lgrp_cookie_stale_func_t os::Solaris::_lgrp_cookie_stale; ++os::Solaris::lgrp_cookie_t os::Solaris::_lgrp_cookie = 0; ++ ++static address resolve_symbol_lazy(const char* name) { ++ address addr = (address) dlsym(RTLD_DEFAULT, name); ++ if (addr == NULL) { ++ // RTLD_DEFAULT was not defined on some early versions of 2.5.1 ++ addr = (address) dlsym(RTLD_NEXT, name); ++ } ++ return addr; ++} ++ ++static address resolve_symbol(const char* name) { ++ address addr = resolve_symbol_lazy(name); ++ if (addr == NULL) { ++ fatal("resolve_symbol failed (%s)", dlerror()); ++ } ++ return addr; ++} ++ ++void os::Solaris::libthread_init() { ++ address func = (address)dlsym(RTLD_DEFAULT, "_thr_suspend_allmutators"); ++ ++ lwp_priocntl_init(); ++ ++ // RTLD_DEFAULT was not defined on some early versions of 5.5.1 ++ if (func == NULL) { ++ func = (address) dlsym(RTLD_NEXT, "_thr_suspend_allmutators"); ++ // Guarantee that this VM is running on an new enough OS (5.6 or ++ // later) that it will have a new enough libthread.so. ++ guarantee(func != NULL, "libthread.so is too old."); ++ } ++ ++ int size; ++ void (*handler_info_func)(address *, int *); ++ handler_info_func = CAST_TO_FN_PTR(void (*)(address *, int *), resolve_symbol("thr_sighndlrinfo")); ++ handler_info_func(&handler_start, &size); ++ handler_end = handler_start + size; ++} ++ ++ ++bool os::Solaris::_synchronization_initialized; ++ ++void os::Solaris::synchronization_init() { ++ _synchronization_initialized = true; ++} ++ ++bool os::Solaris::liblgrp_init() { ++ void *handle = dlopen("liblgrp.so.1", RTLD_LAZY); ++ if (handle != NULL) { ++ os::Solaris::set_lgrp_home(CAST_TO_FN_PTR(lgrp_home_func_t, dlsym(handle, "lgrp_home"))); ++ os::Solaris::set_lgrp_init(CAST_TO_FN_PTR(lgrp_init_func_t, dlsym(handle, "lgrp_init"))); ++ os::Solaris::set_lgrp_fini(CAST_TO_FN_PTR(lgrp_fini_func_t, dlsym(handle, "lgrp_fini"))); ++ os::Solaris::set_lgrp_root(CAST_TO_FN_PTR(lgrp_root_func_t, dlsym(handle, "lgrp_root"))); ++ os::Solaris::set_lgrp_children(CAST_TO_FN_PTR(lgrp_children_func_t, dlsym(handle, "lgrp_children"))); ++ os::Solaris::set_lgrp_resources(CAST_TO_FN_PTR(lgrp_resources_func_t, dlsym(handle, "lgrp_resources"))); ++ os::Solaris::set_lgrp_nlgrps(CAST_TO_FN_PTR(lgrp_nlgrps_func_t, dlsym(handle, "lgrp_nlgrps"))); ++ os::Solaris::set_lgrp_cookie_stale(CAST_TO_FN_PTR(lgrp_cookie_stale_func_t, ++ dlsym(handle, "lgrp_cookie_stale"))); ++ ++ lgrp_cookie_t c = lgrp_init(LGRP_VIEW_CALLER); ++ set_lgrp_cookie(c); ++ return true; ++ } ++ return false; ++} ++ ++// int pset_getloadavg(psetid_t pset, double loadavg[], int nelem); ++typedef long (*pset_getloadavg_type)(psetid_t pset, double loadavg[], int nelem); ++static pset_getloadavg_type pset_getloadavg_ptr = NULL; ++ ++void init_pset_getloadavg_ptr(void) { ++ pset_getloadavg_ptr = ++ (pset_getloadavg_type)dlsym(RTLD_DEFAULT, "pset_getloadavg"); ++ if (pset_getloadavg_ptr == NULL) { ++ log_warning(os)("pset_getloadavg function not found"); ++ } ++} ++ ++int os::Solaris::_dev_zero_fd = -1; ++ ++// this is called _before_ the global arguments have been parsed ++void os::init(void) { ++ _initial_pid = getpid(); ++ ++ max_hrtime = first_hrtime = gethrtime(); ++ ++ init_random(1234567); ++ ++ int page_size = sysconf(_SC_PAGESIZE); ++ OSInfo::set_vm_page_size(page_size); ++ OSInfo::set_vm_allocation_granularity(page_size); ++ if (os::vm_page_size() <= 0) { ++ fatal("os_solaris.cpp: os::init: sysconf failed (%s)", os::strerror(errno)); ++ } ++ _page_sizes.add(os::vm_page_size()); ++ ++ Solaris::initialize_system_info(); ++ ++ int fd = ::open("/dev/zero", O_RDWR); ++ if (fd < 0) { ++ fatal("os::init: cannot open /dev/zero (%s)", os::strerror(errno)); ++ } else { ++ Solaris::set_dev_zero_fd(fd); ++ ++ // Close on exec, child won't inherit. ++ fcntl(fd, F_SETFD, FD_CLOEXEC); ++ } ++ ++ clock_tics_per_sec = CLK_TCK; ++ ++ // check if dladdr1() exists; dladdr1 can provide more information than ++ // dladdr for os::dll_address_to_function_name. It comes with SunOS 5.9 ++ // and is available on linker patches for 5.7 and 5.8. ++ // libdl.so must have been loaded, this call is just an entry lookup ++ void * hdl = dlopen("libdl.so", RTLD_NOW); ++ if (hdl) { ++ dladdr1_func = CAST_TO_FN_PTR(dladdr1_func_type, dlsym(hdl, "dladdr1")); ++ } ++ ++ // main_thread points to the thread that created/loaded the JVM. ++ main_thread = thr_self(); ++ ++ // dynamic lookup of functions that may not be available in our lowest ++ // supported Solaris release ++ void * handle = dlopen("libc.so.1", RTLD_LAZY); ++ if (handle != NULL) { ++ Solaris::_pthread_setname_np = // from 11.3 ++ (Solaris::pthread_setname_np_func_t)dlsym(handle, "pthread_setname_np"); ++ } ++ ++ // Shared Posix initialization ++ os::Posix::init(); ++} ++ ++// To install functions for atexit system call ++extern "C" { ++ static void perfMemory_exit_helper() { ++ perfMemory_exit(); ++ } ++} ++ ++// this is called _after_ the global arguments have been parsed ++jint os::init_2(void) { ++ Solaris::libthread_init(); ++ ++ if (UseNUMA) { ++ if (!Solaris::liblgrp_init()) { ++ FLAG_SET_ERGO(UseNUMA, false); ++ } else { ++ size_t lgrp_limit = os::numa_get_groups_num(); ++ int *lgrp_ids = NEW_C_HEAP_ARRAY(int, lgrp_limit, mtInternal); ++ size_t lgrp_num = os::numa_get_leaf_groups(lgrp_ids, lgrp_limit); ++ FREE_C_HEAP_ARRAY(int, lgrp_ids); ++ if (lgrp_num < 2) { ++ // There's only one locality group, disable NUMA ++ UseNUMA = false; ++ } ++ } ++ } ++ ++ // When NUMA requested, not-NUMA-aware allocations default to interleaving. ++ if (UseNUMA && !UseNUMAInterleaving) { ++ FLAG_SET_ERGO_IF_DEFAULT(UseNUMAInterleaving, true); ++ } ++ ++ if (PosixSignals::init() == JNI_ERR) { ++ return JNI_ERR; ++ } ++ ++ // initialize synchronization primitives ++ Solaris::synchronization_init(); ++ DEBUG_ONLY(os::set_mutex_init_done();) ++ ++ if (MaxFDLimit) { ++ // set the number of file descriptors to max. print out error ++ // if getrlimit/setrlimit fails but continue regardless. ++ struct rlimit nbr_files; ++ int status = getrlimit(RLIMIT_NOFILE, &nbr_files); ++ if (status != 0) { ++ log_info(os)("os::init_2 getrlimit failed: %s", os::strerror(errno)); ++ } else { ++ nbr_files.rlim_cur = nbr_files.rlim_max; ++ status = setrlimit(RLIMIT_NOFILE, &nbr_files); ++ if (status != 0) { ++ log_info(os)("os::init_2 setrlimit failed: %s", os::strerror(errno)); ++ } ++ } ++ } ++ ++ // Calculate theoretical max. size of Threads to guard gainst ++ // artificial out-of-memory situations, where all available address- ++ // space has been reserved by thread stacks. Default stack size is 1Mb. ++ size_t pre_thread_stack_size = (JavaThread::stack_size_at_create()) ? ++ JavaThread::stack_size_at_create() : (1*K*K); ++ assert(pre_thread_stack_size != 0, "Must have a stack"); ++ // Solaris has a maximum of 4Gb of user programs. Calculate the thread limit when ++ // we should start doing Virtual Memory banging. Currently when the threads will ++ // have used all but 200Mb of space. ++ size_t max_address_space = ((unsigned int)4 * K * K * K) - (200 * K * K); ++ Solaris::_os_thread_limit = max_address_space / pre_thread_stack_size; ++ ++ // at-exit methods are called in the reverse order of their registration. ++ // In Solaris 7 and earlier, atexit functions are called on return from ++ // main or as a result of a call to exit(3C). There can be only 32 of ++ // these functions registered and atexit() does not set errno. In Solaris ++ // 8 and later, there is no limit to the number of functions registered ++ // and atexit() sets errno. In addition, in Solaris 8 and later, atexit ++ // functions are called upon dlclose(3DL) in addition to return from main ++ // and exit(3C). ++ ++ if (PerfAllowAtExitRegistration) { ++ // only register atexit functions if PerfAllowAtExitRegistration is set. ++ // atexit functions can be delayed until process exit time, which ++ // can be problematic for embedded VM situations. Embedded VMs should ++ // call DestroyJavaVM() to assure that VM resources are released. ++ ++ // note: perfMemory_exit_helper atexit function may be removed in ++ // the future if the appropriate cleanup code can be added to the ++ // VM_Exit VMOperation's doit method. ++ if (atexit(perfMemory_exit_helper) != 0) { ++ warning("os::init2 atexit(perfMemory_exit_helper) failed"); ++ } ++ } ++ ++ // Init pset_loadavg function pointer ++ init_pset_getloadavg_ptr(); ++ ++ // Shared Posix initialization ++ os::Posix::init_2(); ++ ++ return JNI_OK; ++} ++ ++// This code originates from JDK's sysOpen and open64_w ++// from src/solaris/hpi/src/system_md.c ++ ++int os::open(const char *path, int oflag, int mode) { ++ if (strlen(path) > MAX_PATH - 1) { ++ errno = ENAMETOOLONG; ++ return -1; ++ } ++ int fd; ++ ++ fd = ::open64(path, oflag, mode); ++ if (fd == -1) return -1; ++ ++ // If the open succeeded, the file might still be a directory ++ { ++ struct stat64 buf64; ++ int ret = ::fstat64(fd, &buf64); ++ int st_mode = buf64.st_mode; ++ ++ if (ret != -1) { ++ if ((st_mode & S_IFMT) == S_IFDIR) { ++ errno = EISDIR; ++ ::close(fd); ++ return -1; ++ } ++ } else { ++ ::close(fd); ++ return -1; ++ } ++ } ++ ++ // All file descriptors that are opened in the JVM and not ++ // specifically destined for a subprocess should have the ++ // close-on-exec flag set. If we don't set it, then careless 3rd ++ // party native code might fork and exec without closing all ++ // appropriate file descriptors (e.g. as we do in closeDescriptors in ++ // UNIXProcess.c), and this in turn might: ++ // ++ // - cause end-of-file to fail to be detected on some file ++ // descriptors, resulting in mysterious hangs, or ++ // ++ // - might cause an fopen in the subprocess to fail on a system ++ // suffering from bug 1085341. ++ // ++ // (Yes, the default setting of the close-on-exec flag is a Unix ++ // design flaw) ++ // ++ // See: ++ // 1085341: 32-bit stdio routines should support file descriptors >255 ++ // 4843136: (process) pipe file descriptor from Runtime.exec not being closed ++ // 6339493: (process) Runtime.exec does not close all file descriptors on Solaris 9 ++ // ++#ifdef FD_CLOEXEC ++ { ++ int flags = ::fcntl(fd, F_GETFD); ++ if (flags != -1) { ++ ::fcntl(fd, F_SETFD, flags | FD_CLOEXEC); ++ } ++ } ++#endif ++ ++ return fd; ++} ++ ++// create binary file, rewriting existing file if required ++int os::create_binary_file(const char* path, bool rewrite_existing) { ++ int oflags = O_WRONLY | O_CREAT; ++ if (!rewrite_existing) { ++ oflags |= O_EXCL; ++ } ++ return ::open64(path, oflags, S_IREAD | S_IWRITE); ++} ++ ++// return current position of file pointer ++jlong os::current_file_offset(int fd) { ++ return (jlong)::lseek64(fd, (off64_t)0, SEEK_CUR); ++} ++ ++// move file pointer to the specified offset ++jlong os::seek_to_file_offset(int fd, jlong offset) { ++ return (jlong)::lseek64(fd, (off64_t)offset, SEEK_SET); ++} ++ ++// Map a block of memory. ++char* os::pd_map_memory(int fd, const char* file_name, size_t file_offset, ++ char *addr, size_t bytes, bool read_only, ++ bool allow_exec) { ++ int prot; ++ int flags; ++ ++ if (read_only) { ++ prot = PROT_READ; ++ flags = MAP_SHARED; ++ } else { ++ prot = PROT_READ | PROT_WRITE; ++ flags = MAP_PRIVATE; ++ } ++ ++ if (allow_exec) { ++ prot |= PROT_EXEC; ++ } ++ ++ if (addr != NULL) { ++ flags |= MAP_FIXED; ++ } ++ ++ char* mapped_address = (char*)mmap(addr, (size_t)bytes, prot, flags, ++ fd, file_offset); ++ if (mapped_address == MAP_FAILED) { ++ return NULL; ++ } ++ return mapped_address; ++} ++ ++ ++// Remap a block of memory. ++char* os::pd_remap_memory(int fd, const char* file_name, size_t file_offset, ++ char *addr, size_t bytes, bool read_only, ++ bool allow_exec) { ++ // same as map_memory() on this OS ++ return os::map_memory(fd, file_name, file_offset, addr, bytes, read_only, ++ allow_exec); ++} ++ ++ ++// Unmap a block of memory. ++bool os::pd_unmap_memory(char* addr, size_t bytes) { ++ return munmap(addr, bytes) == 0; ++} ++ ++const intptr_t thr_time_off = (intptr_t)(&((prusage_t *)(NULL))->pr_utime); ++const intptr_t thr_time_size = (intptr_t)(&((prusage_t *)(NULL))->pr_ttime) - ++ (intptr_t)(&((prusage_t *)(NULL))->pr_utime); ++ ++ ++// JVMTI & JVM monitoring and management support ++// The thread_cpu_time() and current_thread_cpu_time() are only ++// supported if is_thread_cpu_time_supported() returns true. ++// They are not supported on Solaris T1. ++ ++// current_thread_cpu_time(bool) and thread_cpu_time(Thread*, bool) ++// are used by JVM M&M and JVMTI to get user+sys or user CPU time ++// of a thread. ++// ++// current_thread_cpu_time() and thread_cpu_time(Thread *) ++// returns the fast estimate available on the platform. ++ ++// hrtime_t gethrvtime() return value includes ++// user time but does not include system time ++jlong os::current_thread_cpu_time() { ++ return (jlong) gethrvtime(); ++} ++ ++jlong os::thread_cpu_time(Thread *thread) { ++ // return user level CPU time only to be consistent with ++ // what current_thread_cpu_time returns. ++ // thread_cpu_time_info() must be changed if this changes ++ return os::thread_cpu_time(thread, false /* user time only */); ++} ++ ++jlong os::current_thread_cpu_time(bool user_sys_cpu_time) { ++ if (user_sys_cpu_time) { ++ return os::thread_cpu_time(Thread::current(), user_sys_cpu_time); ++ } else { ++ return os::current_thread_cpu_time(); ++ } ++} ++ ++jlong os::thread_cpu_time(Thread *thread, bool user_sys_cpu_time) { ++ char proc_name[64]; ++ int count; ++ prusage_t prusage; ++ jlong lwp_time; ++ int fd; ++ ++ sprintf(proc_name, "/proc/%d/lwp/%d/lwpusage", ++ getpid(), ++ thread->osthread()->lwp_id()); ++ fd = ::open(proc_name, O_RDONLY); ++ if (fd == -1) return -1; ++ ++ do { ++ count = ::pread(fd, ++ (void *)&prusage.pr_utime, ++ thr_time_size, ++ thr_time_off); ++ } while (count < 0 && errno == EINTR); ++ ::close(fd); ++ if (count < 0) return -1; ++ ++ if (user_sys_cpu_time) { ++ // user + system CPU time ++ lwp_time = (((jlong)prusage.pr_stime.tv_sec + ++ (jlong)prusage.pr_utime.tv_sec) * (jlong)1000000000) + ++ (jlong)prusage.pr_stime.tv_nsec + ++ (jlong)prusage.pr_utime.tv_nsec; ++ } else { ++ // user level CPU time only ++ lwp_time = ((jlong)prusage.pr_utime.tv_sec * (jlong)1000000000) + ++ (jlong)prusage.pr_utime.tv_nsec; ++ } ++ ++ return (lwp_time); ++} ++ ++void os::current_thread_cpu_time_info(jvmtiTimerInfo *info_ptr) { ++ info_ptr->max_value = ALL_64_BITS; // will not wrap in less than 64 bits ++ info_ptr->may_skip_backward = false; // elapsed time not wall time ++ info_ptr->may_skip_forward = false; // elapsed time not wall time ++ info_ptr->kind = JVMTI_TIMER_USER_CPU; // only user time is returned ++} ++ ++void os::thread_cpu_time_info(jvmtiTimerInfo *info_ptr) { ++ info_ptr->max_value = ALL_64_BITS; // will not wrap in less than 64 bits ++ info_ptr->may_skip_backward = false; // elapsed time not wall time ++ info_ptr->may_skip_forward = false; // elapsed time not wall time ++ info_ptr->kind = JVMTI_TIMER_USER_CPU; // only user time is returned ++} ++ ++bool os::is_thread_cpu_time_supported() { ++ return true; ++} ++ ++// System loadavg support. Returns -1 if load average cannot be obtained. ++// Return the load average for our processor set if the primitive exists ++// (Solaris 9 and later). Otherwise just return system wide loadavg. ++int os::loadavg(double loadavg[], int nelem) { ++ if (pset_getloadavg_ptr != NULL) { ++ return (*pset_getloadavg_ptr)(PS_MYID, loadavg, nelem); ++ } else { ++ return ::getloadavg(loadavg, nelem); ++ } ++} ++ ++//--------------------------------------------------------------------------------- ++ ++bool os::find(address addr, outputStream* st) { ++ Dl_info dlinfo; ++ memset(&dlinfo, 0, sizeof(dlinfo)); ++ if (dladdr(addr, &dlinfo) != 0) { ++ st->print(PTR_FORMAT ": ", p2i(addr)); ++ if (dlinfo.dli_sname != NULL && dlinfo.dli_saddr != NULL) { ++ st->print("%s+" PTR_FORMAT, dlinfo.dli_sname, ++ p2i(addr) - p2i(dlinfo.dli_saddr)); ++ } else if (dlinfo.dli_fbase != NULL) { ++ st->print("", p2i(addr) - p2i(dlinfo.dli_fbase)); ++ } else { ++ st->print(""); ++ } ++ if (dlinfo.dli_fname != NULL) { ++ st->print(" in %s", dlinfo.dli_fname); ++ } ++ if (dlinfo.dli_fbase != NULL) { ++ st->print(" at " PTR_FORMAT, p2i(dlinfo.dli_fbase)); ++ } ++ st->cr(); ++ ++ if (Verbose) { ++ // decode some bytes around the PC ++ address begin = clamp_address_in_page(addr-40, addr, os::vm_page_size()); ++ address end = clamp_address_in_page(addr+40, addr, os::vm_page_size()); ++ address lowest = (address) dlinfo.dli_sname; ++ if (!lowest) lowest = (address) dlinfo.dli_fbase; ++ if (begin < lowest) begin = lowest; ++ Dl_info dlinfo2; ++ if (dladdr(end, &dlinfo2) != 0 && dlinfo2.dli_saddr != dlinfo.dli_saddr ++ && end > dlinfo2.dli_saddr && dlinfo2.dli_saddr > begin) { ++ end = (address) dlinfo2.dli_saddr; ++ } ++ Disassembler::decode(begin, end, st); ++ } ++ return true; ++ } ++ return false; ++} ++ ++// Following function has been added to support HotSparc's libjvm.so running ++// under Solaris production JDK 1.2.2 / 1.3.0. These came from ++// src/solaris/hpi/native_threads in the EVM codebase. ++// ++// NOTE: This is no longer needed in the 1.3.1 and 1.4 production release ++// libraries and should thus be removed. We will leave it behind for a while ++// until we no longer want to able to run on top of 1.3.0 Solaris production ++// JDK. See 4341971. ++ ++#define STACK_SLACK 0x800 ++ ++extern "C" { ++ intptr_t sysThreadAvailableStackWithSlack() { ++ stack_t st; ++ intptr_t retval, stack_top; ++ retval = thr_stksegment(&st); ++ assert(retval == 0, "incorrect return value from thr_stksegment"); ++ assert((address)&st < (address)st.ss_sp, "Invalid stack base returned"); ++ assert((address)&st > (address)st.ss_sp-st.ss_size, "Invalid stack size returned"); ++ stack_top=(intptr_t)st.ss_sp-st.ss_size; ++ return ((intptr_t)&stack_top - stack_top - STACK_SLACK); ++ } ++} ++ ++// ObjectMonitor park-unpark infrastructure ... ++// ++// We implement Solaris and Linux PlatformEvents with the ++// obvious condvar-mutex-flag triple. ++// Another alternative that works quite well is pipes: ++// Each PlatformEvent consists of a pipe-pair. ++// The thread associated with the PlatformEvent ++// calls park(), which reads from the input end of the pipe. ++// Unpark() writes into the other end of the pipe. ++// The write-side of the pipe must be set NDELAY. ++// Unfortunately pipes consume a large # of handles. ++// Native solaris lwp_park() and lwp_unpark() work nicely, too. ++// Using pipes for the 1st few threads might be workable, however. ++// ++// park() is permitted to return spuriously. ++// Callers of park() should wrap the call to park() in ++// an appropriate loop. A litmus test for the correct ++// usage of park is the following: if park() were modified ++// to immediately return 0 your code should still work, ++// albeit degenerating to a spin loop. ++// ++// In a sense, park()-unpark() just provides more polite spinning ++// and polling with the key difference over naive spinning being ++// that a parked thread needs to be explicitly unparked() in order ++// to wake up and to poll the underlying condition. ++// ++// Assumption: ++// Only one parker can exist on an event, which is why we allocate ++// them per-thread. Multiple unparkers can coexist. ++// ++// _event transitions in park() ++// -1 => -1 : illegal ++// 1 => 0 : pass - return immediately ++// 0 => -1 : block; then set _event to 0 before returning ++// ++// _event transitions in unpark() ++// 0 => 1 : just return ++// 1 => 1 : just return ++// -1 => either 0 or 1; must signal target thread ++// That is, we can safely transition _event from -1 to either ++// 0 or 1. ++// ++// _event serves as a restricted-range semaphore. ++// -1 : thread is blocked, i.e. there is a waiter ++// 0 : neutral: thread is running or ready, ++// could have been signaled after a wait started ++// 1 : signaled - thread is running or ready ++// ++// Another possible encoding of _event would be with ++// explicit "PARKED" == 01b and "SIGNALED" == 10b bits. ++// ++// TODO-FIXME: add DTRACE probes for: ++// 1. Tx parks ++// 2. Ty unparks Tx ++// 3. Tx resumes from park ++ ++// JSR166 ++// ------------------------------------------------------- ++ ++// The solaris and linux implementations of park/unpark are fairly ++// conservative for now, but can be improved. They currently use a ++// mutex/condvar pair, plus _counter. ++// Park decrements _counter if > 0, else does a condvar wait. Unpark ++// sets count to 1 and signals condvar. Only one thread ever waits ++// on the condvar. Contention seen when trying to park implies that someone ++// is unparking you, so don't wait. And spurious returns are fine, so there ++// is no need to track notifications. ++ ++// Get the default path to the core file ++// Returns the length of the string ++int os::get_core_path(char* buffer, size_t bufferSize) { ++ const char* p = get_current_directory(buffer, bufferSize); ++ ++ if (p == NULL) { ++ assert(p != NULL, "failed to get current directory"); ++ return 0; ++ } ++ ++ jio_snprintf(buffer, bufferSize, "%s/core or core.%d", ++ p, current_process_id()); ++ ++ return strlen(buffer); ++} ++ ++bool os::supports_map_sync() { ++ return false; ++} ++ ++#ifndef PRODUCT ++void TestReserveMemorySpecial_test() { ++ // No tests available for this platform ++} ++#endif ++ ++bool os::start_debugging(char *buf, int buflen) { ++ int len = (int)strlen(buf); ++ char *p = &buf[len]; ++ ++ jio_snprintf(p, buflen-len, ++ "\n\n" ++ "Do you want to debug the problem?\n\n" ++ "To debug, run 'dbx - %d'; then switch to thread " INTX_FORMAT "\n" ++ "Enter 'yes' to launch dbx automatically (PATH must include dbx)\n" ++ "Otherwise, press RETURN to abort...", ++ os::current_process_id(), os::current_thread_id()); ++ ++ bool yes = os::message_box("Unexpected Error", buf); ++ ++ if (yes) { ++ // yes, user asked VM to launch debugger ++ jio_snprintf(buf, sizeof(buf), "dbx - %d", os::current_process_id()); ++ ++ os::fork_and_exec(buf); ++ yes = false; ++ } ++ return yes; ++} ++ ++void os::print_memory_mappings(char* addr, size_t bytes, outputStream* st) {} ++ ++#if INCLUDE_JFR ++ ++void os::jfr_report_memory_info() {} ++ ++#endif // INCLUDE_JFR ++ ++bool os::pd_dll_unload(void* libhandle, char* ebuf, int ebuflen) { ++ ++ if (ebuf && ebuflen > 0) { ++ ebuf[0] = '\0'; ++ ebuf[ebuflen - 1] = '\0'; ++ } ++ ++ bool res = (0 == ::dlclose(libhandle)); ++ if (!res) { ++ // error analysis when dlopen fails ++ const char* error_report = ::dlerror(); ++ if (error_report == nullptr) { ++ error_report = "dlerror returned no error description"; ++ } ++ if (ebuf != nullptr && ebuflen > 0) { ++ snprintf(ebuf, ebuflen - 1, "%s", error_report); ++ } ++ } ++ ++ return res; ++} // end: os::pd_dll_unload() +diff -urN /tmp/a/os_solaris.hpp b/src/hotspot/os/solaris/os_solaris.hpp +--- /tmp/a/os_solaris.hpp 1970-01-01 01:00:00.000000000 +0100 ++++ b/src/hotspot/os/solaris/os_solaris.hpp 2024-10-15 14:59:36.867931458 +0100 +@@ -0,0 +1,198 @@ ++/* ++ * Copyright (c) 1997, 2020, Oracle and/or its affiliates. All rights reserved. ++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. ++ * ++ * This code is free software; you can redistribute it and/or modify it ++ * under the terms of the GNU General Public License version 2 only, as ++ * published by the Free Software Foundation. ++ * ++ * This code is distributed in the hope that it will be useful, but WITHOUT ++ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or ++ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License ++ * version 2 for more details (a copy is included in the LICENSE file that ++ * accompanied this code). ++ * ++ * You should have received a copy of the GNU General Public License version ++ * 2 along with this work; if not, write to the Free Software Foundation, ++ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. ++ * ++ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA ++ * or visit www.oracle.com if you need additional information or have any ++ * questions. ++ * ++ */ ++ ++#ifndef OS_SOLARIS_OS_SOLARIS_HPP ++#define OS_SOLARIS_OS_SOLARIS_HPP ++ ++#include "runtime/os.hpp" ++ ++// Solaris_OS defines the interface to Solaris operating systems ++ ++// see thr_setprio(3T) for the basis of these numbers ++#define MinimumPriority 0 ++#define NormalPriority 64 ++#define MaximumPriority 127 ++ ++// FX/60 is critical thread class/priority on T4 ++#define FXCriticalPriority 60 ++ ++class os::Solaris { ++ friend class os; ++ ++ private: ++ ++ static bool _synchronization_initialized; ++ ++ typedef uintptr_t lgrp_cookie_t; ++ typedef id_t lgrp_id_t; ++ typedef int lgrp_rsrc_t; ++ typedef enum lgrp_view { ++ LGRP_VIEW_CALLER, // what's available to the caller ++ LGRP_VIEW_OS // what's available to operating system ++ } lgrp_view_t; ++ ++ typedef lgrp_id_t (*lgrp_home_func_t)(idtype_t idtype, id_t id); ++ typedef lgrp_cookie_t (*lgrp_init_func_t)(lgrp_view_t view); ++ typedef int (*lgrp_fini_func_t)(lgrp_cookie_t cookie); ++ typedef lgrp_id_t (*lgrp_root_func_t)(lgrp_cookie_t cookie); ++ typedef int (*lgrp_children_func_t)(lgrp_cookie_t cookie, lgrp_id_t parent, ++ lgrp_id_t *lgrp_array, uint_t lgrp_array_size); ++ typedef int (*lgrp_resources_func_t)(lgrp_cookie_t cookie, lgrp_id_t lgrp, ++ lgrp_id_t *lgrp_array, uint_t lgrp_array_size, ++ lgrp_rsrc_t type); ++ typedef int (*lgrp_nlgrps_func_t)(lgrp_cookie_t cookie); ++ typedef int (*lgrp_cookie_stale_func_t)(lgrp_cookie_t cookie); ++ ++ static lgrp_home_func_t _lgrp_home; ++ static lgrp_init_func_t _lgrp_init; ++ static lgrp_fini_func_t _lgrp_fini; ++ static lgrp_root_func_t _lgrp_root; ++ static lgrp_children_func_t _lgrp_children; ++ static lgrp_resources_func_t _lgrp_resources; ++ static lgrp_nlgrps_func_t _lgrp_nlgrps; ++ static lgrp_cookie_stale_func_t _lgrp_cookie_stale; ++ static lgrp_cookie_t _lgrp_cookie; ++ ++ // Large Page Support ++ static bool is_valid_page_size(size_t bytes); ++ static size_t page_size_for_alignment(size_t alignment); ++ static bool setup_large_pages(caddr_t start, size_t bytes, size_t align); ++ ++ typedef int (*pthread_setname_np_func_t)(pthread_t, const char*); ++ static pthread_setname_np_func_t _pthread_setname_np; ++ ++ public: ++ // Large Page Support--ISM. ++ static bool largepage_range(char* addr, size_t size); ++ ++ static address handler_start, handler_end; // start and end pc of thr_sighndlrinfo ++ ++ static bool valid_ucontext(Thread* thread, const ucontext_t* valid, const ucontext_t* suspect); ++ static const ucontext_t* get_valid_uc_in_signal_handler(Thread* thread, ++ const ucontext_t* uc); ++ ++ static intptr_t* ucontext_get_sp(const ucontext_t* uc); ++ // ucontext_get_fp() is only used by Solaris X86 (see note below) ++ static intptr_t* ucontext_get_fp(const ucontext_t* uc); ++ ++ static bool get_frame_at_stack_banging_point(JavaThread* thread, ucontext_t* uc, frame* fr); ++ ++ static void init_thread_fpu_state(void); ++ ++ protected: ++ // Solaris-specific interface goes here ++ static julong available_memory(); ++ static julong free_memory(); ++ static julong physical_memory() { return _physical_memory; } ++ static julong _physical_memory; ++ static void initialize_system_info(); ++ static int _dev_zero_fd; ++ static int get_dev_zero_fd() { return _dev_zero_fd; } ++ static void set_dev_zero_fd(int fd) { _dev_zero_fd = fd; } ++ static int commit_memory_impl(char* addr, size_t bytes, bool exec); ++ static int commit_memory_impl(char* addr, size_t bytes, ++ size_t alignment_hint, bool exec); ++ static char* mmap_chunk(char *addr, size_t size, int flags, int prot); ++ static char* anon_mmap(char* requested_addr, size_t bytes); ++ static bool mpss_sanity_check(bool warn, size_t * page_size); ++ ++ // Workaround for 4352906. thr_stksegment sometimes returns ++ // a bad value for the primordial thread's stack base when ++ // it is called more than one time. ++ // Workaround is to cache the initial value to avoid further ++ // calls to thr_stksegment. ++ // It appears that someone (Hotspot?) is trashing the user's ++ // proc_t structure (note that this is a system struct). ++ static address _main_stack_base; ++ ++ static void print_distro_info(outputStream* st); ++ static void print_libversion_info(outputStream* st); ++ ++ public: ++ static void libthread_init(); ++ static void synchronization_init(); ++ static bool liblgrp_init(); ++ ++ // alignment with os_posix means we use pthreads ++ static int mutex_lock(pthread_mutex_t *mx) { return pthread_mutex_lock(mx); } ++ static int mutex_trylock(pthread_mutex_t *mx) { return pthread_mutex_trylock(mx); } ++ static int mutex_unlock(pthread_mutex_t *mx) { return pthread_mutex_unlock(mx); } ++ static int mutex_init(pthread_mutex_t *mx) { return pthread_mutex_init(mx, NULL); } ++ static int mutex_destroy(pthread_mutex_t *mx) { return pthread_mutex_destroy(mx); } ++ ++ static int cond_timedwait(pthread_cond_t *cv, pthread_mutex_t *mx, timestruc_t *abst) { return pthread_cond_timedwait(cv, mx, abst); } ++ static int cond_wait(pthread_cond_t *cv, pthread_mutex_t *mx) { return pthread_cond_wait(cv, mx); } ++ static int cond_signal(pthread_cond_t *cv) { return pthread_cond_signal(cv); } ++ static int cond_broadcast(pthread_cond_t *cv) { return pthread_cond_broadcast(cv); } ++ static int cond_init(pthread_cond_t *cv) { return pthread_cond_init(cv, NULL); } ++ static int cond_destroy(pthread_cond_t *cv) { return pthread_cond_destroy(cv); } ++ ++ static bool synchronization_initialized() { return _synchronization_initialized; } ++ ++ static void set_lgrp_home(lgrp_home_func_t func) { _lgrp_home = func; } ++ static void set_lgrp_init(lgrp_init_func_t func) { _lgrp_init = func; } ++ static void set_lgrp_fini(lgrp_fini_func_t func) { _lgrp_fini = func; } ++ static void set_lgrp_root(lgrp_root_func_t func) { _lgrp_root = func; } ++ static void set_lgrp_children(lgrp_children_func_t func) { _lgrp_children = func; } ++ static void set_lgrp_resources(lgrp_resources_func_t func) { _lgrp_resources = func; } ++ static void set_lgrp_nlgrps(lgrp_nlgrps_func_t func) { _lgrp_nlgrps = func; } ++ static void set_lgrp_cookie_stale(lgrp_cookie_stale_func_t func) { _lgrp_cookie_stale = func; } ++ static void set_lgrp_cookie(lgrp_cookie_t cookie) { _lgrp_cookie = cookie; } ++ ++ static id_t lgrp_home(idtype_t type, id_t id) { return _lgrp_home != NULL ? _lgrp_home(type, id) : -1; } ++ static lgrp_cookie_t lgrp_init(lgrp_view_t view) { return _lgrp_init != NULL ? _lgrp_init(view) : 0; } ++ static int lgrp_fini(lgrp_cookie_t cookie) { return _lgrp_fini != NULL ? _lgrp_fini(cookie) : -1; } ++ static lgrp_id_t lgrp_root(lgrp_cookie_t cookie) { return _lgrp_root != NULL ? _lgrp_root(cookie) : -1; } ++ static int lgrp_children(lgrp_cookie_t cookie, lgrp_id_t parent, ++ lgrp_id_t *lgrp_array, uint_t lgrp_array_size) { ++ return _lgrp_children != NULL ? _lgrp_children(cookie, parent, lgrp_array, lgrp_array_size) : -1; ++ } ++ static int lgrp_resources(lgrp_cookie_t cookie, lgrp_id_t lgrp, ++ lgrp_id_t *lgrp_array, uint_t lgrp_array_size, ++ lgrp_rsrc_t type) { ++ return _lgrp_resources != NULL ? _lgrp_resources(cookie, lgrp, lgrp_array, lgrp_array_size, type) : -1; ++ } ++ ++ static int lgrp_nlgrps(lgrp_cookie_t cookie) { return _lgrp_nlgrps != NULL ? _lgrp_nlgrps(cookie) : -1; } ++ static int lgrp_cookie_stale(lgrp_cookie_t cookie) { ++ return _lgrp_cookie_stale != NULL ? _lgrp_cookie_stale(cookie) : -1; ++ } ++ static lgrp_cookie_t lgrp_cookie() { return _lgrp_cookie; } ++ ++ static sigset_t* unblocked_signals(); ++ static sigset_t* vm_signals(); ++ ++ // %%% Following should be promoted to os.hpp: ++ // Trace number of created threads ++ static jint _os_thread_limit; ++ static volatile jint _os_thread_count; ++ ++ static void correct_stack_boundaries_for_primordial_thread(Thread* thr); ++ ++ // Stack repair handling ++ ++ // none present ++ ++}; ++#endif // OS_SOLARIS_OS_SOLARIS_HPP +diff -urN /tmp/a/os_solaris.inline.hpp b/src/hotspot/os/solaris/os_solaris.inline.hpp +--- /tmp/a/os_solaris.inline.hpp 1970-01-01 01:00:00.000000000 +0100 ++++ b/src/hotspot/os/solaris/os_solaris.inline.hpp 2024-10-15 14:59:36.868029490 +0100 +@@ -0,0 +1,72 @@ ++/* ++ * Copyright (c) 1997, 2019, Oracle and/or its affiliates. All rights reserved. ++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. ++ * ++ * This code is free software; you can redistribute it and/or modify it ++ * under the terms of the GNU General Public License version 2 only, as ++ * published by the Free Software Foundation. ++ * ++ * This code is distributed in the hope that it will be useful, but WITHOUT ++ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or ++ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License ++ * version 2 for more details (a copy is included in the LICENSE file that ++ * accompanied this code). ++ * ++ * You should have received a copy of the GNU General Public License version ++ * 2 along with this work; if not, write to the Free Software Foundation, ++ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. ++ * ++ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA ++ * or visit www.oracle.com if you need additional information or have any ++ * questions. ++ * ++ */ ++ ++#ifndef OS_SOLARIS_OS_SOLARIS_INLINE_HPP ++#define OS_SOLARIS_OS_SOLARIS_INLINE_HPP ++ ++#include "os_solaris.hpp" ++ ++#include "runtime/os.hpp" ++#include "os_posix.inline.hpp" ++ ++// System includes ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++inline bool os::zero_page_read_protected() { ++ return true; ++} ++ ++inline bool os::uses_stack_guard_pages() { ++ return true; ++} ++ ++inline bool os::must_commit_stack_guard_pages() { ++ assert(uses_stack_guard_pages(), "sanity check"); ++ int r = thr_main() ; ++ guarantee (r == 0 || r == 1, "CR6501650 or CR6493689") ; ++ return r; ++} ++ ++ ++// Bang the shadow pages if they need to be touched to be mapped. ++inline void os::map_stack_shadow_pages(address sp) { ++} ++ ++// Trim-native support, stubbed out for now, may be enabled later ++inline bool os::can_trim_native_heap() { return false; } ++inline bool os::trim_native_heap(os::size_change_t* rss_change) { return false; } ++ ++////////////////////////////////////////////////////////////////////////////// ++//////////////////////////////////////////////////////////////////////////////// ++ ++inline bool os::numa_has_group_homing() { return true; } ++ ++#endif // OS_SOLARIS_OS_SOLARIS_INLINE_HPP +diff -urN /tmp/a/vmStructs_solaris.hpp b/src/hotspot/os/solaris/vmStructs_solaris.hpp +--- /tmp/a/vmStructs_solaris.hpp 1970-01-01 01:00:00.000000000 +0100 ++++ b/src/hotspot/os/solaris/vmStructs_solaris.hpp 2024-10-15 14:59:36.868118211 +0100 +@@ -0,0 +1,44 @@ ++/* ++ * Copyright (c) 2015, 2019, Oracle and/or its affiliates. All rights reserved. ++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. ++ * ++ * This code is free software; you can redistribute it and/or modify it ++ * under the terms of the GNU General Public License version 2 only, as ++ * published by the Free Software Foundation. ++ * ++ * This code is distributed in the hope that it will be useful, but WITHOUT ++ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or ++ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License ++ * version 2 for more details (a copy is included in the LICENSE file that ++ * accompanied this code). ++ * ++ * You should have received a copy of the GNU General Public License version ++ * 2 along with this work; if not, write to the Free Software Foundation, ++ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. ++ * ++ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA ++ * or visit www.oracle.com if you need additional information or have any ++ * questions. ++ * ++ */ ++ ++#ifndef OS_SOLARIS_VMSTRUCTS_SOLARIS_HPP ++#define OS_SOLARIS_VMSTRUCTS_SOLARIS_HPP ++ ++// These are the OS-specific fields, types and integer ++// constants required by the Serviceability Agent. This file is ++// referenced by vmStructs.cpp. ++ ++#define VM_STRUCTS_OS(nonstatic_field, static_field, unchecked_nonstatic_field, volatile_nonstatic_field, nonproduct_nonstatic_field, c2_nonstatic_field, unchecked_c1_static_field, unchecked_c2_static_field) \ ++ nonstatic_field(OSThread, _thread_id, OSThread::thread_id_t) ++ ++#define VM_TYPES_OS(declare_type, declare_toplevel_type, declare_oop_type, declare_integer_type, declare_unsigned_integer_type, declare_c1_toplevel_type, declare_c2_type, declare_c2_toplevel_type) \ ++ declare_unsigned_integer_type(OSThread::thread_id_t) ++ ++#define VM_INT_CONSTANTS_OS(declare_constant, declare_preprocessor_constant, declare_c1_constant, declare_c2_constant, declare_c2_preprocessor_constant) ++ ++#define VM_LONG_CONSTANTS_OS(declare_constant, declare_preprocessor_constant, declare_c1_constant, declare_c2_constant, declare_c2_preprocessor_constant) ++ ++#define VM_ADDRESSES_OS(declare_address, declare_preprocessor_address, declare_function) ++ ++#endif // OS_SOLARIS_VMSTRUCTS_SOLARIS_HPP diff --git a/build/openjdk21/patches/series b/build/openjdk21/patches/series new file mode 100644 index 0000000000..41ce1a1d98 --- /dev/null +++ b/build/openjdk21/patches/series @@ -0,0 +1,37 @@ +java-solaris-sparc.patch -R +restore_os_solaris.patch +restore_os_cpu_solaris_x86.patch +illumos-jline.patch +illumos-pollerprovider.patch +illumos-port-2.patch +illumos-port-3.patch +illumos-port-5.patch +illumos-port-6.patch +illumos-port-7.patch +illumos-port-10.patch +illumos-port-11.patch +illumos-port-12.patch +illumos-port-16.patch +illumos-port-17.patch +illumos-port-18.patch +illumos-port-19.patch +illumos-port-20.patch +illumos-port-21.patch +illumos-port-22.patch +illumos-port-23.patch +illumos-port-24.patch +illumos-port-25.patch +illumos-port-26.patch +illumos-port-27.patch +illumos-signal-1.patch +patch-make_autoconf_flags-cflags.m4 -p0 +patch-make_autoconf_jdk-options.m4 -p0 +patch-make_GenerateLinkOptData.gmk -p0 +patch-make_launcher_LauncherCommon.gmk -p0 +patch-make_lib_LibCommon.gmk -p0 +patch-src_hotspot_share_gc_g1_g1Analytics.cpp -p0 +tribblix-flags-cflags.patch -p0 +tribblix-flags-ldflags.patch -p0 +tribblix-flags-ldflags3.patch -p0 +omnios-headless.patch +fontpath.patch diff --git a/build/openjdk21/patches/tribblix-flags-cflags.patch b/build/openjdk21/patches/tribblix-flags-cflags.patch new file mode 100644 index 0000000000..49bcbcb557 --- /dev/null +++ b/build/openjdk21/patches/tribblix-flags-cflags.patch @@ -0,0 +1,27 @@ +--- make/autoconf/flags-cflags.m4~ Sun Apr 12 19:51:35 2020 ++++ make/autoconf/flags-cflags.m4 Sun Apr 12 21:38:33 2020 +@@ -597,8 +597,8 @@ + fi + + if test "x$TOOLCHAIN_TYPE" = xgcc; then +- TOOLCHAIN_CFLAGS_JVM="$TOOLCHAIN_CFLAGS_JVM -fstack-protector" +- TOOLCHAIN_CFLAGS_JDK="-pipe -fstack-protector" ++ TOOLCHAIN_CFLAGS_JVM="$TOOLCHAIN_CFLAGS_JVM" ++ TOOLCHAIN_CFLAGS_JDK="-pipe" + # reduce lib size on linux in link step, this needs also special compile flags + # do this on s390x also for libjvm (where serviceability agent is not supported) + if test "x$ENABLE_LINKTIME_GC" = xtrue; then +@@ -647,7 +647,12 @@ + + # CFLAGS C language level for JDK sources (hotspot only uses C++) + if test "x$TOOLCHAIN_TYPE" = xgcc || test "x$TOOLCHAIN_TYPE" = xclang || test "x$TOOLCHAIN_TYPE" = xxlc; then +- LANGSTD_CFLAGS="-std=c11" ++ if test "x$OPENJDK_TARGET_OS" = xsolaris; then ++ # illumos headers are confused by c11 ++ LANGSTD_CFLAGS="-std=gnu11" ++ else ++ LANGSTD_CFLAGS="-std=c11" ++ fi + elif test "x$TOOLCHAIN_TYPE" = xmicrosoft; then + LANGSTD_CFLAGS="-std:c11" + fi diff --git a/build/openjdk21/patches/tribblix-flags-ldflags.patch b/build/openjdk21/patches/tribblix-flags-ldflags.patch new file mode 100644 index 0000000000..a80bdd7824 --- /dev/null +++ b/build/openjdk21/patches/tribblix-flags-ldflags.patch @@ -0,0 +1,19 @@ +--- make/autoconf/flags-ldflags.m4~ Mon Apr 13 13:55:05 2020 ++++ make/autoconf/flags-ldflags.m4 Mon Apr 13 14:10:29 2020 +@@ -58,9 +58,13 @@ + # Setup basic LDFLAGS + if test "x$TOOLCHAIN_TYPE" = xgcc; then + # Add -z,defs, to forbid undefined symbols in object files. +- # add -z,relro (mark relocations read only) for all libs +- # add -z,now ("full relro" - more of the Global Offset Table GOT is marked read only) +- BASIC_LDFLAGS="-Wl,-z,defs -Wl,-z,relro -Wl,-z,now" ++ if test "x$OPENJDK_TARGET_OS" = xsolaris; then ++ BASIC_LDFLAGS="$BASIC_LDFLAGS -Wl,-z,defs" ++ else ++ # add relro (mark relocations read only) for all libs ++ # add -z,now ("full relro" - more of the Global Offset Table GOT is marked read only) ++ BASIC_LDFLAGS="-Wl,-z,defs -Wl,-z,relro -Wl,-z,now" ++ fi + # Linux : remove unused code+data in link step + if test "x$ENABLE_LINKTIME_GC" = xtrue; then + if test "x$OPENJDK_TARGET_CPU" = xs390x; then diff --git a/build/openjdk21/patches/tribblix-flags-ldflags3.patch b/build/openjdk21/patches/tribblix-flags-ldflags3.patch new file mode 100644 index 0000000000..f15e5f6265 --- /dev/null +++ b/build/openjdk21/patches/tribblix-flags-ldflags3.patch @@ -0,0 +1,21 @@ +--- make/autoconf/flags-ldflags.m4~ Wed Apr 15 14:26:49 2020 ++++ make/autoconf/flags-ldflags.m4 Wed Apr 15 14:28:01 2020 +@@ -137,11 +137,13 @@ + + # Setup LDFLAGS for linking executables + if test "x$TOOLCHAIN_TYPE" = xgcc; then +- EXECUTABLE_LDFLAGS="$EXECUTABLE_LDFLAGS -Wl,--allow-shlib-undefined" +- # Enabling pie on 32 bit builds prevents the JVM from allocating a continuous +- # java heap. +- if test "x$OPENJDK_TARGET_CPU_BITS" != "x32"; then +- EXECUTABLE_LDFLAGS="$EXECUTABLE_LDFLAGS -pie" ++ if test "x$OPENJDK_TARGET_OS" != xsolaris; then ++ EXECUTABLE_LDFLAGS="$EXECUTABLE_LDFLAGS -Wl,--allow-shlib-undefined" ++ # Enabling pie on 32 bit builds prevents the JVM from allocating a continuous ++ # java heap. ++ if test "x$OPENJDK_TARGET_CPU_BITS" != "x32"; then ++ EXECUTABLE_LDFLAGS="$EXECUTABLE_LDFLAGS -pie" ++ fi + fi + fi + diff --git a/build/openjdk21/test/.gitignore b/build/openjdk21/test/.gitignore new file mode 100644 index 0000000000..8e9e794863 --- /dev/null +++ b/build/openjdk21/test/.gitignore @@ -0,0 +1,2 @@ +*.class +*.jar diff --git a/build/openjdk21/test/Makefile b/build/openjdk21/test/Makefile new file mode 100644 index 0000000000..4106485243 --- /dev/null +++ b/build/openjdk21/test/Makefile @@ -0,0 +1,31 @@ +# +# This file and its contents are supplied under the terms of the +# Common Development and Distribution License ("CDDL"), version 1.0. +# You may only use this file in accordance with the terms of version +# 1.0 of the CDDL. +# +# A full copy of the text of the CDDL should have accompanied this +# source. A copy of the CDDL is also available via the Internet at +# http://www.illumos.org/license/CDDL. +# + +# Copyright 2021 OmniOS Community Edition (OmniOSce) Association. + +CLASSES = Test + +PROGS = $(CLASSES:%=%.class) $(CLASSES:%=%.jar) + +all: $(PROGS) + +%.class: %.java + javac $< + +%.jar: %.class + jar cvfe $@ $(<:.class=) $< + chmod +x $@ + +clean clobber: FRC + rm -f $(PROGS) + +FRC: + diff --git a/build/openjdk21/test/Test.java b/build/openjdk21/test/Test.java new file mode 100644 index 0000000000..589b6e3950 --- /dev/null +++ b/build/openjdk21/test/Test.java @@ -0,0 +1,66 @@ +/* + * This file and its contents are supplied under the terms of the + * Common Development and Distribution License ("CDDL"), version 1.0. + * You may only use this file in accordance with the terms of version + * 1.0 of the CDDL. + * + * A full copy of the text of the CDDL should have accompanied this + * source. A copy of the CDDL is also available via the Internet at + * http://www.illumos.org/license/CDDL. + * + * Copyright 2021 OmniOS Community Edition (OmniOSce) Association. + */ + +/* + * To build, run `make` in this directory. + * + * The resulting files can be tested in various ways: + * + * java Test + * java -jar Test.jar + * ./Test.jar (which will use the default system java) + */ + +import java.io.IOException; +import java.net.URL; +import java.net.URLConnection; +import java.awt.*; +import java.awt.Image; +import java.awt.image.BufferedImage; + +public class Test +{ + private static String url = "https://omnios.org/"; + + public static void main(String[] args) throws Exception + { + String version = System.getProperty("java.version"); + System.out.println("Runtime version: " + version); + + /* Fonts */ + + Font defaultFont = Font.decode(null); + System.out.println(defaultFont); + + GraphicsEnvironment g = + GraphicsEnvironment.getLocalGraphicsEnvironment(); + + String fonts[] = g.getAvailableFontFamilyNames(); + + System.out.println("Available fonts:"); + for (int i = 0; i < fonts.length; i++) + System.out.println(" " + fonts[i]); + + System.out.println("Rendering image"); + BufferedImage img = new BufferedImage(640, 480, + BufferedImage.TYPE_INT_ARGB); + img.getGraphics().drawString("omnios.org", 20, 20); + + /* TLS */ + System.out.println("Testing " + Test.url); + URLConnection conn = new URL(Test.url).openConnection(); + conn.connect(); + System.out.println("Connected."); + } +} + diff --git a/doc/baseline b/doc/baseline index ff6000d105..f1d148cbdb 100644 --- a/doc/baseline +++ b/doc/baseline @@ -543,6 +543,7 @@ omnios runtime/java r omnios runtime/java/jexec omnios runtime/java/openjdk11 omnios runtime/java/openjdk17 +omnios runtime/java/openjdk21 omnios runtime/java/openjdk8 omnios runtime/java/runtime64 r omnios runtime/perl