diff options
author | Simon Frankenberger <simon@fraho.eu> | 2019-01-27 23:25:17 +0100 |
---|---|---|
committer | Natanael Copa <ncopa@alpinelinux.org> | 2019-02-26 08:28:06 +0000 |
commit | 356b47d2f4120c743b616c561c93eb8d264dd4b5 (patch) | |
tree | 5fa482261d11e3dbd44da7eb7382d765a6fa2711 /testing | |
parent | 81e24164a9d217085c804aed62fe87d1d40c6e5d (diff) | |
download | aports-356b47d2f4120c743b616c561c93eb8d264dd4b5.tar.bz2 aports-356b47d2f4120c743b616c561c93eb8d264dd4b5.tar.xz |
testing/openjdk9: New aport
Diffstat (limited to 'testing')
-rw-r--r-- | testing/openjdk9/APKBUILD | 327 | ||||
-rw-r--r-- | testing/openjdk9/HelloWorld.java | 3 | ||||
-rw-r--r-- | testing/openjdk9/aarch64.patch | 10 | ||||
-rw-r--r-- | testing/openjdk9/arm.patch | 29 | ||||
-rw-r--r-- | testing/openjdk9/build.patch | 540 | ||||
-rw-r--r-- | testing/openjdk9/ppc64le.patch | 150 | ||||
-rw-r--r-- | testing/openjdk9/x86.patch | 130 |
7 files changed, 1189 insertions, 0 deletions
diff --git a/testing/openjdk9/APKBUILD b/testing/openjdk9/APKBUILD new file mode 100644 index 0000000000..a44299a4c9 --- /dev/null +++ b/testing/openjdk9/APKBUILD @@ -0,0 +1,327 @@ +# Contributor: Simon Frankenberger <simon-alpine@fraho.eu> +# Maintainer: Simon Frankenberger <simon-alpine@fraho.eu> +pkgname=openjdk9 +_pkgver=9.0.4+12 +pkgver=${_pkgver/+/.} +pkgrel=0 +pkgdesc="Oracle OpenJDK 9" +url="https://hg.openjdk.java.net/jdk-updates/jdk9u" +arch="all" +license="GPL-2.0 with Classpath" +makedepends="autoconf +bash +gawk +grep +make +openjdk8 +zip +alsa-lib-dev +cups-dev +freetype-dev +giflib-dev +lcms2-dev +libelf-dev +libexecinfo-dev +libffi-dev +libjpeg-turbo-dev +libx11-dev +libxext-dev +libxrender-dev +libxt-dev +libxtst-dev +linux-headers +zlib-dev +" +depends="$pkgname-jmods $pkgname-demos $pkgname-doc $pkgname-dbg $pkgname-jdk" # for the virtual openjdk9 package +subpackages="$pkgname-jmods:_jmods:noarch +$pkgname-demos:_demos:noarch +$pkgname-doc:_doc:noarch +$pkgname-dbg:_dbg +$pkgname-jre-headless:_jre_headless +$pkgname-jre:_jre +$pkgname-jdk:_jdk +" +source="jdk-$_pkgver-root.tar.bz2::http://hg.openjdk.java.net/jdk-updates/jdk9u/archive/jdk-$_pkgver.tar.bz2 +jdk-$_pkgver-corba.tar.bz2::http://hg.openjdk.java.net/jdk-updates/jdk9u/corba/archive/jdk-$_pkgver.tar.bz2 +jdk-$_pkgver-hotspot.tar.bz2::http://hg.openjdk.java.net/jdk-updates/jdk9u/hotspot/archive/jdk-$_pkgver.tar.bz2 +jdk-$_pkgver-jaxp.tar.bz2::http://hg.openjdk.java.net/jdk-updates/jdk9u/jaxp/archive/jdk-$_pkgver.tar.bz2 +jdk-$_pkgver-jaxws.tar.bz2::http://hg.openjdk.java.net/jdk-updates/jdk9u/jaxws/archive/jdk-$_pkgver.tar.bz2 +jdk-$_pkgver-jdk.tar.bz2::http://hg.openjdk.java.net/jdk-updates/jdk9u/jdk/archive/jdk-$_pkgver.tar.bz2 +jdk-$_pkgver-langtools.tar.bz2::http://hg.openjdk.java.net/jdk-updates/jdk9u/langtools/archive/jdk-$_pkgver.tar.bz2 +jdk-$_pkgver-nashorn.tar.bz2::http://hg.openjdk.java.net/jdk-updates/jdk9u/nashorn/archive/jdk-$_pkgver.tar.bz2 + +2019-01-05_config.sub::https://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.sub;h=3b4c7624b68d2d7f84618e1b5fa2badd43a48325;hb=286a38db91ea2dce1749ab7d1d9ea5ae344a16c1 +build.patch +aarch64.patch +arm.patch +ppc64le.patch +x86.patch + +HelloWorld.java +" +builddir="$srcdir/jdk9u-jdk-$_pkgver" + +_java_home="/usr/lib/jvm/java-9-openjdk" +ldpath="$_java_home/lib:$_java_home/lib/jli:$_java_home/lib/server" +sonameprefix="$pkgname:" + +# enable running the JTReg tests in check? +# see comment in that function for explanation +_run_jtreg=0 +if [ $_run_jtreg -ne 0 ]; then + makedepends="$makedepends java-jtreg" + checkdepends="$checkdepends ttf-freefont xvfb" +fi + + +unpack() { + if [ -z "$force" ]; then + verify + initdcheck + fi + mkdir -p "$srcdir" + msg "Unpacking root.tar.bz2" + tar -C "$srcdir" -jxf jdk-$_pkgver-root.tar.bz2 + + for i in corba hotspot jaxp jaxws jdk langtools nashorn; do + msg "Unpacking $i.tar.bz2" + mkdir $builddir/$i + tar -C $builddir/$i --strip-components=1 -jxf "$srcdir/jdk-$_pkgver-$i.tar.bz2" + done +} + +build() { + cd "$builddir" + + # update the config.sub file to detect alpine + cp $srcdir/2019-01-05_config.sub common/autoconf/build-aux/autoconf-config.sub + + # remove not compilable module (hotspot jdk.hotspot.agent) + # this needs libthread_db which is only provided by glibc + # + # haven't found any way to disable this module so just remove it. + rm -r hotspot/src/jdk.hotspot.agent + + if [ $_run_jtreg -ne 0 ]; then + _with_jtreg="--with-jtreg=/usr/share/java/jtreg" + else + _with_jtreg="--with-jtreg=no" + fi + + CFLAGS= CXXFLAGS= LDFLAGS= \ + bash ./configure \ + --openjdk-target=$CHOST \ + --prefix="$_java_home" \ + --sysconfdir=/etc \ + --mandir=/usr/share/man \ + --infodir=/usr/share/info \ + --localstatedir=/var \ + --with-extra-cflags="$CFLAGS" \ + --with-extra-cxxflags="$CXXFLAGS" \ + --with-extra-ldflags="$LDFLAGS" \ + --with-zlib=system \ + --with-libjpeg=system \ + --with-giflib=system \ + --with-libpng=system \ + --with-lcms=system \ + --with-jobs=${JOBS:-4} \ + --with-test-jobs=${JOBS:-4} \ + --with-native-debug-symbols=external \ + $_with_jtreg \ + --disable-warnings-as-errors \ + --disable-precompiled-headers \ + --enable-dtrace=no \ + --with-jvm-variants=server \ + --with-debug-level=release \ + --with-version-pre= \ + --with-version-opt=alpine-r${pkgrel} \ + --with-version-build=${_pkgver#*+} + + MAKEFLAGS= make jdk-image +} + +check() { + cd "$builddir" + + # compile and run a simple hello world + cp "$srcdir/HelloWorld.java" . + ./build/*-normal-server-release/images/jdk/bin/javac HelloWorld.java + ./build/*-normal-server-release/images/jdk/bin/java HelloWorld + + # run the gtest unittest suites + # they don't take long, DO NOT DISABLE THEM! + MAKEFLAGS= make test-hotspot-gtest + + # The jtreg tests take very, very long to finish and show some failures (9 - 12 on my machine, varying between runs) + # I think these are not critical and can be safely ignored. + # As the tests take too long, they are disabled by default. + # When updating this aport please let them run at least once on your machine to see if the failure count changes. + if [ $_run_jtreg -ne 0 ]; then + _logfile=$( mktemp -p "$builddir" ) + if [ -z "$DISPLAY" ]; then + Xvfb :99 & + _xvfb_pid=$! + DISPLAY=:99 + fi + MAKEFLAGS= DISPLAY=$DISPLAY make \ + run-test-tier1 \ + run-test-tier2 \ + run-test-tier3 \ + | tee "$_logfile" + msg "---------------------------------------" + msg "The build log can be found at $_logfile" + if [ -n "$_xvfb_pid" ]; then + kill $_xvfb_pid + fi + false + fi +} + +package() { + cd "$builddir" + + mkdir -p "$pkgdir/$_java_home" + cp -r build/*-normal-server-release/images/jdk/* "$pkgdir/$_java_home" +} + +_jmods() { + pkgdesc="Oracle OpenJDK 9 (jmods)" + depends="" + _fromroot="$pkgdir/$_java_home" + _toroot="$subpkgdir/$_java_home" + + mkdir -p "$_toroot" + mv "$_fromroot/jmods" "$_toroot" +} + +_demos() { + pkgdesc="Oracle OpenJDK 9 (demos)" + depends="" + _fromroot="$pkgdir/$_java_home" + _toroot="$subpkgdir/$_java_home" + + mkdir -p "$_toroot" + mv "$_fromroot/demo" "$_toroot" +} + +_doc() { + pkgdesc="Oracle OpenJDK 9 (Documentation)" + depends="" + _fromroot="$pkgdir/$_java_home" + _toroot="$subpkgdir/$_java_home" + + mkdir -p "$_toroot" + mv "$_fromroot/man" "$_toroot" +} + +_dbg() { + pkgdesc="Oracle OpenJDK 9 (debug)" + depends="$pkgname-jdk" + _fromroot="$pkgdir/$_java_home" + _toroot="$subpkgdir/$_java_home" + + mkdir -p "$_toroot/lib/server" + mkdir -p "$_toroot/lib/jli" + mv "$_fromroot"/lib/server/*.debuginfo "$_toroot"/lib/server + mv "$_fromroot"/lib/jli/*.debuginfo "$_toroot"/lib/jli + mv "$_fromroot"/lib/*.debuginfo "$_toroot"/lib +} + +_jre_headless() { + pkgdesc="Oracle OpenJDK 9 (JRE headless)" + depends="java-common java-cacerts" + _fromroot="$pkgdir/$_java_home" + _toroot="$subpkgdir/$_java_home" + + mkdir -p "$_toroot" + mv "$_fromroot/lib" "$_toroot" + + # move back unwanted libs + mkdir -p "$_fromroot/lib" + mv "$_toroot/lib/src.zip" \ + "$_toroot/lib/libawt_xawt.so" \ + "$_toroot/lib/libfontmanager.so" \ + "$_toroot/lib/libjavajpeg.so" \ + "$_toroot/lib/libjawt.so" \ + "$_toroot/lib/libjsoundalsa.so" \ + "$_toroot/lib/liblcms.so" \ + "$_toroot/lib/libsplashscreen.so" \ + "$_fromroot/lib" + + mkdir -p "$_toroot/bin" + for i in appletviewer \ + idlj \ + java \ + jjs \ + jrunscript \ + keytool \ + orbd \ + pack200 \ + rmid \ + rmiregistry \ + servertool \ + tnameserv \ + unpack200; do + mv "$_fromroot/bin/$i" "$_toroot/bin/$i" + done + + mv "$_fromroot/legal" "$_toroot" + mv "$_fromroot/conf" "$_toroot" + mv "$_fromroot/release" "$_toroot" + cp "$builddir/ASSEMBLY_EXCEPTION" "$_toroot" + cp "$builddir/LICENSE" "$_toroot" + cp "$builddir/README" "$_toroot" + + # symlink to shared cacerts store + rm "$_toroot/lib/security/cacerts" + ln -sf /etc/ssl/certs/java/cacerts \ + "$_toroot/lib/security/cacerts" + + # symlink for java-common to work (expects jre in $_java_home/jre) + ln -sf . "$_toroot/jre" +} + +_jre() { + pkgdesc="Oracle OpenJDK 9 (JRE)" + depends="$pkgname-jre-headless" + _fromroot="$pkgdir/$_java_home" + _toroot="$subpkgdir/$_java_home" + + mkdir -p "$_toroot/lib" + mv "$_fromroot/lib/libawt_xawt.so" \ + "$_fromroot/lib/libfontmanager.so" \ + "$_fromroot/lib/libjavajpeg.so" \ + "$_fromroot/lib/libjawt.so" \ + "$_fromroot/lib/libjsoundalsa.so" \ + "$_fromroot/lib/liblcms.so" \ + "$_fromroot/lib/libsplashscreen.so" \ + "$_toroot/lib" +} + +_jdk() { + pkgdesc="Oracle OpenJDK 9 (JDK)" + depends="$pkgname-jre" + _fromroot="$pkgdir/$_java_home" + _toroot="$subpkgdir/$_java_home" + + mkdir -p "$_toroot" + mv "$_fromroot/lib" "$_toroot" + mv "$_fromroot/bin" "$_toroot" + mv "$_fromroot/include" "$_toroot" +} + +sha512sums="cef3655ae7db657e6c81aa86587e451e58896bb6ee786495f6d757096334435b6a4de26ec3ec927da2487e135f09ce26414f8d6b9b9c508a28d3087be286b1ec jdk-9.0.4+12-root.tar.bz2 +455998437a9e3ff538b921025d57e19e6fb5148b3f124c9c427c3604689884d81b3ce5c9dbd93d88de26bf1b43ce76d75f75afd95e473a94973a668575e41748 jdk-9.0.4+12-corba.tar.bz2 +49d93764b13085a5626bec1c3d4e790f8748c24577a4e990e76bd1006721a5b8b9a256c40bf6419df4dda6f6390e457485f90c1b1101c010476a04d9056e9f16 jdk-9.0.4+12-hotspot.tar.bz2 +82f28586fd576cc01062e2ff37a917987775838910e4a5ecdfd096abec1c8d23028b77bfc87a38ada53bc30d71d89bde7408c1ae572a43c87a71ced64fd08d3a jdk-9.0.4+12-jaxp.tar.bz2 +459978a5e3ca21910781daed848229e043eea5bd82dcd20e9249934ec97a2a982126c6e37aac1a36719e3b73a5e6c8a92a50b63033149913614d8f3edfc0846e jdk-9.0.4+12-jaxws.tar.bz2 +259228d3f439dde239e38cdebb8c3bbb83804ab141d87a9c236310707de9c58cd78cd80ceb4c17755cc1048071f24462839988112c2698f7ec1453a8810610f2 jdk-9.0.4+12-jdk.tar.bz2 +ef3c70be906a4b0dd9c9195c88da045909ee3ef144941fb7b4495ed66b4162f481095cad87626d2bd38e5a62134b440223cd008dd6123b6b43c00e338610a692 jdk-9.0.4+12-langtools.tar.bz2 +848c6ece418e250561572ad704baeb565580098cfc5f849d4e1a3b41b916aae3487eb4d8d0b319f3a503d122ec064ed4de0678d06821c9a2bdb09c990e589c97 jdk-9.0.4+12-nashorn.tar.bz2 +74e3d868d766e605921542969dd2f646a8adec1b82181aaeb02b623a524cb9011e44c261d4e13ab24268c79c6bc1d260e62d41a928b1b402b186dc5676272e36 2019-01-05_config.sub +386490c3be4c9aa9dc4b73911bc0b97298ff8b1a50e53bd601f4d2a7b3e469f5b8e70e446b2bbe6876854302a373522b4819fde24c85eafc00f9524268096615 build.patch +3cc00d9b81377fdffb7f5b3f732a35cebd2575825d85df88330740903dd98de30fe75e69229811d52f2ef192c1df0715c2696edf31f64c8d7de4b502a16792e4 aarch64.patch +fa9fcc0c2f0972435b078669175c44f7d5d3cc29fbecb3e053d196c041ef0ff3feee8ec189a86fce0b35c5fd647ff71963a15e1e6fa50775cc2b6fa35d2ccf0a arm.patch +7244d0dfdb78d2f03ea992ef770ed888e2bd48f49e58438e7f0a763633c9aa8fc27b953d82c023f8f99ff23009a15031c99b2ef5550d277c63db684cd984ce8e ppc64le.patch +427c525e184e2a74f511aad8192dd411fe7fcc4e7a4dc03a3496fb030cec0177b3b520cbdd1c7700f6761a15ff2e5cce59c93d7079b744954122f684d34ce723 x86.patch +d1767dddd8e0956e25c0f77ed45c6fc86a1191bae1704a6dc33be490fd20eaa50461fe5c2a3349512059d555651e2eb41437dd3c1096c351e8ee68b4534a2579 HelloWorld.java" diff --git a/testing/openjdk9/HelloWorld.java b/testing/openjdk9/HelloWorld.java new file mode 100644 index 0000000000..0be813a190 --- /dev/null +++ b/testing/openjdk9/HelloWorld.java @@ -0,0 +1,3 @@ +public class HelloWorld { + public static void main(String[] args) { System.out.println("Hello World!"); } +} diff --git a/testing/openjdk9/aarch64.patch b/testing/openjdk9/aarch64.patch new file mode 100644 index 0000000000..d5b794d771 --- /dev/null +++ b/testing/openjdk9/aarch64.patch @@ -0,0 +1,10 @@ +--- old/hotspot/src/os_cpu/linux_aarch64/vm/os_linux_aarch64.cpp ++++ new/hotspot/src/os_cpu/linux_aarch64/vm/os_linux_aarch64.cpp +@@ -77,7 +77,6 @@ + # include <pwd.h> + # include <poll.h> + # include <ucontext.h> +-# include <fpu_control.h> + + #ifdef BUILTIN_SIM + #define REG_SP REG_RSP diff --git a/testing/openjdk9/arm.patch b/testing/openjdk9/arm.patch new file mode 100644 index 0000000000..157168a501 --- /dev/null +++ b/testing/openjdk9/arm.patch @@ -0,0 +1,29 @@ +--- old/hotspot/src/os_cpu/linux_arm/vm/os_linux_arm.cpp ++++ new/hotspot/src/os_cpu/linux_arm/vm/os_linux_arm.cpp +@@ -71,7 +71,6 @@ + # include <pwd.h> + # include <poll.h> + # include <ucontext.h> +-# include <fpu_control.h> + # include <asm/ptrace.h> + + #define SPELL_REG_SP "sp" +@@ -104,6 +103,18 @@ + #define ARM_REGS_IN_CONTEXT 31 + + #else ++ ++// Stupid hack as the origin if below doesnt compile with gcc 8.2.0: ++// ++// os_linux_arm.cpp:114:5: error: missing binary operator before token "(" ++// #if NGREG == 16 ++// ^~~~~ ++// ++// The NGREG is 18, so force it to that value. ++#ifdef NGREG ++# undef NGREG ++#endif ++#define NGREG 18 + + #if NGREG == 16 + // These definitions are based on the observation that until diff --git a/testing/openjdk9/build.patch b/testing/openjdk9/build.patch new file mode 100644 index 0000000000..a67d7167eb --- /dev/null +++ b/testing/openjdk9/build.patch @@ -0,0 +1,540 @@ +--- old/common/autoconf/build-aux/config.guess ++++ new/common/autoconf/build-aux/config.guess +@@ -30,6 +30,17 @@ + DIR=`dirname $0` + OUT=`. $DIR/autoconf-config.guess` + ++# config.guess doesn't identify systems running the musl C library, and will ++# instead return a string with a -gnu suffix. This block detects musl and ++# modifies the string to have a -musl suffix instead. ++echo $OUT | grep -- -linux- > /dev/null 2> /dev/null ++if test $? = 0; then ++ ldd_version=`ldd --version 2>&1 | head -1 | cut -f1 -d' '` ++ if [ x"${ldd_version}" = x"musl" ]; then ++ OUT=`echo $OUT | sed 's/-gnu/-musl/'` ++ fi ++fi ++ + # Test and fix solaris on x86_64 + echo $OUT | grep i386-pc-solaris > /dev/null 2> /dev/null + if test $? = 0; then +--- old/hotspot/make/lib/CompileJvm.gmk ++++ new/hotspot/make/lib/CompileJvm.gmk +@@ -135,6 +135,7 @@ + -DHOTSPOT_BUILD_USER='"$(USERNAME)"' \ + -DHOTSPOT_VM_DISTRO='"$(HOTSPOT_VM_DISTRO)"' \ + -DCPU='"$(OPENJDK_TARGET_CPU_VM_VERSION)"' \ ++ -DLIBC='"musl"' \ + # + + # -DDONT_USE_PRECOMPILED_HEADER will exclude all includes in precompiled.hpp. +--- old/hotspot/src/os/linux/vm/os_linux.cpp ++++ new/hotspot/src/os/linux/vm/os_linux.cpp +@@ -98,7 +98,6 @@ + # include <string.h> + # include <syscall.h> + # include <sys/sysinfo.h> +-# include <gnu/libc-version.h> + # include <sys/ipc.h> + # include <sys/shm.h> + # include <link.h> +@@ -496,6 +495,11 @@ + // detecting pthread library + + void os::Linux::libpthread_init() { ++#if !defined(__GLIBC__) && !defined(__UCLIBC__) ++ // Hard code Alpine Linux supported musl compatible settings ++ os::Linux::set_glibc_version("glibc 2.9"); ++ os::Linux::set_libpthread_version("NPTL"); ++#else + // Save glibc and pthread version strings. + #if !defined(_CS_GNU_LIBC_VERSION) || \ + !defined(_CS_GNU_LIBPTHREAD_VERSION) +@@ -513,6 +517,7 @@ + str = (char *)malloc(n, mtInternal); + confstr(_CS_GNU_LIBPTHREAD_VERSION, str, n); + os::Linux::set_libpthread_version(str); ++#endif + } + + ///////////////////////////////////////////////////////////////////////////// +@@ -2803,17 +2808,32 @@ + extern "C" JNIEXPORT void numa_warn(int number, char *where, ...) { } + extern "C" JNIEXPORT void numa_error(char *where) { } + ++static void* dlvsym_if_available(void* handle, const char* name, const char* version) { ++ typedef void* (*dlvsym_func_type)(void* handle, const char* name, const char* version); ++ static dlvsym_func_type dlvsym_func; ++ static bool initialized = false; + ++ if (!initialized) { ++ dlvsym_func = (dlvsym_func_type)dlsym(RTLD_NEXT, "dlvsym"); ++ initialized = true; ++ } ++ ++ if (dlvsym_func != NULL) { ++ void *f = dlvsym_func(handle, name, version); ++ if (f != NULL) { ++ return f; ++ } ++ } ++ ++ return dlsym(handle, name); ++} ++ + // If we are running with libnuma version > 2, then we should + // be trying to use symbols with versions 1.1 + // If we are running with earlier version, which did not have symbol versions, + // we should use the base version. + void* os::Linux::libnuma_dlsym(void* handle, const char *name) { +- void *f = dlvsym(handle, name, "libnuma_1.1"); +- if (f == NULL) { +- f = dlsym(handle, name); +- } +- return f; ++ return dlvsym_if_available(handle, name, "libnuma_1.1"); + } + + bool os::Linux::libnuma_init() { +--- old/hotspot/src/os/linux/vm/os_linux.inline.hpp ++++ new/hotspot/src/os/linux/vm/os_linux.inline.hpp +@@ -31,7 +31,7 @@ + + #include <unistd.h> + #include <sys/socket.h> +-#include <sys/poll.h> ++#include <poll.h> + #include <netdb.h> + + // File names are case-sensitive on windows only +--- old/hotspot/src/os_cpu/linux_x86/vm/os_linux_x86.cpp ++++ new/hotspot/src/os_cpu/linux_x86/vm/os_linux_x86.cpp +@@ -73,7 +73,6 @@ + # include <pwd.h> + # include <poll.h> + # include <ucontext.h> +-# include <fpu_control.h> + + #ifdef AMD64 + #define REG_SP REG_RSP +--- old/hotspot/src/share/vm/gc/shared/genCollectedHeap.cpp ++++ new/hotspot/src/share/vm/gc/shared/genCollectedHeap.cpp +@@ -1017,7 +1017,7 @@ + static ScratchBlock *removeSmallestScratch(ScratchBlock **prev_ptr) { + bool first = true; + size_t min_size = 0; // "first" makes this conceptually infinite. +- ScratchBlock **smallest_ptr, *smallest; ++ ScratchBlock **smallest_ptr = NULL, *smallest; + ScratchBlock *cur = *prev_ptr; + while (cur) { + assert(*prev_ptr == cur, "just checking"); +--- old/hotspot/src/share/vm/runtime/vm_version.cpp ++++ new/hotspot/src/share/vm/runtime/vm_version.cpp +@@ -263,7 +263,7 @@ + #endif + + #define INTERNAL_VERSION_SUFFIX VM_RELEASE ")" \ +- " for " OS "-" CPU FLOAT_ARCH_STR \ ++ " for " OS "-" CPU FLOAT_ARCH_STR LIBC \ + " JRE (" VERSION_STRING "), built on " __DATE__ " " __TIME__ \ + " by " XSTR(HOTSPOT_BUILD_USER) " with " HOTSPOT_BUILD_COMPILER + +--- old/hotspot/src/share/vm/utilities/globalDefinitions_gcc.hpp ++++ new/hotspot/src/share/vm/utilities/globalDefinitions_gcc.hpp +@@ -216,7 +216,7 @@ + #elif defined(__APPLE__) + inline int g_isnan(double f) { return isnan(f); } + #elif defined(LINUX) || defined(_ALLBSD_SOURCE) +-inline int g_isnan(float f) { return isnanf(f); } ++inline int g_isnan(float f) { return isnan(f); } + inline int g_isnan(double f) { return isnan(f); } + #else + #error "missing platform-specific definition here" +--- old/hotspot/test/runtime/StackGuardPages/exeinvoke.c ++++ new/hotspot/test/runtime/StackGuardPages/exeinvoke.c +@@ -33,6 +33,7 @@ + + #include <assert.h> + #include <jni.h> ++#include <jvm.h> + #include <alloca.h> + #include <signal.h> + #include <string.h> +@@ -91,6 +92,20 @@ + } + } + ++int get_java_stacksize () { ++ size_t stacksize; ++ pthread_attr_t attr; ++ JDK1_1InitArgs jdk_args; ++ ++ jdk_args.version = JNI_VERSION_1_1; ++ JNI_GetDefaultJavaVMInitArgs(&jdk_args); ++ if (jdk_args.javaStackSize <= 0) { ++ fprintf(stderr, "Test ERROR. Can't get a valid value for the default stacksize.\n"); ++ exit(7); ++ } ++ return jdk_args.javaStackSize; ++} ++ + void *run_java_overflow (void *p) { + JNIEnv *env; + jclass class_id; +@@ -254,13 +269,19 @@ + exit(7); + } + ++ int stack_size = get_java_stacksize(); + pthread_t thr; ++ pthread_attr_t thread_attr; + ++ pthread_attr_init(&thread_attr); ++ pthread_attr_setstacksize(&thread_attr, stack_size); ++ + if (argc > 1 && strcmp(argv[1], "test_java_overflow") == 0) { + printf("\nTesting JAVA_OVERFLOW\n"); + + printf("Testing stack guard page behaviour for other thread\n"); +- pthread_create (&thr, NULL, run_java_overflow, NULL); ++ ++ pthread_create (&thr, &thread_attr, run_java_overflow, NULL); + pthread_join (thr, NULL); + + printf("Testing stack guard page behaviour for initial thread\n"); +@@ -273,7 +294,7 @@ + printf("\nTesting NATIVE_OVERFLOW\n"); + + printf("Testing stack guard page behaviour for other thread\n"); +- pthread_create (&thr, NULL, run_native_overflow, NULL); ++ pthread_create (&thr, &thread_attr, run_native_overflow, NULL); + pthread_join (thr, NULL); + + printf("Testing stack guard page behaviour for initial thread\n"); +--- old/jdk/make/lib/CoreLibraries.gmk ++++ new/jdk/make/lib/CoreLibraries.gmk +@@ -339,6 +339,7 @@ + endif + + LIBJLI_CFLAGS += $(addprefix -I, $(LIBJLI_SRC_DIRS)) ++LIBJLI_CFLAGS += -DLIBC=\"musl\" + + ifneq ($(USE_EXTERNAL_LIBZ), true) + LIBJLI_CFLAGS += $(ZLIB_CPPFLAGS) +--- old/jdk/src/java.base/linux/native/libnet/linux_close.c ++++ new/jdk/src/java.base/linux/native/libnet/linux_close.c +@@ -58,7 +58,7 @@ + /* + * Signal to unblock thread + */ +-static int sigWakeup = (__SIGRTMAX - 2); ++static int sigWakeup; + + /* + * fdTable holds one entry per file descriptor, up to a certain +@@ -147,6 +147,7 @@ + /* + * Setup the signal handler + */ ++ sigWakeup = SIGRTMAX - 2; + sa.sa_handler = sig_wakeup; + sa.sa_flags = 0; + sigemptyset(&sa.sa_mask); +--- old/jdk/src/java.base/unix/native/include/jvm_md.h ++++ new/jdk/src/java.base/unix/native/include/jvm_md.h +@@ -65,7 +65,7 @@ + #include <sys/stat.h> + #include <fcntl.h> + #include <errno.h> +-#include <sys/signal.h> ++#include <signal.h> + + /* O Flags */ + +--- old/jdk/src/java.base/unix/native/libjava/childproc.c ++++ new/jdk/src/java.base/unix/native/libjava/childproc.c +@@ -237,7 +237,13 @@ + { + if (envp == NULL || (char **) envp == environ) { + execvp(file, (char **) argv); +- return; ++ // ENOEXEC indicates that the file header was not recognized. The musl C ++ // library does not implement the fallback to /bin/sh for that case, so fall ++ // through to the code below which implements that fallback using ++ // execve_with_shell_fallback. ++ if (errno != ENOEXEC) { ++ return; ++ } + } + + if (*file == '\0') { +--- old/jdk/src/java.base/unix/native/libjava/jdk_util_md.h ++++ new/jdk/src/java.base/unix/native/libjava/jdk_util_md.h +@@ -37,7 +37,7 @@ + #define ISNAND(d) isnan(d) + #elif defined(__linux__) || defined(_ALLBSD_SOURCE) + #include <math.h> +-#define ISNANF(f) isnanf(f) ++#define ISNANF(f) isnan(f) + #define ISNAND(d) isnan(d) + #elif defined(_AIX) + #include <math.h> +--- old/jdk/src/java.base/unix/native/libjli/java_md_solinux.c ++++ new/jdk/src/java.base/unix/native/libjli/java_md_solinux.c +@@ -241,6 +241,39 @@ + char *dmllp = NULL; + char *p; /* a utility pointer */ + ++#ifdef __linux ++#ifndef LIBC ++#error "LIBC not set" ++#endif ++ ++ if (strcmp(LIBC, "musl") == 0) { ++ /* ++ * The musl library loader requires LD_LIBRARY_PATH to be set in ++ * order to correctly resolve the dependency libjava.so has on libjvm.so. ++ * ++ * Specifically, it differs from glibc in the sense that even if ++ * libjvm.so has already been loaded it will not be considered a ++ * candidate for resolving the dependency unless the *full* path ++ * of the already loaded library matches the dependency being loaded. ++ * ++ * libjvm.so is being loaded by the launcher using a long path to ++ * dlopen, not just the basename of the library. Typically this ++ * is something like "../lib/server/libjvm.so". However, if/when ++ * libjvm.so later tries to dlopen libjava.so (which it does in ++ * order to get access to a few functions implemented in ++ * libjava.so) the musl loader will, as part of loading ++ * dependent libraries, try to load libjvm.so using only its ++ * basename "libjvm.so". Since this does not match the longer ++ * path path it was first loaded with, the already loaded ++ * library is not considered a candidate, and the loader will ++ * instead look for libjvm.so elsewhere. If it's not in ++ * LD_LIBRARY_PATH the dependency load will fail, and libjava.so ++ * will therefore fail as well. ++ */ ++ return JNI_TRUE; ++ } ++#endif ++ + #ifdef AIX + /* We always have to set the LIBPATH on AIX because ld doesn't support $ORIGIN. */ + return JNI_TRUE; +--- old/jdk/src/java.base/unix/native/libnet/net_util_md.h ++++ new/jdk/src/java.base/unix/native/libnet/net_util_md.h +@@ -27,7 +27,7 @@ + #define NET_UTILS_MD_H + + #include <netdb.h> +-#include <sys/poll.h> ++#include <poll.h> + #include <sys/socket.h> + + /************************************************************************ +--- old/jdk/src/java.base/unix/native/libnio/ch/NativeThread.c ++++ new/jdk/src/java.base/unix/native/libnio/ch/NativeThread.c +@@ -36,7 +36,7 @@ + #include <pthread.h> + #include <sys/signal.h> + /* Also defined in net/linux_close.c */ +- #define INTERRUPT_SIGNAL (__SIGRTMAX - 2) ++ #define INTERRUPT_SIGNAL (SIGRTMAX - 2) + #elif _AIX + #include <pthread.h> + #include <sys/signal.h> +--- old/jdk/src/java.desktop/unix/native/libawt_xawt/xawt/XToolkit.c ++++ new/jdk/src/java.desktop/unix/native/libawt_xawt/xawt/XToolkit.c +@@ -27,9 +27,6 @@ + #include <X11/Xutil.h> + #include <X11/Xos.h> + #include <X11/Xatom.h> +-#ifdef __linux__ +-#include <execinfo.h> +-#endif + + #include <jvm.h> + #include <jni.h> +@@ -786,26 +783,6 @@ + } + return ret; + } +- +-#ifdef __linux__ +-void print_stack(void) +-{ +- void *array[10]; +- size_t size; +- char **strings; +- size_t i; +- +- size = backtrace (array, 10); +- strings = backtrace_symbols (array, size); +- +- fprintf (stderr, "Obtained %zd stack frames.\n", size); +- +- for (i = 0; i < size; i++) +- fprintf (stderr, "%s\n", strings[i]); +- +- free (strings); +-} +-#endif + + Window get_xawt_root_shell(JNIEnv *env) { + static jclass classXRootWindow = NULL; +--- old/jdk/test/java/lang/ProcessBuilder/Basic.java ++++ new/jdk/test/java/lang/ProcessBuilder/Basic.java +@@ -391,8 +391,8 @@ + if (failed != 0) throw new Error("null PATH"); + } else if (action.equals("PATH search algorithm")) { + equal(System.getenv("PATH"), "dir1:dir2:"); +- check(new File("/bin/true").exists()); +- check(new File("/bin/false").exists()); ++ check(new File(TrueExe.path()).exists()); ++ check(new File(FalseExe.path()).exists()); + String[] cmd = {"prog"}; + ProcessBuilder pb1 = new ProcessBuilder(cmd); + ProcessBuilder pb2 = new ProcessBuilder(cmd); +@@ -433,13 +433,13 @@ + checkPermissionDenied(pb); + + // continue searching if EACCES +- copy("/bin/true", "dir2/prog"); ++ copy(TrueExe.path(), "dir2/prog"); + equal(run(pb).exitValue(), True.exitValue()); + new File("dir1/prog").delete(); + new File("dir2/prog").delete(); + + new File("dir2/prog").mkdirs(); +- copy("/bin/true", "dir1/prog"); ++ copy(TrueExe.path(), "dir1/prog"); + equal(run(pb).exitValue(), True.exitValue()); + + // Check empty PATH component means current directory. +@@ -455,10 +455,10 @@ + pb.command(command); + File prog = new File("./prog"); + // "Normal" binaries +- copy("/bin/true", "./prog"); ++ copy(TrueExe.path(), "./prog"); + equal(run(pb).exitValue(), + True.exitValue()); +- copy("/bin/false", "./prog"); ++ copy(FalseExe.path(), "./prog"); + equal(run(pb).exitValue(), + False.exitValue()); + prog.delete(); +@@ -513,12 +513,12 @@ + new File("dir2/prog").delete(); + new File("prog").delete(); + new File("dir3").mkdirs(); +- copy("/bin/true", "dir1/prog"); +- copy("/bin/false", "dir3/prog"); ++ copy(TrueExe.path(), "dir1/prog"); ++ copy(FalseExe.path(), "dir3/prog"); + pb.environment().put("PATH","dir3"); + equal(run(pb).exitValue(), True.exitValue()); +- copy("/bin/true", "dir3/prog"); +- copy("/bin/false", "dir1/prog"); ++ copy(TrueExe.path(), "dir3/prog"); ++ copy(FalseExe.path(), "dir1/prog"); + equal(run(pb).exitValue(), False.exitValue()); + + } finally { +@@ -615,6 +615,13 @@ + new File("/bin/false").exists()); + } + ++ static class BusyBox { ++ public static boolean is() { return is; } ++ private static final boolean is = ++ (! Windows.is() && ++ new File("/bin/busybox").exists()); ++ } ++ + static class UnicodeOS { + public static boolean is() { return is; } + private static final String osName = System.getProperty("os.name"); +@@ -653,6 +660,45 @@ + } + } + ++ // On alpine linux, /bin/true and /bin/false are just links to /bin/busybox. ++ // Some tests copy /bin/true and /bin/false to files with a different filename. ++ // However, copying the busbox executable into a file with a different name ++ // won't result in the expected return codes. As workaround, we create ++ // executable files that can be copied and produce the exepected return ++ // values. We use this workaround, if we find the busybox executable. ++ ++ private static class TrueExe { ++ public static String path() { return path; } ++ private static final String path = path0(); ++ private static String path0(){ ++ if (!BusyBox.is()) { ++ return "/bin/true"; ++ } ++ else { ++ File trueExe = new File("true"); ++ setFileContents(trueExe, "#!/bin/true\n"); ++ trueExe.setExecutable(true); ++ return trueExe.getAbsolutePath(); ++ } ++ } ++ } ++ ++ private static class FalseExe { ++ public static String path() { return path; } ++ private static final String path = path0(); ++ private static String path0(){ ++ if (!BusyBox.is()) { ++ return "/bin/false"; ++ } ++ else { ++ File falseExe = new File("false"); ++ setFileContents(falseExe, "#!/bin/false\n"); ++ falseExe.setExecutable(true); ++ return falseExe.getAbsolutePath(); ++ } ++ } ++ } ++ + static class EnglishUnix { + private static final Boolean is = + (! Windows.is() && isEnglish("LANG") && isEnglish("LC_ALL")); +@@ -1956,7 +2002,7 @@ + //---------------------------------------------------------------- + try { + new File("suBdiR").mkdirs(); +- copy("/bin/true", "suBdiR/unliKely"); ++ copy(TrueExe.path(), "suBdiR/unliKely"); + final ProcessBuilder pb = + new ProcessBuilder(new String[]{"unliKely"}); + pb.environment().put("PATH", "suBdiR"); +--- old/jdk/test/java/lang/ProcessHandle/InfoTest.java ++++ new/jdk/test/java/lang/ProcessHandle/InfoTest.java +@@ -293,7 +293,14 @@ + } + if (info.command().isPresent()) { + String command = info.command().get(); +- String expected = Platform.isWindows() ? "sleep.exe" : "sleep"; ++ String expected = "sleep"; ++ if (Platform.isWindows()) { ++ expected = "sleep.exe"; ++ } else if (new File("/bin/busybox").exists()) { ++ // With busybox sleep is just a sym link to busybox. ++ // The busbox executable is seen as ProcessHandle.Info command. ++ expected = "busybox"; ++ } + Assert.assertTrue(command.endsWith(expected), "Command: expected: \'" + + expected + "\', actual: " + command); + +--- old/make/ReleaseFile.gmk ++++ new/make/ReleaseFile.gmk +@@ -50,6 +50,7 @@ + $(call info-file-item, "IMPLEMENTOR", "$(COMPANY_NAME)") + $(call info-file-item, "OS_NAME", "$(RELEASE_FILE_OS_NAME)") + $(call info-file-item, "OS_ARCH", "$(RELEASE_FILE_OS_ARCH)") ++ $(call info-file-item, "LIBC", "musl") + endef + + # Param 1 - The file containing the MODULES list diff --git a/testing/openjdk9/ppc64le.patch b/testing/openjdk9/ppc64le.patch new file mode 100644 index 0000000000..8995627304 --- /dev/null +++ b/testing/openjdk9/ppc64le.patch @@ -0,0 +1,150 @@ +--- old/hotspot/src/cpu/ppc/vm/macroAssembler_ppc.cpp ++++ new/hotspot/src/cpu/ppc/vm/macroAssembler_ppc.cpp +@@ -1292,7 +1292,11 @@ + // the safepoing polling page. + ucontext_t* uc = (ucontext_t*) ucontext; + // Set polling address. ++#if defined(__GLIBC__) || defined(__UCLIBC__) + address addr = (address)uc->uc_mcontext.regs->gpr[ra] + (ssize_t)ds; ++#else // Musl ++ address addr = (address)uc->uc_mcontext.gp_regs[ra] + (ssize_t) ds; ++#endif + if (polling_address_ptr != NULL) { + *polling_address_ptr = addr; + } +@@ -1313,15 +1317,24 @@ + int rb = inv_rb_field(instruction); + + // look up content of ra and rb in ucontext ++#if defined(__GLIBC__) || defined(__UCLIBC__) + address ra_val=(address)uc->uc_mcontext.regs->gpr[ra]; + long rb_val=(long)uc->uc_mcontext.regs->gpr[rb]; ++#else // Musl ++ address ra_val=(address)uc->uc_mcontext.gp_regs[ra]; ++ long rb_val=(long)uc->uc_mcontext.gp_regs[rb]; ++#endif + return os::is_memory_serialize_page(thread, ra_val+rb_val); + } else if (is_stw(instruction) || is_stwu(instruction)) { + int ra = inv_ra_field(instruction); + int d1 = inv_d1_field(instruction); + + // look up content of ra in ucontext ++#if defined(__GLIBC__) || defined(__UCLIBC__) + address ra_val=(address)uc->uc_mcontext.regs->gpr[ra]; ++#else // Musl ++ address ra_val=(address)uc->uc_mcontext.gp_regs[ra]; ++#endif + return os::is_memory_serialize_page(thread, ra_val+d1); + } else { + return false; +@@ -1384,11 +1397,20 @@ + || (is_stdu(instruction) && rs == 1)) { + int ds = inv_ds_field(instruction); + // return banged address ++#if defined(__GLIBC__) || defined(__UCLIBC__) + return ds+(address)uc->uc_mcontext.regs->gpr[ra]; ++#else // Musl ++ return ds+(address)uc->uc_mcontext.gp_regs[ra]; ++#endif + } else if (is_stdux(instruction) && rs == 1) { + int rb = inv_rb_field(instruction); ++#if defined(__GLIBC__) || defined(__UCLIBC__) + address sp = (address)uc->uc_mcontext.regs->gpr[1]; + long rb_val = (long)uc->uc_mcontext.regs->gpr[rb]; ++#else // Musl ++ address sp = (address)uc->uc_mcontext.gp_regs[1]; ++ long rb_val = (long)uc->uc_mcontext.gp_regs[rb]; ++#endif + return ra != 1 || rb_val >= 0 ? NULL // not a stack bang + : sp + rb_val; // banged address + } +--- old/hotspot/src/os_cpu/linux_ppc/vm/os_linux_ppc.cpp ++++ new/hotspot/src/os_cpu/linux_ppc/vm/os_linux_ppc.cpp +@@ -109,20 +109,34 @@ + // - if uc was filled by getcontext(), it is undefined - getcontext() does not fill + // it because the volatile registers are not needed to make setcontext() work. + // Hopefully it was zero'd out beforehand. ++#if defined(__GLIBC__) || defined(__UCLIBC__) + guarantee(uc->uc_mcontext.regs != NULL, "only use ucontext_get_pc in sigaction context"); + return (address)uc->uc_mcontext.regs->nip; ++#else // Musl ++ guarantee(uc->uc_mcontext.gp_regs != NULL, "only use ucontext_get_pc in sigaction context"); ++ return (address)uc->uc_mcontext.gp_regs[32]; ++#endif + } + + // modify PC in ucontext. + // Note: Only use this for an ucontext handed down to a signal handler. See comment + // in ucontext_get_pc. + void os::Linux::ucontext_set_pc(ucontext_t * uc, address pc) { ++#if defined(__GLIBC__) || defined(__UCLIBC__) + guarantee(uc->uc_mcontext.regs != NULL, "only use ucontext_set_pc in sigaction context"); + uc->uc_mcontext.regs->nip = (unsigned long)pc; ++#else // Musl ++ guarantee(uc->uc_mcontext.gp_regs != NULL, "only use ucontext_set_pc in sigaction context"); ++ uc->uc_mcontext.gp_regs[32] = (unsigned long)pc; ++#endif + } + + intptr_t* os::Linux::ucontext_get_sp(const ucontext_t * uc) { ++#if defined(__GLIBC__) || defined(__UCLIBC__) + return (intptr_t*)uc->uc_mcontext.regs->gpr[1/*REG_SP*/]; ++#else // Musl ++ return (intptr_t*)uc->uc_mcontext.gp_regs[1/*REG_SP*/]; ++#endif + } + + intptr_t* os::Linux::ucontext_get_fp(const ucontext_t * uc) { +@@ -252,7 +266,13 @@ + // 3.2.1 "Machine State Register"), however note that ISA notation for bit + // numbering is MSB 0, so for normal bit numbering (LSB 0) they come to be + // bits 33 and 34. It's not related to endianness, just a notation matter. ++#if defined(__GLIBC__) || defined(__UCLIBC__) + if (second_uc->uc_mcontext.regs->msr & 0x600000000) { ++#else // Musl ++ // why 33? ++ // see comment for glibc NGREG: "r0-r31, nip, msr, lr, etc." ++ if (second_uc->uc_mcontext.gp_regs[33] & 0x600000000) { ++#endif + if (TraceTraps) { + tty->print_cr("caught signal in transaction, " + "ignoring to jump to abort handler"); +@@ -557,6 +577,7 @@ + const ucontext_t* uc = (const ucontext_t*)context; + + st->print_cr("Registers:"); ++#if defined(__GLIBC__) || defined(__UCLIBC__) + st->print("pc =" INTPTR_FORMAT " ", uc->uc_mcontext.regs->nip); + st->print("lr =" INTPTR_FORMAT " ", uc->uc_mcontext.regs->link); + st->print("ctr=" INTPTR_FORMAT " ", uc->uc_mcontext.regs->ctr); +@@ -565,8 +586,18 @@ + st->print("r%-2d=" INTPTR_FORMAT " ", i, uc->uc_mcontext.regs->gpr[i]); + if (i % 3 == 2) st->cr(); + } ++#else // Musl ++ st->print("pc =" INTPTR_FORMAT " ", uc->uc_mcontext.gp_regs[32]); ++ st->print("lr =" INTPTR_FORMAT " ", uc->uc_mcontext.gp_regs[36]); ++ st->print("ctr=" INTPTR_FORMAT " ", uc->uc_mcontext.gp_regs[35]); + st->cr(); ++ for (int i = 0; i < 32; i++) { ++ st->print("r%-2d=" INTPTR_FORMAT " ", i, uc->uc_mcontext.gp_regs[i]); ++ if (i % 3 == 2) st->cr(); ++ } ++#endif + st->cr(); ++ st->cr(); + + intptr_t *sp = (intptr_t *)os::Linux::ucontext_get_sp(uc); + st->print_cr("Top of Stack: (sp=" PTR_FORMAT ")", p2i(sp)); +@@ -593,7 +624,11 @@ + // this is only for the "general purpose" registers + for (int i = 0; i < 32; i++) { + st->print("r%-2d=", i); ++#if defined(__GLIBC__) || defined(__UCLIBC__) + print_location(st, uc->uc_mcontext.regs->gpr[i]); ++#else // Musl ++ print_location(st, uc->uc_mcontext.gp_regs[i]); ++#endif + } + st->cr(); + } diff --git a/testing/openjdk9/x86.patch b/testing/openjdk9/x86.patch new file mode 100644 index 0000000000..2ee42325df --- /dev/null +++ b/testing/openjdk9/x86.patch @@ -0,0 +1,130 @@ +Only in old: build.patch +--- old/hotspot/src/os_cpu/linux_x86/vm/os_linux_x86.cpp ++++ new/hotspot/src/os_cpu/linux_x86/vm/os_linux_x86.cpp +@@ -88,6 +88,126 @@ + #define SPELL_REG_FP "ebp" + #endif // AMD64 + ++// ============================================================================== ++// Taken from glibc 2.28 ++// source: https://sourceware.org/git/?p=glibc.git;a=blob;f=sysdeps/x86/fpu_control.h;h=4cb98c5679b2897ff4e5826d228cba6be589e24d;hb=3c03baca37fdcb52c3881e653ca392bba7a99c2b ++// ============================================================================== ++#ifndef AMD64 ++/* FPU control word bits. x86 version. ++ Copyright (C) 1993-2018 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ Contributed by Olaf Flebbe. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library 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 ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ <http://www.gnu.org/licenses/>. */ ++ ++#ifndef _FPU_CONTROL_H ++#define _FPU_CONTROL_H 1 ++ ++/* Note that this file sets on x86-64 only the x87 FPU, it does not ++ touch the SSE unit. */ ++ ++/* Here is the dirty part. Set up your 387 through the control word ++ * (cw) register. ++ * ++ * 15-13 12 11-10 9-8 7-6 5 4 3 2 1 0 ++ * | reserved | IC | RC | PC | reserved | PM | UM | OM | ZM | DM | IM ++ * ++ * IM: Invalid operation mask ++ * DM: Denormalized operand mask ++ * ZM: Zero-divide mask ++ * OM: Overflow mask ++ * UM: Underflow mask ++ * PM: Precision (inexact result) mask ++ * ++ * Mask bit is 1 means no interrupt. ++ * ++ * PC: Precision control ++ * 11 - round to extended precision ++ * 10 - round to double precision ++ * 00 - round to single precision ++ * ++ * RC: Rounding control ++ * 00 - rounding to nearest ++ * 01 - rounding down (toward - infinity) ++ * 10 - rounding up (toward + infinity) ++ * 11 - rounding toward zero ++ * ++ * IC: Infinity control ++ * That is for 8087 and 80287 only. ++ * ++ * The hardware default is 0x037f which we use. ++ */ ++ ++#include <features.h> ++ ++/* masking of interrupts */ ++#define _FPU_MASK_IM 0x01 ++#define _FPU_MASK_DM 0x02 ++#define _FPU_MASK_ZM 0x04 ++#define _FPU_MASK_OM 0x08 ++#define _FPU_MASK_UM 0x10 ++#define _FPU_MASK_PM 0x20 ++ ++/* precision control */ ++#define _FPU_EXTENDED 0x300 /* libm requires double extended precision. */ ++#define _FPU_DOUBLE 0x200 ++#define _FPU_SINGLE 0x0 ++ ++/* rounding control */ ++#define _FPU_RC_NEAREST 0x0 /* RECOMMENDED */ ++#define _FPU_RC_DOWN 0x400 ++#define _FPU_RC_UP 0x800 ++#define _FPU_RC_ZERO 0xC00 ++ ++#define _FPU_RESERVED 0xF0C0 /* Reserved bits in cw */ ++ ++ ++/* The fdlibm code requires strict IEEE double precision arithmetic, ++ and no interrupts for exceptions, rounding to nearest. */ ++ ++#define _FPU_DEFAULT 0x037f ++ ++/* IEEE: same as above. */ ++#define _FPU_IEEE 0x037f ++ ++/* Type of the control word. */ ++typedef unsigned int fpu_control_t __attribute__ ((__mode__ (__HI__))); ++ ++/* Macros for accessing the hardware control word. "*&" is used to ++ work around a bug in older versions of GCC. __volatile__ is used ++ to support combination of writing the control register and reading ++ it back. Without __volatile__, the old value may be used for reading ++ back under compiler optimization. ++ ++ Note that the use of these macros is not sufficient anymore with ++ recent hardware nor on x86-64. Some floating point operations are ++ executed in the SSE/SSE2 engines which have their own control and ++ status register. */ ++#define _FPU_GETCW(cw) __asm__ __volatile__ ("fnstcw %0" : "=m" (*&cw)) ++#define _FPU_SETCW(cw) __asm__ __volatile__ ("fldcw %0" : : "m" (*&cw)) ++ ++/* Default control word set at startup. */ ++extern fpu_control_t __fpu_control; ++ ++#endif /* fpu_control.h */ ++ ++#endif // AMD64 ++// ============================================================================== ++// ============================================================================== ++// ============================================================================== ++ + address os::current_stack_pointer() { + #ifdef SPARC_WORKS + register void *esp; |