mirror of
https://github.com/AngelAuraMC/angelauramc-openjdk-build.git
synced 2025-08-03 15:46:08 -04:00
2500 lines
88 KiB
Diff
2500 lines
88 KiB
Diff
diff --git a/make/autoconf/flags-cflags.m4 b/make/autoconf/flags-cflags.m4
|
|
index 1fdd0143a..705b3e1f9 100644
|
|
--- a/make/autoconf/flags-cflags.m4
|
|
+++ b/make/autoconf/flags-cflags.m4
|
|
@@ -409,7 +409,8 @@ AC_DEFUN([FLAGS_SETUP_CFLAGS_HELPER],
|
|
#### OS DEFINES, these should be independent on toolchain
|
|
if test "x$OPENJDK_TARGET_OS" = xlinux; then
|
|
CFLAGS_OS_DEF_JVM="-DLINUX"
|
|
- CFLAGS_OS_DEF_JDK="-D_GNU_SOURCE -D_REENTRANT -D_LARGEFILE64_SOURCE"
|
|
+ # CFLAGS_OS_DEF_JDK="-D_GNU_SOURCE -D_REENTRANT -D_LARGEFILE64_SOURCE"
|
|
+ CFLAGS_OS_DEF_JDK="-D_GNU_SOURCE -D_REENTRANT -D_LARGEFILE64_SOURCE -D__USE_BSD"
|
|
elif test "x$OPENJDK_TARGET_OS" = xmacosx; then
|
|
CFLAGS_OS_DEF_JVM="-D_ALLBSD_SOURCE -D_DARWIN_C_SOURCE -D_XOPEN_SOURCE"
|
|
CFLAGS_OS_DEF_JDK="-D_ALLBSD_SOURCE -D_DARWIN_UNLIMITED_SELECT"
|
|
diff --git a/make/autoconf/flags-ldflags.m4 b/make/autoconf/flags-ldflags.m4
|
|
index 2aca285d3..494262487 100644
|
|
--- a/make/autoconf/flags-ldflags.m4
|
|
+++ b/make/autoconf/flags-ldflags.m4
|
|
@@ -173,7 +173,9 @@ AC_DEFUN([FLAGS_SETUP_LDFLAGS_CPU_DEP],
|
|
test "x${OPENJDK_$1_CPU}" = xmips64el; then
|
|
$1_CPU_LDFLAGS="${$1_CPU_LDFLAGS} -Wl,--hash-style=sysv"
|
|
else
|
|
- $1_CPU_LDFLAGS="${$1_CPU_LDFLAGS} -Wl,--hash-style=gnu"
|
|
+ # Android 5.x does not support GNU hash style
|
|
+ # gnu
|
|
+ $1_CPU_LDFLAGS="${$1_CPU_LDFLAGS} -Wl,--hash-style=sysv"
|
|
fi
|
|
|
|
elif test "x$TOOLCHAIN_TYPE" = xmicrosoft; then
|
|
diff --git a/make/autoconf/lib-freetype.m4 b/make/autoconf/lib-freetype.m4
|
|
index 6a7109342..2d74ffc5b 100644
|
|
--- a/make/autoconf/lib-freetype.m4
|
|
+++ b/make/autoconf/lib-freetype.m4
|
|
@@ -103,7 +103,8 @@ AC_DEFUN_ONCE([LIB_SETUP_FREETYPE],
|
|
FREETYPE_TO_USE=bundled
|
|
if test "x$OPENJDK_TARGET_OS" != "xwindows" && \
|
|
test "x$OPENJDK_TARGET_OS" != "xmacosx" && \
|
|
- test "x$OPENJDK_TARGET_OS" != "xaix"; then
|
|
+ test "x$OPENJDK_TARGET_OS" != "xaix" && \
|
|
+ test "x$OPENJDK_TARGET_OS" != "xandroid"; then
|
|
FREETYPE_TO_USE=system
|
|
fi
|
|
if test "x$with_freetype" != "x" ; then
|
|
diff --git a/make/autoconf/libraries.m4 b/make/autoconf/libraries.m4
|
|
index a50ce5731..eb9545984 100644
|
|
--- a/make/autoconf/libraries.m4
|
|
+++ b/make/autoconf/libraries.m4
|
|
@@ -42,8 +42,8 @@ m4_include([lib-tests.m4])
|
|
AC_DEFUN_ONCE([LIB_DETERMINE_DEPENDENCIES],
|
|
[
|
|
# Check if X11 is needed
|
|
- if test "x$OPENJDK_TARGET_OS" = xwindows || test "x$OPENJDK_TARGET_OS" = xmacosx; then
|
|
- # No X11 support on windows or macosx
|
|
+ if test "x$OPENJDK_TARGET_OS" = xwindows || test "x$OPENJDK_TARGET_OS" = xmacosx || test "x$OPENJDK_TARGET_OS" = xandroid; then
|
|
+ # No X11 support on windows, macosx or android
|
|
NEEDS_LIB_X11=false
|
|
else
|
|
# All other instances need X11, even if building headless only, libawt still
|
|
@@ -52,8 +52,8 @@ AC_DEFUN_ONCE([LIB_DETERMINE_DEPENDENCIES],
|
|
fi
|
|
|
|
# Check if fontconfig is needed
|
|
- if test "x$OPENJDK_TARGET_OS" = xwindows || test "x$OPENJDK_TARGET_OS" = xmacosx; then
|
|
- # No fontconfig support on windows or macosx
|
|
+ if test "x$OPENJDK_TARGET_OS" = xwindows || test "x$OPENJDK_TARGET_OS" = xmacosx || test "x$OPENJDK_TARGET_OS" = xandroid; then
|
|
+ # No fontconfig support on windows, macosx or android
|
|
NEEDS_LIB_FONTCONFIG=false
|
|
else
|
|
# All other instances need fontconfig, even if building headless only,
|
|
diff --git a/make/autoconf/platform.m4 b/make/autoconf/platform.m4
|
|
index babb24a9b..bcf1e9b41 100644
|
|
--- a/make/autoconf/platform.m4
|
|
+++ b/make/autoconf/platform.m4
|
|
@@ -202,6 +202,10 @@ AC_DEFUN([PLATFORM_EXTRACT_VARS_FROM_OS],
|
|
VAR_OS=linux
|
|
VAR_OS_TYPE=unix
|
|
;;
|
|
+ *android*)
|
|
+ VAR_OS=linux
|
|
+ VAR_OS_TYPE=unix
|
|
+ ;;
|
|
*darwin*)
|
|
VAR_OS=macosx
|
|
VAR_OS_TYPE=unix
|
|
diff --git a/make/autoconf/toolchain.m4 b/make/autoconf/toolchain.m4
|
|
index adb4e182d..e2ee96798 100644
|
|
--- a/make/autoconf/toolchain.m4
|
|
+++ b/make/autoconf/toolchain.m4
|
|
@@ -903,11 +903,14 @@ AC_DEFUN_ONCE([TOOLCHAIN_SETUP_BUILD_COMPILERS],
|
|
|
|
PATH="$OLDPATH"
|
|
|
|
- TOOLCHAIN_EXTRACT_COMPILER_VERSION(BUILD_CC, [BuildC])
|
|
- TOOLCHAIN_EXTRACT_COMPILER_VERSION(BUILD_CXX, [BuildC++])
|
|
- TOOLCHAIN_PREPARE_FOR_VERSION_COMPARISONS([BUILD_], [OPENJDK_BUILD_], [build ])
|
|
- TOOLCHAIN_EXTRACT_LD_VERSION(BUILD_LD, [build linker])
|
|
- TOOLCHAIN_PREPARE_FOR_LD_VERSION_COMPARISONS([BUILD_], [OPENJDK_BUILD_])
|
|
+ # xandroid
|
|
+ if test "x$OPENJDK_BUILD_OS" != "xlinux"; then
|
|
+ TOOLCHAIN_EXTRACT_COMPILER_VERSION(BUILD_CC, [BuildC])
|
|
+ TOOLCHAIN_EXTRACT_COMPILER_VERSION(BUILD_CXX, [BuildC++])
|
|
+ TOOLCHAIN_PREPARE_FOR_VERSION_COMPARISONS([BUILD_], [OPENJDK_BUILD_], [build ])
|
|
+ TOOLCHAIN_EXTRACT_LD_VERSION(BUILD_LD, [build linker])
|
|
+ TOOLCHAIN_PREPARE_FOR_LD_VERSION_COMPARISONS([BUILD_], [OPENJDK_BUILD_])
|
|
+ fi
|
|
else
|
|
# If we are not cross compiling, use the normal target compilers for
|
|
# building the build platform executables.
|
|
diff --git a/make/common/JdkNativeCompilation.gmk b/make/common/JdkNativeCompilation.gmk
|
|
index 6a963ac2c..349ff126b 100644
|
|
--- a/make/common/JdkNativeCompilation.gmk
|
|
+++ b/make/common/JdkNativeCompilation.gmk
|
|
@@ -41,6 +41,12 @@ FindSrcDirsForLib += \
|
|
$(TOPDIR)/src/$(strip $1)/$(OPENJDK_TARGET_OS_TYPE)/native/lib$(strip $2) \
|
|
$(TOPDIR)/src/$(strip $1)/share/native/lib$(strip $2)))
|
|
|
|
+ifeq ($(OPENJDK_TARGET_OS), android)
|
|
+ FindSrcDirsForLib += \
|
|
+ $(call uniq, $(wildcard \
|
|
+ $(TOPDIR)/src/$(strip $1)/linux/native/lib$(strip $2)))
|
|
+endif
|
|
+
|
|
FindSrcDirsForComponent += \
|
|
$(call uniq, $(wildcard \
|
|
$(TOPDIR)/src/$(strip $1)/$(OPENJDK_TARGET_OS)/native/$(strip $2) \
|
|
diff --git a/make/common/Modules.gmk b/make/common/Modules.gmk
|
|
index 0eb0fb2dd..e0431de0b 100644
|
|
--- a/make/common/Modules.gmk
|
|
+++ b/make/common/Modules.gmk
|
|
@@ -83,6 +83,10 @@ GENERATED_SRC_DIRS += \
|
|
TOP_SRC_DIRS += \
|
|
$(TOPDIR)/src \
|
|
#
|
|
+ifeq ($(OPENJDK_TARGET_OS), android)
|
|
+ SRC_SUBDIRS += linux/classes
|
|
+endif
|
|
+
|
|
|
|
SRC_SUBDIRS += $(OPENJDK_TARGET_OS)/classes
|
|
ifneq ($(OPENJDK_TARGET_OS), $(OPENJDK_TARGET_OS_TYPE))
|
|
diff --git a/make/common/Utils.gmk b/make/common/Utils.gmk
|
|
index 00e73f7dd..70accf224 100644
|
|
--- a/make/common/Utils.gmk
|
|
+++ b/make/common/Utils.gmk
|
|
@@ -346,6 +346,12 @@ check-jvm-variant = \
|
|
isTargetOs = \
|
|
$(strip $(if $(filter $(OPENJDK_TARGET_OS), $1), true, false))
|
|
|
|
+ifeq ($(call isTargetOs, android), true)
|
|
+ # PATCH: Since Android is Linux, so Linux specific things are also built for Android.
|
|
+ isTargetOs = \
|
|
+ $(strip $(if $(filter $(OPENJDK_TARGET_OS), $1), true, $(if $(filter linux, $1), true, false)))
|
|
+endif
|
|
+
|
|
isTargetOsType = \
|
|
$(strip $(if $(filter $(OPENJDK_TARGET_OS_TYPE), $1), true, false))
|
|
|
|
diff --git a/make/hotspot/lib/JvmMapfile.gmk b/make/hotspot/lib/JvmMapfile.gmk
|
|
index d80b804a2..fd2a8ed15 100644
|
|
--- a/make/hotspot/lib/JvmMapfile.gmk
|
|
+++ b/make/hotspot/lib/JvmMapfile.gmk
|
|
@@ -52,7 +52,7 @@ endif
|
|
# Create a dynamic list of symbols from the built object files. This is highly
|
|
# platform dependent.
|
|
|
|
-ifeq ($(call isTargetOs, linux), true)
|
|
+ifeq ($(call isTargetOs, android linux), true)
|
|
DUMP_SYMBOLS_CMD := $(NM) --defined-only *$(OBJ_SUFFIX)
|
|
ifneq ($(FILTER_SYMBOLS_PATTERN), )
|
|
FILTER_SYMBOLS_PATTERN := $(FILTER_SYMBOLS_PATTERN)|
|
|
diff --git a/make/hotspot/lib/JvmOverrideFiles.gmk b/make/hotspot/lib/JvmOverrideFiles.gmk
|
|
index 377018cdb..c1c624896 100644
|
|
--- a/make/hotspot/lib/JvmOverrideFiles.gmk
|
|
+++ b/make/hotspot/lib/JvmOverrideFiles.gmk
|
|
@@ -62,7 +62,8 @@ ifeq ($(call isTargetOs, linux), true)
|
|
#
|
|
endif
|
|
|
|
- ifeq ($(call isTargetCpu, x86), true)
|
|
+ #ifeq ($(call isTargetCpu, x86), true)
|
|
+ ifeq (false, true)
|
|
# Performance measurements show that by compiling GC related code, we could
|
|
# significantly reduce the GC pause time on 32 bit Linux/Unix platforms by
|
|
# compiling without the PIC flag (-fPIC on linux).
|
|
diff --git a/make/modules/java.base/lib/CoreLibraries.gmk b/make/modules/java.base/lib/CoreLibraries.gmk
|
|
index 186eff3d6..ca76357b0 100644
|
|
--- a/make/modules/java.base/lib/CoreLibraries.gmk
|
|
+++ b/make/modules/java.base/lib/CoreLibraries.gmk
|
|
@@ -117,6 +117,10 @@ $(eval $(call SetupJdkLibrary, BUILD_LIBJAVA, \
|
|
|
|
TARGETS += $(BUILD_LIBJAVA)
|
|
|
|
+ifeq ($(OPENJDK_TARGET_OS), linux)
|
|
+ $(BUILD_LIBJAVA): $(BUILD_LIBTINYICONV)
|
|
+endif
|
|
+
|
|
$(BUILD_LIBJAVA): $(BUILD_LIBVERIFY)
|
|
|
|
|
|
diff --git a/make/modules/java.desktop/Lib.gmk b/make/modules/java.desktop/Lib.gmk
|
|
index be1ac3f1f..4dd31c4b1 100644
|
|
--- a/make/modules/java.desktop/Lib.gmk
|
|
+++ b/make/modules/java.desktop/Lib.gmk
|
|
@@ -76,7 +76,7 @@ ifeq ($(call isTargetOs, aix), false)
|
|
|
|
$(BUILD_LIBJSOUND): $(call FindLib, java.base, java)
|
|
|
|
- TARGETS += $(BUILD_LIBJSOUND)
|
|
+ # TARGETS += $(BUILD_LIBJSOUND)
|
|
|
|
endif
|
|
|
|
diff --git a/make/modules/java.desktop/lib/Awt2dLibraries.gmk b/make/modules/java.desktop/lib/Awt2dLibraries.gmk
|
|
index 96576bb8d..13dd8e3e5 100644
|
|
--- a/make/modules/java.desktop/lib/Awt2dLibraries.gmk
|
|
+++ b/make/modules/java.desktop/lib/Awt2dLibraries.gmk
|
|
@@ -538,7 +538,7 @@ $(eval $(call SetupJdkLibrary, BUILD_LIBFONTMANAGER, \
|
|
LDFLAGS_unix := -L$(INSTALL_LIBRARIES_HERE), \
|
|
LDFLAGS_aix := -Wl$(COMMA)-berok, \
|
|
LIBS := $(BUILD_LIBFONTMANAGER_FONTLIB), \
|
|
- LIBS_unix := -lawt -ljava -ljvm $(LIBM) $(LIBCXX), \
|
|
+ LIBS_unix := -lawt -lawt_headless -ljava -ljvm $(LIBM) $(LIBCXX), \
|
|
LIBS_macosx := -lawt_lwawt -framework CoreText -framework CoreFoundation -framework CoreGraphics, \
|
|
LIBS_windows := $(WIN_JAVA_LIB) advapi32.lib user32.lib gdi32.lib \
|
|
$(WIN_AWT_LIB), \
|
|
@@ -777,7 +777,7 @@ ifeq ($(ENABLE_HEADLESS_ONLY), false)
|
|
LIBS_aix := -liconv, \
|
|
))
|
|
|
|
- TARGETS += $(BUILD_LIBSPLASHSCREEN)
|
|
+ # TARGETS += $(BUILD_LIBSPLASHSCREEN)
|
|
|
|
ifeq ($(call isTargetOs, macosx), true)
|
|
$(BUILD_LIBSPLASHSCREEN): $(call FindLib, $(MODULE), osxapp)
|
|
diff --git a/make/modules/java.instrument/Lib.gmk b/make/modules/java.instrument/Lib.gmk
|
|
index ae985b315..c93425263 100644
|
|
--- a/make/modules/java.instrument/Lib.gmk
|
|
+++ b/make/modules/java.instrument/Lib.gmk
|
|
@@ -36,9 +36,11 @@ endif
|
|
$(eval $(call SetupJdkLibrary, BUILD_LIBINSTRUMENT, \
|
|
NAME := instrument, \
|
|
OPTIMIZATION := LOW, \
|
|
+ EXTRA_SRC := java.base:libtinyiconv, \
|
|
CFLAGS := $(CFLAGS_JDKLIB) $(LIBINSTRUMENT_CFLAGS), \
|
|
CFLAGS_debug := -DJPLIS_LOGGING, \
|
|
CFLAGS_release := -DNO_JPLIS_LOGGING, \
|
|
+ CXXFLAGS := $(CXXFLAGS_JDKLIB), \
|
|
EXTRA_HEADER_DIRS := java.base:libjli, \
|
|
LDFLAGS := $(LDFLAGS_JDKLIB) \
|
|
$(call SET_SHARED_LIBRARY_ORIGIN) \
|
|
diff --git a/make/modules/jdk.hotspot.agent/Lib.gmk b/make/modules/jdk.hotspot.agent/Lib.gmk
|
|
index 478d199e5..9477a96c9 100644
|
|
--- a/make/modules/jdk.hotspot.agent/Lib.gmk
|
|
+++ b/make/modules/jdk.hotspot.agent/Lib.gmk
|
|
@@ -76,6 +76,6 @@ $(eval $(call SetupJdkLibrary, BUILD_LIBSA, \
|
|
LIBS_windows := dbgeng.lib $(WIN_JAVA_LIB), \
|
|
))
|
|
|
|
-TARGETS += $(BUILD_LIBSA)
|
|
+# TARGETS += $(BUILD_LIBSA)
|
|
|
|
################################################################################
|
|
diff --git a/make/modules/jdk.jdwp.agent/Lib.gmk b/make/modules/jdk.jdwp.agent/Lib.gmk
|
|
index b5ea40803..f92adb8d3 100644
|
|
--- a/make/modules/jdk.jdwp.agent/Lib.gmk
|
|
+++ b/make/modules/jdk.jdwp.agent/Lib.gmk
|
|
@@ -52,6 +52,7 @@ $(eval $(call SetupJdkLibrary, BUILD_LIBJDWP, \
|
|
NAME := jdwp, \
|
|
OPTIMIZATION := LOW, \
|
|
CFLAGS := $(CFLAGS_JDKLIB) -DJDWP_LOGGING, \
|
|
+ CXXFLAGS := $(CXXFLAGS_JDKLIB), \
|
|
DISABLED_WARNINGS_gcc_SDE.c := unused-function, \
|
|
DISABLED_WARNINGS_clang_error_messages.c := format-nonliteral, \
|
|
DISABLED_WARNINGS_clang_EventRequestImpl.c := self-assign, \
|
|
@@ -60,6 +61,7 @@ $(eval $(call SetupJdkLibrary, BUILD_LIBJDWP, \
|
|
EXTRA_HEADER_DIRS := \
|
|
include \
|
|
libjdwp/export, \
|
|
+ EXTRA_SRC := java.base:libtinyiconv, \
|
|
LDFLAGS := $(LDFLAGS_JDKLIB) \
|
|
$(call SET_SHARED_LIBRARY_ORIGIN), \
|
|
LIBS := $(JDKLIB_LIBS), \
|
|
diff --git a/make/modules/jdk.net/Lib.gmk b/make/modules/jdk.net/Lib.gmk
|
|
index 2a43e81b3..ccb0afff5 100644
|
|
--- a/make/modules/jdk.net/Lib.gmk
|
|
+++ b/make/modules/jdk.net/Lib.gmk
|
|
@@ -27,7 +27,7 @@ include LibCommon.gmk
|
|
|
|
################################################################################
|
|
|
|
-ifeq ($(call isTargetOs, linux macosx windows aix), true)
|
|
+ifeq ($(call isTargetOs, linux macosx windows aix android), true)
|
|
|
|
$(eval $(call SetupJdkLibrary, BUILD_LIBEXTNET, \
|
|
NAME := extnet, \
|
|
diff --git a/src/hotspot/cpu/arm/icache_arm.cpp b/src/hotspot/cpu/arm/icache_arm.cpp
|
|
index 61fcb8a35..93d2ad4f4 100644
|
|
--- a/src/hotspot/cpu/arm/icache_arm.cpp
|
|
+++ b/src/hotspot/cpu/arm/icache_arm.cpp
|
|
@@ -31,7 +31,7 @@
|
|
|
|
|
|
static int icache_flush(address addr, int lines, int magic) {
|
|
- __builtin___clear_cache(addr, addr + (lines << ICache::log2_line_size));
|
|
+ __builtin___clear_cache((char*) addr, (char*) (addr + (lines << ICache::log2_line_size)));
|
|
return magic;
|
|
}
|
|
|
|
diff --git a/src/hotspot/os/linux/os_linux.cpp b/src/hotspot/os/linux/os_linux.cpp
|
|
index 42680218d..403d8905b 100644
|
|
--- a/src/hotspot/os/linux/os_linux.cpp
|
|
+++ b/src/hotspot/os/linux/os_linux.cpp
|
|
@@ -135,7 +135,7 @@
|
|
// for timer info max values which include all bits
|
|
#define ALL_64_BITS CONST64(0xFFFFFFFFFFFFFFFF)
|
|
|
|
-#ifdef MUSL_LIBC
|
|
+#if defined(MUSL_LIBC) || defined(__ANDROID__)
|
|
// dlvsym is not a part of POSIX
|
|
// and musl libc doesn't implement it.
|
|
static void *dlvsym(void *handle,
|
|
@@ -214,6 +214,8 @@ static int clock_tics_per_sec = 100;
|
|
// avoid this
|
|
static bool suppress_primordial_thread_resolution = false;
|
|
|
|
+static bool read_so_path_from_maps(const char* so_name, char* buf, int buflen);
|
|
+
|
|
// utility functions
|
|
|
|
julong os::Linux::available_memory_in_container() {
|
|
@@ -336,11 +338,11 @@ bool os::Linux::get_tick_information(CPUPerfTicks* pticks, int which_logical_cpu
|
|
}
|
|
|
|
#ifndef SYS_gettid
|
|
-// i386: 224, ia64: 1105, amd64: 186, sparc: 143
|
|
+// i386 & arm: 224, ia64: 1105, amd64: 186, sparc: 143
|
|
#ifdef __ia64__
|
|
#define SYS_gettid 1105
|
|
#else
|
|
- #ifdef __i386__
|
|
+ #if defined(__i386__) || defined(__arm__)
|
|
#define SYS_gettid 224
|
|
#else
|
|
#ifdef __amd64__
|
|
@@ -348,6 +350,8 @@ bool os::Linux::get_tick_information(CPUPerfTicks* pticks, int which_logical_cpu
|
|
#else
|
|
#ifdef __sparc__
|
|
#define SYS_gettid 143
|
|
+ #elif defined(__arm64__) || defined(__aarch64__)
|
|
+ #define SYS_gettid 178
|
|
#else
|
|
#error define gettid for the arch
|
|
#endif
|
|
@@ -535,6 +539,7 @@ extern "C" void breakpoint() {
|
|
// detecting pthread library
|
|
|
|
void os::Linux::libpthread_init() {
|
|
+#ifndef __ANDROID__
|
|
// Save glibc and pthread version strings.
|
|
#if !defined(_CS_GNU_LIBC_VERSION) || \
|
|
!defined(_CS_GNU_LIBPTHREAD_VERSION)
|
|
@@ -559,6 +564,9 @@ void os::Linux::libpthread_init() {
|
|
confstr(_CS_GNU_LIBPTHREAD_VERSION, str, n);
|
|
os::Linux::set_libpthread_version(str);
|
|
#endif
|
|
+#else
|
|
+ os::Linux::set_libpthread_version("NPTL");
|
|
+#endif
|
|
}
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
@@ -1348,7 +1356,13 @@ int os::current_process_id() {
|
|
|
|
// This must be hard coded because it's the system's temporary
|
|
// directory not the java application's temp directory, ala java.io.tmpdir.
|
|
-const char* os::get_temp_directory() { return "/tmp"; }
|
|
+const char* os::get_temp_directory() {
|
|
+#ifndef __ANDROID__
|
|
+ return "/tmp";
|
|
+#else
|
|
+ return "/data/tmp";
|
|
+#endif
|
|
+}
|
|
|
|
// check if addr is inside libjvm.so
|
|
bool os::address_is_in_vm(address addr) {
|
|
@@ -1420,6 +1434,30 @@ bool os::dll_address_to_library_name(address addr, char* buf,
|
|
return false;
|
|
}
|
|
|
|
+static bool read_so_path_from_maps(const char* so_name, char* buf, int buflen) {
|
|
+ FILE *fp = fopen("/proc/self/maps", "r");
|
|
+ assert(fp, "Failed to open /proc/self/maps");
|
|
+ if (!fp) {
|
|
+ return false;
|
|
+ }
|
|
+
|
|
+ char maps_buffer[2048];
|
|
+ while (fgets(maps_buffer, 2048, fp) != NULL) {
|
|
+ if (strstr(maps_buffer, so_name) == NULL) {
|
|
+ continue;
|
|
+ }
|
|
+
|
|
+ char *so_path = strchr(maps_buffer, '/');
|
|
+ so_path[strlen(so_path) - 1] = '\0'; // Cut trailing \n
|
|
+ jio_snprintf(buf, buflen, "%s", so_path);
|
|
+ fclose(fp);
|
|
+ return true;
|
|
+ }
|
|
+
|
|
+ fclose(fp);
|
|
+ return false;
|
|
+}
|
|
+
|
|
// Remember the stack's state. The Linux dynamic linker will change
|
|
// the stack to 'executable' at most once, so we must safepoint only once.
|
|
bool os::Linux::_stack_is_executable = false;
|
|
@@ -1753,6 +1791,7 @@ void * os::Linux::dll_load_in_vmthread(const char *filename, char *ebuf,
|
|
}
|
|
|
|
const char* os::Linux::dll_path(void* lib) {
|
|
+#ifdef RTLD_DI_LINKMAP
|
|
struct link_map *lmap;
|
|
const char* l_path = nullptr;
|
|
assert(lib != nullptr, "dll_path parameter must not be null");
|
|
@@ -1762,6 +1801,9 @@ const char* os::Linux::dll_path(void* lib) {
|
|
l_path = lmap->l_name;
|
|
}
|
|
return l_path;
|
|
+#else
|
|
+ return NULL;
|
|
+#endif
|
|
}
|
|
|
|
static unsigned count_newlines(const char* s) {
|
|
@@ -2475,6 +2517,20 @@ void os::jvm_path(char *buf, jint buflen) {
|
|
CAST_FROM_FN_PTR(address, os::jvm_path),
|
|
dli_fname, sizeof(dli_fname), nullptr);
|
|
assert(ret, "cannot locate libjvm");
|
|
+
|
|
+#ifdef __ANDROID__
|
|
+ if (dli_fname[0] == '\0') {
|
|
+ return;
|
|
+ }
|
|
+
|
|
+ if (strchr(dli_fname, '/') == NULL) {
|
|
+ bool ok = read_so_path_from_maps(dli_fname, buf, buflen);
|
|
+ assert(ok, "unable to turn relative libjvm.so path into absolute");
|
|
+ return;
|
|
+ }
|
|
+
|
|
+ snprintf(buf, buflen, /* "%s/lib/%s/server/%s", java_home_var, cpu_arch, */ "%s", dli_fname);
|
|
+#else // !__ANDROID__
|
|
char *rp = nullptr;
|
|
if (ret && dli_fname[0] != '\0') {
|
|
rp = os::Posix::realpath(dli_fname, buf, buflen);
|
|
@@ -2540,6 +2596,7 @@ void os::jvm_path(char *buf, jint buflen) {
|
|
}
|
|
}
|
|
}
|
|
+#endif
|
|
|
|
strncpy(saved_jvm_path, buf, MAXPATHLEN);
|
|
saved_jvm_path[MAXPATHLEN - 1] = '\0';
|
|
@@ -2855,7 +2912,8 @@ void os::Linux::sched_getcpu_init() {
|
|
}
|
|
|
|
if (sched_getcpu() == -1) {
|
|
- vm_exit_during_initialization("getcpu(2) system call not supported by kernel");
|
|
+ // vm_exit_during_initialization
|
|
+ warning("getcpu(2) system call not supported by kernel");
|
|
}
|
|
}
|
|
|
|
@@ -3475,6 +3533,7 @@ bool os::Linux::hugetlbfs_sanity_check(bool warn, size_t page_size) {
|
|
}
|
|
|
|
bool os::Linux::shm_hugetlbfs_sanity_check(bool warn, size_t page_size) {
|
|
+#ifndef __ANDROID__
|
|
// Try to create a large shared memory segment.
|
|
int shmid = shmget(IPC_PRIVATE, page_size, SHM_HUGETLB|IPC_CREAT|SHM_R|SHM_W);
|
|
if (shmid == -1) {
|
|
@@ -3496,6 +3555,10 @@ bool os::Linux::shm_hugetlbfs_sanity_check(bool warn, size_t page_size) {
|
|
// Managed to create a segment, now delete it.
|
|
shmctl(shmid, IPC_RMID, nullptr);
|
|
return true;
|
|
+#else
|
|
+ warning("UseSHM not supported on this platform");
|
|
+ return false;
|
|
+#endif
|
|
}
|
|
|
|
// From the coredump_filter documentation:
|
|
@@ -3759,6 +3822,8 @@ void os::large_page_init() {
|
|
#define SHM_HUGETLB 04000
|
|
#endif
|
|
|
|
+#ifndef __ANDROID__
|
|
+
|
|
#define shm_warning_format(format, ...) \
|
|
do { \
|
|
if (UseLargePages && \
|
|
@@ -3851,8 +3916,11 @@ static char* shmat_large_pages(int shmid, size_t bytes, size_t alignment, char*
|
|
}
|
|
}
|
|
|
|
+#endif // !__ANDROID__
|
|
+
|
|
char* os::Linux::reserve_memory_special_shm(size_t bytes, size_t alignment,
|
|
char* req_addr, bool exec) {
|
|
+#ifndef __ANDROID__
|
|
// "exec" is passed in but not used. Creating the shared image for
|
|
// the code cache doesn't have an SHM_X executable permission to check.
|
|
assert(UseLargePages && UseSHM, "only for SHM large pages");
|
|
@@ -3897,6 +3965,10 @@ char* os::Linux::reserve_memory_special_shm(size_t bytes, size_t alignment,
|
|
shmctl(shmid, IPC_RMID, nullptr);
|
|
|
|
return addr;
|
|
+#else
|
|
+ assert(0, "SHM not supported on this platform");
|
|
+ return NULL;
|
|
+#endif // !__ANDROID__
|
|
}
|
|
|
|
static void log_on_commit_special_failure(char* req_addr, size_t bytes,
|
|
@@ -4023,8 +4095,13 @@ char* os::pd_reserve_memory_special(size_t bytes, size_t alignment, size_t page_
|
|
}
|
|
|
|
bool os::Linux::release_memory_special_shm(char* base, size_t bytes) {
|
|
+#ifndef __ANDROID__
|
|
// detaching the SHM segment will also delete it, see reserve_memory_special_shm()
|
|
return shmdt(base) == 0;
|
|
+#else
|
|
+ assert(0, "SHM not supported on this platform");
|
|
+ return false;
|
|
+#endif // SUPPORTS_SHM
|
|
}
|
|
|
|
bool os::Linux::release_memory_special_huge_tlbfs(char* base, size_t bytes) {
|
|
@@ -5101,7 +5178,46 @@ bool os::is_thread_cpu_time_supported() {
|
|
// 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) {
|
|
- return ::getloadavg(loadavg, nelem);
|
|
+#ifndef __ANDROID__
|
|
+ return ::getloadavg(loadavg, nelem);
|
|
+#else
|
|
+/*
|
|
+ * Copyright (C) 2018 The Android Open Source Project
|
|
+ * All rights reserved.
|
|
+ *
|
|
+ * Redistribution and use in source and binary forms, with or without
|
|
+ * modification, are permitted provided that the following conditions
|
|
+ * are met:
|
|
+ * * Redistributions of source code must retain the above copyright
|
|
+ * notice, this list of conditions and the following disclaimer.
|
|
+ * * Redistributions in binary form must reproduce the above copyright
|
|
+ * notice, this list of conditions and the following disclaimer in
|
|
+ * the documentation and/or other materials provided with the
|
|
+ * distribution.
|
|
+ *
|
|
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
|
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
|
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
|
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
|
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
|
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
|
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
|
|
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
|
|
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
|
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
|
|
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
|
+ * SUCH DAMAGE.
|
|
+ */
|
|
+
|
|
+ if (nelem < 0) return -1;
|
|
+ if (nelem > 3) nelem = 3;
|
|
+ struct sysinfo si;
|
|
+ if (sysinfo(&si) == -1) return -1;
|
|
+ for (int i = 0; i < nelem; ++i) {
|
|
+ loadavg[i] = static_cast<double>(si.loads[i]) / static_cast<double>(1 << SI_LOAD_SHIFT);
|
|
+ }
|
|
+ return nelem;
|
|
+#endif
|
|
}
|
|
|
|
// Get the default path to the core file
|
|
diff --git a/src/hotspot/os/linux/os_perf_linux.cpp b/src/hotspot/os/linux/os_perf_linux.cpp
|
|
index ff416d47e..fca2f6aa4 100644
|
|
--- a/src/hotspot/os/linux/os_perf_linux.cpp
|
|
+++ b/src/hotspot/os/linux/os_perf_linux.cpp
|
|
@@ -45,9 +45,312 @@
|
|
#include <dlfcn.h>
|
|
#include <pthread.h>
|
|
#include <limits.h>
|
|
+#ifndef __ANDROID__
|
|
#include <ifaddrs.h>
|
|
+#else
|
|
+#include <sys/cdefs.h>
|
|
+#include <netinet/in.h>
|
|
+#include <sys/socket.h>
|
|
+#include <linux/if_packet.h>
|
|
+#include <linux/netlink.h>
|
|
+#include <linux/rtnetlink.h>
|
|
+#include <net/if.h>
|
|
+#include <stdint.h>
|
|
+#endif
|
|
#include <fcntl.h>
|
|
|
|
+#ifdef __ANDROID__
|
|
+/*
|
|
+ * Copyright (C) 2015 The Android Open Source Project
|
|
+ * All rights reserved.
|
|
+ *
|
|
+ * Redistribution and use in source and binary forms, with or without
|
|
+ * modification, are permitted provided that the following conditions
|
|
+ * are met:
|
|
+ * * Redistributions of source code must retain the above copyright
|
|
+ * notice, this list of conditions and the following disclaimer.
|
|
+ * * Redistributions in binary form must reproduce the above copyright
|
|
+ * notice, this list of conditions and the following disclaimer in
|
|
+ * the documentation and/or other materials provided with the
|
|
+ * distribution.
|
|
+ *
|
|
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
|
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
|
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
|
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
|
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
|
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
|
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
|
|
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
|
|
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
|
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
|
|
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
|
+ * SUCH DAMAGE.
|
|
+ */
|
|
+
|
|
+__BEGIN_DECLS
|
|
+
|
|
+/**
|
|
+ * Returned by getifaddrs() and freed by freeifaddrs().
|
|
+ */
|
|
+struct ifaddrs {
|
|
+ /** Pointer to the next element in the linked list. */
|
|
+ struct ifaddrs* ifa_next;
|
|
+
|
|
+ /** Interface name. */
|
|
+ char* ifa_name;
|
|
+
|
|
+ /** Interface flags (like `SIOCGIFFLAGS`). */
|
|
+ unsigned int ifa_flags;
|
|
+
|
|
+ /** Interface address. */
|
|
+ struct sockaddr* ifa_addr;
|
|
+
|
|
+ /** Interface netmask. */
|
|
+ struct sockaddr* ifa_netmask;
|
|
+
|
|
+ union {
|
|
+ /** Interface broadcast address (if IFF_BROADCAST is set). */
|
|
+ struct sockaddr* ifu_broadaddr;
|
|
+
|
|
+ /** Interface destination address (if IFF_POINTOPOINT is set). */
|
|
+ struct sockaddr* ifu_dstaddr;
|
|
+ } ifa_ifu;
|
|
+
|
|
+ /** Unused. */
|
|
+ void* ifa_data;
|
|
+};
|
|
+
|
|
+/** Synonym for `ifa_ifu.ifu_broadaddr` in `struct ifaddrs`. */
|
|
+#define ifa_broadaddr ifa_ifu.ifu_broadaddr
|
|
+
|
|
+/** Synonym for `ifa_ifu.ifu_dstaddr` in `struct ifaddrs`. */
|
|
+#define ifa_dstaddr ifa_ifu.ifu_dstaddr
|
|
+
|
|
+/**
|
|
+ * [getifaddrs(3)](http://man7.org/linux/man-pages/man3/getifaddrs.3.html) creates a linked list
|
|
+ * of `struct ifaddrs`. The list must be freed by freeifaddrs().
|
|
+ *
|
|
+ * Returns 0 and stores the list in `*__list_ptr` on success,
|
|
+ * and returns -1 and sets `errno` on failure.
|
|
+ *
|
|
+ * Available since API level 24.
|
|
+ */
|
|
+int getifaddrs(struct ifaddrs** __list_ptr); // __INTRODUCED_IN(24);
|
|
+
|
|
+/**
|
|
+ * [freeifaddrs(3)](http://man7.org/linux/man-pages/man3/freeifaddrs.3.html) frees a linked list
|
|
+ * of `struct ifaddrs` returned by getifaddrs().
|
|
+ *
|
|
+ * Available since API level 24.
|
|
+ */
|
|
+void freeifaddrs(struct ifaddrs* __ptr); // __INTRODUCED_IN(24);
|
|
+
|
|
+__END_DECLS
|
|
+
|
|
+#define nullptr 0
|
|
+
|
|
+// The public ifaddrs struct is full of pointers. Rather than track several
|
|
+// different allocations, we use a maximally-sized structure with the public
|
|
+// part at offset 0, and pointers into its hidden tail.
|
|
+struct ifaddrs_storage {
|
|
+ // Must come first, so that `ifaddrs_storage` is-a `ifaddrs`.
|
|
+ ifaddrs ifa;
|
|
+ // The interface index, so we can match RTM_NEWADDR messages with
|
|
+ // earlier RTM_NEWLINK messages (to copy the interface flags).
|
|
+ int interface_index;
|
|
+ // Storage for the pointers in `ifa`.
|
|
+ sockaddr_storage addr;
|
|
+ sockaddr_storage netmask;
|
|
+ sockaddr_storage ifa_ifu;
|
|
+ char name[IFNAMSIZ + 1];
|
|
+ // Netlink gives us the address family in the header, and the
|
|
+ // sockaddr_in or sockaddr_in6 bytes as the payload. We need to
|
|
+ // stitch the two bits together into the sockaddr that's part of
|
|
+ // our portable interface.
|
|
+ void SetAddress(int family, const void* data, size_t byteCount) {
|
|
+ addr.ss_family = family;
|
|
+ memcpy(SockaddrBytes(family, &addr), data, byteCount);
|
|
+ ifa.ifa_addr = reinterpret_cast<sockaddr*>(&addr);
|
|
+ }
|
|
+ void SetBroadcastAddress(int family, const void* data, size_t byteCount) {
|
|
+ ifa_ifu.ss_family = family;
|
|
+ memcpy(SockaddrBytes(family, &ifa_ifu), data, byteCount);
|
|
+ ifa.ifa_dstaddr = reinterpret_cast<sockaddr*>(&ifa_ifu);
|
|
+ }
|
|
+ // Netlink gives us the prefix length as a bit count. We need to turn
|
|
+ // that into a BSD-compatible netmask represented by a sockaddr*.
|
|
+ void SetNetmask(int family, size_t prefix_length) {
|
|
+ // ...and work out the netmask from the prefix length.
|
|
+ netmask.ss_family = family;
|
|
+ uint8_t* dst = SockaddrBytes(family, &netmask);
|
|
+ memset(dst, 0xff, prefix_length / 8);
|
|
+ if ((prefix_length % 8) != 0) {
|
|
+ dst[prefix_length/8] = (0xff << (8 - (prefix_length % 8)));
|
|
+ }
|
|
+ ifa.ifa_netmask = reinterpret_cast<sockaddr*>(&netmask);
|
|
+ }
|
|
+ void SetPacketAttributes(int ifindex, unsigned short hatype, unsigned char halen) {
|
|
+ sockaddr_ll* sll = reinterpret_cast<sockaddr_ll*>(&addr);
|
|
+ sll->sll_ifindex = ifindex;
|
|
+ sll->sll_hatype = hatype;
|
|
+ sll->sll_halen = halen;
|
|
+ }
|
|
+ private:
|
|
+ // Returns a pointer to the first byte in the address data (which is
|
|
+ // stored in network byte order).
|
|
+ uint8_t* SockaddrBytes(int family, sockaddr_storage* ss) {
|
|
+ if (family == AF_INET) {
|
|
+ sockaddr_in* ss4 = reinterpret_cast<sockaddr_in*>(ss);
|
|
+ return reinterpret_cast<uint8_t*>(&ss4->sin_addr);
|
|
+ } else if (family == AF_INET6) {
|
|
+ sockaddr_in6* ss6 = reinterpret_cast<sockaddr_in6*>(ss);
|
|
+ return reinterpret_cast<uint8_t*>(&ss6->sin6_addr);
|
|
+ } else if (family == AF_PACKET) {
|
|
+ sockaddr_ll* sll = reinterpret_cast<sockaddr_ll*>(ss);
|
|
+ return reinterpret_cast<uint8_t*>(&sll->sll_addr);
|
|
+ }
|
|
+ return nullptr;
|
|
+ }
|
|
+};
|
|
+ifaddrs_storage* new_ifaddrs_storage(ifaddrs** list) {
|
|
+ ifaddrs_storage *storage;
|
|
+ memset(storage, 0, sizeof(*storage));
|
|
+ // push_front onto `list`.
|
|
+ storage->ifa.ifa_next = *list;
|
|
+ *list = reinterpret_cast<ifaddrs*>(storage);
|
|
+ return storage;
|
|
+}
|
|
+#if !defined(__clang__)
|
|
+// GCC gets confused by NLMSG_DATA and doesn't realize that the old-style
|
|
+// cast is from a system header and should be ignored.
|
|
+#pragma GCC diagnostic ignored "-Wold-style-cast"
|
|
+#endif
|
|
+static void __handle_netlink_response(ifaddrs** out, nlmsghdr* hdr) {
|
|
+ if (hdr->nlmsg_type == RTM_NEWLINK) {
|
|
+ ifinfomsg* ifi = reinterpret_cast<ifinfomsg*>(NLMSG_DATA(hdr));
|
|
+ // Create a new ifaddr entry, and set the interface index and flags.
|
|
+ ifaddrs_storage* new_addr = new_ifaddrs_storage(out);
|
|
+ new_addr->interface_index = ifi->ifi_index;
|
|
+ new_addr->ifa.ifa_flags = ifi->ifi_flags;
|
|
+ // Go through the various bits of information and find the name.
|
|
+ rtattr* rta = IFLA_RTA(ifi);
|
|
+ size_t rta_len = IFLA_PAYLOAD(hdr);
|
|
+ while (RTA_OK(rta, rta_len)) {
|
|
+ if (rta->rta_type == IFLA_ADDRESS) {
|
|
+ if (RTA_PAYLOAD(rta) < sizeof(new_addr->addr)) {
|
|
+ new_addr->SetAddress(AF_PACKET, RTA_DATA(rta), RTA_PAYLOAD(rta));
|
|
+ new_addr->SetPacketAttributes(ifi->ifi_index, ifi->ifi_type, RTA_PAYLOAD(rta));
|
|
+ }
|
|
+ } else if (rta->rta_type == IFLA_BROADCAST) {
|
|
+ if (RTA_PAYLOAD(rta) < sizeof(new_addr->ifa_ifu)) {
|
|
+ new_addr->SetBroadcastAddress(AF_PACKET, RTA_DATA(rta), RTA_PAYLOAD(rta));
|
|
+ new_addr->SetPacketAttributes(ifi->ifi_index, ifi->ifi_type, RTA_PAYLOAD(rta));
|
|
+ }
|
|
+ } else if (rta->rta_type == IFLA_IFNAME) {
|
|
+ if (RTA_PAYLOAD(rta) < sizeof(new_addr->name)) {
|
|
+ memcpy(new_addr->name, RTA_DATA(rta), RTA_PAYLOAD(rta));
|
|
+ new_addr->ifa.ifa_name = new_addr->name;
|
|
+ }
|
|
+ }
|
|
+ rta = RTA_NEXT(rta, rta_len);
|
|
+ }
|
|
+ } else if (hdr->nlmsg_type == RTM_NEWADDR) {
|
|
+ ifaddrmsg* msg = reinterpret_cast<ifaddrmsg*>(NLMSG_DATA(hdr));
|
|
+ // We should already know about this from an RTM_NEWLINK message.
|
|
+ const ifaddrs_storage* addr = reinterpret_cast<const ifaddrs_storage*>(*out);
|
|
+ while (addr != nullptr && addr->interface_index != static_cast<int>(msg->ifa_index)) {
|
|
+ addr = reinterpret_cast<const ifaddrs_storage*>(addr->ifa.ifa_next);
|
|
+ }
|
|
+ // If this is an unknown interface, ignore whatever we're being told about it.
|
|
+ if (addr == nullptr) return;
|
|
+ // Create a new ifaddr entry and copy what we already know.
|
|
+ ifaddrs_storage* new_addr = new_ifaddrs_storage(out);
|
|
+ // We can just copy the name rather than look for IFA_LABEL.
|
|
+ strcpy(new_addr->name, addr->name);
|
|
+ new_addr->ifa.ifa_name = new_addr->name;
|
|
+ new_addr->ifa.ifa_flags = addr->ifa.ifa_flags;
|
|
+ new_addr->interface_index = addr->interface_index;
|
|
+ // Go through the various bits of information and find the address
|
|
+ // and any broadcast/destination address.
|
|
+ rtattr* rta = IFA_RTA(msg);
|
|
+ size_t rta_len = IFA_PAYLOAD(hdr);
|
|
+ while (RTA_OK(rta, rta_len)) {
|
|
+ if (rta->rta_type == IFA_ADDRESS) {
|
|
+ if (msg->ifa_family == AF_INET || msg->ifa_family == AF_INET6) {
|
|
+ new_addr->SetAddress(msg->ifa_family, RTA_DATA(rta), RTA_PAYLOAD(rta));
|
|
+ new_addr->SetNetmask(msg->ifa_family, msg->ifa_prefixlen);
|
|
+ }
|
|
+ } else if (rta->rta_type == IFA_BROADCAST) {
|
|
+ if (msg->ifa_family == AF_INET || msg->ifa_family == AF_INET6) {
|
|
+ new_addr->SetBroadcastAddress(msg->ifa_family, RTA_DATA(rta), RTA_PAYLOAD(rta));
|
|
+ }
|
|
+ }
|
|
+ rta = RTA_NEXT(rta, rta_len);
|
|
+ }
|
|
+ }
|
|
+}
|
|
+static bool __send_netlink_request(int fd, int type) {
|
|
+ struct NetlinkMessage {
|
|
+ nlmsghdr hdr;
|
|
+ rtgenmsg msg;
|
|
+ } request;
|
|
+ memset(&request, 0, sizeof(request));
|
|
+ request.hdr.nlmsg_flags = NLM_F_DUMP | NLM_F_REQUEST;
|
|
+ request.hdr.nlmsg_type = type;
|
|
+ request.hdr.nlmsg_len = sizeof(request);
|
|
+ request.msg.rtgen_family = AF_UNSPEC; // All families.
|
|
+ return (TEMP_FAILURE_RETRY(send(fd, &request, sizeof(request), 0)) == sizeof(request));
|
|
+}
|
|
+static bool __read_netlink_responses(int fd, ifaddrs** out, char* buf, size_t buf_len) {
|
|
+ ssize_t bytes_read;
|
|
+ // Read through all the responses, handing interesting ones to __handle_netlink_response.
|
|
+ while ((bytes_read = TEMP_FAILURE_RETRY(recv(fd, buf, buf_len, 0))) > 0) {
|
|
+ nlmsghdr* hdr = reinterpret_cast<nlmsghdr*>(buf);
|
|
+ for (; NLMSG_OK(hdr, static_cast<size_t>(bytes_read)); hdr = NLMSG_NEXT(hdr, bytes_read)) {
|
|
+ if (hdr->nlmsg_type == NLMSG_DONE) return true;
|
|
+ if (hdr->nlmsg_type == NLMSG_ERROR) return false;
|
|
+ __handle_netlink_response(out, hdr);
|
|
+ }
|
|
+ }
|
|
+ // We only get here if recv fails before we see a NLMSG_DONE.
|
|
+ return false;
|
|
+}
|
|
+int getifaddrs(ifaddrs** out) {
|
|
+ // Make cleanup easy.
|
|
+ *out = nullptr;
|
|
+ // The kernel keeps packets under 8KiB (NLMSG_GOODSIZE),
|
|
+ // but that's a bit too large to go on the stack.
|
|
+ size_t buf_len = 8192;
|
|
+ char* buf = NEW_C_HEAP_ARRAY(char, buf_len, mtInternal);
|
|
+ if (buf == nullptr) return -1;
|
|
+ // Open the netlink socket and ask for all the links and addresses.
|
|
+ int fd = socket(PF_NETLINK, SOCK_RAW | SOCK_CLOEXEC, NETLINK_ROUTE);
|
|
+ bool okay = fd != -1 &&
|
|
+ __send_netlink_request(fd, RTM_GETLINK) && __read_netlink_responses(fd, out, buf, buf_len) &&
|
|
+ __send_netlink_request(fd, RTM_GETADDR) && __read_netlink_responses(fd, out, buf, buf_len);
|
|
+ if (!okay) {
|
|
+ freeifaddrs(*out);
|
|
+ // Ensure that callers crash if they forget to check for success.
|
|
+ *out = nullptr;
|
|
+ }
|
|
+ {
|
|
+ int saved_errno = errno;
|
|
+ close(fd);
|
|
+ FREE_C_HEAP_ARRAY(char, buf);
|
|
+ errno = saved_errno;
|
|
+ }
|
|
+ return okay ? 0 : -1;
|
|
+}
|
|
+void freeifaddrs(ifaddrs* list) {
|
|
+ while (list != nullptr) {
|
|
+ ifaddrs* current = list;
|
|
+ list = list->ifa_next;
|
|
+ free(current);
|
|
+ }
|
|
+}
|
|
+#endif
|
|
+
|
|
/**
|
|
/proc/[number]/stat
|
|
Status information about the process. This is used by ps(1). It is defined in /usr/src/linux/fs/proc/array.c.
|
|
diff --git a/src/hotspot/os/posix/os_posix.cpp b/src/hotspot/os/posix/os_posix.cpp
|
|
index cf0f48974..04a5930b5 100644
|
|
--- a/src/hotspot/os/posix/os_posix.cpp
|
|
+++ b/src/hotspot/os/posix/os_posix.cpp
|
|
@@ -74,7 +74,9 @@
|
|
#include <sys/wait.h>
|
|
#include <time.h>
|
|
#include <unistd.h>
|
|
+#ifndef __ANDROID__
|
|
#include <utmpx.h>
|
|
+#endif
|
|
|
|
#ifdef __APPLE__
|
|
#include <crt_externs.h>
|
|
@@ -453,6 +455,7 @@ void os::Posix::print_load_average(outputStream* st) {
|
|
// unfortunately it does not work on macOS and Linux because the utx chain has no entry
|
|
// for reboot at least on my test machines
|
|
void os::Posix::print_uptime_info(outputStream* st) {
|
|
+#ifndef __ANDROID__
|
|
int bootsec = -1;
|
|
int currsec = time(nullptr);
|
|
struct utmpx* ent;
|
|
@@ -467,6 +470,7 @@ void os::Posix::print_uptime_info(outputStream* st) {
|
|
if (bootsec != -1) {
|
|
os::print_dhm(st, "OS uptime:", (long) (currsec-bootsec));
|
|
}
|
|
+#endif
|
|
}
|
|
|
|
static void print_rlimit(outputStream* st, const char* msg,
|
|
@@ -1921,11 +1925,31 @@ int os::fork_and_exec(const char* cmd) {
|
|
const char* argv[4] = {"sh", "-c", cmd, nullptr};
|
|
pid_t pid = -1;
|
|
char** env = os::get_environ();
|
|
+#ifndef __ANDROID__
|
|
// Note: cast is needed because posix_spawn() requires - for compatibility with ancient
|
|
// C-code - a non-const argv/envp pointer array. But it is fine to hand in literal
|
|
// strings and just cast the constness away. See also ProcessImpl_md.c.
|
|
int rc = ::posix_spawn(&pid, "/bin/sh", nullptr, nullptr, (char**) argv, env);
|
|
if (rc == 0) {
|
|
+#else
|
|
+ pid = ::fork();
|
|
+
|
|
+ if (pid < 0) {
|
|
+ // fork failed
|
|
+ return -1;
|
|
+
|
|
+ } else if (pid == 0) {
|
|
+ // child process
|
|
+
|
|
+ ::execve("/bin/sh", (char* const*)argv, env);
|
|
+
|
|
+ // execve failed
|
|
+ ::_exit(-1);
|
|
+
|
|
+ } else {
|
|
+ // copied from J2SE ..._waitForProcessExit() in UNIXProcess_md.c; we don't
|
|
+ // care about the actual exit code, for now.
|
|
+#endif
|
|
int status;
|
|
// Wait for the child process to exit. This returns immediately if
|
|
// the child has already exited. */
|
|
@@ -1950,9 +1974,11 @@ int os::fork_and_exec(const char* cmd) {
|
|
// Unknown exit code; pass it through
|
|
return status;
|
|
}
|
|
+#ifndef __ANDROID__
|
|
} else {
|
|
// Don't log, we are inside error handling
|
|
return -1;
|
|
+#endif
|
|
}
|
|
}
|
|
|
|
diff --git a/src/hotspot/os_cpu/linux_aarch64/threadLS_linux_aarch64.S b/src/hotspot/os_cpu/linux_aarch64/threadLS_linux_aarch64.S
|
|
index ac60d6aa9..0645f0e00 100644
|
|
--- a/src/hotspot/os_cpu/linux_aarch64/threadLS_linux_aarch64.S
|
|
+++ b/src/hotspot/os_cpu/linux_aarch64/threadLS_linux_aarch64.S
|
|
@@ -19,6 +19,7 @@
|
|
// or visit www.oracle.com if you need additional information or have any
|
|
// questions.
|
|
|
|
+#ifndef __ANDROID__
|
|
// JavaThread::aarch64_get_thread_helper()
|
|
//
|
|
// Return the current thread pointer in x0.
|
|
@@ -44,3 +45,4 @@ _ZN10JavaThread25aarch64_get_thread_helperEv:
|
|
ret
|
|
|
|
.size _ZN10JavaThread25aarch64_get_thread_helperEv, .-_ZN10JavaThread25aarch64_get_thread_helperEv
|
|
+#endif
|
|
diff --git a/src/hotspot/os_cpu/linux_arm/fpu_control.h b/src/hotspot/os_cpu/linux_arm/fpu_control.h
|
|
new file mode 100644
|
|
index 000000000..745243d62
|
|
--- /dev/null
|
|
+++ b/src/hotspot/os_cpu/linux_arm/fpu_control.h
|
|
@@ -0,0 +1,59 @@
|
|
+/* FPU control word definitions. ARM VFP version.
|
|
+ Copyright (C) 2004-2019 Free Software Foundation, Inc.
|
|
+ This file is part of the GNU C Library.
|
|
+ The GNU C Library is free software; you can redistribute it and/or
|
|
+ modify it under the terms of the GNU Lesser General Public
|
|
+ License as published by the Free Software Foundation; either
|
|
+ version 2.1 of the License, or (at your option) any later version.
|
|
+ The GNU C Library is distributed in the hope that it will be useful,
|
|
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
+ Lesser General Public License for more details.
|
|
+ You should have received a copy of the GNU Lesser General Public
|
|
+ License along with the GNU C Library. If not, see
|
|
+ <http://www.gnu.org/licenses/>. */
|
|
+#ifndef _FPU_CONTROL_H
|
|
+#define _FPU_CONTROL_H
|
|
+#if !(defined(_LIBC) && !defined(_LIBC_TEST)) && defined(__SOFTFP__)
|
|
+#define _FPU_RESERVED 0xffffffff
|
|
+#define _FPU_DEFAULT 0x00000000
|
|
+typedef unsigned int fpu_control_t;
|
|
+#define _FPU_GETCW(cw) (cw) = 0
|
|
+#define _FPU_SETCW(cw) (void) (cw)
|
|
+extern fpu_control_t __fpu_control;
|
|
+#else
|
|
+/* masking of interrupts */
|
|
+#define _FPU_MASK_IM 0x00000100 /* invalid operation */
|
|
+#define _FPU_MASK_ZM 0x00000200 /* divide by zero */
|
|
+#define _FPU_MASK_OM 0x00000400 /* overflow */
|
|
+#define _FPU_MASK_UM 0x00000800 /* underflow */
|
|
+#define _FPU_MASK_PM 0x00001000 /* inexact */
|
|
+#define _FPU_MASK_NZCV 0xf0000000 /* NZCV flags */
|
|
+#define _FPU_MASK_RM 0x00c00000 /* rounding mode */
|
|
+#define _FPU_MASK_EXCEPT 0x00001f1f /* all exception flags */
|
|
+/* Some bits in the FPSCR are not yet defined. They must be preserved when
|
|
+ modifying the contents. */
|
|
+#define _FPU_RESERVED 0x00086060
|
|
+#define _FPU_DEFAULT 0x00000000
|
|
+/* Default + exceptions enabled. */
|
|
+#define _FPU_IEEE (_FPU_DEFAULT | 0x00001f00)
|
|
+/* Type of the control word. */
|
|
+typedef unsigned int fpu_control_t;
|
|
+/* Macros for accessing the hardware control word. */
|
|
+#ifdef __SOFTFP__
|
|
+/* This is fmrx %0, fpscr. */
|
|
+# define _FPU_GETCW(cw) \
|
|
+ __asm__ __volatile__ ("mrc p10, 7, %0, cr1, cr0, 0" : "=r" (cw))
|
|
+/* This is fmxr fpscr, %0. */
|
|
+# define _FPU_SETCW(cw) \
|
|
+ __asm__ __volatile__ ("mcr p10, 7, %0, cr1, cr0, 0" : : "r" (cw))
|
|
+#else
|
|
+# define _FPU_GETCW(cw) \
|
|
+ __asm__ __volatile__ ("vmrs %0, fpscr" : "=r" (cw))
|
|
+# define _FPU_SETCW(cw) \
|
|
+ __asm__ __volatile__ ("vmsr fpscr, %0" : : "r" (cw))
|
|
+#endif
|
|
+/* Default control word set at startup. */
|
|
+extern fpu_control_t __fpu_control;
|
|
+#endif /* __SOFTFP__ */
|
|
+#endif /* _FPU_CONTROL_H */
|
|
diff --git a/src/hotspot/os_cpu/linux_arm/linux_arm_32.S b/src/hotspot/os_cpu/linux_arm/linux_arm_32.S
|
|
index eb560d8f0..be8da136b 100644
|
|
--- a/src/hotspot/os_cpu/linux_arm/linux_arm_32.S
|
|
+++ b/src/hotspot/os_cpu/linux_arm/linux_arm_32.S
|
|
@@ -88,7 +88,7 @@ dw_f2b_loop_32:
|
|
stmia to!, {r3 - r9, ip}
|
|
bgt dw_f2b_loop_32
|
|
dw_f2b_loop_32_finish:
|
|
- addlts r2, #32
|
|
+ addslt r2, #32
|
|
beq disjoint_words_finish
|
|
cmp r2, #16
|
|
blt disjoint_words_small
|
|
@@ -136,7 +136,7 @@ cw_f2b_loop_32:
|
|
stmia to!, {r3 - r9, ip}
|
|
bgt cw_f2b_loop_32
|
|
cw_f2b_loop_32_finish:
|
|
- addlts r2, #32
|
|
+ addslt r2, #32
|
|
beq conjoint_words_finish
|
|
cmp r2, #16
|
|
blt conjoint_words_small
|
|
@@ -169,7 +169,7 @@ cw_b2f_loop_32:
|
|
stmdb to!, {r3-r9,ip}
|
|
bgt cw_b2f_loop_32
|
|
cw_b2f_loop_32_finish:
|
|
- addlts r2, #32
|
|
+ addslt r2, #32
|
|
beq conjoint_words_finish
|
|
cmp r2, #16
|
|
blt cw_b2f_copy_small
|
|
@@ -221,7 +221,7 @@ cs_f2b_loop_32:
|
|
stmia to!, {r3 - r9, ip}
|
|
bgt cs_f2b_loop_32
|
|
cs_f2b_loop_32_finish:
|
|
- addlts r2, #32
|
|
+ addslt r2, #32
|
|
beq conjoint_shorts_finish
|
|
movs r6, r2, lsr #3
|
|
.align 3
|
|
@@ -237,11 +237,11 @@ cs_f2b_4:
|
|
beq conjoint_shorts_finish
|
|
cmp r2, #4
|
|
ldrh r3, [from], #2
|
|
- ldrgeh r4, [from], #2
|
|
- ldrgth r5, [from], #2
|
|
+ ldrhge r4, [from], #2
|
|
+ ldrhgt r5, [from], #2
|
|
strh r3, [to], #2
|
|
- strgeh r4, [to], #2
|
|
- strgth r5, [to], #2
|
|
+ strhge r4, [to], #2
|
|
+ strhgt r5, [to], #2
|
|
b conjoint_shorts_finish
|
|
|
|
# Destination not aligned
|
|
@@ -299,11 +299,11 @@ cs_f2b_4_u:
|
|
beq conjoint_shorts_finish
|
|
cmp r2, #4
|
|
ldrh r3, [from], #2
|
|
- ldrgeh r4, [from], #2
|
|
- ldrgth r5, [from], #2
|
|
+ ldrhge r4, [from], #2
|
|
+ ldrhgt r5, [from], #2
|
|
strh r3, [to], #2
|
|
- strgeh r4, [to], #2
|
|
- strgth r5, [to], #2
|
|
+ strhge r4, [to], #2
|
|
+ strhgt r5, [to], #2
|
|
b conjoint_shorts_finish
|
|
|
|
# Src and dest overlap, copy in a descending order
|
|
@@ -326,7 +326,7 @@ cs_b2f_loop_32:
|
|
stmdb to!, {r3-r9,ip}
|
|
bgt cs_b2f_loop_32
|
|
cs_b2f_loop_32_finish:
|
|
- addlts r2, #32
|
|
+ addslt r2, #32
|
|
beq conjoint_shorts_finish
|
|
cmp r2, #24
|
|
blt cs_b2f_16
|
|
@@ -352,11 +352,11 @@ cs_b2f_8:
|
|
cs_b2f_all_copy:
|
|
cmp r2, #4
|
|
ldrh r3, [from, #-2]!
|
|
- ldrgeh r4, [from, #-2]!
|
|
- ldrgth r5, [from, #-2]!
|
|
+ ldrhge r4, [from, #-2]!
|
|
+ ldrhgt r5, [from, #-2]!
|
|
strh r3, [to, #-2]!
|
|
- strgeh r4, [to, #-2]!
|
|
- strgth r5, [to, #-2]!
|
|
+ strhge r4, [to, #-2]!
|
|
+ strhgt r5, [to, #-2]!
|
|
b conjoint_shorts_finish
|
|
|
|
# Destination not aligned
|
|
@@ -391,7 +391,7 @@ cs_b2f_16_loop_u:
|
|
bgt cs_b2f_16_loop_u
|
|
beq conjoint_shorts_finish
|
|
cs_b2f_16_loop_u_finished:
|
|
- addlts r2, #16
|
|
+ addslt r2, #16
|
|
ldr r3, [from]
|
|
cmp r2, #10
|
|
blt cs_b2f_2_u_loop
|
|
@@ -454,7 +454,7 @@ cl_f2b_loop_32:
|
|
stmia to!, {r3 - r9, ip}
|
|
bgt cl_f2b_loop_32
|
|
cl_f2b_loop_32_finish:
|
|
- addlts r2, #32
|
|
+ addslt r2, #32
|
|
beq conjoint_longs_finish
|
|
conjoint_longs_small:
|
|
cmp r2, #16
|
|
@@ -487,7 +487,7 @@ cl_b2f_loop_32:
|
|
stmdb to!, {r3 - r9, ip}
|
|
bgt cl_b2f_loop_32
|
|
cl_b2f_loop_32_finish:
|
|
- addlts r2, #32
|
|
+ addslt r2, #32
|
|
beq conjoint_longs_finish
|
|
cmp r2, #16
|
|
blt cl_b2f_copy_8
|
|
diff --git a/src/hotspot/os_cpu/linux_arm/os_linux_arm.cpp b/src/hotspot/os_cpu/linux_arm/os_linux_arm.cpp
|
|
index d4c9bb304..3123efef2 100644
|
|
--- a/src/hotspot/os_cpu/linux_arm/os_linux_arm.cpp
|
|
+++ b/src/hotspot/os_cpu/linux_arm/os_linux_arm.cpp
|
|
@@ -72,7 +72,11 @@
|
|
# include <pwd.h>
|
|
# include <poll.h>
|
|
# include <ucontext.h>
|
|
+#ifndef __ANDROID__
|
|
# include <fpu_control.h>
|
|
+#else
|
|
+# include "fpu_control.h" //include the local header
|
|
+#endif
|
|
# include <asm/ptrace.h>
|
|
|
|
#define SPELL_REG_SP "sp"
|
|
@@ -90,8 +94,14 @@ enum {
|
|
#endif
|
|
|
|
address os::current_stack_pointer() {
|
|
+#if defined(__clang__) || defined(__llvm__)
|
|
+ void *sp;
|
|
+ __asm__("mov %0, " SPELL_REG_SP : "=r"(sp));
|
|
+ return (address) sp;
|
|
+#else
|
|
register address sp __asm__ (SPELL_REG_SP);
|
|
return sp;
|
|
+#endif
|
|
}
|
|
|
|
char* os::non_memory_address_word() {
|
|
@@ -415,8 +425,8 @@ void os::setup_fpu() {
|
|
#if !defined(__SOFTFP__) && defined(__VFP_FP__)
|
|
// Turn on IEEE-754 compliant VFP mode
|
|
__asm__ volatile (
|
|
- "mov %%r0, #0;"
|
|
- "fmxr fpscr, %%r0"
|
|
+ "mov r0, #0;"
|
|
+ "fmxr fpscr, r0"
|
|
: /* no output */ : /* no input */ : "r0"
|
|
);
|
|
#endif
|
|
diff --git a/src/hotspot/os_cpu/linux_x86/fpu_control.h b/src/hotspot/os_cpu/linux_x86/fpu_control.h
|
|
new file mode 100644
|
|
index 000000000..605302c09
|
|
--- /dev/null
|
|
+++ b/src/hotspot/os_cpu/linux_x86/fpu_control.h
|
|
@@ -0,0 +1,109 @@
|
|
+/* FPU control word bits. x86 version.
|
|
+ Copyright (C) 1993-2012 Free Software Foundation, Inc.
|
|
+ This file is part of the GNU C Library.
|
|
+ Contributed by Olaf Flebbe.
|
|
+
|
|
+ The GNU C Library is free software; you can redistribute it and/or
|
|
+ modify it under the terms of the GNU Lesser General Public
|
|
+ License as published by the Free Software Foundation; either
|
|
+ version 2.1 of the License, or (at your option) any later version.
|
|
+
|
|
+ The GNU C Library is distributed in the hope that it will be useful,
|
|
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
+ Lesser General Public License for more details.
|
|
+
|
|
+ You should have received a copy of the GNU Lesser General Public
|
|
+ License along with the GNU C Library; if not, see
|
|
+ <http://www.gnu.org/licenses/>. */
|
|
+
|
|
+#ifndef _FPU_CONTROL_H
|
|
+#define _FPU_CONTROL_H 1
|
|
+
|
|
+/* Note that this file sets on x86-64 only the x87 FPU, it does not
|
|
+ touch the SSE unit. */
|
|
+
|
|
+/* Here is the dirty part. Set up your 387 through the control word
|
|
+ * (cw) register.
|
|
+ *
|
|
+ * 15-13 12 11-10 9-8 7-6 5 4 3 2 1 0
|
|
+ * | reserved | IC | RC | PC | reserved | PM | UM | OM | ZM | DM | IM
|
|
+ *
|
|
+ * IM: Invalid operation mask
|
|
+ * DM: Denormalized operand mask
|
|
+ * ZM: Zero-divide mask
|
|
+ * OM: Overflow mask
|
|
+ * UM: Underflow mask
|
|
+ * PM: Precision (inexact result) mask
|
|
+ *
|
|
+ * Mask bit is 1 means no interrupt.
|
|
+ *
|
|
+ * PC: Precision control
|
|
+ * 11 - round to extended precision
|
|
+ * 10 - round to double precision
|
|
+ * 00 - round to single precision
|
|
+ *
|
|
+ * RC: Rounding control
|
|
+ * 00 - rounding to nearest
|
|
+ * 01 - rounding down (toward - infinity)
|
|
+ * 10 - rounding up (toward + infinity)
|
|
+ * 11 - rounding toward zero
|
|
+ *
|
|
+ * IC: Infinity control
|
|
+ * That is for 8087 and 80287 only.
|
|
+ *
|
|
+ * The hardware default is 0x037f which we use.
|
|
+ */
|
|
+
|
|
+#include <features.h>
|
|
+
|
|
+/* masking of interrupts */
|
|
+#define _FPU_MASK_IM 0x01
|
|
+#define _FPU_MASK_DM 0x02
|
|
+#define _FPU_MASK_ZM 0x04
|
|
+#define _FPU_MASK_OM 0x08
|
|
+#define _FPU_MASK_UM 0x10
|
|
+#define _FPU_MASK_PM 0x20
|
|
+
|
|
+/* precision control */
|
|
+#define _FPU_EXTENDED 0x300 /* libm requires double extended precision. */
|
|
+#define _FPU_DOUBLE 0x200
|
|
+#define _FPU_SINGLE 0x0
|
|
+
|
|
+/* rounding control */
|
|
+#define _FPU_RC_NEAREST 0x0 /* RECOMMENDED */
|
|
+#define _FPU_RC_DOWN 0x400
|
|
+#define _FPU_RC_UP 0x800
|
|
+#define _FPU_RC_ZERO 0xC00
|
|
+
|
|
+#define _FPU_RESERVED 0xF0C0 /* Reserved bits in cw */
|
|
+
|
|
+
|
|
+/* The fdlibm code requires strict IEEE double precision arithmetic,
|
|
+ and no interrupts for exceptions, rounding to nearest. */
|
|
+
|
|
+#define _FPU_DEFAULT 0x037f
|
|
+
|
|
+/* IEEE: same as above. */
|
|
+#define _FPU_IEEE 0x037f
|
|
+
|
|
+/* Type of the control word. */
|
|
+typedef unsigned int fpu_control_t __attribute__ ((__mode__ (__HI__)));
|
|
+
|
|
+/* Macros for accessing the hardware control word. "*&" is used to
|
|
+ work around a bug in older versions of GCC. __volatile__ is used
|
|
+ to support combination of writing the control register and reading
|
|
+ it back. Without __volatile__, the old value may be used for reading
|
|
+ back under compiler optimization.
|
|
+
|
|
+ Note that the use of these macros is not sufficient anymore with
|
|
+ recent hardware nor on x86-64. Some floating point operations are
|
|
+ executed in the SSE/SSE2 engines which have their own control and
|
|
+ status register. */
|
|
+#define _FPU_GETCW(cw) __asm__ __volatile__ ("fnstcw %0" : "=m" (*&cw))
|
|
+#define _FPU_SETCW(cw) __asm__ __volatile__ ("fldcw %0" : : "m" (*&cw))
|
|
+
|
|
+/* Default control word set at startup. */
|
|
+extern fpu_control_t __fpu_control;
|
|
+
|
|
+#endif /* fpu_control.h */
|
|
diff --git a/src/hotspot/os_cpu/linux_x86/os_linux_x86.cpp b/src/hotspot/os_cpu/linux_x86/os_linux_x86.cpp
|
|
index 90c7d3c93..0a10fba48 100644
|
|
--- a/src/hotspot/os_cpu/linux_x86/os_linux_x86.cpp
|
|
+++ b/src/hotspot/os_cpu/linux_x86/os_linux_x86.cpp
|
|
@@ -74,8 +74,10 @@
|
|
# include <pwd.h>
|
|
# include <poll.h>
|
|
# include <ucontext.h>
|
|
-#ifndef AMD64
|
|
+#if !defined(AMD64) && !defined(__ANDROID__)
|
|
# include <fpu_control.h>
|
|
+#elif defined(__ANDROID__)
|
|
+# include "fpu_control.h"
|
|
#endif
|
|
|
|
#ifdef AMD64
|
|
diff --git a/src/hotspot/share/utilities/elfFile.hpp b/src/hotspot/share/utilities/elfFile.hpp
|
|
index 32ce08821..7103f3736 100644
|
|
--- a/src/hotspot/share/utilities/elfFile.hpp
|
|
+++ b/src/hotspot/share/utilities/elfFile.hpp
|
|
@@ -47,8 +47,10 @@ typedef Elf64_Phdr Elf_Phdr;
|
|
typedef Elf64_Sym Elf_Sym;
|
|
|
|
#if !defined(_ALLBSD_SOURCE) || defined(__APPLE__)
|
|
+#ifndef ELF_ST_TYPE
|
|
#define ELF_ST_TYPE ELF64_ST_TYPE
|
|
#endif
|
|
+#endif
|
|
|
|
#else
|
|
|
|
@@ -62,7 +64,7 @@ typedef Elf32_Shdr Elf_Shdr;
|
|
typedef Elf32_Phdr Elf_Phdr;
|
|
typedef Elf32_Sym Elf_Sym;
|
|
|
|
-#if !defined(_ALLBSD_SOURCE) || defined(__APPLE__)
|
|
+#if (!defined(_ALLBSD_SOURCE) || defined(__APPLE__)) && !defined(ELF_ST_TYPE)
|
|
#define ELF_ST_TYPE ELF32_ST_TYPE
|
|
#endif
|
|
#endif
|
|
diff --git a/src/hotspot/share/utilities/globalDefinitions_gcc.hpp b/src/hotspot/share/utilities/globalDefinitions_gcc.hpp
|
|
index 3da670ef4..89f2d944a 100644
|
|
--- a/src/hotspot/share/utilities/globalDefinitions_gcc.hpp
|
|
+++ b/src/hotspot/share/utilities/globalDefinitions_gcc.hpp
|
|
@@ -48,6 +48,10 @@
|
|
#include <limits.h>
|
|
#include <errno.h>
|
|
|
|
+#if defined(__ANDROID__) && !defined(ANDROID)
|
|
+#define ANDROID 1
|
|
+#endif
|
|
+
|
|
#if defined(LINUX) || defined(_ALLBSD_SOURCE)
|
|
#include <inttypes.h>
|
|
#include <signal.h>
|
|
diff --git a/src/java.base/share/native/libtinyiconv/iconv.cpp b/src/java.base/share/native/libtinyiconv/iconv.cpp
|
|
new file mode 100644
|
|
index 000000000..7018b6ce2
|
|
--- /dev/null
|
|
+++ b/src/java.base/share/native/libtinyiconv/iconv.cpp
|
|
@@ -0,0 +1,438 @@
|
|
+/*
|
|
+ * Copyright (C) 2017 The Android Open Source Project
|
|
+ * All rights reserved.
|
|
+ *
|
|
+ * Redistribution and use in source and binary forms, with or without
|
|
+ * modification, are permitted provided that the following conditions
|
|
+ * are met:
|
|
+ * * Redistributions of source code must retain the above copyright
|
|
+ * notice, this list of conditions and the following disclaimer.
|
|
+ * * Redistributions in binary form must reproduce the above copyright
|
|
+ * notice, this list of conditions and the following disclaimer in
|
|
+ * the documentation and/or other materials provided with the
|
|
+ * distribution.
|
|
+ *
|
|
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
|
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
|
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
|
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
|
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
|
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
|
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
|
|
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
|
|
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
|
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
|
|
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
|
+ * SUCH DAMAGE.
|
|
+ */
|
|
+
|
|
+#ifdef __ANDROID__
|
|
+
|
|
+#include <ctype.h>
|
|
+#include <endian.h>
|
|
+#include <errno.h>
|
|
+#include <iconv.h>
|
|
+#include <stdbool.h>
|
|
+#include <stdint.h>
|
|
+#include <stdlib.h>
|
|
+#include <string.h>
|
|
+#include <uchar.h>
|
|
+#include <wchar.h>
|
|
+
|
|
+__BEGIN_DECLS
|
|
+
|
|
+/*
|
|
+ * These return values are specified by POSIX for multibyte conversion
|
|
+ * functions.
|
|
+ */
|
|
+
|
|
+#ifdef __cplusplus
|
|
+#define __MB_ERR_ILLEGAL_SEQUENCE static_cast<size_t>(-1)
|
|
+#define __MB_ERR_INCOMPLETE_SEQUENCE static_cast<size_t>(-2)
|
|
+#else
|
|
+#define __MB_ERR_ILLEGAL_SEQUENCE (size_t)(-1)
|
|
+#define __MB_ERR_INCOMPLETE_SEQUENCE (size_t)(-2)
|
|
+#endif // __cplusplus
|
|
+#define __MB_IS_ERR(rv) (rv == __MB_ERR_ILLEGAL_SEQUENCE || \
|
|
+ rv == __MB_ERR_INCOMPLETE_SEQUENCE)
|
|
+static inline __wur size_t mbstate_bytes_so_far(const mbstate_t* ps) {
|
|
+ return
|
|
+ (ps->__seq[2] != 0) ? 3 :
|
|
+ (ps->__seq[1] != 0) ? 2 :
|
|
+ (ps->__seq[0] != 0) ? 1 : 0;
|
|
+}
|
|
+static inline void mbstate_set_byte(mbstate_t* ps, int i, char byte) {
|
|
+ ps->__seq[i] = (uint8_t)(byte);
|
|
+}
|
|
+static inline __wur uint8_t mbstate_get_byte(const mbstate_t* ps, int n) {
|
|
+ return ps->__seq[n];
|
|
+}
|
|
+static inline __wur size_t mbstate_reset_and_return_illegal(int _errno, mbstate_t* ps) {
|
|
+ errno = _errno;
|
|
+#ifdef __cplusplus
|
|
+ *(reinterpret_cast<uint32_t*>(ps->__seq)) = 0;
|
|
+#else
|
|
+ *(uint32_t*)(ps->__seq) = 0;
|
|
+#endif // __cplusplus
|
|
+ return __MB_ERR_ILLEGAL_SEQUENCE;
|
|
+}
|
|
+static inline __wur size_t mbstate_reset_and_return(int _return, mbstate_t* ps) {
|
|
+#ifdef __cplusplus
|
|
+ *(reinterpret_cast<uint32_t*>(ps->__seq)) = 0;
|
|
+#else
|
|
+ *(uint32_t*)(ps->__seq) = 0;
|
|
+#endif // __cplusplus
|
|
+ return _return;
|
|
+}
|
|
+
|
|
+#ifdef __cplusplus
|
|
+# define INVALID_ICONV_T reinterpret_cast<iconv_t>(-1)
|
|
+#else // !__cplusplus
|
|
+# define INVALID_ICONV_T (iconv_t)(-1)
|
|
+#endif // __cplusplus
|
|
+
|
|
+// Ideally we'd use icu4c but the API mismatch seems too great. So we just offer something
|
|
+// equivalent to (but slightly easier to use for runs of text than) <uchar.h>. If you're
|
|
+// here to add more encodings, consider working on finishing the icu4c NDK wrappers instead.
|
|
+
|
|
+#ifdef __cplusplus
|
|
+ enum Encoding
|
|
+#else
|
|
+ typedef enum
|
|
+#endif // __cplusplus
|
|
+{
|
|
+ US_ASCII,
|
|
+ UTF_8,
|
|
+ UTF_16_LE,
|
|
+ UTF_16_BE,
|
|
+ UTF_32_LE,
|
|
+ UTF_32_BE,
|
|
+ WCHAR_T,
|
|
+#ifdef __cplusplus
|
|
+ };
|
|
+#else
|
|
+ } Encoding;
|
|
+#endif // __cplusplus
|
|
+
|
|
+#ifdef __cplusplus
|
|
+ enum Mode
|
|
+#else
|
|
+ typedef enum
|
|
+#endif // __cplusplus
|
|
+{
|
|
+ ERROR,
|
|
+ IGNORE,
|
|
+ TRANSLIT,
|
|
+#ifdef __cplusplus
|
|
+ };
|
|
+#else
|
|
+ } Mode;
|
|
+#endif // __cplusplus
|
|
+
|
|
+// This matching is strange but true.
|
|
+// See http://www.unicode.org/reports/tr22/#Charset_Alias_Matching.
|
|
+static bool __match_encoding(const char* lhs, const char* rhs) {
|
|
+ while (*lhs && *rhs) {
|
|
+ // Skip non-alnum in lhs; "UTF-8", "UTF_8", "UTF8", "UTF 8" are all equivalent.
|
|
+ // Also implement the "delete each 0 that is not preceded by a digit" rule.
|
|
+ for (; *lhs; ++lhs) {
|
|
+ if (isalnum(*lhs) && (*lhs != '0' || !isdigit(*(lhs + 1)))) break;
|
|
+ }
|
|
+ // Case doesn't matter either.
|
|
+ if (tolower(*lhs) != tolower(*rhs)) break;
|
|
+ ++lhs;
|
|
+ ++rhs;
|
|
+ }
|
|
+ // As a special case we treat the GNU "//" extensions as end of string.
|
|
+ if ((*lhs == '\0' || strstr(lhs, "//") == lhs) && *rhs == '\0') return true;
|
|
+ return false;
|
|
+}
|
|
+
|
|
+static bool __parse_encoding(const char* s, Encoding* encoding, Mode* mode) {
|
|
+ const char* suffix = strstr(s, "//");
|
|
+ if (suffix) {
|
|
+ if (!mode) return false;
|
|
+ if (strcmp(suffix, "//IGNORE") == 0) {
|
|
+ *mode = IGNORE;
|
|
+ } else if (strcmp(suffix, "//TRANSLIT") == 0) {
|
|
+ *mode = TRANSLIT;
|
|
+ } else {
|
|
+ return false;
|
|
+ }
|
|
+ }
|
|
+ if (__match_encoding(s, "utf8")) {
|
|
+ *encoding = UTF_8;
|
|
+ } else if (__match_encoding(s, "ascii") || __match_encoding(s, "usascii")) {
|
|
+ *encoding = US_ASCII;
|
|
+ } else if (__match_encoding(s, "utf16le")) {
|
|
+ *encoding = UTF_16_LE;
|
|
+ } else if (__match_encoding(s, "utf16be")) {
|
|
+ *encoding = UTF_16_BE;
|
|
+ } else if (__match_encoding(s, "utf32le")) {
|
|
+ *encoding = UTF_32_LE;
|
|
+ } else if (__match_encoding(s, "utf32be")) {
|
|
+ *encoding = UTF_32_BE;
|
|
+ } else if (__match_encoding(s, "wchart")) {
|
|
+ *encoding = WCHAR_T;
|
|
+ } else {
|
|
+ return false;
|
|
+ }
|
|
+ return true;
|
|
+}
|
|
+
|
|
+struct __iconv_t {
|
|
+ Encoding src_encoding;
|
|
+ Encoding dst_encoding;
|
|
+ Mode mode;
|
|
+/*
|
|
+ __iconv_t() : mode(ERROR) {
|
|
+ }
|
|
+*/
|
|
+ int Convert(char** src_buf0, size_t* src_bytes_left0, char** dst_buf0, size_t* dst_bytes_left0) {
|
|
+ // Reset state.
|
|
+ wc = 0;
|
|
+ memset(&ps, 0, sizeof(ps));
|
|
+ replacement_count = 0;
|
|
+ ignored = false;
|
|
+ src_buf = src_buf0;
|
|
+ src_bytes_left = src_bytes_left0;
|
|
+ dst_buf = dst_buf0;
|
|
+ dst_bytes_left = dst_bytes_left0;
|
|
+ while (*src_bytes_left > 0) {
|
|
+ if (!GetNext() || !Convert()) return -1;
|
|
+ }
|
|
+ return Done();
|
|
+ }
|
|
+ private:
|
|
+ char32_t wc;
|
|
+ char buf[16];
|
|
+ size_t src_bytes_used;
|
|
+ size_t dst_bytes_used;
|
|
+ mbstate_t ps;
|
|
+ size_t replacement_count;
|
|
+ bool ignored;
|
|
+ char** src_buf;
|
|
+ size_t* src_bytes_left;
|
|
+ char** dst_buf;
|
|
+ size_t* dst_bytes_left;
|
|
+ bool GetNext() {
|
|
+ errno = 0;
|
|
+ switch (src_encoding) {
|
|
+ case US_ASCII:
|
|
+ wc = **src_buf;
|
|
+ src_bytes_used = 1;
|
|
+ if (wc > 0x7f) errno = EILSEQ;
|
|
+ break;
|
|
+ case UTF_8:
|
|
+ src_bytes_used = mbrtoc32(&wc, *src_buf, *src_bytes_left, &ps);
|
|
+ if (src_bytes_used == __MB_ERR_ILLEGAL_SEQUENCE) {
|
|
+ break; // EILSEQ already set.
|
|
+ } else if (src_bytes_used == __MB_ERR_INCOMPLETE_SEQUENCE) {
|
|
+ errno = EINVAL;
|
|
+ return false;
|
|
+ }
|
|
+ break;
|
|
+ case UTF_16_BE:
|
|
+ case UTF_16_LE: {
|
|
+ if (*src_bytes_left < 2) {
|
|
+ errno = EINVAL;
|
|
+ return false;
|
|
+ }
|
|
+ bool swap = (src_encoding == UTF_16_BE);
|
|
+ wc = In16(*src_buf, swap);
|
|
+ // 0xd800-0xdbff: high surrogates
|
|
+ // 0xdc00-0xdfff: low surrogates
|
|
+ if (wc >= 0xd800 && wc <= 0xdfff) {
|
|
+ if (wc >= 0xdc00) { // Low surrogate before high surrogate.
|
|
+ errno = EILSEQ;
|
|
+ return false;
|
|
+ }
|
|
+ if (*src_bytes_left < 4) {
|
|
+ errno = EINVAL;
|
|
+ return false;
|
|
+ }
|
|
+ uint16_t hi = wc;
|
|
+ uint16_t lo = In16(*src_buf + 2, swap);
|
|
+ wc = 0x10000 + ((hi - 0xd800) << 10) + (lo - 0xdc00);
|
|
+ src_bytes_used = 4;
|
|
+ }
|
|
+ break;
|
|
+ }
|
|
+ case UTF_32_BE:
|
|
+ case UTF_32_LE:
|
|
+ case WCHAR_T:
|
|
+ if (*src_bytes_left < 4) {
|
|
+ errno = EINVAL;
|
|
+ return false;
|
|
+ }
|
|
+ wc = In32(*src_buf, (src_encoding == UTF_32_BE));
|
|
+ break;
|
|
+ }
|
|
+ if (errno == EILSEQ) {
|
|
+ switch (mode) {
|
|
+ case ERROR:
|
|
+ return false;
|
|
+ case IGNORE:
|
|
+ *src_buf += src_bytes_used;
|
|
+ *src_bytes_left -= src_bytes_used;
|
|
+ ignored = true;
|
|
+ return GetNext();
|
|
+ case TRANSLIT:
|
|
+ wc = '?';
|
|
+ ++replacement_count;
|
|
+ return true;
|
|
+ }
|
|
+ }
|
|
+ return true;
|
|
+ }
|
|
+
|
|
+ bool Convert() {
|
|
+ errno = 0;
|
|
+ switch (dst_encoding) {
|
|
+ case US_ASCII:
|
|
+ buf[0] = wc;
|
|
+ dst_bytes_used = 1;
|
|
+ if (wc > 0x7f) errno = EILSEQ;
|
|
+ break;
|
|
+ case UTF_8:
|
|
+ dst_bytes_used = c32rtomb(buf, wc, &ps);
|
|
+ if (dst_bytes_used == __MB_ERR_ILLEGAL_SEQUENCE) {
|
|
+ break; // EILSEQ already set.
|
|
+ } else if (dst_bytes_used == __MB_ERR_INCOMPLETE_SEQUENCE) {
|
|
+ errno = EINVAL;
|
|
+ return false;
|
|
+ }
|
|
+ break;
|
|
+ case UTF_16_BE:
|
|
+ case UTF_16_LE: {
|
|
+ bool swap = (dst_encoding == UTF_16_BE);
|
|
+ if (wc < 0x10000) { // BMP.
|
|
+ Out16(buf, wc, swap);
|
|
+ } else { // Supplementary plane; output surrogate pair.
|
|
+ wc -= 0x10000;
|
|
+ char16_t hi = 0xd800 | (wc >> 10);
|
|
+ char16_t lo = 0xdc00 | (wc & 0x3ff);
|
|
+ Out16(buf + 0, hi, swap);
|
|
+ Out16(buf + 2, lo, swap);
|
|
+ dst_bytes_used = 4;
|
|
+ }
|
|
+ } break;
|
|
+ case UTF_32_BE:
|
|
+ case UTF_32_LE:
|
|
+ case WCHAR_T:
|
|
+ Out32(wc, (dst_encoding == UTF_32_BE));
|
|
+ break;
|
|
+ }
|
|
+ if (errno == EILSEQ) {
|
|
+ if (mode == IGNORE) {
|
|
+ *src_buf += src_bytes_used;
|
|
+ *src_bytes_left -= src_bytes_used;
|
|
+ ignored = true;
|
|
+ return true;
|
|
+ } else if (mode == TRANSLIT) {
|
|
+ wc = '?';
|
|
+ ++replacement_count;
|
|
+ return Convert();
|
|
+ }
|
|
+ return false;
|
|
+ }
|
|
+ return Emit();
|
|
+ }
|
|
+
|
|
+ uint16_t In16(const char* buf, bool swap) {
|
|
+#ifdef __cplusplus
|
|
+ const uint8_t* src = reinterpret_cast<const uint8_t*>(buf);
|
|
+#else // !__cplusplus
|
|
+ const uint8_t* src = (const uint8_t*)(buf);
|
|
+#endif // __cplusplus
|
|
+ uint16_t wc = (src[0]) | (src[1] << 8);
|
|
+ if (swap) wc = __swap16(wc);
|
|
+ src_bytes_used = 2;
|
|
+ return wc;
|
|
+ }
|
|
+
|
|
+ uint32_t In32(const char* buf, bool swap) {
|
|
+#ifdef __cplusplus
|
|
+ const uint8_t* src = reinterpret_cast<const uint8_t*>(buf);
|
|
+#else // !__cplusplus
|
|
+ const uint8_t* src = (const uint8_t*)(buf);
|
|
+#endif // __cplusplus
|
|
+ uint32_t wc = (src[0]) | (src[1] << 8) | (src[2] << 16) | (src[3] << 24);
|
|
+ if (swap) wc = __swap32(wc);
|
|
+ src_bytes_used = 4;
|
|
+ return wc;
|
|
+ }
|
|
+
|
|
+ void Out16(char* dst, char16_t ch, bool swap) {
|
|
+ if (swap) ch = __swap16(ch);
|
|
+ dst[0] = ch;
|
|
+ dst[1] = ch >> 8;
|
|
+ dst_bytes_used = 2;
|
|
+ }
|
|
+
|
|
+ void Out32(char32_t ch, bool swap) {
|
|
+ if (swap) ch = __swap32(ch);
|
|
+ buf[0] = ch;
|
|
+ buf[1] = ch >> 8;
|
|
+ buf[2] = ch >> 16;
|
|
+ buf[3] = ch >> 24;
|
|
+ dst_bytes_used = 4;
|
|
+ }
|
|
+
|
|
+ bool Emit() {
|
|
+ if (dst_bytes_used > *dst_bytes_left) {
|
|
+ errno = E2BIG;
|
|
+ return false;
|
|
+ }
|
|
+ memcpy(*dst_buf, buf, dst_bytes_used);
|
|
+ *src_buf += src_bytes_used;
|
|
+ *src_bytes_left -= src_bytes_used;
|
|
+ *dst_buf += dst_bytes_used;
|
|
+ *dst_bytes_left -= dst_bytes_used;
|
|
+ return true;
|
|
+ }
|
|
+
|
|
+ int Done() {
|
|
+ if (mode == TRANSLIT) return replacement_count;
|
|
+ if (ignored) {
|
|
+ errno = EILSEQ;
|
|
+ return -1;
|
|
+ }
|
|
+ return 0;
|
|
+ }
|
|
+};
|
|
+
|
|
+iconv_t iconv_open(const char* __dst_encoding, const char* __src_encoding) {
|
|
+ iconv_t result = iconv_t();
|
|
+ result->mode = ERROR;
|
|
+ if (!__parse_encoding(__src_encoding, &result->src_encoding, 0 /* nullptr */) ||
|
|
+ !__parse_encoding(__dst_encoding, &result->dst_encoding, &result->mode)) {
|
|
+ free(result);
|
|
+ errno = EINVAL;
|
|
+ return INVALID_ICONV_T;
|
|
+ }
|
|
+ return result;
|
|
+}
|
|
+
|
|
+size_t iconv(iconv_t __converter,
|
|
+ char** __src_buf, size_t* __src_bytes_left,
|
|
+ char** __dst_buf, size_t* __dst_bytes_left) {
|
|
+ if (__converter == INVALID_ICONV_T) {
|
|
+ errno = EBADF;
|
|
+ return -1;
|
|
+ }
|
|
+ return __converter->Convert(__src_buf, __src_bytes_left, __dst_buf, __dst_bytes_left);
|
|
+}
|
|
+
|
|
+int iconv_close(iconv_t __converter) {
|
|
+ if (__converter == INVALID_ICONV_T) {
|
|
+ errno = EBADF;
|
|
+ return -1;
|
|
+ }
|
|
+ free(__converter);
|
|
+ return 0;
|
|
+}
|
|
+
|
|
+__END_DECLS
|
|
+
|
|
+#endif // __ANDROID__
|
|
diff --git a/src/java.base/unix/classes/sun/net/dns/ResolverConfigurationImpl.java b/src/java.base/unix/classes/sun/net/dns/ResolverConfigurationImpl.java
|
|
index 6074d323f..8b337d6e3 100644
|
|
--- a/src/java.base/unix/classes/sun/net/dns/ResolverConfigurationImpl.java
|
|
+++ b/src/java.base/unix/classes/sun/net/dns/ResolverConfigurationImpl.java
|
|
@@ -63,8 +63,9 @@ public final class ResolverConfigurationImpl
|
|
ArrayList<String> ll = new ArrayList<>();
|
|
|
|
try {
|
|
+ String resolvPath = System.getProperty("ext.net.resolvPath", "/etc/resolv.conf");
|
|
BufferedReader in =
|
|
- new BufferedReader(new FileReader("/etc/resolv.conf"));
|
|
+ new BufferedReader(new FileReader(resolvPath));
|
|
String line;
|
|
while ((line = in.readLine()) != null) {
|
|
int maxvalues = maxperkeyword;
|
|
diff --git a/src/java.base/unix/native/libjava/java_props_md.c b/src/java.base/unix/native/libjava/java_props_md.c
|
|
index 230de04c0..8e858b736 100644
|
|
--- a/src/java.base/unix/native/libjava/java_props_md.c
|
|
+++ b/src/java.base/unix/native/libjava/java_props_md.c
|
|
@@ -46,6 +46,100 @@
|
|
#include "java_props_macosx.h"
|
|
#endif
|
|
|
|
+#ifdef __ANDROID__
|
|
+// From https://android.googlesource.com/platform/bionic/+/master/libc/bionic/langinfo.cpp
|
|
+/*
|
|
+ * Copyright (C) 2016 The Android Open Source Project
|
|
+ * All rights reserved.
|
|
+ *
|
|
+ * Redistribution and use in source and binary forms, with or without
|
|
+ * modification, are permitted provided that the following conditions
|
|
+ * are met:
|
|
+ * * Redistributions of source code must retain the above copyright
|
|
+ * notice, this list of conditions and the following disclaimer.
|
|
+ * * Redistributions in binary form must reproduce the above copyright
|
|
+ * notice, this list of conditions and the following disclaimer in
|
|
+ * the documentation and/or other materials provided with the
|
|
+ * distribution.
|
|
+ *
|
|
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
|
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
|
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
|
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
|
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
|
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
|
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
|
|
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
|
|
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
|
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
|
|
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
|
+ * SUCH DAMAGE.
|
|
+ */
|
|
+
|
|
+char* nl_langinfo(nl_item item) {
|
|
+ const char* result = "";
|
|
+ switch (item) {
|
|
+ case CODESET: result = (MB_CUR_MAX == 1) ? "ASCII" : "UTF-8"; break;
|
|
+ case D_T_FMT: result = "%F %T %z"; break;
|
|
+ case D_FMT: result = "%F"; break;
|
|
+ case T_FMT: result = "%T"; break;
|
|
+ case T_FMT_AMPM: result = "%I:%M:%S %p"; break;
|
|
+ case AM_STR: result = "AM"; break;
|
|
+ case PM_STR: result = "PM"; break;
|
|
+ case DAY_1: result = "Sunday"; break;
|
|
+ case DAY_2: result = "Monday"; break;
|
|
+ case DAY_3: result = "Tuesday"; break;
|
|
+ case DAY_4: result = "Wednesday"; break;
|
|
+ case DAY_5: result = "Thursday"; break;
|
|
+ case DAY_6: result = "Friday"; break;
|
|
+ case DAY_7: result = "Saturday"; break;
|
|
+ case ABDAY_1: result = "Sun"; break;
|
|
+ case ABDAY_2: result = "Mon"; break;
|
|
+ case ABDAY_3: result = "Tue"; break;
|
|
+ case ABDAY_4: result = "Wed"; break;
|
|
+ case ABDAY_5: result = "Thu"; break;
|
|
+ case ABDAY_6: result = "Fri"; break;
|
|
+ case ABDAY_7: result = "Sat"; break;
|
|
+ case MON_1: result = "January"; break;
|
|
+ case MON_2: result = "February"; break;
|
|
+ case MON_3: result = "March"; break;
|
|
+ case MON_4: result = "April"; break;
|
|
+ case MON_5: result = "May"; break;
|
|
+ case MON_6: result = "June"; break;
|
|
+ case MON_7: result = "July"; break;
|
|
+ case MON_8: result = "August"; break;
|
|
+ case MON_9: result = "September"; break;
|
|
+ case MON_10: result = "October"; break;
|
|
+ case MON_11: result = "November"; break;
|
|
+ case MON_12: result = "December"; break;
|
|
+ case ABMON_1: result = "Jan"; break;
|
|
+ case ABMON_2: result = "Feb"; break;
|
|
+ case ABMON_3: result = "Mar"; break;
|
|
+ case ABMON_4: result = "Apr"; break;
|
|
+ case ABMON_5: result = "May"; break;
|
|
+ case ABMON_6: result = "Jun"; break;
|
|
+ case ABMON_7: result = "Jul"; break;
|
|
+ case ABMON_8: result = "Aug"; break;
|
|
+ case ABMON_9: result = "Sep"; break;
|
|
+ case ABMON_10: result = "Oct"; break;
|
|
+ case ABMON_11: result = "Nov"; break;
|
|
+ case ABMON_12: result = "Dec"; break;
|
|
+ case ERA: result = ""; break;
|
|
+ case ERA_D_FMT: result = ""; break;
|
|
+ case ERA_D_T_FMT: result = ""; break;
|
|
+ case ERA_T_FMT: result = ""; break;
|
|
+ case ALT_DIGITS: result = ""; break;
|
|
+ case RADIXCHAR: result = "."; break;
|
|
+ case THOUSEP: result = ""; break;
|
|
+ case YESEXPR: result = "^[yY]"; break;
|
|
+ case NOEXPR: result = "^[nN]"; break;
|
|
+ case CRNCYSTR: result = ""; break;
|
|
+ default: break;
|
|
+ }
|
|
+ return (char*) result;
|
|
+}
|
|
+#endif
|
|
+
|
|
#if defined(_ALLBSD_SOURCE)
|
|
#if !defined(P_tmpdir)
|
|
#include <paths.h>
|
|
diff --git a/src/java.base/unix/native/libjava/jni_util_md.c b/src/java.base/unix/native/libjava/jni_util_md.c
|
|
index 460503cd7..193480e73 100644
|
|
--- a/src/java.base/unix/native/libjava/jni_util_md.c
|
|
+++ b/src/java.base/unix/native/libjava/jni_util_md.c
|
|
@@ -31,7 +31,7 @@
|
|
#include "jni_util.h"
|
|
#include "dlfcn.h"
|
|
|
|
-#if defined(LINUX) && (defined(_GNU_SOURCE) || \
|
|
+#if !defined(__ANDROID__) && defined(LINUX) && (defined(_GNU_SOURCE) || \
|
|
(defined(_POSIX_C_SOURCE) && _POSIX_C_SOURCE < 200112L \
|
|
&& defined(_XOPEN_SOURCE) && _XOPEN_SOURCE < 600))
|
|
extern int __xpg_strerror_r(int, char *, size_t);
|
|
diff --git a/src/java.base/unix/native/libjava/posix_spawn.c b/src/java.base/unix/native/libjava/posix_spawn.c
|
|
new file mode 100644
|
|
index 000000000..f9032bab4
|
|
--- /dev/null
|
|
+++ b/src/java.base/unix/native/libjava/posix_spawn.c
|
|
@@ -0,0 +1,147 @@
|
|
+// From https://android.googlesource.com/platform/external/dhcpcd-6.8.2/+/refs/heads/pie-dr1-release/compat/posix_spawn.c
|
|
+/*
|
|
+ * dhcpcd - DHCP client daemon
|
|
+ * Copyright (c) 2006-2012 Roy Marples <roy@marples.name>
|
|
+ * All rights reserved
|
|
+ * Redistribution and use in source and binary forms, with or without
|
|
+ * modification, are permitted provided that the following conditions
|
|
+ * are met:
|
|
+ * 1. Redistributions of source code must retain the above copyright
|
|
+ * notice, this list of conditions and the following disclaimer.
|
|
+ * 2. Redistributions in binary form must reproduce the above copyright
|
|
+ * notice, this list of conditions and the following disclaimer in the
|
|
+ * documentation and/or other materials provided with the distribution.
|
|
+ *
|
|
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
|
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
|
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
|
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
|
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
|
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
|
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
|
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
|
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
|
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
|
+ * SUCH DAMAGE.
|
|
+ */
|
|
+
|
|
+/* This implementation of posix_spawn is only suitable for the needs of dhcpcd
|
|
+ * but it could easily be extended to other applications. */
|
|
+
|
|
+#include <sys/types.h>
|
|
+#include <sys/wait.h>
|
|
+#include <errno.h>
|
|
+#include <signal.h>
|
|
+#include <stdlib.h>
|
|
+#include <string.h>
|
|
+#include <unistd.h>
|
|
+
|
|
+#include "posix_spawn.h"
|
|
+
|
|
+#ifndef _NSIG
|
|
+#ifdef _SIG_MAXSIG
|
|
+#define _NSIG _SIG_MAXSIG + 1
|
|
+#else
|
|
+/* Guess */
|
|
+#define _NSIG SIGPWR + 1
|
|
+#endif
|
|
+#endif
|
|
+
|
|
+extern char **environ;
|
|
+
|
|
+static int
|
|
+posix_spawnattr_handle(const posix_spawnattr_t *attrp)
|
|
+{
|
|
+ struct sigaction sa;
|
|
+ int i;
|
|
+ if (attrp->posix_attr_flags & POSIX_SPAWN_SETSIGMASK)
|
|
+ sigprocmask(SIG_SETMASK, &attrp->posix_attr_sigmask, NULL);
|
|
+ if (attrp->posix_attr_flags & POSIX_SPAWN_SETSIGDEF) {
|
|
+ memset(&sa, 0, sizeof(sa));
|
|
+ sa.sa_handler = SIG_DFL;
|
|
+ for (i = 1; i < _NSIG; i++) {
|
|
+ if (sigismember(&attrp->posix_attr_sigdefault, i)) {
|
|
+ if (sigaction(i, &sa, NULL) == -1)
|
|
+ return -1;
|
|
+ }
|
|
+ }
|
|
+ }
|
|
+ return 0;
|
|
+}
|
|
+
|
|
+inline static int
|
|
+is_vfork_safe(short int flags)
|
|
+{
|
|
+ return !(flags & (POSIX_SPAWN_SETSIGDEF | POSIX_SPAWN_SETSIGMASK));
|
|
+}
|
|
+
|
|
+int
|
|
+posix_spawn(pid_t *pid, const char *path,
|
|
+ const posix_spawn_file_actions_t *file_actions,
|
|
+ const posix_spawnattr_t *attrp,
|
|
+ char *const argv[], char *const envp[])
|
|
+{
|
|
+ short int flags;
|
|
+ pid_t p;
|
|
+ volatile int error;
|
|
+ error = 0;
|
|
+ flags = attrp ? attrp->posix_attr_flags : 0;
|
|
+ if (file_actions == NULL && is_vfork_safe(flags))
|
|
+ p = vfork();
|
|
+ else
|
|
+#ifdef THERE_IS_NO_FORK
|
|
+ return ENOSYS;
|
|
+#else
|
|
+ p = fork();
|
|
+#endif
|
|
+ switch (p) {
|
|
+ case -1:
|
|
+ return errno;
|
|
+ case 0:
|
|
+ if (attrp) {
|
|
+ error = posix_spawnattr_handle(attrp);
|
|
+ if (error)
|
|
+ _exit(127);
|
|
+ }
|
|
+ execve(path, argv, envp);
|
|
+ error = errno;
|
|
+ _exit(127);
|
|
+ default:
|
|
+ if (error != 0)
|
|
+ waitpid(p, NULL, WNOHANG);
|
|
+ else if (pid != NULL)
|
|
+ *pid = p;
|
|
+ return error;
|
|
+ }
|
|
+}
|
|
+
|
|
+int
|
|
+posix_spawnattr_init(posix_spawnattr_t *attr)
|
|
+{
|
|
+ memset(attr, 0, sizeof(*attr));
|
|
+ attr->posix_attr_flags = 0;
|
|
+ sigprocmask(0, NULL, &attr->posix_attr_sigmask);
|
|
+ sigemptyset(&attr->posix_attr_sigdefault);
|
|
+ return 0;
|
|
+}
|
|
+
|
|
+int
|
|
+posix_spawnattr_setflags(posix_spawnattr_t *attr, short flags)
|
|
+{
|
|
+ attr->posix_attr_flags = flags;
|
|
+ return 0;
|
|
+}
|
|
+
|
|
+int
|
|
+posix_spawnattr_setsigmask(posix_spawnattr_t *attr, const sigset_t *sigmask)
|
|
+{
|
|
+ attr->posix_attr_sigmask = *sigmask;
|
|
+ return 0;
|
|
+}
|
|
+
|
|
+int
|
|
+posix_spawnattr_setsigdefault(posix_spawnattr_t *attr, const sigset_t *sigmask)
|
|
+{
|
|
+ attr->posix_attr_sigdefault = *sigmask;
|
|
+ return 0;
|
|
+}
|
|
diff --git a/src/java.base/unix/native/libjava/posix_spawn.h b/src/java.base/unix/native/libjava/posix_spawn.h
|
|
new file mode 100644
|
|
index 000000000..388016eb3
|
|
--- /dev/null
|
|
+++ b/src/java.base/unix/native/libjava/posix_spawn.h
|
|
@@ -0,0 +1,53 @@
|
|
+// From https://android.googlesource.com/platform/external/dhcpcd-6.8.2/+/refs/heads/pie-dr1-release/compat/posix_spawn.h
|
|
+/*
|
|
+ * dhcpcd - DHCP client daemon
|
|
+ * Copyright (c) 2006-2012 Roy Marples <roy@marples.name>
|
|
+ * All rights reserved
|
|
+ * Redistribution and use in source and binary forms, with or without
|
|
+ * modification, are permitted provided that the following conditions
|
|
+ * are met:
|
|
+ * 1. Redistributions of source code must retain the above copyright
|
|
+ * notice, this list of conditions and the following disclaimer.
|
|
+ * 2. Redistributions in binary form must reproduce the above copyright
|
|
+ * notice, this list of conditions and the following disclaimer in the
|
|
+ * documentation and/or other materials provided with the distribution.
|
|
+ *
|
|
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
|
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
|
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
|
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
|
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
|
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
|
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
|
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
|
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
|
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
|
+ * SUCH DAMAGE.
|
|
+ */
|
|
+
|
|
+#ifndef POSIX_SPAWN_H
|
|
+#define POSIX_SPAWN_H
|
|
+
|
|
+#include <signal.h>
|
|
+
|
|
+typedef struct {
|
|
+ short posix_attr_flags;
|
|
+#define POSIX_SPAWN_SETSIGDEF 0x10
|
|
+#define POSIX_SPAWN_SETSIGMASK 0x20
|
|
+ sigset_t posix_attr_sigmask;
|
|
+ sigset_t posix_attr_sigdefault;
|
|
+} posix_spawnattr_t;
|
|
+
|
|
+typedef struct {
|
|
+// int unused;
|
|
+} posix_spawn_file_actions_t;
|
|
+
|
|
+int posix_spawn(pid_t *, const char *,
|
|
+ const posix_spawn_file_actions_t *, const posix_spawnattr_t *,
|
|
+ char *const [], char *const []);
|
|
+int posix_spawnattr_init(posix_spawnattr_t *);
|
|
+int posix_spawnattr_setflags(posix_spawnattr_t *, short);
|
|
+int posix_spawnattr_setsigmask(posix_spawnattr_t *, const sigset_t *);
|
|
+int posix_spawnattr_setsigdefault(posix_spawnattr_t *, const sigset_t *);
|
|
+
|
|
+#endif
|
|
diff --git a/src/java.base/unix/native/libjli/java_md.c b/src/java.base/unix/native/libjli/java_md.c
|
|
index 21ef40688..b8c2520d2 100644
|
|
--- a/src/java.base/unix/native/libjli/java_md.c
|
|
+++ b/src/java.base/unix/native/libjli/java_md.c
|
|
@@ -584,7 +584,58 @@ const char*
|
|
SetExecname(char **argv)
|
|
{
|
|
char* exec_path = NULL;
|
|
-#if defined(__linux__)
|
|
+#if defined(__ANDROID__) //Since both __ANDROID__ and __linux__ are defined, we must let the preprocessor preprocess the __ANDRIOD__ part first
|
|
+ char *__java_home = getenv("JAVA_HOME");
|
|
+ // From http://hg.openjdk.java.net/mobile/jdk9/jdk/file/17bb8a98d5e3/src/java.base/unix/native/libjli/java_md_solinux.c#l844
|
|
+ /* For Android, 'self' would point to /system/bin/app_process
|
|
+ * since we are really executing a Dalvik program at this point.
|
|
+ * argv[0] points to the Dalvik application name and we set the
|
|
+ * path to __java_home.
|
|
+ */
|
|
+ char buf[PATH_MAX+1];
|
|
+ char *p = NULL;
|
|
+ if ((p = JLI_StrRChr(argv[0], '/')) != 0) {
|
|
+ /* may be running from command line */
|
|
+ p++;
|
|
+ if ((JLI_StrLen(p) == 4) && JLI_StrCmp(p, "java") == 0) {
|
|
+ /* started as 'java'. Must be command line */
|
|
+ JLI_TraceLauncher("SetExecName maybe command line = %s\n", argv[0]);
|
|
+ if (*argv[0] != '/') {
|
|
+ char *curdir = NULL;
|
|
+ /* get absolute path */
|
|
+ getcwd(buf, PATH_MAX);
|
|
+ curdir = JLI_StringDup(buf);
|
|
+ JLI_Snprintf(buf, PATH_MAX, "%s/%s", curdir, argv[0]);
|
|
+ JLI_MemFree(curdir);
|
|
+ } else {
|
|
+ JLI_Snprintf(buf, PATH_MAX, "%s", argv[0]);
|
|
+ }
|
|
+ } else {
|
|
+ /* Not command line, see if __java_home set */
|
|
+ if (__java_home != NULL) {
|
|
+ JLI_TraceLauncher("SetExecName not java = %s\n", __java_home);
|
|
+ JLI_Snprintf(buf, PATH_MAX, "%s/bin/java", __java_home);
|
|
+ } else {
|
|
+ /* Fake it as best we can or should we punt? */
|
|
+ JLI_TraceLauncher("SetExecName fake it = %s\n", argv[0]);
|
|
+ JLI_Snprintf(buf, PATH_MAX, "/data/data/%s/storage/jvm/bin/java",
|
|
+ argv[0]);
|
|
+ }
|
|
+ }
|
|
+ } else {
|
|
+ /* Not started as 'java', see if __java_home set */
|
|
+ if (__java_home != NULL) {
|
|
+ JLI_TraceLauncher("SetExecName not command line = %s\n", __java_home);
|
|
+ JLI_Snprintf(buf, PATH_MAX, "%s/bin/java", __java_home);
|
|
+ } else {
|
|
+ /* Fake it as best we can or should we punt? */
|
|
+ JLI_TraceLauncher("SetExecName fake it 2 = %s\n", argv[0]);
|
|
+ JLI_Snprintf(buf, PATH_MAX, "/data/data/%s/storage/jvm/bin/java",
|
|
+ argv[0]);
|
|
+ }
|
|
+ }
|
|
+ exec_path = JLI_StringDup(buf);
|
|
+#elif defined(__linux__)
|
|
{
|
|
const char* self = "/proc/self/exe";
|
|
char buf[PATH_MAX+1];
|
|
@@ -594,10 +645,6 @@ SetExecname(char **argv)
|
|
exec_path = JLI_StringDup(buf);
|
|
}
|
|
}
|
|
-#else /* !__linux__ */
|
|
- {
|
|
- /* Not implemented */
|
|
- }
|
|
#endif
|
|
|
|
if (exec_path == NULL) {
|
|
diff --git a/src/java.base/unix/native/libnet/net_util_md.h b/src/java.base/unix/native/libnet/net_util_md.h
|
|
index 902cf9673..3b8acd66b 100644
|
|
--- a/src/java.base/unix/native/libnet/net_util_md.h
|
|
+++ b/src/java.base/unix/native/libnet/net_util_md.h
|
|
@@ -26,6 +26,9 @@
|
|
#ifndef NET_UTILS_MD_H
|
|
#define NET_UTILS_MD_H
|
|
|
|
+#ifdef ANDROID
|
|
+#include <netinet/in.h>
|
|
+#endif
|
|
#include <netdb.h>
|
|
#include <poll.h>
|
|
#include <sys/socket.h>
|
|
diff --git a/src/java.base/unix/native/libnio/fs/UnixNativeDispatcher.c b/src/java.base/unix/native/libnio/fs/UnixNativeDispatcher.c
|
|
index 9371bc001..ab7dd0fc0 100644
|
|
--- a/src/java.base/unix/native/libnio/fs/UnixNativeDispatcher.c
|
|
+++ b/src/java.base/unix/native/libnio/fs/UnixNativeDispatcher.c
|
|
@@ -140,6 +140,7 @@ typedef int fstatat64_func(int, const char *, struct stat64 *, int);
|
|
typedef int unlinkat_func(int, const char*, int);
|
|
typedef int renameat_func(int, const char*, int, const char*);
|
|
typedef int futimesat_func(int, const char *, const struct timeval *);
|
|
+typedef int utimensat_func(int, const char *, const struct timespec *, int flags);
|
|
typedef int futimens_func(int, const struct timespec *);
|
|
typedef int lutimes_func(const char *, const struct timeval *);
|
|
typedef DIR* fdopendir_func(int);
|
|
@@ -149,10 +150,46 @@ static fstatat64_func* my_fstatat64_func = NULL;
|
|
static unlinkat_func* my_unlinkat_func = NULL;
|
|
static renameat_func* my_renameat_func = NULL;
|
|
static futimesat_func* my_futimesat_func = NULL;
|
|
+static utimensat_func* my_utimensat_func = NULL;
|
|
static futimens_func* my_futimens_func = NULL;
|
|
static lutimes_func* my_lutimes_func = NULL;
|
|
static fdopendir_func* my_fdopendir_func = NULL;
|
|
|
|
+#ifdef __ANDROID__
|
|
+/*
|
|
+ * TODO: Android lacks support for the methods listed below. In it's place are
|
|
+ * alternatives that use existing Android functionality, but lack reentrant
|
|
+ * support. Determine if the following are the most suitable alternatives.
|
|
+ *
|
|
+ */
|
|
+int getgrgid_r(gid_t gid, struct group* grp, char* buf, size_t buflen, struct group** result) {
|
|
+
|
|
+ *result = NULL;
|
|
+ errno = 0;
|
|
+ grp = getgrgid(gid);
|
|
+ if (grp == NULL) {
|
|
+ return errno;
|
|
+ }
|
|
+ // buf not used by caller (see below)
|
|
+ *result = grp;
|
|
+ return 0;
|
|
+}
|
|
+
|
|
+int getgrnam_r(const char *name, struct group* grp, char* buf, size_t buflen, struct group** result) {
|
|
+
|
|
+ *result = NULL;
|
|
+ errno = 0;
|
|
+ grp = getgrnam(name);
|
|
+ if (grp == NULL) {
|
|
+ return errno;
|
|
+ }
|
|
+ // buf not used by caller (see below)
|
|
+ *result = grp;
|
|
+ return 0;
|
|
+
|
|
+}
|
|
+#endif
|
|
+
|
|
/**
|
|
* fstatat missing from glibc on Linux.
|
|
*/
|
|
@@ -272,6 +309,9 @@ Java_sun_nio_fs_UnixNativeDispatcher_init(JNIEnv* env, jclass this)
|
|
#ifndef _ALLBSD_SOURCE
|
|
my_futimesat_func = (futimesat_func*) dlsym(RTLD_DEFAULT, "futimesat");
|
|
my_lutimes_func = (lutimes_func*) dlsym(RTLD_DEFAULT, "lutimes");
|
|
+#endif
|
|
+#ifdef __ANDROID__
|
|
+ my_utimensat_func = (utimensat_func*) dlsym(RTLD_DEFAULT, "utimensat");
|
|
#endif
|
|
my_futimens_func = (futimens_func*) dlsym(RTLD_DEFAULT, "futimens");
|
|
#if defined(_AIX)
|
|
@@ -292,7 +332,7 @@ Java_sun_nio_fs_UnixNativeDispatcher_init(JNIEnv* env, jclass this)
|
|
capabilities |= sun_nio_fs_UnixNativeDispatcher_SUPPORTS_FUTIMES;
|
|
capabilities |= sun_nio_fs_UnixNativeDispatcher_SUPPORTS_LUTIMES;
|
|
#else
|
|
- if (my_futimesat_func != NULL)
|
|
+ if (my_futimesat_func != NULL || my_utimensat_func != NULL)
|
|
capabilities |= sun_nio_fs_UnixNativeDispatcher_SUPPORTS_FUTIMES;
|
|
if (my_lutimes_func != NULL)
|
|
capabilities |= sun_nio_fs_UnixNativeDispatcher_SUPPORTS_LUTIMES;
|
|
@@ -304,7 +344,7 @@ Java_sun_nio_fs_UnixNativeDispatcher_init(JNIEnv* env, jclass this)
|
|
|
|
if (my_openat64_func != NULL && my_fstatat64_func != NULL &&
|
|
my_unlinkat_func != NULL && my_renameat_func != NULL &&
|
|
- my_futimesat_func != NULL && my_fdopendir_func != NULL)
|
|
+ (my_futimesat_func != NULL || my_utimensat_func != NULL) && my_fdopendir_func != NULL)
|
|
{
|
|
capabilities |= sun_nio_fs_UnixNativeDispatcher_SUPPORTS_OPENAT;
|
|
}
|
|
@@ -675,22 +715,30 @@ Java_sun_nio_fs_UnixNativeDispatcher_futimes0(JNIEnv* env, jclass this, jint fil
|
|
jlong accessTime, jlong modificationTime)
|
|
{
|
|
struct timeval times[2];
|
|
+ struct timespec times2[2];
|
|
int err = 0;
|
|
|
|
- times[0].tv_sec = accessTime / 1000000;
|
|
+ times[0].tv_sec = times2[0].tv_sec = accessTime / 1000000;
|
|
times[0].tv_usec = accessTime % 1000000;
|
|
|
|
- times[1].tv_sec = modificationTime / 1000000;
|
|
+ times[1].tv_sec = times2[1].tv_sec = modificationTime / 1000000;
|
|
times[1].tv_usec = modificationTime % 1000000;
|
|
|
|
+ times2[0].tv_nsec = times[0].tv_usec * 1000;
|
|
+ times2[1].tv_nsec = times[1].tv_usec * 1000;
|
|
+
|
|
#ifdef _ALLBSD_SOURCE
|
|
RESTARTABLE(futimes(filedes, ×[0]), err);
|
|
#else
|
|
- if (my_futimesat_func == NULL) {
|
|
- JNU_ThrowInternalError(env, "my_futimesat_func is NULL");
|
|
+ if (my_futimesat_func == NULL && my_utimensat_func == NULL) {
|
|
+ JNU_ThrowInternalError(env, "my_futimesat_func and my_utimensat_func are NULL");
|
|
return;
|
|
}
|
|
- RESTARTABLE((*my_futimesat_func)(filedes, NULL, ×[0]), err);
|
|
+ if (my_futimesat_func != NULL) {
|
|
+ RESTARTABLE((*my_futimesat_func)(filedes, NULL, ×[0]), err);
|
|
+ } else {
|
|
+ RESTARTABLE((*my_utimensat_func)(filedes, NULL, ×2[0], 0), err);
|
|
+ }
|
|
#endif
|
|
if (err == -1) {
|
|
throwUnixException(env, errno);
|
|
diff --git a/src/java.desktop/unix/native/libawt/awt/awt_LoadLibrary.c b/src/java.desktop/unix/native/libawt/awt/awt_LoadLibrary.c
|
|
index b2dedca35..c01ccfb8d 100644
|
|
--- a/src/java.desktop/unix/native/libawt/awt/awt_LoadLibrary.c
|
|
+++ b/src/java.desktop/unix/native/libawt/awt/awt_LoadLibrary.c
|
|
@@ -30,6 +30,7 @@
|
|
#include <jni.h>
|
|
#include <jni_util.h>
|
|
#include <jvm.h>
|
|
+#include <stdbool.h>
|
|
#include "gdefs.h"
|
|
|
|
#include <sys/param.h>
|
|
@@ -98,6 +99,30 @@ JNIEXPORT jboolean JNICALL AWTIsHeadless() {
|
|
#define HEADLESS_PATH "/libawt_headless.so"
|
|
#endif
|
|
|
|
+static bool read_so_path_from_maps(const char* so_name, char* buf) {
|
|
+ FILE *fp = fopen("/proc/self/maps", "r");
|
|
+
|
|
+ if (!fp) {
|
|
+ return false;
|
|
+ }
|
|
+
|
|
+ char maps_buffer[2048];
|
|
+ while (fgets(maps_buffer, 2048, fp) != NULL) {
|
|
+ if (strstr(maps_buffer, so_name) == NULL) {
|
|
+ continue;
|
|
+ }
|
|
+
|
|
+ char *so_path = strchr(maps_buffer, '/');
|
|
+ so_path[strlen(so_path) - 1] = '\0'; // Cut trailing \n
|
|
+ strcpy(buf,so_path);
|
|
+ fclose(fp);
|
|
+ return true;
|
|
+ }
|
|
+
|
|
+ fclose(fp);
|
|
+ return false;
|
|
+}
|
|
+
|
|
jint
|
|
AWT_OnLoad(JavaVM *vm, void *reserved)
|
|
{
|
|
@@ -119,7 +144,11 @@ AWT_OnLoad(JavaVM *vm, void *reserved)
|
|
#ifndef STATIC_BUILD
|
|
/* Get address of this library and the directory containing it. */
|
|
dladdr((void *)AWT_OnLoad, &dlinfo);
|
|
- realpath((char *)dlinfo.dli_fname, buf);
|
|
+ if (strrchr(dlinfo.dli_fname, '/') != NULL) {
|
|
+ realpath((char *)dlinfo.dli_fname, buf);
|
|
+ }else{
|
|
+ read_so_path_from_maps(dlinfo.dli_fname,buf);
|
|
+ }
|
|
len = strlen(buf);
|
|
p = strrchr(buf, '/');
|
|
#endif
|
|
diff --git a/src/java.instrument/unix/native/libinstrument/EncodingSupport_md.c b/src/java.instrument/unix/native/libinstrument/EncodingSupport_md.c
|
|
index 490eea9a5..27ee1c23e 100644
|
|
--- a/src/java.instrument/unix/native/libinstrument/EncodingSupport_md.c
|
|
+++ b/src/java.instrument/unix/native/libinstrument/EncodingSupport_md.c
|
|
@@ -65,7 +65,11 @@ utfInitialize(void)
|
|
(void)setlocale(LC_ALL, "");
|
|
|
|
/* Get the codeset name */
|
|
+#ifndef __ANDROID__
|
|
codeset = (char*)nl_langinfo(CODESET);
|
|
+#else
|
|
+ codeset = "ASCII"; // (MB_CUR_MAX == 1) ? "ASCII" : "UTF-8";
|
|
+#endif
|
|
if ( codeset == NULL || codeset[0] == 0 ) {
|
|
UTF_DEBUG(("NO codeset returned by nl_langinfo(CODESET)\n"));
|
|
return;
|
|
diff --git a/src/jdk.jdwp.agent/share/native/libjdwp/utf_util.c b/src/jdk.jdwp.agent/share/native/libjdwp/utf_util.c
|
|
index f5573930d..b64e30046 100644
|
|
--- a/src/jdk.jdwp.agent/share/native/libjdwp/utf_util.c
|
|
+++ b/src/jdk.jdwp.agent/share/native/libjdwp/utf_util.c
|
|
@@ -483,7 +483,11 @@ static int iconvConvert(conv_direction drn, char *bytes, size_t len, char *outpu
|
|
// locale is not initialized, do it now
|
|
if (setlocale(LC_ALL, "") != NULL) {
|
|
// nl_langinfo returns ANSI_X3.4-1968 by default
|
|
+#ifndef __ANDROID__
|
|
codeset = (char*)nl_langinfo(CODESET);
|
|
+#else
|
|
+ codeset = "ASCII";
|
|
+#endif
|
|
}
|
|
|
|
if (codeset == NULL) {
|
|
diff --git a/src/hotspot/os_cpu/linux_aarch64/javaThread_linux_aarch64.hpp b/src/hotspot/os_cpu/linux_aarch64/javaThread_linux_aarch64.hpp
|
|
index c6e012ecf..d4f956756 100644
|
|
--- a/src/hotspot/os_cpu/linux_aarch64/javaThread_linux_aarch64.hpp
|
|
+++ b/src/hotspot/os_cpu/linux_aarch64/javaThread_linux_aarch64.hpp
|
|
@@ -47,6 +47,8 @@ private:
|
|
bool pd_get_top_frame(frame* fr_addr, void* ucontext, bool isInJava);
|
|
public:
|
|
|
|
- static Thread *aarch64_get_thread_helper();
|
|
+ static Thread *aarch64_get_thread_helper() {
|
|
+ return Thread::current();
|
|
+ }
|
|
|
|
#endif // OS_CPU_LINUX_AARCH64_JAVATHREAD_LINUX_AARCH64_HPP
|