diff options
author | Waldemar Brodkorb <wbx@openadk.org> | 2014-05-13 18:07:03 +0200 |
---|---|---|
committer | Waldemar Brodkorb <wbx@openadk.org> | 2014-05-13 18:07:26 +0200 |
commit | 3cf55e2bc095ac6dc345217c993f80d74c6b5714 (patch) | |
tree | 84773de439ee4137c60a25cd347adc0715a4b992 /package/openjdk7 | |
parent | d7f94b4993de82698282bea85d494ea54a2da85a (diff) |
fix openjdk build errors for arm target
Diffstat (limited to 'package/openjdk7')
-rw-r--r-- | package/openjdk7/Makefile | 1 | ||||
-rw-r--r-- | package/openjdk7/patches/openadk.patch | 6490 |
2 files changed, 6384 insertions, 107 deletions
diff --git a/package/openjdk7/Makefile b/package/openjdk7/Makefile index 41697c9c2..1b654300b 100644 --- a/package/openjdk7/Makefile +++ b/package/openjdk7/Makefile @@ -102,6 +102,7 @@ OPENJDK_NATIVE_ENV:= JAVACFLAGS="-cp ${STAGING_HOST_DIR}/usr/share/java/libgcj-$ BOOTCLASSPATH="$(STAGING_HOST_DIR)/usr/share/jamvm/classes.zip:$(STAGING_HOST_DIR)/usr/share/classpath/glibj.zip" \ FFI_LDFLAGS="$(LDFLAGS_FOR_BUILD)" \ OTHER_LDFLAGS='$(LDFLAGS_FOR_BUILD)' \ + ALT_OPENWIN_HOME=$(STAGING_HOST_DIR)/usr/ \ ALT_CUPS_HEADERS_PATH="$(STAGING_HOST_DIR)/usr/include" \ ALT_FREETYPE_HEADERS_PATH="$(STAGING_HOST_DIR)/usr/include" \ ALT_FREETYPE_LIB_PATH="$(STAGING_HOST_DIR)/usr/lib" \ diff --git a/package/openjdk7/patches/openadk.patch b/package/openjdk7/patches/openadk.patch index dd31ed5ba..3001aff5b 100644 --- a/package/openjdk7/patches/openadk.patch +++ b/package/openjdk7/patches/openadk.patch @@ -12,11 +12,39 @@ 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-08 21:02:03.459173373 +0200 -@@ -0,0 +1,733 @@ ++++ icedtea-2.4.7/patches/openadk.patch 2014-05-13 16:57:07.173804037 +0200 +@@ -0,0 +1,7009 @@ ++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 ++@@ -39,20 +39,20 @@ ++ ++ offsets_arm.s: mkoffsets ++ @echo Generating assembler offsets ++- ./mkoffsets > $@ +++ $(QEMU) ./mkoffsets > $@ ++ ++ bytecodes_arm.s: bytecodes_arm.def mkbc ++ @echo Generating ARM assembler bytecode sequences ++- $(CXX_COMPILE) -E -x c++ - < $< | ./mkbc - $@ $(COMPILE_DONE) +++ $(CXX_COMPILE) -E -x c++ - < $< | $(QEMU) ./mkbc - $@ $(COMPILE_DONE) ++ ++ mkbc: $(GAMMADIR)/tools/mkbc.c ++ @echo Compiling mkbc tool ++- $(CC_COMPILE) -o $@ $< $(COMPILE_DONE) +++ $(CC_COMPILE) -static -o $@ $< $(COMPILE_DONE) ++ ++ mkoffsets: asm_helper.cpp ++ @echo Compiling offset generator ++ $(QUIETLY) $(REMOVE_TARGET) ++- $(CXX_COMPILE) -DSTATIC_OFFSETS -o $@ $< $(COMPILE_DONE) +++ $(CXX_COMPILE) -static -DSTATIC_OFFSETS -o $@ $< $(COMPILE_DONE) ++ ++ endif ++ 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-01-28 18:58:08.000000000 +0100 -++++ openjdk/hotspot/src/os/linux/vm/os_linux.cpp 2014-02-10 11:31:48.000000000 +0100 ++--- 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 +@@ -112,7 +112,6 @@ + # include <string.h> + # include <syscall.h> @@ -48,7 +76,7 @@ diff -Nur icedtea-2.4.7.orig/patches/openadk.patch icedtea-2.4.7/patches/openadk + return f; + } + -+@@ -5312,7 +5306,21 @@ ++@@ -5329,7 +5323,21 @@ + // Linux doesn't yet have a (official) notion of processor sets, + // so just return the system wide load average. + int os::loadavg(double loadavg[], int nelem) { @@ -71,9 +99,6002 @@ 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); +++ } |