--- 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
