summaryrefslogtreecommitdiff
path: root/package/openjdk7
diff options
context:
space:
mode:
authorWaldemar Brodkorb <wbx@openadk.org>2014-05-13 18:07:03 +0200
committerWaldemar Brodkorb <wbx@openadk.org>2014-05-13 18:07:26 +0200
commit3cf55e2bc095ac6dc345217c993f80d74c6b5714 (patch)
tree84773de439ee4137c60a25cd347adc0715a4b992 /package/openjdk7
parentd7f94b4993de82698282bea85d494ea54a2da85a (diff)
fix openjdk build errors for arm target
Diffstat (limited to 'package/openjdk7')
-rw-r--r--package/openjdk7/Makefile1
-rw-r--r--package/openjdk7/patches/openadk.patch6490
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);
+++ }