diff options
author | Waldemar Brodkorb <wbx@openadk.org> | 2014-06-17 19:10:16 +0200 |
---|---|---|
committer | Waldemar Brodkorb <wbx@openadk.org> | 2014-06-17 19:10:42 +0200 |
commit | dfecd740e315f8af5f122a8b9c63a056542ec4d1 (patch) | |
tree | cb34d2b6fdf1d6977ca66236b8f40979b3689088 | |
parent | 7fdf66e444a1973d060414a73f726569f096d922 (diff) |
fix openjdk7 build for glibc
-rw-r--r-- | package/openjdk7/Makefile | 3 | ||||
-rw-r--r-- | package/openjdk7/patches/openadk.patch | 6389 |
2 files changed, 32 insertions, 6360 deletions
diff --git a/package/openjdk7/Makefile b/package/openjdk7/Makefile index 18578561c..027309fbf 100644 --- a/package/openjdk7/Makefile +++ b/package/openjdk7/Makefile @@ -5,7 +5,7 @@ include $(TOPDIR)/rules.mk PKG_NAME:= openjdk7 PKG_VERSION:= 2.4.7 -PKG_RELEASE:= 5 +PKG_RELEASE:= 6 PKG_MD5SUM:= f6b28633b9978fadc724247cfc264ff0 PKG_DESCR:= java virtual machine PKG_SECTION:= dev/lang @@ -21,6 +21,7 @@ PKG_DEPENDS+= libpng giflib libgtk glib fontconfig PKG_URL:= http://openjdk.org/ PKG_SITES:= http://icedtea.classpath.org/download/source/ +PKG_BUILDDEP_UCLIBC:= libiconv-tiny DISTFILES:= icedtea-$(PKG_VERSION).tar.xz WRKDIST= ${WRKDIR}/icedtea-${PKG_VERSION} diff --git a/package/openjdk7/patches/openadk.patch b/package/openjdk7/patches/openadk.patch index 601640a92..16f4fae8c 100644 --- a/package/openjdk7/patches/openadk.patch +++ b/package/openjdk7/patches/openadk.patch @@ -1,6 +1,6 @@ diff -Nur icedtea-2.4.7.orig/Makefile.in icedtea-2.4.7/Makefile.in --- icedtea-2.4.7.orig/Makefile.in 2014-04-16 06:20:44.689988653 +0200 -+++ icedtea-2.4.7/Makefile.in 2014-05-01 13:34:58.421434811 +0200 ++++ icedtea-2.4.7/Makefile.in 2014-06-17 17:37:10.283965087 +0200 @@ -712,7 +712,7 @@ $(am__append_14) $(am__append_15) $(DISTRIBUTION_PATCHES) @@ -12,11 +12,11 @@ diff -Nur icedtea-2.4.7.orig/Makefile.in icedtea-2.4.7/Makefile.in patches/boot/demos.patch patches/boot/fphexconstants.patch \ diff -Nur icedtea-2.4.7.orig/patches/openadk.patch icedtea-2.4.7/patches/openadk.patch --- icedtea-2.4.7.orig/patches/openadk.patch 1970-01-01 01:00:00.000000000 +0100 -+++ icedtea-2.4.7/patches/openadk.patch 2014-05-15 15:52:54.503242117 +0200 -@@ -0,0 +1,7020 @@ ++++ icedtea-2.4.7/patches/openadk.patch 2014-06-17 17:42:10.926234673 +0200 +@@ -0,0 +1,691 @@ +diff -Nur openjdk.orig/hotspot/make/linux/makefiles/zeroshark.make openjdk/hotspot/make/linux/makefiles/zeroshark.make +--- openjdk.orig/hotspot/make/linux/makefiles/zeroshark.make 2014-02-20 19:51:45.000000000 +0100 -++++ openjdk/hotspot/make/linux/makefiles/zeroshark.make 2014-05-13 16:56:38.917714592 +0200 +++++ openjdk/hotspot/make/linux/makefiles/zeroshark.make 2014-06-17 17:39:28.697018938 +0200 +@@ -39,20 +39,20 @@ + + offsets_arm.s: mkoffsets @@ -44,7 +44,7 @@ diff -Nur icedtea-2.4.7.orig/patches/openadk.patch icedtea-2.4.7/patches/openadk + endif +diff -Nur openjdk.orig/hotspot/src/os/linux/vm/os_linux.cpp openjdk/hotspot/src/os/linux/vm/os_linux.cpp +--- openjdk.orig/hotspot/src/os/linux/vm/os_linux.cpp 2014-02-20 19:51:45.000000000 +0100 -++++ openjdk/hotspot/src/os/linux/vm/os_linux.cpp 2014-05-13 16:14:56.637091447 +0200 +++++ openjdk/hotspot/src/os/linux/vm/os_linux.cpp 2014-06-17 17:39:28.701018968 +0200 +@@ -112,7 +112,6 @@ + # include <string.h> + # include <syscall.h> @@ -99,6002 +99,9 @@ diff -Nur icedtea-2.4.7.orig/patches/openadk.patch icedtea-2.4.7/patches/openadk + } + + void os::pause() { -+diff -Nur openjdk.orig/hotspot/src/os/linux/vm/os_linux.cpp.orig openjdk/hotspot/src/os/linux/vm/os_linux.cpp.orig -+--- openjdk.orig/hotspot/src/os/linux/vm/os_linux.cpp.orig 1970-01-01 01:00:00.000000000 +0100 -++++ openjdk/hotspot/src/os/linux/vm/os_linux.cpp.orig 2014-02-20 19:51:45.000000000 +0100 -+@@ -0,0 +1,5989 @@ -++/* -++ * Copyright (c) 1999, 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. -++ * -++ */ -++ -++// no precompiled headers -++#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 "interpreter/interpreter.hpp" -++#include "jvm_linux.h" -++#include "memory/allocation.inline.hpp" -++#include "memory/filemap.hpp" -++#include "mutex_linux.inline.hpp" -++#include "oops/oop.inline.hpp" -++#include "os_share_linux.hpp" -++#include "prims/jniFastGetField.hpp" -++#include "prims/jvm.h" -++#include "prims/jvm_misc.hpp" -++#include "runtime/arguments.hpp" -++#include "runtime/extendedPC.hpp" -++#include "runtime/globals.hpp" -++#include "runtime/interfaceSupport.hpp" -++#include "runtime/init.hpp" -++#include "runtime/java.hpp" -++#include "runtime/javaCalls.hpp" -++#include "runtime/mutexLocker.hpp" -++#include "runtime/objectMonitor.hpp" -++#include "runtime/osThread.hpp" -++#include "runtime/perfMemory.hpp" -++#include "runtime/sharedRuntime.hpp" -++#include "runtime/statSampler.hpp" -++#include "runtime/stubRoutines.hpp" -++#include "runtime/threadCritical.hpp" -++#include "runtime/timer.hpp" -++#include "services/attachListener.hpp" -++#include "services/memTracker.hpp" -++#include "services/runtimeService.hpp" -++#include "thread_linux.inline.hpp" -++#include "utilities/decoder.hpp" -++#include "utilities/defaultStream.hpp" -++#include "utilities/events.hpp" -++#include "utilities/elfFile.hpp" -++#include "utilities/growableArray.hpp" -++#include "utilities/vmError.hpp" -++#ifdef TARGET_ARCH_x86 -++# include "assembler_x86.inline.hpp" -++# include "nativeInst_x86.hpp" -++#endif -++#ifdef TARGET_ARCH_sparc -++# include "assembler_sparc.inline.hpp" -++# include "nativeInst_sparc.hpp" -++#endif -++#ifdef TARGET_ARCH_zero -++# include "assembler_zero.inline.hpp" -++# include "nativeInst_zero.hpp" -++#endif -++#ifdef TARGET_ARCH_arm -++# include "assembler_arm.inline.hpp" -++# include "nativeInst_arm.hpp" -++#endif -++#ifdef TARGET_ARCH_ppc -++# include "assembler_ppc.inline.hpp" -++# include "nativeInst_ppc.hpp" -++#endif -++ -++// put OS-includes here -++# include <sys/types.h> -++# include <sys/mman.h> -++# include <sys/stat.h> -++# include <sys/select.h> -++# include <pthread.h> -++# include <signal.h> -++# include <errno.h> -++# include <dlfcn.h> -++# include <stdio.h> -++# include <unistd.h> -++# include <sys/resource.h> -++# include <pthread.h> -++# include <sys/stat.h> -++# include <sys/time.h> -++# include <sys/times.h> -++# include <sys/utsname.h> -++# include <sys/socket.h> -++# include <sys/wait.h> -++# include <pwd.h> -++# include <poll.h> -++# include <semaphore.h> -++# include <fcntl.h> -++# 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> -++# include <stdint.h> -++# include <inttypes.h> -++# include <sys/ioctl.h> -++ -++#define MAX_PATH (2 * K) -++ -++// for timer info max values which include all bits -++#define ALL_64_BITS CONST64(0xFFFFFFFFFFFFFFFF) -++ -++#define LARGEPAGES_BIT (1 << 6) -++ -++#ifndef EM_AARCH64 -++#define EM_AARCH64 183 /* ARM AARCH64 */ -++#endif -++ -++//////////////////////////////////////////////////////////////////////////////// -++// global variables -++julong os::Linux::_physical_memory = 0; -++ -++address os::Linux::_initial_thread_stack_bottom = NULL; -++uintptr_t os::Linux::_initial_thread_stack_size = 0; -++ -++int (*os::Linux::_clock_gettime)(clockid_t, struct timespec *) = NULL; -++int (*os::Linux::_pthread_getcpuclockid)(pthread_t, clockid_t *) = NULL; -++Mutex* os::Linux::_createThread_lock = NULL; -++pthread_t os::Linux::_main_thread; -++int os::Linux::_page_size = -1; -++const int os::Linux::_vm_default_page_size = (8 * K); -++bool os::Linux::_is_floating_stack = false; -++bool os::Linux::_is_NPTL = false; -++bool os::Linux::_supports_fast_thread_cpu_time = false; -++const char * os::Linux::_glibc_version = NULL; -++const char * os::Linux::_libpthread_version = NULL; -++ -++static jlong initial_time_count=0; -++ -++static int clock_tics_per_sec = 100; -++ -++// For diagnostics to print a message once. see run_periodic_checks -++static sigset_t check_signal_done; -++static bool check_signals = true;; -++ -++static pid_t _initial_pid = 0; -++ -++/* Signal number used to suspend/resume a thread */ -++ -++/* do not use any signal number less than SIGSEGV, see 4355769 */ -++static int SR_signum = SIGUSR2; -++sigset_t SR_sigset; -++ -++/* Used to protect dlsym() calls */ -++static pthread_mutex_t dl_mutex; -++ -++// Declarations -++static void unpackTime(timespec* absTime, bool isAbsolute, jlong time); -++ -++#ifdef JAVASE_EMBEDDED -++class MemNotifyThread: public Thread { -++ friend class VMStructs; -++ public: -++ virtual void run(); -++ -++ private: -++ static MemNotifyThread* _memnotify_thread; -++ int _fd; -++ -++ public: -++ -++ // Constructor -++ MemNotifyThread(int fd); -++ -++ // Tester -++ bool is_memnotify_thread() const { return true; } -++ -++ // Printing -++ char* name() const { return (char*)"Linux MemNotify Thread"; } -++ -++ // Returns the single instance of the MemNotifyThread -++ static MemNotifyThread* memnotify_thread() { return _memnotify_thread; } -++ -++ // Create and start the single instance of MemNotifyThread -++ static void start(); -++}; -++#endif // JAVASE_EMBEDDED -++ -++// utility functions -++ -++static int SR_initialize(); -++static int SR_finalize(); -++ -++julong os::available_memory() { -++ return Linux::available_memory(); -++} -++ -++julong os::Linux::available_memory() { -++ // values in struct sysinfo are "unsigned long" -++ struct sysinfo si; -++ sysinfo(&si); -++ -++ return (julong)si.freeram * si.mem_unit; -++} -++ -++julong os::physical_memory() { -++ return Linux::physical_memory(); -++} -++ -++julong os::allocatable_physical_memory(julong size) { -++#ifdef _LP64 -++ return size; -++#else -++ julong result = MIN2(size, (julong)3800*M); -++ if (!is_allocatable(result)) { -++ // See comments under solaris for alignment considerations -++ julong reasonable_size = (julong)2*G - 2 * os::vm_page_size(); -++ result = MIN2(size, reasonable_size); -++ } -++ return result; -++#endif // _LP64 -++} -++ -++//////////////////////////////////////////////////////////////////////////////// -++// environment support -++ -++bool os::getenv(const char* name, char* buf, int len) { -++ const char* val = ::getenv(name); -++ if (val != NULL && strlen(val) < (size_t)len) { -++ strcpy(buf, val); -++ return true; -++ } -++ if (len > 0) buf[0] = 0; // return a null string -++ return false; -++} -++ -++ -++// Return true if user is running as root. -++ -++bool os::have_special_privileges() { -++ static bool init = false; -++ static bool privileges = false; -++ if (!init) { -++ privileges = (getuid() != geteuid()) || (getgid() != getegid()); -++ init = true; -++ } -++ return privileges; -++} -++ -++ -++#ifndef SYS_gettid -++// i386: 224, ia64: 1105, amd64: 186, sparc 143 -++#ifdef __ia64__ -++#define SYS_gettid 1105 -++#elif __i386__ -++#define SYS_gettid 224 -++#elif __amd64__ -++#define SYS_gettid 186 -++#elif __sparc__ -++#define SYS_gettid 143 -++#else -++#error define gettid for the arch -++#endif -++#endif -++ -++// Cpu architecture string -++#if defined(ZERO) -++static char cpu_arch[] = ZERO_LIBARCH; -++#elif defined(IA64) -++static char cpu_arch[] = "ia64"; -++#elif defined(IA32) -++static char cpu_arch[] = "i386"; -++#elif defined(AMD64) -++static char cpu_arch[] = "amd64"; -++#elif defined(ARM) -++static char cpu_arch[] = "arm"; -++#elif defined(PPC) -++static char cpu_arch[] = "ppc"; -++#elif defined(SPARC) -++# ifdef _LP64 -++static char cpu_arch[] = "sparcv9"; -++# else -++static char cpu_arch[] = "sparc"; -++# endif -++#else -++#error Add appropriate cpu_arch setting -++#endif -++ -++ -++// pid_t gettid() -++// -++// Returns the kernel thread id of the currently running thread. Kernel -++// thread id is used to access /proc. -++// -++// (Note that getpid() on LinuxThreads returns kernel thread id too; but -++// on NPTL, it returns the same pid for all threads, as required by POSIX.) -++// -++pid_t os::Linux::gettid() { -++ int rslt = syscall(SYS_gettid); -++ if (rslt == -1) { -++ // old kernel, no NPTL support -++ return getpid(); -++ } else { -++ return (pid_t)rslt; -++ } -++} -++ -++// Most versions of linux have a bug where the number of processors are -++// determined by looking at the /proc file system. In a chroot environment, -++// the system call returns 1. This causes the VM to act as if it is -++// a single processor and elide locking (see is_MP() call). -++static bool unsafe_chroot_detected = false; -++static const char *unstable_chroot_error = "/proc file system not found.\n" -++ "Java may be unstable running multithreaded in a chroot " -++ "environment on Linux when /proc filesystem is not mounted."; -++ -++void os::Linux::initialize_system_info() { -++ set_processor_count(sysconf(_SC_NPROCESSORS_CONF)); -++ if (processor_count() == 1) { -++ pid_t pid = os::Linux::gettid(); -++ char fname[32]; -++ jio_snprintf(fname, sizeof(fname), "/proc/%d", pid); -++ FILE *fp = fopen(fname, "r"); -++ if (fp == NULL) { -++ unsafe_chroot_detected = true; -++ } else { -++ fclose(fp); -++ } -++ } -++ _physical_memory = (julong)sysconf(_SC_PHYS_PAGES) * (julong)sysconf(_SC_PAGESIZE); -++ assert(processor_count() > 0, "linux error"); -++} -++ -++void os::init_system_properties_values() { -++// char arch[12]; -++// sysinfo(SI_ARCHITECTURE, arch, sizeof(arch)); -++ -++ // The next steps are taken in the product version: -++ // -++ // Obtain the JAVA_HOME value from the location of libjvm[_g].so. -++ // This library should be located at: -++ // <JAVA_HOME>/jre/lib/<arch>/{client|server}/libjvm[_g].so. -++ // -++ // If "/jre/lib/" appears at the right place in the path, then we -++ // assume libjvm[_g].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/<arch>, -++ // then we append a fake suffix "hotspot/libjvm[_g].so" to this path so -++ // it looks like libjvm[_g].so is installed there -++ // <JAVA_HOME>/jre/lib/<arch>/hotspot/libjvm[_g].so. -++ // -++ // Otherwise exit. -++ // -++ // Important note: if the location of libjvm.so changes this -++ // code needs to be changed accordingly. -++ -++ // The next few definitions allow the code to be verbatim: -++#define malloc(n) (char*)NEW_C_HEAP_ARRAY(char, (n), mtInternal) -++#define getenv(n) ::getenv(n) -++ -++/* -++ * See ld(1): -++ * The linker uses the following search paths to locate required -++ * shared libraries: -++ * 1: ... -++ * ... -++ * 7: The default directories, normally /lib and /usr/lib. -++ */ -++#if defined(AMD64) || defined(_LP64) && (defined(SPARC) || defined(PPC) || defined(S390) || defined(AARCH64)) -++#define DEFAULT_LIBPATH "/usr/lib64:/lib64:/lib:/usr/lib" -++#else -++#define DEFAULT_LIBPATH "/lib:/usr/lib" -++#endif -++ -++#define EXTENSIONS_DIR "/lib/ext" -++#define ENDORSED_DIR "/lib/endorsed" -++#define REG_DIR "/usr/java/packages" -++ -++ { -++ /* sysclasspath, java_home, dll_dir */ -++ { -++ char *home_path; -++ char *dll_path; -++ char *pslash; -++ char buf[MAXPATHLEN]; -++ os::jvm_path(buf, sizeof(buf)); -++ -++ // Found the full path to libjvm.so. -++ // Now cut the path to <java_home>/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} */ -++ dll_path = malloc(strlen(buf) + 1); -++ if (dll_path == NULL) -++ return; -++ strcpy(dll_path, buf); -++ Arguments::set_dll_dir(dll_path); -++ -++ if (pslash != NULL) { -++ pslash = strrchr(buf, '/'); -++ if (pslash != NULL) { -++ *pslash = '\0'; /* get rid of /<arch> */ -++ pslash = strrchr(buf, '/'); -++ if (pslash != NULL) -++ *pslash = '\0'; /* get rid of /lib */ -++ } -++ } -++ -++ home_path = malloc(strlen(buf) + 1); -++ if (home_path == NULL) -++ return; -++ strcpy(home_path, buf); -++ Arguments::set_java_home(home_path); -++ -++ if (!set_boot_path('/', ':')) -++ return; -++ } -++ -++ /* -++ * Where to look for native libraries -++ * -++ * Note: Due to a legacy implementation, most of the library path -++ * is set in the launcher. This was to accomodate linking restrictions -++ * on legacy Linux 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/java/packages is added here. -++ * Eventually, all the library path setting will be done here. -++ */ -++ { -++ char *ld_library_path; -++ -++ /* -++ * Construct the invariant part of ld_library_path. Note that the -++ * space for the colon and the trailing null are provided by the -++ * nulls included by the sizeof operator (so actually we allocate -++ * a byte more than necessary). -++ */ -++ ld_library_path = (char *) malloc(sizeof(REG_DIR) + sizeof("/lib/") + -++ strlen(cpu_arch) + sizeof(DEFAULT_LIBPATH)); -++ sprintf(ld_library_path, REG_DIR "/lib/%s:" DEFAULT_LIBPATH, cpu_arch); -++ -++ /* -++ * Get the user setting of LD_LIBRARY_PATH, and prepended it. It -++ * should always exist (until the legacy problem cited above is -++ * addressed). -++ */ -++ char *v = getenv("LD_LIBRARY_PATH"); -++ if (v != NULL) { -++ char *t = ld_library_path; -++ /* That's +1 for the colon and +1 for the trailing '\0' */ -++ ld_library_path = (char *) malloc(strlen(v) + 1 + strlen(t) + 1); -++ sprintf(ld_library_path, "%s:%s", v, t); -++ } -++ Arguments::set_library_path(ld_library_path); -++ } -++ -++ /* -++ * Extensions directories. -++ * -++ * Note that the space for the colon and the trailing null are provided -++ * by the nulls included by the sizeof operator (so actually one byte more -++ * than necessary is allocated). -++ */ -++ { -++ char *buf = malloc(strlen(Arguments::get_java_home()) + -++ sizeof(EXTENSIONS_DIR) + sizeof(REG_DIR) + sizeof(EXTENSIONS_DIR)); -++ sprintf(buf, "%s" EXTENSIONS_DIR ":" REG_DIR EXTENSIONS_DIR, -++ Arguments::get_java_home()); -++ Arguments::set_ext_dirs(buf); -++ } -++ -++ /* Endorsed standards default directory. */ -++ { -++ char * buf; -++ buf = malloc(strlen(Arguments::get_java_home()) + sizeof(ENDORSED_DIR)); -++ sprintf(buf, "%s" ENDORSED_DIR, Arguments::get_java_home()); -++ Arguments::set_endorsed_dirs(buf); -++ } -++ } -++ -++#undef malloc -++#undef getenv -++#undef EXTENSIONS_DIR -++#undef ENDORSED_DIR -++ -++ // Done -++ return; -++} -++ -++//////////////////////////////////////////////////////////////////////////////// -++// breakpoint support -++ -++void os::breakpoint() { -++ BREAKPOINT; -++} -++ -++extern "C" void breakpoint() { -++ // use debugger to set breakpoint here -++} -++ -++//////////////////////////////////////////////////////////////////////////////// -++// signal support -++ -++debug_only(static bool signal_sets_initialized = false); -++static sigset_t unblocked_sigs, vm_sigs, allowdebug_blocked_sigs; -++ -++bool os::Linux::is_sig_ignored(int sig) { -++ struct sigaction oact; -++ sigaction(sig, (struct sigaction*)NULL, &oact); -++ void* ohlr = oact.sa_sigaction ? CAST_FROM_FN_PTR(void*, oact.sa_sigaction) -++ : CAST_FROM_FN_PTR(void*, oact.sa_handler); -++ if (ohlr == CAST_FROM_FN_PTR(void*, SIG_IGN)) -++ return true; -++ else -++ return false; -++} -++ -++void os::Linux::signal_sets_init() { -++ // Should also have an assertion stating we are still single-threaded. -++ assert(!signal_sets_initialized, "Already initialized"); -++ // Fill in signals that are necessarily unblocked for all threads in -++ // the VM. Currently, we unblock the following signals: -++ // SHUTDOWN{1,2,3}_SIGNAL: for shutdown hooks support (unless over-ridden -++ // by -Xrs (=ReduceSignalUsage)); -++ // BREAK_SIGNAL which is unblocked only by the VM thread and blocked by all -++ // other threads. The "ReduceSignalUsage" boolean tells us not to alter -++ // the dispositions or masks wrt these signals. -++ // Programs embedding the VM that want to use the above signals for their -++ // own purposes must, at this time, use the "-Xrs" option to prevent -++ // interference with shutdown hooks and BREAK_SIGNAL thread dumping. -++ // (See bug 4345157, and other related bugs). -++ // In reality, though, unblocking these signals is really a nop, since -++ // these signals are not blocked by default. -++ sigemptyset(&unblocked_sigs); -++ sigemptyset(&allowdebug_blocked_sigs); -++ sigaddset(&unblocked_sigs, SIGILL); -++ sigaddset(&unblocked_sigs, SIGSEGV); -++ sigaddset(&unblocked_sigs, SIGBUS); -++ sigaddset(&unblocked_sigs, SIGFPE); -++ sigaddset(&unblocked_sigs, SR_signum); -++ -++ if (!ReduceSignalUsage) { -++ if (!os::Linux::is_sig_ignored(SHUTDOWN1_SIGNAL)) { -++ sigaddset(&unblocked_sigs, SHUTDOWN1_SIGNAL); -++ sigaddset(&allowdebug_blocked_sigs, SHUTDOWN1_SIGNAL); -++ } -++ if (!os::Linux::is_sig_ignored(SHUTDOWN2_SIGNAL)) { -++ sigaddset(&unblocked_sigs, SHUTDOWN2_SIGNAL); -++ sigaddset(&allowdebug_blocked_sigs, SHUTDOWN2_SIGNAL); -++ } -++ if (!os::Linux::is_sig_ignored(SHUTDOWN3_SIGNAL)) { -++ sigaddset(&unblocked_sigs, SHUTDOWN3_SIGNAL); -++ sigaddset(&allowdebug_blocked_sigs, SHUTDOWN3_SIGNAL); -++ } -++ } -++ // Fill in signals that are blocked by all but the VM thread. -++ sigemptyset(&vm_sigs); -++ if (!ReduceSignalUsage) -++ sigaddset(&vm_sigs, BREAK_SIGNAL); -++ debug_only(signal_sets_initialized = true); -++ -++} -++ -++// These are signals that are unblocked while a thread is running Java. -++// (For some reason, they get blocked by default.) -++sigset_t* os::Linux::unblocked_signals() { -++ assert(signal_sets_initialized, "Not initialized"); -++ return &unblocked_sigs; -++} -++ -++// These are the signals that are blocked while a (non-VM) thread is -++// running Java. Only the VM thread handles these signals. -++sigset_t* os::Linux::vm_signals() { -++ assert(signal_sets_initialized, "Not initialized"); -++ return &vm_sigs; -++} -++ -++// These are signals that are blocked during cond_wait to allow debugger in -++sigset_t* os::Linux::allowdebug_blocked_signals() { -++ assert(signal_sets_initialized, "Not initialized"); -++ return &allowdebug_blocked_sigs; -++} -++ -++void os::Linux::hotspot_sigmask(Thread* thread) { -++ -++ //Save caller's signal mask before setting VM signal mask -++ sigset_t caller_sigmask; -++ pthread_sigmask(SIG_BLOCK, NULL, &caller_sigmask); -++ -++ OSThread* osthread = thread->osthread(); -++ osthread->set_caller_sigmask(caller_sigmask); -++ -++ pthread_sigmask(SIG_UNBLOCK, os::Linux::unblocked_signals(), NULL); -++ -++ if (!ReduceSignalUsage) { -++ if (thread->is_VM_thread()) { -++ // Only the VM thread handles BREAK_SIGNAL ... -++ pthread_sigmask(SIG_UNBLOCK, vm_signals(), NULL); -++ } else { -++ // ... all other threads block BREAK_SIGNAL -++ pthread_sigmask(SIG_BLOCK, vm_signals(), NULL); -++ } -++ } -++} -++ -++////////////////////////////////////////////////////////////////////////////// -++// detecting pthread library -++ -++void os::Linux::libpthread_init() { -++ // Save glibc and pthread version strings. Note that _CS_GNU_LIBC_VERSION -++ // and _CS_GNU_LIBPTHREAD_VERSION are supported in glibc >= 2.3.2. Use a -++ // generic name for earlier versions. -++ // Define macros here so we can build HotSpot on old systems. -++# ifndef _CS_GNU_LIBC_VERSION -++# define _CS_GNU_LIBC_VERSION 2 -++# endif -++# ifndef _CS_GNU_LIBPTHREAD_VERSION -++# define _CS_GNU_LIBPTHREAD_VERSION 3 -++# endif -++ -++ size_t n = confstr(_CS_GNU_LIBC_VERSION, NULL, 0); -++ if (n > 0) { -++ char *str = (char *)malloc(n, mtInternal); -++ confstr(_CS_GNU_LIBC_VERSION, str, n); -++ os::Linux::set_glibc_version(str); -++ } else { -++ // _CS_GNU_LIBC_VERSION is not supported, try gnu_get_libc_version() -++ static char _gnu_libc_version[32]; -++ jio_snprintf(_gnu_libc_version, sizeof(_gnu_libc_version), -++ "glibc %s %s", gnu_get_libc_version(), gnu_get_libc_release()); -++ os::Linux::set_glibc_version(_gnu_libc_version); -++ } -++ -++ n = confstr(_CS_GNU_LIBPTHREAD_VERSION, NULL, 0); -++ if (n > 0) { -++ char *str = (char *)malloc(n, mtInternal); -++ confstr(_CS_GNU_LIBPTHREAD_VERSION, str, n); -++ // Vanilla RH-9 (glibc 2.3.2) has a bug that confstr() always tells -++ // us "NPTL-0.29" even we are running with LinuxThreads. Check if this -++ // is the case. LinuxThreads has a hard limit on max number of threads. -++ // So sysconf(_SC_THREAD_THREADS_MAX) will return a positive value. -++ // On the other hand, NPTL does not have such a limit, sysconf() -++ // will return -1 and errno is not changed. Check if it is really NPTL. -++ if (strcmp(os::Linux::glibc_version(), "glibc 2.3.2") == 0 && -++ strstr(str, "NPTL") && -++ sysconf(_SC_THREAD_THREADS_MAX) > 0) { -++ free(str); -++ os::Linux::set_libpthread_version("linuxthreads"); -++ } else { -++ os::Linux::set_libpthread_version(str); -++ } -++ } else { -++ // glibc before 2.3.2 only has LinuxThreads. -++ os::Linux::set_libpthread_version("linuxthreads"); -++ } -++ -++ if (strstr(libpthread_version(), "NPTL")) { -++ os::Linux::set_is_NPTL(); -++ } else { -++ os::Linux::set_is_LinuxThreads(); -++ } -++ -++ // LinuxThreads have two flavors: floating-stack mode, which allows variable -++ // stack size; and fixed-stack mode. NPTL is always floating-stack. -++ if (os::Linux::is_NPTL() || os::Linux::supports_variable_stack_size()) { -++ os::Linux::set_is_floating_stack(); -++ } -++} -++ -++///////////////////////////////////////////////////////////////////////////// -++// thread stack -++ -++// Force Linux kernel to expand current thread stack. If "bottom" is close -++// to the stack guard, caller should block all signals. -++// -++// MAP_GROWSDOWN: -++// A special mmap() flag that is used to implement thread stacks. It tells -++// kernel that the memory region should extend downwards when needed. This -++// allows early versions of LinuxThreads to only mmap the first few pages -++// when creating a new thread. Linux kernel will automatically expand thread -++// stack as needed (on page faults). -++// -++// However, because the memory region of a MAP_GROWSDOWN stack can grow on -++// demand, if a page fault happens outside an already mapped MAP_GROWSDOWN -++// region, it's hard to tell if the fault is due to a legitimate stack -++// access or because of reading/writing non-exist memory (e.g. buffer -++// overrun). As a rule, if the fault happens below current stack pointer, -++// Linux kernel does not expand stack, instead a SIGSEGV is sent to the -++// application (see Linux kernel fault.c). -++// -++// This Linux feature can cause SIGSEGV when VM bangs thread stack for -++// stack overflow detection. -++// -++// Newer version of LinuxThreads (since glibc-2.2, or, RH-7.x) and NPTL do -++// not use this flag. However, the stack of initial thread is not created -++// by pthread, it is still MAP_GROWSDOWN. Also it's possible (though -++// unlikely) that user code can create a thread with MAP_GROWSDOWN stack -++// and then attach the thread to JVM. -++// -++// To get around the problem and allow stack banging on Linux, we need to -++// manually expand thread stack after receiving the SIGSEGV. -++// -++// There are two ways to expand thread stack to address "bottom", we used -++// both of them in JVM before 1.5: -++// 1. adjust stack pointer first so that it is below "bottom", and then -++// touch "bottom" -++// 2. mmap() the page in question -++// -++// Now alternate signal stack is gone, it's harder to use 2. For instance, -++// if current sp is already near the lower end of page 101, and we need to -++// call mmap() to map page 100, it is possible that part of the mmap() frame -++// will be placed in page 100. When page 100 is mapped, it is zero-filled. -++// That will destroy the mmap() frame and cause VM to crash. -++// -++// The following code works by adjusting sp first, then accessing the "bottom" -++// page to force a page fault. Linux kernel will then automatically expand the -++// stack mapping. -++// -++// _expand_stack_to() assumes its frame size is less than page size, which -++// should always be true if the function is not inlined. -++ -++#if __GNUC__ < 3 // gcc 2.x does not support noinline attribute -++#define NOINLINE -++#else -++#define NOINLINE __attribute__ ((noinline)) -++#endif -++ -++static void _expand_stack_to(address bottom) NOINLINE; -++ -++static void _expand_stack_to(address bottom) { -++ address sp; -++ size_t size; -++ volatile char *p; -++ -++ // Adjust bottom to point to the largest address within the same page, it -++ // gives us a one-page buffer if alloca() allocates slightly more memory. -++ bottom = (address)align_size_down((uintptr_t)bottom, os::Linux::page_size()); -++ bottom += os::Linux::page_size() - 1; -++ -++ // sp might be slightly above current stack pointer; if that's the case, we -++ // will alloca() a little more space than necessary, which is OK. Don't use -++ // os::current_stack_pointer(), as its result can be slightly below current -++ // stack pointer, causing us to not alloca enough to reach "bottom". -++ sp = (address)&sp; -++ -++ if (sp > bottom) { -++ size = sp - bottom; -++ p = (volatile char *)alloca(size); -++ assert(p != NULL && p <= (volatile char *)bottom, "alloca problem?"); -++ p[0] = '\0'; -++ } -++} -++ -++bool os::Linux::manually_expand_stack(JavaThread * t, address addr) { -++ assert(t!=NULL, "just checking"); -++ assert(t->osthread()->expanding_stack(), "expand should be set"); -++ assert(t->stack_base() != NULL, "stack_base was not initialized"); -++ -++ if (addr < t->stack_base() && addr >= t->stack_yellow_zone_base()) { -++ sigset_t mask_all, old_sigset; -++ sigfillset(&mask_all); -++ pthread_sigmask(SIG_SETMASK, &mask_all, &old_sigset); -++ _expand_stack_to(addr); -++ pthread_sigmask(SIG_SETMASK, &old_sigset, NULL); -++ return true; -++ } -++ return false; -++} -++ -++////////////////////////////////////////////////////////////////////////////// -++// create new thread -++ -++static address highest_vm_reserved_address(); -++ -++// check if it's safe to start a new thread -++static bool _thread_safety_check(Thread* thread) { -++ if (os::Linux::is_LinuxThreads() && !os::Linux::is_floating_stack()) { -++ // Fixed stack LinuxThreads (SuSE Linux/x86, and some versions of Redhat) -++ // Heap is mmap'ed at lower end of memory space. Thread stacks are -++ // allocated (MAP_FIXED) from high address space. Every thread stack -++ // occupies a fixed size slot (usually 2Mbytes, but user can change -++ // it to other values if they rebuild LinuxThreads). -++ // -++ // Problem with MAP_FIXED is that mmap() can still succeed even part of -++ // the memory region has already been mmap'ed. That means if we have too -++ // many threads and/or very large heap, eventually thread stack will -++ // collide with heap. -++ // -++ // Here we try to prevent heap/stack collision by comparing current -++ // stack bottom with the highest address that has been mmap'ed by JVM -++ // plus a safety margin for memory maps created by native code. -++ // -++ // This feature can be disabled by setting ThreadSafetyMargin to 0 -++ // -++ if (ThreadSafetyMargin > 0) { -++ address stack_bottom = os::current_stack_base() - os::current_stack_size(); -++ -++ // not safe if our stack extends below the safety margin -++ return stack_bottom - ThreadSafetyMargin >= highest_vm_reserved_address(); -++ } else { -++ return true; -++ } -++ } else { -++ // Floating stack LinuxThreads or NPTL: -++ // Unlike fixed stack LinuxThreads, thread stacks are not MAP_FIXED. When -++ // there's not enough space left, pthread_create() will fail. If we come -++ // here, that means enough space has been reserved for stack. -++ return true; -++ } -++} -++ -++// Thread start routine for all newly created threads -++static void *java_start(Thread *thread) { -++ // 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); -++ -++ ThreadLocalStorage::set_thread(thread); -++ -++ OSThread* osthread = thread->osthread(); -++ Monitor* sync = osthread->startThread_lock(); -++ -++ // non floating stack LinuxThreads needs extra check, see above -++ if (!_thread_safety_check(thread)) { -++ // notify parent thread -++ MutexLockerEx ml(sync, Mutex::_no_safepoint_check_flag); -++ osthread->set_state(ZOMBIE); -++ sync->notify_all(); -++ return NULL; -++ } -++ -++ // thread_id is kernel thread id (similar to Solaris LWP id) -++ osthread->set_thread_id(os::Linux::gettid()); -++ -++ if (UseNUMA) { -++ int lgrp_id = os::numa_get_group_id(); -++ if (lgrp_id != -1) { -++ thread->set_lgrp_id(lgrp_id); -++ } -++ } -++ // initialize signal mask for this thread -++ os::Linux::hotspot_sigmask(thread); -++ -++ // initialize floating point control register -++ os::Linux::init_thread_fpu_state(); -++ -++ // handshaking with parent thread -++ { -++ MutexLockerEx ml(sync, Mutex::_no_safepoint_check_flag); -++ -++ // notify parent thread -++ osthread->set_state(INITIALIZED); -++ sync->notify_all(); -++ -++ // wait until os::start_thread() -++ while (osthread->get_state() == INITIALIZED) { -++ sync->wait(Mutex::_no_safepoint_check_flag); -++ } -++ } -++ -++ // call one more level start routine -++ thread->run(); -++ -++ return 0; -++} -++ -++bool os::create_thread(Thread* thread, ThreadType thr_type, size_t stack_size) { -++ assert(thread->osthread() == NULL, "caller responsible"); -++ -++ // Allocate the OSThread object -++ OSThread* osthread = new OSThread(NULL, NULL); -++ if (osthread == NULL) { -++ return false; -++ } -++ -++ // set the correct thread state -++ osthread->set_thread_type(thr_type); -++ -++ // Initial state is ALLOCATED but not INITIALIZED -++ osthread->set_state(ALLOCATED); -++ -++ thread->set_osthread(osthread); -++ -++ // init thread attributes -++ pthread_attr_t attr; -++ pthread_attr_init(&attr); -++ pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); -++ -++ // stack size -++ if (os::Linux::supports_variable_stack_size()) { -++ / |