#if 0
#define DEBUG
#define DEBUG_TEST
#endif
#if defined(J9ZTPF)
#include <tpf/icstk.h>
#include <tpf/c_eb0eb.h>
#define USE_BSD_SELECT_PROTOTYPE 1
#include <tpf/sysapi.h>
#include <tpf/tpfapi.h>
#include <time.h>
#endif
#include "j9vm_internal.h"
#include "j9pool.h"
#include "util_api.h"
#include "j9lib.h"
#include "exelib_api.h"
#include "j9.h"
#include "j9protos.h"
#include "j9consts.h"
#include "fltconst.h"
#include "j9comp.h"
#include "omrthread.h"
#include "j9cp.h"
#include "j2sever.h"
#include "j2senls.h"
#include "hashtable_api.h"
#include "rommeth.h"
#include "util_api.h"
#include "vmargs_api.h"
#include "mmhook.h"
#include "jvminit.h"
#include "sunvmi_api.h"
#include "omrformatconsts.h"
#ifdef J9VM_OPT_ZIP_SUPPORT
#include "vmi.h"
#include "vmzipcachehook.h"
#endif
#if defined(J9VM_OPT_JITSERVER)
#include "jitserver_api.h"
#include "jitserver_error.h"
#endif
#if defined(AIXPPC)
#include <procinfo.h>
#include <sys/types.h>
#include <unistd.h>
#endif
#if defined(J9ZOS390)
#include <stdlib.h>
#if defined(J9VM_ENV_DATA64)
#define OFFSET_CAA_CEDB 0x348
#define OFFSET_CEDB_LANG 0x18
#else
#define OFFSET_CAA_CEDB 0x218
#define OFFSET_CEDB_LANG 0x10
#endif
#pragma convlit(suspend)
static const char cedb_eye[4] = "CEDB";
#pragma convlit(resume)
static BOOLEAN
mainlineLanguageIsC(void)
{
BOOLEAN result = FALSE;
const char *caa = (const char *)_gtca();
const char *cedb = *(const char * const *)(caa + OFFSET_CAA_CEDB);
if ((NULL != cedb) && (0 == memcmp(cedb, cedb_eye, sizeof(cedb_eye)))) {
int16_t language = *(const int16_t *)(cedb + OFFSET_CEDB_LANG);
if (3 == language) {
result = TRUE;
}
}
return result;
}
struct arg_string
{
uint32_t length;
char value[];
};
struct arg_list
{
uint32_t argc;
uint32_t env_size;
const struct arg_string *string[];
};
#endif
#if defined(OSX)
#include <sys/types.h>
#include <sys/sysctl.h>
#endif
#if defined(WIN32)
#include <processenv.h>
#include <stdlib.h>
#endif
#include <string.h>
#define _UTE_STATIC_
#include "ut_j9scar.h"
#ifdef J9OS_I5
#include "Xj9I5OSDebug.H"
#include "Xj9I5OSInterface.H"
#endif
#if defined(DEBUG)
#define DBG_MSG(x) printf x
#else
#define DBG_MSG(x)
#endif
#if defined(LINUX) && !defined(J9VM_ENV_DATA64)
#include <unistd.h>
#if !__GLIBC_PREREQ(2,4)
#include <linux/unistd.h>
_syscall5(int, _llseek, uint, fd, ulong, hi, ulong, lo, loff_t *, res, uint, wh);
#endif
#endif
#ifdef WIN32
#define IBM_MALLOCTRACE_STR L"IBM_MALLOCTRACE"
#define ALT_JAVA_HOME_DIR_STR L"_ALT_JAVA_HOME_DIR"
#else
#define IBM_MALLOCTRACE_STR "IBM_MALLOCTRACE"
#endif
#define MIN_GROWTH 128
#define jclSeparator DIR_SEPARATOR
#define CALL_BUNDLED_FUNCTIONS_DIRECTLY 0
#if !CALL_BUNDLED_FUNCTIONS_DIRECTLY
#define CREATE_JAVA_VM_ENTRYPOINT "J9_CreateJavaVM"
#define GET_JAVA_VMS_ENTRYPOINT "J9_GetCreatedJavaVMs"
typedef jint (JNICALL *CreateVM)(JavaVM ** p_vm, void ** p_env, J9CreateJavaVMParams *createparams);
typedef jint (JNICALL *GetVMs)(JavaVM**, jsize, jsize*);
typedef jint (JNICALL *DetachThread)(JavaVM *);
#endif
typedef jint (JNICALL *DestroyVM)(JavaVM *);
typedef int (*SigAction) (int signum, const struct sigaction *act, struct sigaction *oldact);
#ifdef J9ZOS390
typedef jint (JNICALL *pGetStringPlatform)(JNIEnv*, jstring, char*, jint, const char *);
typedef jint (JNICALL *pGetStringPlatformLength)(JNIEnv*, jstring, jint *, const char *);
typedef jint (JNICALL *pNewStringPlatform)(JNIEnv*, const char*, jstring *, const char *);
typedef jint (JNICALL *p_a2e_vsprintf)(char *, const char *, va_list);
#endif
#if !CALL_BUNDLED_FUNCTIONS_DIRECTLY
typedef UDATA* (*ThreadGlobal)(const char* name);
typedef IDATA (*ThreadAttachEx)(omrthread_t *handle, omrthread_attr_t *attr);
typedef void (*ThreadDetach)(omrthread_t thread);
typedef IDATA (*MonitorEnter)(omrthread_monitor_t monitor);
typedef IDATA (*MonitorExit)(omrthread_monitor_t monitor);
typedef IDATA (*MonitorInit)(omrthread_monitor_t* handle, UDATA flags, char* name);
typedef IDATA (*MonitorDestroy)(omrthread_monitor_t monitor);
typedef IDATA (*MonitorWait)(omrthread_monitor_t monitor);
typedef IDATA (*MonitorWaitTimed)(omrthread_monitor_t monitor, I_64 millis, IDATA nanos);
typedef IDATA (*MonitorNotify)(omrthread_monitor_t monitor);
typedef IDATA (*MonitorNotifyAll)(omrthread_monitor_t monitor) ;
typedef IDATA (* ThreadLibControl)(const char * key, UDATA value) ;
typedef IDATA (*SetCategory)(omrthread_t thread, UDATA category, UDATA type);
typedef IDATA (*LibEnableCPUMonitor)(omrthread_t thread);
typedef I_32 (*PortInitLibrary)(J9PortLibrary *portLib, J9PortLibraryVersion *version, UDATA size);
typedef UDATA (*PortGetSize)(struct J9PortLibraryVersion *version);
typedef I_32 (*PortGetVersion)(struct J9PortLibrary *portLibrary, struct J9PortLibraryVersion *version);
typedef void* (*J9GetInterface)(J9_INTERFACE_SELECTOR interfaceSelector, J9PortLibrary* portLib, void *userData);
#endif
#if defined(J9ZOS390)
#define ZOS_THR_WEIGHT_NOT_FOUND ((UDATA) 0U)
#define ZOS_THR_WEIGHT_MEDIUM ((UDATA) 1U)
#define ZOS_THR_WEIGHT_HEAVY ((UDATA) 2U)
static UDATA checkZOSThrWeightEnvVar(void);
static BOOLEAN setZOSThrWeight(void);
#endif
#ifdef WIN32
#define J9_MAX_ENV 32767
#define J9_MAX_PATH _MAX_PATH
static HINSTANCE j9vm_dllHandle = (HINSTANCE) 0;
static HANDLE jvm_dllHandle;
#else
#define J9_MAX_PATH PATH_MAX
static void *j9vm_dllHandle = NULL;
static void *java_dllHandle = NULL;
#endif
static J9StringBuffer * j9binBuffer = NULL;
static J9StringBuffer * jrebinBuffer = NULL;
static J9StringBuffer * j9libBuffer = NULL;
static J9StringBuffer * j9libvmBuffer = NULL;
static J9StringBuffer * j9Buffer = NULL;
static BOOLEAN jvmInSubdir=TRUE;
#if !CALL_BUNDLED_FUNCTIONS_DIRECTLY
static CreateVM globalCreateVM;
static GetVMs globalGetVMs;
static J9GetInterface f_j9_GetInterface = NULL;
#endif
static DestroyVM globalDestroyVM;
#ifdef J9ZOS390
static pGetStringPlatform globalGetStringPlatform;
static pGetStringPlatformLength globalGetStringPlatformLength;
static pNewStringPlatform globalNewStringPlatform;
static p_a2e_vsprintf global_a2e_vsprintf;
#endif
#if !CALL_BUNDLED_FUNCTIONS_DIRECTLY
static ThreadGlobal f_threadGlobal;
static ThreadAttachEx f_threadAttachEx;
static ThreadDetach f_threadDetach;
MonitorEnter f_monitorEnter;
MonitorExit f_monitorExit;
static MonitorInit f_monitorInit;
static MonitorDestroy f_monitorDestroy;
static MonitorWaitTimed f_monitorWaitTimed;
static MonitorNotify f_monitorNotify;
static MonitorNotifyAll f_monitorNotifyAll;
static PortInitLibrary portInitLibrary;
static PortGetSize portGetSizeFn;
static PortGetVersion portGetVersionFn;
static ThreadLibControl f_threadLibControl;
static SetCategory f_setCategory;
static LibEnableCPUMonitor f_libEnableCPUMonitor;
#endif
static UDATA monitor = 0;
static J9InternalVMFunctions globalInvokeInterface;
static struct J9PortLibrary j9portLibrary;
static char * newPath = NULL;
J9JavaVM *BFUjavaVM = NULL;
static jclass jlClass = NULL;
#ifdef J9VM_IVE_RAW_BUILD
static jfieldID classNameFID = NULL;
#endif
static jmethodID classDepthMID = NULL;
static jmethodID classLoaderDepthMID = NULL;
static jmethodID currentClassLoaderMID = NULL;
static jmethodID currentLoadedClassMID = NULL;
static jmethodID getNameMID = NULL;
static jclass jlThread = NULL;
static jmethodID sleepMID = NULL;
static jmethodID waitMID = NULL;
static jmethodID notifyMID = NULL;
static jmethodID notifyAllMID = NULL;
static UDATA jvmSEVersion = -1;
static void *omrsigDLL = NULL;
static void addToLibpath(const char *, BOOLEAN isPrepend);
#if defined(AIXPPC)
typedef struct J9LibpathBackup {
char *fullpath;
size_t j9prefixLen;
} J9LibpathBackup;
static J9LibpathBackup libpathBackup = { NULL, 0 };
static void backupLibpath(J9LibpathBackup *, size_t origLibpathLen);
static void freeBackupLibpath(J9LibpathBackup *);
static void restoreLibpath(J9LibpathBackup *);
static const char *findInLibpath(const char *libpath, const char *path);
static char *deleteDirsFromLibpath(const char *const libpath, const char *const deleteStart, const size_t deleteLen);
static void setLibpath(const char *libpath);
#ifdef DEBUG_TEST
static void testBackupAndRestoreLibpath(void);
#endif
#endif
extern OMRMemCategorySet j9MainMemCategorySet;
void exitHook(J9JavaVM *vm);
static jint JNI_CreateJavaVM_impl(JavaVM **pvm, void **penv, void *vm_args, BOOLEAN isJITServer);
static void* preloadLibrary(char* dllName, BOOLEAN inJVMDir);
static UDATA protectedStrerror(J9PortLibrary* portLib, void* savedErrno);
static UDATA strerrorSignalHandler(struct J9PortLibrary* portLibrary, U_32 gpType, void* gpInfo, void* userData);
static void throwNewUnsatisfiedLinkError(JNIEnv *env, char *message);
static int findDirContainingFile(J9StringBuffer **result, char *paths, char pathSeparator, char *fileToFind, int elementsToSkip);
static int findDirUplevelToDirContainingFile(J9StringBuffer **result, char *pathEnvar, char pathSeparator, char *fileInPath, int upLevels, int elementsToSkip);
static void truncatePath(char *inputPath);
#if defined(WIN32)
static jint formatErrorMessage(int errorCode, char *inBuffer, jint inBufferLength);
#endif
#if defined(J9VM_OPT_JITSERVER)
static int32_t startJITServer(struct JITServer *);
static int32_t waitForJITServerTermination(struct JITServer *);
static int32_t destroyJITServer(struct JITServer **);
#endif
static BOOLEAN preloadLibraries(void);
static BOOLEAN librariesLoaded(void);
#if defined(WIN32) || defined(WIN64)
#define strdup _strdup
#define write _write
#define close _close
#define read _read
#define open _open
#endif
#if defined(J9ZTPF)
#define LD_ENV_PATH "LD_LIBRARY_PATH"
#elif defined(J9ZOS390)
#define LD_ENV_PATH "LIBPATH"
#endif
#define J9_SIG_ERR -1
#define J9_SIG_IGNORED 1
#define J9_PRE_DEFINED_HANDLER_CHECK 2
#define J9_USE_OLD_JAVA_SIGNAL_HANDLER 2
#define J9_SIG_PREFIX "SIG"
#define J9_SIGNAME_BUFFER_LENGTH 16
static void dummySignalHandler(jint sigNum);
static BOOLEAN isSignalUsedForShutdown(jint sigNum);
static BOOLEAN isSignalReservedByJVM(jint sigNum);
typedef struct {
const char *signalName;
jint signalValue;
} J9SignalMapping;
#if defined(WIN32)
#define J9_SIGNAL_MAP_ENTRY(name, value) { name, value }
#else
#define J9_SIGNAL_MAP_ENTRY(name, value) { "SIG" name, value }
#endif
static const J9SignalMapping signalMap[] = {
#if defined(SIGABRT)
J9_SIGNAL_MAP_ENTRY("ABRT", SIGABRT),
#endif
#if defined(SIGALRM)
J9_SIGNAL_MAP_ENTRY("ALRM", SIGALRM),
#endif
#if defined(SIGBREAK)
J9_SIGNAL_MAP_ENTRY("BREAK", SIGBREAK),
#endif
#if defined(SIGBUS)
J9_SIGNAL_MAP_ENTRY("BUS", SIGBUS),
#endif
#if defined(SIGCHLD)
J9_SIGNAL_MAP_ENTRY("CHLD", SIGCHLD),
#endif
#if defined(SIGCONT)
J9_SIGNAL_MAP_ENTRY("CONT", SIGCONT),
#endif
#if defined(SIGFPE)
J9_SIGNAL_MAP_ENTRY("FPE", SIGFPE),
#endif
#if defined(SIGHUP)
J9_SIGNAL_MAP_ENTRY("HUP", SIGHUP),
#endif
#if defined(SIGILL)
J9_SIGNAL_MAP_ENTRY("ILL", SIGILL),
#endif
#if defined(SIGINT)
J9_SIGNAL_MAP_ENTRY("INT", SIGINT),
#endif
#if defined(SIGIO)
J9_SIGNAL_MAP_ENTRY("IO", SIGIO),
#endif
#if defined(SIGPIPE)
J9_SIGNAL_MAP_ENTRY("PIPE", SIGPIPE),
#endif
#if defined(SIGPROF)
J9_SIGNAL_MAP_ENTRY("PROF", SIGPROF),
#endif
#if defined(SIGQUIT)
J9_SIGNAL_MAP_ENTRY("QUIT", SIGQUIT),
#endif
#if defined(SIGSEGV)
J9_SIGNAL_MAP_ENTRY("SEGV", SIGSEGV),
#endif
#if defined(SIGSYS)
J9_SIGNAL_MAP_ENTRY("SYS", SIGSYS),
#endif
#if defined(SIGTERM)
J9_SIGNAL_MAP_ENTRY("TERM", SIGTERM),
#endif
#if defined(SIGTRAP)
J9_SIGNAL_MAP_ENTRY("TRAP", SIGTRAP),
#endif
#if defined(SIGTSTP)
J9_SIGNAL_MAP_ENTRY("TSTP", SIGTSTP),
#endif
#if defined(SIGTTIN)
J9_SIGNAL_MAP_ENTRY("TTIN", SIGTTIN),
#endif
#if defined(SIGTTOU)
J9_SIGNAL_MAP_ENTRY("TTOU", SIGTTOU),
#endif
#if defined(SIGURG)
J9_SIGNAL_MAP_ENTRY("URG", SIGURG),
#endif
#if defined(SIGUSR1)
J9_SIGNAL_MAP_ENTRY("USR1", SIGUSR1),
#endif
#if defined(SIGUSR2)
J9_SIGNAL_MAP_ENTRY("USR2", SIGUSR2),
#endif
#if defined(SIGVTALRM)
J9_SIGNAL_MAP_ENTRY("VTALRM", SIGVTALRM),
#endif
#if defined(SIGWINCH)
J9_SIGNAL_MAP_ENTRY("WINCH", SIGWINCH),
#endif
#if defined(SIGXCPU)
J9_SIGNAL_MAP_ENTRY("XCPU", SIGXCPU),
#endif
#if defined(SIGXFSZ)
J9_SIGNAL_MAP_ENTRY("XFSZ", SIGXFSZ),
#endif
#if defined(SIGRECONFIG)
J9_SIGNAL_MAP_ENTRY("RECONFIG", SIGRECONFIG),
#endif
#if defined(SIGKILL)
J9_SIGNAL_MAP_ENTRY("KILL", SIGKILL),
#endif
#if defined(SIGSTOP)
J9_SIGNAL_MAP_ENTRY("STOP", SIGSTOP),
#endif
#if defined(SIGINFO)
J9_SIGNAL_MAP_ENTRY("INFO", SIGINFO),
#endif
#if defined(SIGIOT)
J9_SIGNAL_MAP_ENTRY("IOT", SIGIOT),
#endif
#if defined(SIGPOLL)
J9_SIGNAL_MAP_ENTRY("POLL", SIGPOLL),
#endif
{NULL, J9_SIG_ERR}
};
static void
captureCommandLine(void)
{
#if defined(WIN32)
#define ENV_VAR_NAME L"OPENJ9_JAVA_COMMAND_LINE"
#else
#define ENV_VAR_NAME "OPENJ9_JAVA_COMMAND_LINE"
#endif
#if defined(AIXPPC)
long int bufferSize = sysconf(_SC_ARG_MAX);
if (bufferSize > 0) {
char *buffer = malloc(bufferSize);
if (NULL != buffer) {
#if defined(J9VM_ENV_DATA64)
struct procsinfo64 info;
#else
struct procsinfo info;
#endif
memset(&info, '\0', sizeof(info));
info.pi_pid = getpid();
if (0 == getargs(&info, sizeof(info), buffer, bufferSize)) {
char *cursor = buffer;
for (;; ++cursor) {
if ('\0' == *cursor) {
if ('\0' == cursor[1]) {
break;
}
*cursor = ' ';
}
}
setenv(ENV_VAR_NAME, buffer, 1 );
}
free(buffer);
}
}
#elif defined(J9ZOS390)
#pragma convlit(suspend)
if (mainlineLanguageIsC()) {
void *plist = __osplist;
if (NULL != plist) {
const struct arg_list *args = *(const struct arg_list **)plist;
uint32_t argc = args->argc;
uint32_t i = 0;
size_t length = 0;
char *buffer = NULL;
for (i = 0; i < argc; ++i) {
length += args->string[i]->length;
}
buffer = malloc(length);
if (NULL != buffer) {
char *cursor = buffer;
for (i = 0; i < argc; ++i) {
const struct arg_string *arg = args->string[i];
if (0 != i) {
*cursor = ' ';
cursor += 1;
}
memcpy(cursor, arg->value, arg->length - 1);
cursor += arg->length - 1;
}
*cursor = '\0';
setenv(ENV_VAR_NAME, buffer, 1 );
free(buffer);
}
}
}
#pragma convlit(resume)
#elif defined(LINUX)
int fd = open("/proc/self/cmdline", O_RDONLY, 0);
if (fd >= 0) {
char *buffer = NULL;
size_t length = 0;
for (;;) {
char small_buffer[512];
ssize_t count = read(fd, small_buffer, sizeof(small_buffer));
if (count <= 0) {
break;
}
length += (size_t)count;
}
if (length < 2) {
goto done;
}
buffer = malloc(length);
if (NULL == buffer) {
goto done;
}
if ((off_t)-1 == lseek(fd, 0, SEEK_SET)) {
goto done;
}
if (read(fd, buffer, length) != length) {
goto done;
}
for (length -= 2;; length -= 1) {
if (0 == length) {
break;
}
if ('\0' == buffer[length]) {
buffer[length] = ' ';
}
}
setenv(ENV_VAR_NAME, buffer, 1 );
done:
if (NULL != buffer) {
free(buffer);
}
close(fd);
}
#elif defined(OSX)
int argmax = 0;
size_t length = 0;
int mib[3];
mib[0] = CTL_KERN;
mib[1] = KERN_ARGMAX;
length = sizeof(argmax);
if (0 == sysctl(mib, 2, &argmax, &length, NULL, 0)) {
char *buffer = malloc(argmax);
if (NULL != buffer) {
int argc = 0;
int pid = getpid();
mib[0] = CTL_KERN;
mib[1] = KERN_PROCARGS2;
mib[2] = pid;
length = argmax;
if ((argmax >= sizeof(argc)) && (0 == sysctl(mib, 3, buffer, &length, NULL, 0))) {
memcpy(&argc, buffer, sizeof(argc));
mib[0] = CTL_KERN;
mib[1] = KERN_PROCARGS;
mib[2] = pid;
length = argmax;
if (0 == sysctl(mib, 3, buffer, &length, NULL, 0)) {
char *cursor = buffer;
char *start = NULL;
char *limit = buffer + length;
for (; (cursor < limit) && ('\0' != *cursor); ++cursor) {
}
for (; (cursor < limit) && ('\0' == *cursor); ++cursor) {
}
start = cursor;
for (; cursor < limit; ++cursor) {
if ('\0' == *cursor) {
argc -= 1;
if (0 == argc) {
break;
}
*cursor = ' ';
}
}
setenv(ENV_VAR_NAME, start, 1 );
}
}
free(buffer);
}
}
#elif defined(WIN32)
const wchar_t *commandLine = GetCommandLineW();
if (NULL != commandLine) {
_wputenv_s(ENV_VAR_NAME, commandLine);
}
#endif
#undef ENV_VAR_NAME
}
static void freeGlobals(void)
{
free(newPath);
newPath = NULL;
free(j9binBuffer);
j9binBuffer = NULL;
free(jrebinBuffer);
jrebinBuffer = NULL;
free(j9libBuffer);
j9libBuffer = NULL;
free(j9libvmBuffer);
j9libvmBuffer = NULL;
free(j9Buffer);
j9Buffer = NULL;
}
static J9StringBuffer* jvmBufferEnsure(J9StringBuffer* buffer, UDATA len) {
if (buffer == NULL) {
UDATA newSize = len > MIN_GROWTH ? len : MIN_GROWTH;
buffer = (J9StringBuffer*) malloc( newSize + 1 + sizeof(UDATA));
if (buffer != NULL) {
buffer->remaining = newSize;
buffer->data[0] = '\0';
}
return buffer;
}
if (len > buffer->remaining) {
UDATA newSize = len > MIN_GROWTH ? len : MIN_GROWTH;
J9StringBuffer* new = (J9StringBuffer*) malloc( strlen((const char*)buffer->data) + newSize + sizeof(UDATA) + 1 );
if (new) {
new->remaining = newSize;
strcpy(new->data, (const char*)buffer->data);
}
free(buffer);
return new;
}
return buffer;
}
static J9StringBuffer*
jvmBufferCat(J9StringBuffer* buffer, const char* string)
{
UDATA len = strlen(string);
buffer = jvmBufferEnsure(buffer, len);
if (buffer) {
strcat(buffer->data, string);
buffer->remaining -= len;
}
return buffer;
}
static char* jvmBufferData(J9StringBuffer* buffer) {
return buffer ? buffer->data : NULL;
}
jint JNICALL DestroyJavaVM(JavaVM * javaVM)
{
jint rc;
UT_MODULE_UNLOADED(J9_UTINTERFACE_FROM_VM((J9JavaVM*)javaVM));
rc = globalDestroyVM(javaVM);
if (JNI_OK == rc) {
if (NULL != j9portLibrary.port_shutdown_library) {
j9portLibrary.port_shutdown_library(&j9portLibrary);
}
freeGlobals();
#if defined(J9UNIX) || defined(J9ZOS390)
j9vm_dllHandle = 0;
java_dllHandle = 0;
#endif
BFUjavaVM = NULL;
} else {
memoryCheck_print_report(&j9portLibrary);
}
return rc;
}
static BOOLEAN
librariesLoaded(void)
{
#if !CALL_BUNDLED_FUNCTIONS_DIRECTLY
if ((globalCreateVM == NULL)||(globalGetVMs == NULL)) {
return FALSE;
}
#endif
return TRUE;
}
#ifdef WIN32
BOOL APIENTRY DllMain(HANDLE hModule, DWORD ul_reason_for_call, LPVOID lpReserved)
{
BOOL rcDllMain = TRUE;
jvm_dllHandle = hModule;
if (ul_reason_for_call == DLL_PROCESS_ATTACH) {
DisableThreadLibraryCalls(hModule);
}
return rcDllMain;
}
static BOOLEAN
preloadLibraries(void)
{
char* tempchar = 0;
char jvmDLLName[J9_MAX_PATH];
J9StringBuffer * jvmDLLNameBuffer = NULL;
wchar_t unicodeDLLName[J9_MAX_PATH + 1] = {0};
DWORD unicodeDLLNameLength = 0;
UINT prevMode;
HINSTANCE vmDLL = 0;
HINSTANCE threadDLL = 0;
HINSTANCE portDLL = 0;
char* vmDllName = J9_VM_DLL_NAME;
char* vmName = NULL;
static beenRun=FALSE;
if(beenRun) {
return TRUE;
}
beenRun = TRUE;
unicodeDLLNameLength = GetModuleFileNameW(jvm_dllHandle, unicodeDLLName, (J9_MAX_PATH + 1));
if (unicodeDLLNameLength > (DWORD)J9_MAX_PATH) {
fprintf(stderr,"ERROR: failed to load library. Path is too long: %ls\n", unicodeDLLName);
return FALSE;
}
WideCharToMultiByte(OS_ENCODING_CODE_PAGE, OS_ENCODING_WC_FLAGS, unicodeDLLName, -1, jvmDLLName, J9_MAX_PATH, NULL, NULL);
jvmDLLNameBuffer = jvmBufferCat(NULL, jvmDLLName);
j9binBuffer = jvmBufferCat(j9binBuffer, jvmDLLName);
truncatePath(jvmBufferData(jvmDLLNameBuffer));
jvmDLLNameBuffer = jvmBufferCat(jvmDLLNameBuffer, "\\");
jvmDLLNameBuffer = jvmBufferCat(jvmDLLNameBuffer, vmDllName);
jvmDLLNameBuffer = jvmBufferCat(jvmDLLNameBuffer, ".dll");
MultiByteToWideChar(OS_ENCODING_CODE_PAGE, OS_ENCODING_MB_FLAGS, jvmBufferData(jvmDLLNameBuffer), -1, unicodeDLLName, J9_MAX_PATH);
if(INVALID_FILE_ATTRIBUTES != GetFileAttributesW(unicodeDLLName)) {
jvmInSubdir = TRUE;
} else {
jvmInSubdir = FALSE;
}
prevMode = SetErrorMode( SEM_NOOPENFILEERRORBOX|SEM_FAILCRITICALERRORS );
free(jvmDLLNameBuffer);
jvmDLLNameBuffer = NULL;
free(jrebinBuffer);
jrebinBuffer = NULL;
if(jvmInSubdir) {
truncatePath(jvmBufferData(j9binBuffer));
jrebinBuffer = jvmBufferCat(NULL, jvmBufferData(j9binBuffer));
truncatePath(jvmBufferData(jrebinBuffer));
} else {
truncatePath(jvmBufferData(j9binBuffer));
truncatePath(jvmBufferData(j9binBuffer));
jrebinBuffer = jvmBufferCat(NULL, jvmBufferData(j9binBuffer));
}
j9libBuffer = jvmBufferCat(NULL, jvmBufferData(jrebinBuffer));
truncatePath(jvmBufferData(j9libBuffer));
j9Buffer = jvmBufferCat(NULL, jvmBufferData(j9libBuffer));
truncatePath(jvmBufferData(j9Buffer));
j9libBuffer = jvmBufferCat(j9libBuffer, DIR_SEPARATOR_STR "lib");
j9libvmBuffer = jvmBufferCat(NULL, jvmBufferData(j9libBuffer));
vmName = strrchr(jvmBufferData(j9binBuffer), DIR_SEPARATOR);
if (NULL != vmName) {
j9libvmBuffer = jvmBufferCat(j9libvmBuffer, vmName);
}
DBG_MSG(("j9binBuffer = <%s>\n", jvmBufferData(j9binBuffer)));
DBG_MSG(("jrebinBuffer = <%s>\n", jvmBufferData(jrebinBuffer)));
DBG_MSG(("j9libBuffer = <%s>\n", jvmBufferData(j9libBuffer)));
DBG_MSG(("j9libvmBuffer = <%s>\n", jvmBufferData(j9libvmBuffer)));
DBG_MSG(("j9Buffer = <%s>\n", jvmBufferData(j9Buffer)));
#if !CALL_BUNDLED_FUNCTIONS_DIRECTLY
vmDLL = (HINSTANCE) preloadLibrary(vmDllName, TRUE);
preloadLibrary(J9_HOOKABLE_DLL_NAME, TRUE);
SetErrorMode( prevMode );
if (vmDLL < (HINSTANCE)HINSTANCE_ERROR) {
fprintf(stderr,"jvm.dll failed to load: %s\n", vmDllName);
return FALSE;
}
globalCreateVM = (CreateVM) GetProcAddress (vmDLL, (LPCSTR) CREATE_JAVA_VM_ENTRYPOINT );
globalGetVMs = (GetVMs) GetProcAddress (vmDLL, (LPCSTR) GET_JAVA_VMS_ENTRYPOINT);
if (!globalCreateVM || !globalGetVMs) {
FreeLibrary(vmDLL);
fprintf(stderr,"jvm.dll failed to load: global entrypoints not found\n");
return FALSE;
}
j9vm_dllHandle = vmDLL;
threadDLL = (HINSTANCE) preloadLibrary(J9_THREAD_DLL_NAME, TRUE);
f_threadGlobal = (ThreadGlobal) GetProcAddress (threadDLL, (LPCSTR) "omrthread_global");
f_threadAttachEx = (ThreadAttachEx) GetProcAddress (threadDLL, (LPCSTR) "omrthread_attach_ex");
f_threadDetach = (ThreadDetach) GetProcAddress (threadDLL, (LPCSTR) "omrthread_detach");
f_monitorEnter = (MonitorEnter) GetProcAddress (threadDLL, (LPCSTR) "omrthread_monitor_enter");
f_monitorExit = (MonitorExit) GetProcAddress (threadDLL, (LPCSTR) "omrthread_monitor_exit");
f_monitorInit = (MonitorInit) GetProcAddress (threadDLL, (LPCSTR) "omrthread_monitor_init_with_name");
f_monitorDestroy = (MonitorDestroy) GetProcAddress (threadDLL, (LPCSTR) "omrthread_monitor_destroy");
f_monitorWaitTimed = (MonitorWaitTimed) GetProcAddress (threadDLL, (LPCSTR) "omrthread_monitor_wait_timed");
f_monitorNotify = (MonitorNotify) GetProcAddress (threadDLL, (LPCSTR) "omrthread_monitor_notify");
f_monitorNotifyAll = (MonitorNotifyAll) GetProcAddress (threadDLL, (LPCSTR) "omrthread_monitor_notify_all");
f_threadLibControl = (ThreadLibControl) GetProcAddress (threadDLL, (LPCSTR) "omrthread_lib_control");
f_setCategory = (SetCategory) GetProcAddress (threadDLL, (LPCSTR) "omrthread_set_category");
f_libEnableCPUMonitor = (LibEnableCPUMonitor) GetProcAddress (threadDLL, (LPCSTR) "omrthread_lib_enable_cpu_monitor");
if (!f_threadGlobal || !f_threadAttachEx || !f_threadDetach || !f_monitorEnter || !f_monitorExit || !f_monitorInit || !f_monitorDestroy || !f_monitorWaitTimed
|| !f_monitorNotify || !f_monitorNotifyAll || !f_threadLibControl || !f_setCategory || !f_libEnableCPUMonitor) {
FreeLibrary(vmDLL);
FreeLibrary(threadDLL);
fprintf(stderr,"jvm.dll failed to load: thread library entrypoints not found\n");
return FALSE;
}
portDLL = (HINSTANCE) preloadLibrary(J9_PORT_DLL_NAME, TRUE);
portInitLibrary = (PortInitLibrary) GetProcAddress (portDLL, (LPCSTR) "j9port_init_library");
portGetSizeFn = (PortGetSize) GetProcAddress (portDLL, (LPCSTR) "j9port_getSize");
portGetVersionFn = (PortGetVersion) GetProcAddress (portDLL, (LPCSTR) "j9port_getVersion");
if (!portInitLibrary) {
FreeLibrary(vmDLL);
FreeLibrary(threadDLL);
FreeLibrary(portDLL);
fprintf(stderr,"jvm.dll failed to load: %s entrypoints not found\n", J9_PORT_DLL_NAME);
return FALSE;
}
preloadLibrary(J9_ZIP_DLL_NAME, TRUE);
#endif
return TRUE;
}
static void
bfuThreadStart(J9HookInterface** vmHooks, UDATA eventNum, void* eventData, void* userData)
{
J9VMThreadCreatedEvent* event = eventData;
if (event->continueInitialization) {
HANDLE win32Event = CreateEvent(NULL, FALSE, FALSE, NULL);
if (win32Event == NULL) {
event->continueInitialization = 0;
} else {
event->vmThread->sidecarEvent = win32Event;
}
}
}
static void
bfuThreadEnd(J9HookInterface** vmHooks, UDATA eventNum, void* eventData, void* userData)
{
J9VMThread* vmThread = ((J9VMThreadDestroyEvent*)eventData)->vmThread;
HANDLE event = (HANDLE) vmThread->sidecarEvent;
if (event) {
CloseHandle(event);
vmThread->sidecarEvent = NULL;
}
}
static void bfuInterrupt(J9VMThread * vmThread)
{
HANDLE event = (HANDLE) vmThread->sidecarEvent;
if (event) {
SetEvent(event);
}
}
static void bfuClearInterrupt(J9VMThread * vmThread)
{
HANDLE event = (HANDLE) vmThread->sidecarEvent;
if (event) {
ResetEvent(event);
}
}
static jint
initializeWin32ThreadEvents(J9JavaVM* javaVM)
{
J9VMThread* aThread;
J9HookInterface** hookInterface = javaVM->internalVMFunctions->getVMHookInterface(javaVM);
javaVM->sidecarInterruptFunction = bfuInterrupt;
javaVM->sidecarClearInterruptFunction = bfuClearInterrupt;
if ((*hookInterface)->J9HookRegisterWithCallSite(hookInterface, J9HOOK_VM_THREAD_CREATED, bfuThreadStart, OMR_GET_CALLSITE(), NULL)) {
return JNI_ERR;
}
if ((*hookInterface)->J9HookRegisterWithCallSite(hookInterface, J9HOOK_VM_THREAD_DESTROY, bfuThreadEnd, OMR_GET_CALLSITE(), NULL)) {
return JNI_ERR;
}
aThread = javaVM->mainThread;
do {
aThread->sidecarEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
if (aThread->sidecarEvent == NULL) {
return JNI_ERR;
}
aThread = aThread->linkNext;
} while (aThread != javaVM->mainThread);
return JNI_OK;
}
#endif
#ifndef WIN32
J9StringBuffer *
getj9bin()
{
J9StringBuffer *result = NULL;
#if (defined(LINUX) && !defined(J9ZTPF)) || defined(OSX)
Dl_info libraryInfo;
int rc = dladdr((void *)getj9bin, &libraryInfo);
if (0 == rc) {
fprintf(stderr, "ERROR: cannot determine JAVA home directory\n");
abort();
}
result = jvmBufferCat(NULL, libraryInfo.dli_fname);
truncatePath(jvmBufferData(result));
#elif defined(J9ZOS390) || defined(J9ZTPF)
#define VMDLL_NAME J9_VM_DLL_NAME
int foundPosition = 0;
while(foundPosition = findDirUplevelToDirContainingFile(&result, LD_ENV_PATH, ':', "libjvm.so", 0, foundPosition)) {
DBG_MSG(("found a libjvm.so at offset %d - looking at elem: %s\n", foundPosition, result));
if (isFileInDir(jvmBufferData(result), "lib" VMDLL_NAME J9PORT_LIBRARY_SUFFIX)) {
return result;
}
truncatePath(jvmBufferData(result));
if (isFileInDir(jvmBufferData(result), "lib" VMDLL_NAME J9PORT_LIBRARY_SUFFIX)) {
return result;
}
}
fprintf(stderr, "ERROR: cannot determine JAVA home directory\n");
abort();
#else
struct ld_info *linfo, *linfop;
int linfoSize, rc;
char *myAddress, *filename, *membername;
linfoSize = 1024;
linfo = malloc(linfoSize);
for(;;) {
rc = loadquery(L_GETINFO, linfo, linfoSize);
if (rc != -1) {
break;
}
linfoSize *=2;
linfo = realloc(linfo, linfoSize);
}
myAddress = ((char **)&getj9bin)[0];
for (linfop = linfo;;) {
char *textorg = (char *)linfop->ldinfo_textorg;
char *textend = textorg + (unsigned long)linfop->ldinfo_textsize;
if (myAddress >=textorg && (myAddress < textend)) {
break;
}
if (!linfop->ldinfo_next) {
abort();
}
linfop = (struct ld_info *)((char *)linfop + linfop->ldinfo_next);
}
filename = linfop->ldinfo_filename;
membername = filename+strlen(filename)+1;
#ifdef DEBUG
printf("ldinfo: filename is %s. membername is %s\n", filename, membername);
#endif
result = jvmBufferCat(NULL, filename);
truncatePath(jvmBufferData(result));
free(linfo);
#endif
return result;
}
#endif
#if defined(RS6000) || defined(LINUXPPC)
#ifdef PPC64
#ifdef J9VM_ENV_LITTLE_ENDIAN
#define JVM_ARCH_DIR "ppc64le"
#else
#define JVM_ARCH_DIR "ppc64"
#endif
#else
#define JVM_ARCH_DIR "ppc"
#endif
#elif defined(J9X86) || defined(WIN32)
#define JVM_ARCH_DIR "i386"
#elif defined(S390) || defined(J9ZOS390)
#if defined(S39064) || defined(J9ZOS39064)
#define JVM_ARCH_DIR "s390x"
#else
#define JVM_ARCH_DIR "s390"
#endif
#elif defined(J9HAMMER)
#define JVM_ARCH_DIR "amd64"
#elif defined(J9ARM)
#define JVM_ARCH_DIR "arm"
#elif defined(J9AARCH64)
#define JVM_ARCH_DIR "aarch64"
#elif defined(RISCV64)
#define JVM_ARCH_DIR "riscv64"
#else
#error "Must define an architecture"
#endif
#if (JAVA_SPEC_VERSION >= 9) || defined(OSX)
#define J9VM_LIB_ARCH_DIR "/lib/"
#else
#define J9VM_LIB_ARCH_DIR "/lib/" JVM_ARCH_DIR "/"
#endif
#if JAVA_SPEC_VERSION == 8
static void
removeSuffix(char *string, const char *suffix)
{
size_t stringLength = strlen(string);
size_t suffixLength = strlen(suffix);
if (stringLength >= suffixLength) {
char *tail = &string[stringLength - suffixLength];
if (0 == strcmp(tail, suffix)) {
*tail = '\0';
}
}
}
#endif
#if defined(J9UNIX) || defined(J9ZOS390)
static BOOLEAN
preloadLibraries(void)
{
void *vmDLL, *threadDLL, *portDLL;
char* lastSep = 0;
char* tempchar = 0;
char* exeInBuf;
J9StringBuffer * jvmDLLNameBuffer = NULL;
char *lastDirName;
char* vmDllName = J9_VM_DLL_NAME;
struct stat statBuf;
#if defined(J9ZOS390)
void *javaDLL;
#endif
#if defined(AIXPPC)
size_t origLibpathLen = 0;
const char *origLibpath = NULL;
#endif
if (j9vm_dllHandle != 0) {
return FALSE;
}
#if defined(J9ZOS390)
iconv_init();
#endif
#if defined(AIXPPC)
origLibpath = getenv("LIBPATH");
if (NULL != origLibpath) {
origLibpathLen = strlen(origLibpath);
}
#endif
jvmDLLNameBuffer = getj9bin();
j9binBuffer = jvmBufferCat(NULL, jvmBufferData(jvmDLLNameBuffer));
addToLibpath(jvmBufferData(j9binBuffer), TRUE);
lastDirName = strrchr(jvmBufferData(j9binBuffer), DIR_SEPARATOR);
if (NULL == lastDirName) {
fprintf(stderr, "Preload libraries failed to find a valid J9 binary location\n" );
exit( -1 );
}
if (0 == strcmp(lastDirName + 1, "classic")) {
truncatePath(jvmBufferData(j9binBuffer));
truncatePath(jvmBufferData(j9binBuffer));
#if JAVA_SPEC_VERSION == 8
removeSuffix(jvmBufferData(j9binBuffer), "/lib");
#endif
j9binBuffer = jvmBufferCat(j9binBuffer, J9VM_LIB_ARCH_DIR "j9vm/");
if (-1 != stat(jvmBufferData(j9binBuffer), &statBuf)) {
jvmDLLNameBuffer = jvmBufferCat(NULL, jvmBufferData(j9binBuffer));
} else {
free(j9binBuffer);
j9binBuffer = NULL;
j9binBuffer = jvmBufferCat(NULL, jvmBufferData(jvmDLLNameBuffer));
}
}
jvmDLLNameBuffer = jvmBufferCat(jvmDLLNameBuffer, "/lib");
jvmDLLNameBuffer = jvmBufferCat(jvmDLLNameBuffer, vmDllName);
jvmDLLNameBuffer = jvmBufferCat(jvmDLLNameBuffer, J9PORT_LIBRARY_SUFFIX);
if(-1 != stat (jvmBufferData(jvmDLLNameBuffer), &statBuf)) {
jvmInSubdir = TRUE;
} else {
jvmInSubdir = FALSE;
}
DBG_MSG(("jvmInSubdir: %d\n", jvmInSubdir));
free(jrebinBuffer);
jrebinBuffer = NULL;
if(jvmInSubdir) {
jrebinBuffer = jvmBufferCat(NULL, jvmBufferData(j9binBuffer));
truncatePath(jvmBufferData(jrebinBuffer));
} else {
truncatePath(jvmBufferData(j9binBuffer));
jrebinBuffer = jvmBufferCat(NULL, jvmBufferData(j9binBuffer));
}
j9libBuffer = jvmBufferCat(NULL, jvmBufferData(jrebinBuffer));
#if !defined(OSX)
#if JAVA_SPEC_VERSION == 8
truncatePath(jvmBufferData(j9libBuffer));
#endif
#endif
j9libvmBuffer = jvmBufferCat(NULL, jvmBufferData(j9binBuffer));
j9Buffer = jvmBufferCat(NULL, jvmBufferData(jrebinBuffer));
truncatePath(jvmBufferData(j9Buffer));
DBG_MSG(("j9binBuffer = <%s>\n", jvmBufferData(j9binBuffer)));
DBG_MSG(("jrebinBuffer = <%s>\n", jvmBufferData(jrebinBuffer)));
DBG_MSG(("j9libBuffer = <%s>\n", jvmBufferData(j9libBuffer)));
DBG_MSG(("j9libvmBuffer = <%s>\n", jvmBufferData(j9libvmBuffer)));
DBG_MSG(("j9Buffer = <%s>\n", jvmBufferData(j9Buffer)));
addToLibpath(jvmBufferData(jrebinBuffer), TRUE);
#if defined(AIXPPC)
backupLibpath(&libpathBackup, origLibpathLen);
#endif
omrsigDLL = preloadLibrary("omrsig", TRUE);
if (NULL == omrsigDLL) {
fprintf(stderr, "libomrsig failed to load: omrsig\n" );
exit( -1 );
}
vmDLL = preloadLibrary(vmDllName, TRUE);
if (NULL == vmDLL) {
fprintf(stderr,"libjvm.so failed to load: %s\n", vmDllName);
exit( -1 );
}
globalCreateVM = (CreateVM) dlsym (vmDLL, CREATE_JAVA_VM_ENTRYPOINT );
globalGetVMs = (GetVMs) dlsym (vmDLL, GET_JAVA_VMS_ENTRYPOINT);
if ((NULL == globalCreateVM) || (NULL == globalGetVMs)) {
dlclose(vmDLL);
fprintf(stderr,"libjvm.so failed to load: global entrypoints not found\n");
exit( -1 );
}
j9vm_dllHandle = vmDLL;
#ifdef J9ZOS390
javaDLL = preloadLibrary("java", FALSE);
if (!javaDLL) {
fprintf(stderr,"libjava.dll failed to load: %s\n", "java");
exit( -1 );
}
globalGetStringPlatform = (pGetStringPlatform) dlsym (javaDLL, "IBMZOS_GetStringPlatform");
globalGetStringPlatformLength = (pGetStringPlatformLength) dlsym (javaDLL, "IBMZOS_GetStringPlatformLength");
globalNewStringPlatform = (pNewStringPlatform) dlsym (javaDLL, "IBMZOS_NewStringPlatform");
global_a2e_vsprintf = (p_a2e_vsprintf) dlsym (javaDLL, "IBMZOS_a2e_vsprintf");
if (!globalGetStringPlatform || !globalGetStringPlatformLength || !globalNewStringPlatform || !global_a2e_vsprintf) {
dlclose(vmDLL);
dlclose(javaDLL);
fprintf(stderr,"libjava.dll failed to load: global entrypoints not found\n");
exit( -1 );
}
java_dllHandle = javaDLL;
#endif
threadDLL = preloadLibrary(J9_THREAD_DLL_NAME, TRUE);
f_threadGlobal = (ThreadGlobal) dlsym (threadDLL, "omrthread_global");
f_threadAttachEx = (ThreadAttachEx) dlsym (threadDLL, "omrthread_attach_ex");
f_threadDetach = (ThreadDetach) dlsym (threadDLL, "omrthread_detach");
f_monitorEnter = (MonitorEnter) dlsym (threadDLL, "omrthread_monitor_enter");
f_monitorExit = (MonitorExit) dlsym (threadDLL, "omrthread_monitor_exit");
f_monitorInit = (MonitorInit) dlsym (threadDLL, "omrthread_monitor_init_with_name");
f_monitorDestroy = (MonitorDestroy) dlsym (threadDLL, "omrthread_monitor_destroy");
f_monitorWaitTimed = (MonitorWaitTimed) dlsym (threadDLL, "omrthread_monitor_wait_timed");
f_monitorNotify = (MonitorNotify) dlsym (threadDLL, "omrthread_monitor_notify");
f_monitorNotifyAll = (MonitorNotifyAll) dlsym (threadDLL, "omrthread_monitor_notify_all");
f_threadLibControl = (ThreadLibControl) dlsym (threadDLL, "omrthread_lib_control");
f_setCategory = (SetCategory) dlsym (threadDLL, "omrthread_set_category");
f_libEnableCPUMonitor = (LibEnableCPUMonitor) dlsym (threadDLL, "omrthread_lib_enable_cpu_monitor");
if (!f_threadGlobal || !f_threadAttachEx || !f_threadDetach || !f_monitorEnter || !f_monitorExit || !f_monitorInit || !f_monitorDestroy || !f_monitorWaitTimed
|| !f_monitorNotify || !f_monitorNotifyAll || !f_threadLibControl || !f_setCategory || !f_libEnableCPUMonitor) {
dlclose(vmDLL);
#ifdef J9ZOS390
dlclose(javaDLL);
#endif
dlclose(threadDLL);
fprintf(stderr,"libjvm.so failed to load: thread library entrypoints not found\n");
exit( -1 );
}
portDLL = preloadLibrary(J9_PORT_DLL_NAME, TRUE);
portInitLibrary = (PortInitLibrary) dlsym (portDLL, "j9port_init_library");
portGetSizeFn = (PortGetSize) dlsym (portDLL, "j9port_getSize");
portGetVersionFn = (PortGetVersion) dlsym (portDLL, "j9port_getVersion");
if (!portInitLibrary) {
dlclose(vmDLL);
#ifdef J9ZOS390
dlclose(javaDLL);
#endif
dlclose(threadDLL);
dlclose(portDLL);
fprintf(stderr,"libjvm.so failed to load: %s entrypoints not found\n", J9_PORT_DLL_NAME);
exit( -1 );
}
return TRUE;
}
#endif
int jio_fprintf(FILE * stream, const char * format, ...) {
va_list args;
Trc_SC_fprintf_Entry();
va_start( args, format );
vfprintf(stream, format, args);
va_end( args );
Trc_SC_fprintf_Exit(0);
return 0;
}
int
jio_snprintf(char * str, int n, const char * format, ...)
{
va_list args;
int result;
Trc_SC_snprintf_Entry();
va_start(args, format);
result = vsnprintf( str, n, format, args );
va_end(args);
Trc_SC_snprintf_Exit(result);
return result;
}
int
jio_vfprintf(FILE * stream, const char * format, va_list args)
{
Trc_SC_vfprintf_Entry(stream, format);
vfprintf(stream, format, args);
Trc_SC_vfprintf_Exit(0);
return 0;
}
int
jio_vsnprintf(char * str, int n, const char * format, va_list args)
{
int result;
Trc_SC_vsnprintf_Entry(str, n, format);
result = vsnprintf( str, n, format, args );
Trc_SC_vsnprintf_Exit(result);
return result;
}
typedef struct J9SpecialArguments {
UDATA localVerboseLevel;
IDATA *xoss;
UDATA *argEncoding;
IDATA *ibmMallocTraceSet;
const char *executableJarPath;
} J9SpecialArguments;
static UDATA
initialArgumentScan(JavaVMInitArgs *args, J9SpecialArguments *specialArgs)
{
BOOLEAN xCheckFound = FALSE;
const char *xCheckString = "-Xcheck";
const char *javaCommand = "-Dsun.java.command=";
const char *javaCommandValue = NULL;
const char *classPath = "-Djava.class.path=";
const char *classPathValue = NULL;
jint argCursor;
UDATA argumentsSize = 0;
#ifdef WIN32
Assert_SC_notNull(specialArgs->argEncoding);
#endif
for (argCursor=0; argCursor < args->nOptions; argCursor++) {
argumentsSize += strlen(args->options[argCursor].optionString) + 1;
if (0 == strncmp(args->options[argCursor].optionString, "-Xoss", 5)) {
*(specialArgs->xoss) = argCursor;
} else if (strncmp(args->options[argCursor].optionString, OPT_VERBOSE_INIT, strlen(OPT_VERBOSE_INIT))==0) {
specialArgs->localVerboseLevel = VERBOSE_INIT;
} else if (0 == strncmp(args->options[argCursor].optionString, javaCommand, strlen(javaCommand))) {
javaCommandValue = args->options[argCursor].optionString + strlen(javaCommand);
} else if (0 == strncmp(args->options[argCursor].optionString, classPath, strlen(classPath))) {
classPathValue = args->options[argCursor].optionString + strlen(classPath);
} else if (0 == strncmp(args->options[argCursor].optionString, xCheckString, strlen(xCheckString))) {
xCheckFound = TRUE;
} else if (0 == strcmp(args->options[argCursor].optionString, VMOPT_XARGENCODING)) {
*(specialArgs->argEncoding) = ARG_ENCODING_PLATFORM;
} else if (0 == strcmp(args->options[argCursor].optionString, VMOPT_XNOARGSCONVERSION)) {
*(specialArgs->argEncoding) = ARG_ENCODING_LATIN;
} else if (0 == strcmp(args->options[argCursor].optionString, VMOPT_XARGENCODINGUTF8)) {
*(specialArgs->argEncoding) = ARG_ENCODING_UTF;
} else if (0 == strcmp(args->options[argCursor].optionString, VMOPT_XARGENCODINGLATIN)) {
*(specialArgs->argEncoding) = ARG_ENCODING_LATIN;
}
}
if ((NULL != classPathValue) && (NULL != javaCommandValue) && (strcmp(javaCommandValue, classPathValue) == 0)) {
specialArgs->executableJarPath = javaCommandValue;
}
if (TRUE == xCheckFound) {
for( argCursor = args->nOptions - 1 ; argCursor >= 0; argCursor-- ) {
char* memcheckArgs[2];
memcheckArgs[0] = "";
memcheckArgs[1] = args->options[argCursor].optionString;
if (memoryCheck_parseCmdLine(&j9portLibrary, 1, memcheckArgs) != 0) {
*(specialArgs->ibmMallocTraceSet) = FALSE;
break;
}
}
}
return argumentsSize;
}
static void
printVmArgumentsList(J9VMInitArgs *argList)
{
UDATA i;
JavaVMInitArgs *actualArgs = argList->actualVMArgs;
for (i = 0; i < argList->nOptions; ++i) {
J9CmdLineOption* j9Option = &(argList->j9Options[i]);
char *envVar = j9Option->fromEnvVar;
if (NULL == envVar) {
envVar = "N/A";
}
fprintf(stderr, "Option %" OMR_PRIuPTR " optionString=\"%s\" extraInfo=%p from environment variable =\"%s\"\n", i,
actualArgs->options[i].optionString,
actualArgs->options[i].extraInfo,
envVar);
}
}
static void
setNLSCatalog(struct J9PortLibrary* portLib)
{
J9StringBuffer *nlsSearchPathBuffer = NULL;
const char *nlsSearchPaths = NULL;
PORT_ACCESS_FROM_PORT(portLib);
if (J2SE_CURRENT_VERSION >= J2SE_V11) {
nlsSearchPathBuffer = jvmBufferCat(nlsSearchPathBuffer, jvmBufferData(j9libBuffer));
} else {
nlsSearchPathBuffer = jvmBufferCat(nlsSearchPathBuffer, jvmBufferData(j9binBuffer));
}
nlsSearchPathBuffer = jvmBufferCat(nlsSearchPathBuffer, DIR_SEPARATOR_STR);
nlsSearchPaths = jvmBufferData(nlsSearchPathBuffer);
j9nls_set_catalog(&nlsSearchPaths, 1, "java", "properties");
free(nlsSearchPathBuffer);
nlsSearchPathBuffer = NULL;
}
static jint initializeReflectionGlobals(JNIEnv * env, BOOLEAN includeAccessors) {
J9VMThread *vmThread = (J9VMThread *) env;
J9JavaVM * vm = vmThread->javaVM;
jclass clazz, clazzConstructorAccessorImpl, clazzMethodAccessorImpl;
clazz = (*env)->FindClass(env, "java/lang/Class");
if (!clazz) {
return JNI_ERR;
}
jlClass = (*env)->NewGlobalRef(env, clazz);
if (!jlClass) {
return JNI_ERR;
}
#ifdef J9VM_IVE_RAW_BUILD
classNameFID = (*env)->GetFieldID(env, clazz, "name", "Ljava/lang/String;");
if (!classNameFID) {
return JNI_ERR;
}
#else
classDepthMID = (*env)->GetStaticMethodID(env, clazz, "classDepth", "(Ljava/lang/String;)I");
if (!classDepthMID) {
return JNI_ERR;
}
classLoaderDepthMID = (*env)->GetStaticMethodID(env, clazz, "classLoaderDepth", "()I");
if (!classLoaderDepthMID) {
return JNI_ERR;
}
currentClassLoaderMID = (*env)->GetStaticMethodID(env, clazz, "currentClassLoader", "()Ljava/lang/ClassLoader;");
if (!currentClassLoaderMID) {
return JNI_ERR;
}
currentLoadedClassMID = (*env)->GetStaticMethodID(env, clazz, "currentLoadedClass", "()Ljava/lang/Class;");
if (!currentLoadedClassMID) {
return JNI_ERR;
}
#endif
getNameMID = (*env)->GetMethodID(env, clazz, "getName", "()Ljava/lang/String;");
if (!getNameMID) {
return JNI_ERR;
}
clazz = (*env)->FindClass(env, "java/lang/Thread");
if (!clazz) {
return JNI_ERR;
}
jlThread = (*env)->NewGlobalRef(env, clazz);
if (!jlThread) {
return JNI_ERR;
}
sleepMID = (*env)->GetStaticMethodID(env, clazz, "sleep", "(J)V");
if (!sleepMID) {
return JNI_ERR;
}
clazz = (*env)->FindClass(env, "java/lang/Object");
if (!clazz) {
return JNI_ERR;
}
waitMID = (*env)->GetMethodID(env, clazz, "wait", "(J)V");
if (!waitMID) {
return JNI_ERR;
}
notifyMID = (*env)->GetMethodID(env, clazz, "notify", "()V");
if (!notifyMID) {
return JNI_ERR;
}
notifyAllMID = (*env)->GetMethodID(env, clazz, "notifyAll", "()V");
if (!notifyAllMID) {
return JNI_ERR;
}
if (includeAccessors) {
if (J2SE_VERSION(vm) >= J2SE_V11) {
clazzConstructorAccessorImpl = (*env)->FindClass(env, "jdk/internal/reflect/ConstructorAccessorImpl");
clazzMethodAccessorImpl = (*env)->FindClass(env, "jdk/internal/reflect/MethodAccessorImpl");
} else {
clazzConstructorAccessorImpl = (*env)->FindClass(env, "sun/reflect/ConstructorAccessorImpl");
clazzMethodAccessorImpl = (*env)->FindClass(env, "sun/reflect/MethodAccessorImpl");
}
if ( (NULL == clazzConstructorAccessorImpl) || (NULL == clazzMethodAccessorImpl)) {
return JNI_ERR;
}
vm->srConstructorAccessor = (*env)->NewGlobalRef(env, clazzConstructorAccessorImpl);
if (NULL == vm->srConstructorAccessor) {
return JNI_ERR;
}
vm->srMethodAccessor = (*env)->NewGlobalRef(env, clazzMethodAccessorImpl);
if (NULL == vm->srMethodAccessor) {
return JNI_ERR;
}
}
return JNI_OK;
}
jint JNICALL
JNI_CreateJavaVM(JavaVM **pvm, void **penv, void *vm_args)
{
return JNI_CreateJavaVM_impl(pvm, penv, vm_args, FALSE);
}
#if defined(J9VM_OPT_JITSERVER)
int32_t JNICALL
JITServer_CreateServer(JITServer **jitServer, void *serverArgs)
{
JNIEnv *env = NULL;
JITServer *server = NULL;
jint rc = JITSERVER_OK;
server = malloc(sizeof(JITServer));
if (NULL == server) {
rc = JITSERVER_OOM;
goto _end;
}
server->startJITServer = startJITServer;
server->waitForJITServerTermination = waitForJITServerTermination;
server->destroyJITServer = destroyJITServer;
rc = JNI_CreateJavaVM_impl(&server->jvm, (void **)&env, serverArgs, TRUE);
if (JNI_OK != rc) {
rc = JITSERVER_CREATE_FAILED;
goto _end;
}
*jitServer = server;
rc = JITSERVER_OK;
_end:
if ((JITSERVER_OK != rc) && (NULL != server)) {
free(server);
*jitServer = NULL;
}
return rc;
}
static int32_t
startJITServer(JITServer *jitServer)
{
JavaVM *vm = jitServer->jvm;
JNIEnv *env = NULL;
int32_t rc = JITSERVER_OK;
rc = (*vm)->AttachCurrentThread(vm, (void **)&env, NULL);
if (JNI_OK == rc) {
J9JITConfig *jitConfig = ((J9JavaVM *)vm)->jitConfig;
rc = jitConfig->startJITServer(jitConfig);
if (0 != rc) {
rc = JITSERVER_STARTUP_FAILED;
} else {
rc = JITSERVER_OK;
}
(*vm)->DetachCurrentThread(vm);
} else {
rc = JITSERVER_THREAD_ATTACH_FAILED;
}
return rc;
}
static int32_t
waitForJITServerTermination(JITServer *jitServer)
{
JavaVM *vm = jitServer->jvm;
JNIEnv *env = NULL;
int32_t rc = JITSERVER_OK;
rc = (*vm)->AttachCurrentThread(vm, (void **)&env, NULL);
if (JNI_OK == rc) {
J9JITConfig *jitConfig = ((J9JavaVM *)vm)->jitConfig;
rc = jitConfig->waitJITServerTermination(jitConfig);
if (0 != rc) {
rc = JITSERVER_WAIT_TERM_FAILED;
} else {
rc = JITSERVER_OK;
}
(*vm)->DetachCurrentThread(vm);
} else {
rc = JITSERVER_THREAD_ATTACH_FAILED;
}
return rc;
}
static int32_t
destroyJITServer(JITServer **jitServer)
{
JavaVM *vm = (*jitServer)->jvm;
jint rc = (*vm)->DestroyJavaVM(vm);
free(*jitServer);
*jitServer = NULL;
if (JNI_OK == rc) {
rc = JITSERVER_OK;
} else {
rc = JITSERVER_DESTROY_ERROR;
}
return rc;
}
#endif
static jint
JNI_CreateJavaVM_impl(JavaVM **pvm, void **penv, void *vm_args, BOOLEAN isJITServer)
{
J9JavaVM *j9vm = NULL;
jint result = JNI_OK;
IDATA xoss = -1;
IDATA ibmMallocTraceSet = FALSE;
char cwd[J9_MAX_PATH];
#if defined(WIN32)
wchar_t unicodeTemp[J9_MAX_PATH];
char *altLibraryPathBuffer = NULL;
char *executableJarPath = NULL;
#endif
UDATA argEncoding = ARG_ENCODING_DEFAULT;
UDATA altJavaHomeSpecified = 0;
J9PortLibraryVersion portLibraryVersion;
#if defined(AIXPPC)
char *origLibpath = NULL;
#endif
I_32 portLibraryInitStatus;
UDATA expectedLibrarySize;
UDATA localVerboseLevel = 0;
J9CreateJavaVMParams createParams = {0};
JavaVMInitArgs *args = NULL;
UDATA launcherArgumentsSize = 0;
J9VMInitArgs *j9ArgList = NULL;
char *xServiceBuffer = NULL;
const char *libpathValue = NULL;
const char *ldLibraryPathValue = NULL;
J9SpecialArguments specialArgs;
omrthread_t attachedThread = NULL;
specialArgs.localVerboseLevel = localVerboseLevel;
specialArgs.xoss = &xoss;
specialArgs.argEncoding = &argEncoding;
specialArgs.executableJarPath = NULL;
specialArgs.ibmMallocTraceSet = &ibmMallocTraceSet;
#ifdef J9ZTPF
result = tpf_eownrc(TPF_SET_EOWNR, "IBMRT4J ");
if (result < 0) {
fprintf(stderr, "Failed to issue tpf_eownrc.");
return JNI_ERR;
}
result = tmslc(TMSLC_ENABLE+TMSLC_HOLD, "IBMRT4J");
if (result < 0) {
fprintf(stderr, "Failed to start time slicing.");
return JNI_ERR;
}
#endif
captureCommandLine();
#if defined(AIXPPC) || defined(J9ZOS390)
libpathValue = getenv(ENV_LIBPATH);
if (NULL != libpathValue) {
size_t pathLength = strlen(libpathValue) +1;
char *envTemp = malloc(pathLength);
if (NULL == envTemp) {
result = JNI_ERR;
goto exit;
}
strcpy(envTemp, libpathValue);
libpathValue = envTemp;
}
#endif
#if defined(J9UNIX)
ldLibraryPathValue = getenv(ENV_LD_LIB_PATH);
if (NULL != ldLibraryPathValue) {
size_t pathLength = strlen(ldLibraryPathValue) +1;
char *envTemp = malloc(pathLength);
if (NULL == envTemp) {
result = JNI_ERR;
goto exit;
}
strcpy(envTemp, ldLibraryPathValue);
ldLibraryPathValue = envTemp;
}
#endif
if (BFUjavaVM != NULL) {
result = JNI_ERR;
goto exit;
}
#ifdef J9OS_I5
Xj9BreakPoint("jvm");
if (Xj9IleCreateJavaVmCalled() == 0) {
result = Xj9CallIleCreateJavaVm(pvm, penv, vm_args);
goto exit;
}
#endif
#if defined(AIXPPC)
{
const char *currentLibPath = getenv("LIBPATH");
BOOLEAN appendToLibPath = TRUE;
if (NULL != currentLibPath) {
const size_t currentLibPathLength = strlen(currentLibPath);
const char *usrLib = "/usr/lib";
const UDATA usrLibLength = LITERAL_STRLEN("/usr/lib");
const char *needle = strstr(currentLibPath, usrLib);
while (NULL != needle) {
const ptrdiff_t offsetFromStart = needle - currentLibPath;
if ((0 == offsetFromStart) || (':' == needle[-1])) {
if ((':' == needle[usrLibLength]) || ('\0' == needle[usrLibLength])) {
appendToLibPath = FALSE;
break;
}
}
needle = strstr(needle + usrLibLength, usrLib);
}
}
if (appendToLibPath) {
addToLibpath("/usr/lib", FALSE);
}
}
origLibpath = getenv("LIBPATH");
#endif
preloadLibraries();
#ifdef WIN32
if (GetCurrentDirectoryW(J9_MAX_PATH, unicodeTemp) == 0) {
strcpy(cwd, "\\");
} else {
WideCharToMultiByte(OS_ENCODING_CODE_PAGE, OS_ENCODING_WC_FLAGS, unicodeTemp, -1, cwd, J9_MAX_PATH, NULL, NULL);
}
#else
if (getcwd(cwd, J9_MAX_PATH) == NULL) {
strcpy(cwd, ".");
}
#endif
#ifdef DEBUG
printf("cwd = %s\n", cwd);
#endif
#if CALL_BUNDLED_FUNCTIONS_DIRECTLY
if (0 != omrthread_attach_ex(&attachedThread, J9THREAD_ATTR_DEFAULT)) {
result = JNI_ERR;
}
#else
if (0 != f_threadAttachEx(&attachedThread, J9THREAD_ATTR_DEFAULT)) {
result = JNI_ERR;
}
#endif
if (JNI_OK != result) {
goto exit;
}
#if CALL_BUNDLED_FUNCTIONS_DIRECTLY
omrthread_lib_enable_cpu_monitor(attachedThread);
#else
f_libEnableCPUMonitor(attachedThread);
#endif
#if defined(J9ZOS390)
if (!setZOSThrWeight()) {
return JNI_ERR;
}
#endif
J9PORT_SET_VERSION(&portLibraryVersion, J9PORT_CAPABILITY_MASK);
expectedLibrarySize = sizeof(J9PortLibrary);
#if CALL_BUNDLED_FUNCTIONS_DIRECTLY
portLibraryInitStatus = j9port_init_library(&j9portLibrary, &portLibraryVersion, expectedLibrarySize);
#else
portLibraryInitStatus = portInitLibrary(&j9portLibrary, &portLibraryVersion, expectedLibrarySize);
#endif
if (0 != portLibraryInitStatus) {
J9PortLibraryVersion actualVersion;
switch (portLibraryInitStatus) {
case J9PORT_ERROR_INIT_WRONG_MAJOR_VERSION: {
#if CALL_BUNDLED_FUNCTIONS_DIRECTLY
j9port_getVersion(&j9portLibrary, &actualVersion);
#else
portGetVersionFn(&j9portLibrary, &actualVersion);
#endif
fprintf(stderr,"Error: Port Library failed to initialize: expected major version %u, actual version is %u\n",
portLibraryVersion.majorVersionNumber, actualVersion.majorVersionNumber);
break;
}
case J9PORT_ERROR_INIT_WRONG_SIZE: {
#if CALL_BUNDLED_FUNCTIONS_DIRECTLY
UDATA actualSize = j9port_getSize(&portLibraryVersion);
#else
UDATA actualSize = portGetSizeFn(&portLibraryVersion);
#endif
fprintf(stderr,"Error: Port Library failed to initialize: expected library size %" OMR_PRIuPTR ", actual size is %" OMR_PRIuPTR "\n",
expectedLibrarySize, actualSize);
break;
}
case J9PORT_ERROR_INIT_WRONG_CAPABILITIES: {
fprintf(stderr,"Error: Port Library failed to initialize: capabilities do not match\n");
break;
}
default: fprintf(stderr,"Error: Port Library failed to initialize: %i\n", portLibraryInitStatus); break;
}
#if defined(AIXPPC)
freeBackupLibpath(&libpathBackup);
setLibpath(origLibpath);
#endif
result = JNI_ERR;
goto exit;
}
{
#if CALL_BUNDLED_FUNCTIONS_DIRECTLY
IDATA threadCategoryResult = omrthread_lib_control(J9THREAD_LIB_CONTROL_GET_MEM_CATEGORIES, (UDATA)&j9MainMemCategorySet);
#else
IDATA threadCategoryResult = f_threadLibControl(J9THREAD_LIB_CONTROL_GET_MEM_CATEGORIES, (UDATA)&j9MainMemCategorySet);
#endif
if (threadCategoryResult) {
fprintf(stderr,"Error: Couldn't get memory categories from thread library.\n");
#if defined(AIXPPC)
freeBackupLibpath(&libpathBackup);
setLibpath(origLibpath);
#endif
result = JNI_ERR;
goto exit;
}
}
j9portLibrary.omrPortLibrary.port_control(&j9portLibrary.omrPortLibrary, J9PORT_CTLDATA_MEM_CATEGORIES_SET, (UDATA)&j9MainMemCategorySet);
Assert_SC_true(J2SE_CURRENT_VERSION >= J2SE_18);
setNLSCatalog(&j9portLibrary);
#ifdef WIN32
if (GetEnvironmentVariableW(IBM_MALLOCTRACE_STR, NULL, 0) > 0)
ibmMallocTraceSet = TRUE;
altJavaHomeSpecified = (GetEnvironmentVariableW(ALT_JAVA_HOME_DIR_STR, NULL, 0) > 0);
#endif
#if defined(J9UNIX) || defined(J9ZOS390)
if (getenv(IBM_MALLOCTRACE_STR)) {
ibmMallocTraceSet = TRUE;
}
#endif
args = (JavaVMInitArgs *)vm_args;
launcherArgumentsSize = initialArgumentScan(args, &specialArgs);
localVerboseLevel = specialArgs.localVerboseLevel;
if (VERBOSE_INIT == localVerboseLevel) {
createParams.flags |= J9_CREATEJAVAVM_VERBOSE_INIT;
}
#if defined(J9VM_OPT_JITSERVER)
if (isJITServer) {
createParams.flags |= J9_CREATEJAVAVM_START_JITSERVER;
}
#endif
if (ibmMallocTraceSet) {
memoryCheck_initialize(&j9portLibrary, "all", NULL);
}
{
char *optionsDefaultFileLocation = NULL;
BOOLEAN doAddExtDir = FALSE;
J9JavaVMArgInfoList vmArgumentsList;
J9ZipFunctionTable *zipFuncs = NULL;
vmArgumentsList.pool = pool_new(sizeof(J9JavaVMArgInfo),
32,
0, 0,
J9_GET_CALLSITE(), OMRMEM_CATEGORY_VM, POOL_FOR_PORT(&j9portLibrary));
if (NULL == vmArgumentsList.pool) {
result = JNI_ERR;
goto exit;
}
vmArgumentsList.head = NULL;
vmArgumentsList.tail = NULL;
if (NULL != specialArgs.executableJarPath) {
#if !CALL_BUNDLED_FUNCTIONS_DIRECTLY
if (NULL == f_j9_GetInterface) {
#ifdef WIN32
f_j9_GetInterface = (J9GetInterface) GetProcAddress (j9vm_dllHandle, (LPCSTR) "J9_GetInterface");
#else
f_j9_GetInterface = (J9GetInterface) dlsym (j9vm_dllHandle, "J9_GetInterface");
#endif
}
zipFuncs = (J9ZipFunctionTable*) f_j9_GetInterface(IF_ZIPSUP, &j9portLibrary, j9binBuffer->data);
#else
zipFuncs = (J9ZipFunctionTable*) J9_GetInterface(IF_ZIPSUP, &j9portLibrary, j9binBuffer);
#endif
#if defined(WIN32)
{
BOOLEAN conversionSucceed = FALSE;
int32_t size = 0;
UDATA pathLen = strlen(specialArgs.executableJarPath);
PORT_ACCESS_FROM_PORT(&j9portLibrary);
size = j9str_convert(J9STR_CODE_WINDEFAULTACP, J9STR_CODE_MUTF8, specialArgs.executableJarPath, pathLen, NULL, 0);
if (size > 0) {
size += 1;
executableJarPath = j9mem_allocate_memory(size, OMRMEM_CATEGORY_VM);
if (NULL != executableJarPath) {
size = j9str_convert(J9STR_CODE_WINDEFAULTACP, J9STR_CODE_MUTF8, specialArgs.executableJarPath, pathLen, executableJarPath, size);
if (size > 0) {
conversionSucceed = TRUE;
}
}
}
if (!conversionSucceed) {
result = JNI_ERR;
goto exit;
}
specialArgs.executableJarPath = executableJarPath;
}
#endif
}
if (J2SE_CURRENT_VERSION >= J2SE_V11) {
optionsDefaultFileLocation = jvmBufferData(j9libBuffer);
} else {
optionsDefaultFileLocation = jvmBufferData(j9binBuffer);
doAddExtDir = TRUE;
}
if (
(0 != addOptionsDefaultFile(&j9portLibrary, &vmArgumentsList, optionsDefaultFileLocation, localVerboseLevel))
|| (0 != addXjcl(&j9portLibrary, &vmArgumentsList, J2SE_CURRENT_VERSION))
|| (0 != addBootLibraryPath(&j9portLibrary, &vmArgumentsList, "-Dcom.ibm.oti.vm.bootstrap.library.path=",
jvmBufferData(j9binBuffer), jvmBufferData(jrebinBuffer)))
|| (0 != addBootLibraryPath(&j9portLibrary, &vmArgumentsList, "-Dsun.boot.library.path=",
jvmBufferData(j9binBuffer), jvmBufferData(jrebinBuffer)))
|| (0 != addJavaLibraryPath(&j9portLibrary, &vmArgumentsList, argEncoding, jvmInSubdir,
jvmBufferData(j9binBuffer), jvmBufferData(jrebinBuffer),
libpathValue, ldLibraryPathValue))
|| (0 != addJavaHome(&j9portLibrary, &vmArgumentsList, altJavaHomeSpecified, jvmBufferData(j9libBuffer)))
|| (doAddExtDir && (0 != addExtDir(&j9portLibrary, &vmArgumentsList, jvmBufferData(j9libBuffer), args, J2SE_CURRENT_VERSION)))
|| (0 != addUserDir(&j9portLibrary, &vmArgumentsList, cwd))
#if !defined(OPENJ9_BUILD)
|| (0 != addJavaPropertiesOptions(&j9portLibrary, &vmArgumentsList, localVerboseLevel))
#endif
|| (0 != addJarArguments(&j9portLibrary, &vmArgumentsList, specialArgs.executableJarPath, zipFuncs, localVerboseLevel))
|| (0 != addEnvironmentVariables(&j9portLibrary, args, &vmArgumentsList, localVerboseLevel))
|| (0 != addLauncherArgs(&j9portLibrary, args, launcherArgumentsSize, &vmArgumentsList,
&xServiceBuffer, argEncoding, localVerboseLevel))
#if (JAVA_SPEC_VERSION != 8) || defined(OPENJ9_BUILD)
|| (0 != addEnvironmentVariableArguments(&j9portLibrary, ENVVAR_JAVA_OPTIONS, &vmArgumentsList, localVerboseLevel))
#endif
|| (0 != addXserviceArgs(&j9portLibrary, &vmArgumentsList, xServiceBuffer, localVerboseLevel))
) {
result = JNI_ERR;
goto exit;
}
if (NULL != libpathValue) {
free((void *)libpathValue);
}
if (NULL != ldLibraryPathValue) {
free((void *)ldLibraryPathValue);
}
j9ArgList = createJvmInitArgs(&j9portLibrary, args, &vmArgumentsList, &argEncoding);
if (ARG_ENCODING_LATIN == argEncoding) {
createParams.flags |= J9_CREATEJAVAVM_ARGENCODING_LATIN;
} else if (ARG_ENCODING_UTF == argEncoding) {
createParams.flags |= J9_CREATEJAVAVM_ARGENCODING_UTF8;
} else if (ARG_ENCODING_PLATFORM == argEncoding) {
createParams.flags |= J9_CREATEJAVAVM_ARGENCODING_PLATFORM;
}
pool_kill(vmArgumentsList.pool);
if (NULL == j9ArgList) {
result = JNI_ERR;
goto exit;
}
}
createParams.j2seVersion = J2SE_CURRENT_VERSION;
if (jvmInSubdir) {
createParams.j2seVersion |= J2SE_LAYOUT_VM_IN_SUBDIR;
}
createParams.j2seRootDirectory = jvmBufferData(j9binBuffer);
createParams.j9libvmDirectory = jvmBufferData(j9libvmBuffer);
createParams.portLibrary = &j9portLibrary;
createParams.globalJavaVM = &BFUjavaVM;
if (VERBOSE_INIT == localVerboseLevel) {
fprintf(stderr, "VM known paths\t- j9libvm directory: %s\n\t\t- j2seRoot directory: %s\n",
createParams.j9libvmDirectory,
createParams.j2seRootDirectory);
printVmArgumentsList(j9ArgList);
}
createParams.vm_args = j9ArgList;
#if CALL_BUNDLED_FUNCTIONS_DIRECTLY
result = J9_CreateJavaVM((JavaVM**)&BFUjavaVM, penv, &createParams);
#else
result = globalCreateVM((JavaVM**)&BFUjavaVM, penv, &createParams);
#endif
#ifdef DEBUG
fprintf(stdout,"Finished, result %d, env %llx\n", result, (long long)*penv);
fflush(stdout);
#endif
if (result == JNI_OK) {
BOOLEAN initializeReflectAccessors = TRUE;
JavaVM * vm = (JavaVM*)BFUjavaVM;
*pvm = vm;
ENSURE_VMI();
memcpy(&globalInvokeInterface, *vm, sizeof(J9InternalVMFunctions));
globalDestroyVM = globalInvokeInterface.DestroyJavaVM;
globalInvokeInterface.DestroyJavaVM = DestroyJavaVM;
issueWriteBarrier();
*vm = (struct JNIInvokeInterface_ *) &globalInvokeInterface;
#ifdef WIN32
result = initializeWin32ThreadEvents(BFUjavaVM);
if (result != JNI_OK) {
(**pvm)->DestroyJavaVM(*pvm);
goto exit;
}
#endif
result = initializeReflectionGlobals(*penv, initializeReflectAccessors);
if (result != JNI_OK) {
(**pvm)->DestroyJavaVM(*pvm);
goto exit;
}
} else {
freeGlobals();
}
if ((result == JNI_OK) && (BFUjavaVM->runtimeFlags & J9_RUNTIME_SHOW_VERSION)) {
JNIEnv * env = *penv;
jclass clazz = (*env)->FindClass(env, "sun/misc/Version");
if (clazz == NULL) {
(*env)->ExceptionClear(env);
} else {
jmethodID mid = (*env)->GetStaticMethodID(env, clazz, "print", "()V");
if (mid != NULL) {
(*env)->CallStaticVoidMethod(env, clazz, mid);
if (!(*env)->ExceptionCheck(env)) {
j9portLibrary.omrPortLibrary.tty_printf(&j9portLibrary.omrPortLibrary, "\n");
}
}
(*env)->ExceptionClear(env);
(*env)->DeleteLocalRef(env, clazz);
}
}
#if defined(AIXPPC)
restoreLibpath(&libpathBackup);
#ifdef DEBUG_TEST
testBackupAndRestoreLibpath();
#endif
#endif
if (JNI_OK == result) {
J9JavaVM *env = (J9JavaVM *) BFUjavaVM;
J9VMThread *currentThread = env->mainThread;
omrthread_t thread = currentThread->osThread;
#if CALL_BUNDLED_FUNCTIONS_DIRECTLY
omrthread_set_category(thread, J9THREAD_CATEGORY_APPLICATION_THREAD, J9THREAD_TYPE_SET_MODIFY);
#else
f_setCategory(thread, J9THREAD_CATEGORY_APPLICATION_THREAD, J9THREAD_TYPE_SET_MODIFY);
#endif
}
exit:
#if CALL_BUNDLED_FUNCTIONS_DIRECTLY
if (NULL != attachedThread) {
omrthread_detach(attachedThread);
}
#else
if (NULL != attachedThread) {
f_threadDetach(attachedThread);
}
#endif
#if defined(WIN32)
if (NULL != executableJarPath) {
PORT_ACCESS_FROM_PORT(&j9portLibrary);
j9mem_free_memory(executableJarPath);
}
#endif
return result;
}
jint JNICALL
JNI_GetCreatedJavaVMs(JavaVM **vmBuf, jsize bufLen, jsize *nVMs)
{
jint result;
Trc_SC_GetCreatedJavaVMs_Entry(vmBuf, bufLen, nVMs);
if(librariesLoaded()){
#if CALL_BUNDLED_FUNCTIONS_DIRECTLY
result = J9_GetCreatedJavaVMs(vmBuf, bufLen, nVMs);
#else
result = globalGetVMs(vmBuf, bufLen, nVMs);
#endif
} else {
result = JNI_OK;
*nVMs = 0;
}
Trc_SC_GetCreatedJavaVMs_Exit(result, *nVMs);
return result;
}
jint JNICALL JNI_GetDefaultJavaVMInitArgs(void *vm_args) {
jint requestedVersion = ((JavaVMInitArgs *)vm_args)->version;
switch (requestedVersion) {
case JNI_VERSION_1_1:
((JDK1_1InitArgs *)vm_args)->javaStackSize = J9_OS_STACK_SIZE;
break;
case JNI_VERSION_1_2:
case JNI_VERSION_1_4:
case JNI_VERSION_1_6:
case JNI_VERSION_1_8:
#if JAVA_SPEC_VERSION >= 9
case JNI_VERSION_9:
#endif
#if JAVA_SPEC_VERSION >= 10
case JNI_VERSION_10:
#endif
return JNI_OK;
}
return JNI_EVERSION;
}
#ifdef J9ZOS390
jint
GetStringPlatform(JNIEnv* env, jstring instr, char* outstr, jint outlen, const char* encoding)
{
jint result;
preloadLibraries();
Trc_SC_GetStringPlatform_Entry(env, instr, outstr, outlen, encoding);
result = globalGetStringPlatform(env, instr, outstr, outlen, encoding);
Trc_SC_GetStringPlatform_Exit(env, result);
return result;
}
jint
GetStringPlatformLength(JNIEnv* env, jstring instr, jint* outlen, const char* encoding)
{
jint result;
preloadLibraries();
Trc_SC_GetStringPlatformLength_Entry(env, instr, outlen, encoding);
result = globalGetStringPlatformLength(env, instr, outlen, encoding);
Trc_SC_GetStringPlatformLength_Exit(env, result, *outlen);
return result;
}
jint
NewStringPlatform(JNIEnv* env, const char* instr, jstring* outstr, const char* encoding)
{
jint result;
preloadLibraries();
Trc_SC_NewStringPlatform_Entry(env, instr, outstr, encoding);
result = globalNewStringPlatform(env, instr, outstr, encoding);
Trc_SC_NewStringPlatform_Exit(env, result);
return result;
}
jint
JNI_a2e_vsprintf(char *target, const char *format, va_list args)
{
jint result;
preloadLibraries();
Trc_SC_a2e_vsprintf_Entry(target, format);
result = global_a2e_vsprintf(target, format, args);
Trc_SC_a2e_vsprintf_Exit(result);
return result;
}
#endif
int isFileInDir(char *dir, char *file){
size_t length, dirLength;
char *fullpath = NULL;
FILE *f = NULL;
int foundFile = 0;
dirLength = strlen(dir);
if (dir[dirLength-1] == DIR_SEPARATOR) {
dir[dirLength-1] = '\0';
dirLength--;
}
length = dirLength + strlen(file) + 2;
fullpath = malloc(length);
if (NULL != fullpath) {
strcpy(fullpath, dir);
fullpath[dirLength] = DIR_SEPARATOR;
strcpy(fullpath+dirLength+1, file);
f = fopen(fullpath, "rb");
if (NULL != f) {
foundFile = 1;
fclose(f);
}
free(fullpath);
}
return foundFile;
}
int findDirContainingFile(J9StringBuffer **result, char *paths, char pathSeparator, char *fileToFind, int elementsToSkip) {
char *startOfDir, *endOfDir, *pathsCopy;
int isEndOfPaths, foundIt, count=elementsToSkip;
paths = strdup(paths);
if (!paths) {
return FALSE;
}
pathsCopy = paths;
while(elementsToSkip--) {
pathsCopy = strchr(pathsCopy, pathSeparator);
if(pathsCopy) {
pathsCopy++;
} else {
free(paths);
return 0;
}
}
startOfDir = endOfDir = pathsCopy;
for (isEndOfPaths=FALSE, foundIt=FALSE; !foundIt && !isEndOfPaths; endOfDir++) {
isEndOfPaths = endOfDir[0] == '\0';
if (isEndOfPaths || (endOfDir[0] == pathSeparator)) {
endOfDir[0] = '\0';
if (strlen(startOfDir) && isFileInDir(startOfDir, fileToFind)) {
foundIt = TRUE;
if (NULL != *result) {
free(*result);
*result = NULL;
}
*result = jvmBufferCat(NULL, startOfDir);
}
startOfDir = endOfDir+1;
count+=1;
}
}
free(paths);
if(foundIt) {
return count;
} else {
return 0;
}
}
int findDirUplevelToDirContainingFile(J9StringBuffer **result, char *pathEnvar, char pathSeparator, char *fileInPath, int upLevels, int elementsToSkip) {
char *paths;
int rc;
paths = getenv(pathEnvar);
if (!paths) {
return FALSE;
}
rc = findDirContainingFile(result, paths, pathSeparator, fileInPath, elementsToSkip);
if (rc) {
for (; upLevels > 0; upLevels--) {
truncatePath(jvmBufferData(*result));
}
}
return rc;
}
void
exitHook(J9JavaVM *vm)
{
#if CALL_BUNDLED_FUNCTIONS_DIRECTLY
while (omrthread_monitor_enter(vm->vmThreadListMutex), vm->sidecarExitFunctions)
#else
while (f_monitorEnter(vm->vmThreadListMutex), vm->sidecarExitFunctions)
#endif
{
J9SidecarExitFunction * current = vm->sidecarExitFunctions;
vm->sidecarExitFunctions = current->next;
#if CALL_BUNDLED_FUNCTIONS_DIRECTLY
omrthread_monitor_exit(vm->vmThreadListMutex);
#else
f_monitorExit(vm->vmThreadListMutex);
#endif
current->func();
free(current);
}
#if CALL_BUNDLED_FUNCTIONS_DIRECTLY
omrthread_monitor_exit(vm->vmThreadListMutex);
#else
f_monitorExit(vm->vmThreadListMutex);
#endif
}
static void*
preloadLibrary(char* dllName, BOOLEAN inJVMDir)
{
J9StringBuffer *buffer = NULL;
void* handle = NULL;
#ifdef WIN32
wchar_t unicodePath[J9_MAX_PATH];
char * bufferData;
size_t bufferLength;
#endif
if(inJVMDir) {
buffer = jvmBufferCat(buffer, jvmBufferData(j9binBuffer));
} else {
buffer = jvmBufferCat(buffer, jvmBufferData(jrebinBuffer));
}
#ifdef WIN32
buffer = jvmBufferCat(buffer, "\\");
buffer = jvmBufferCat(buffer, dllName);
buffer = jvmBufferCat(buffer, ".dll");
bufferData = jvmBufferData(buffer);
bufferLength = strlen(bufferData);
MultiByteToWideChar(OS_ENCODING_CODE_PAGE, OS_ENCODING_MB_FLAGS, bufferData, -1, unicodePath, (int)bufferLength + 1);
handle = (void*)LoadLibraryExW (unicodePath, NULL, LOAD_WITH_ALTERED_SEARCH_PATH);
if (handle == NULL) {
fprintf(stderr,"jvm.dll preloadLibrary: LoadLibrary(%s) error: %x\n", buffer->data, GetLastError());
}
#endif
#if defined(J9UNIX)
buffer = jvmBufferCat(buffer, "/lib");
buffer = jvmBufferCat(buffer, dllName);
buffer = jvmBufferCat(buffer, J9PORT_LIBRARY_SUFFIX);
#ifdef AIXPPC
loadAndInit(jvmBufferData(buffer), L_RTLD_LOCAL, NULL);
#endif
handle = (void*)dlopen(jvmBufferData(buffer), RTLD_NOW);
#ifdef AIXPPC
if (handle == NULL) {
int len = strlen(buffer->data);
buffer->data[len - 2] = 'a';
buffer->data[len - 1] = '\0';
loadAndInit(buffer->data, L_RTLD_LOCAL, NULL);
handle = (void*)dlopen(buffer->data, RTLD_NOW);
if (handle == NULL) {
buffer->data[len - 2] = 's';
buffer->data[len - 1] = 'o';
loadAndInit(buffer->data, L_RTLD_LOCAL, NULL);
handle = (void*)dlopen(buffer->data, RTLD_NOW);
}
}
#endif
if (handle == NULL) {
fprintf(stderr,"libjvm.so preloadLibrary(%s): %s\n", buffer->data, dlerror());
}
#endif
#ifdef J9ZOS390
buffer = jvmBufferCat(buffer, "/lib");
buffer = jvmBufferCat(buffer, dllName);
buffer = jvmBufferCat(buffer, ".so");
handle = (void*)dllload(jvmBufferData(buffer));
if (handle == NULL) {
perror("libjvm.so preloadLibrary: dllload() failed");
}
#endif
free(buffer);
return handle;
}
int
pre_block(pre_block_t buf)
{
return 0;
}
int
post_block() {
return 0;
}
#if defined(AIXPPC)
static void
setLibpath(const char *libpath)
{
setenv("LIBPATH", libpath, 1);
}
#endif
static void
addToLibpath(const char *dir, BOOLEAN isPrepend)
{
#if defined(AIXPPC) || defined(J9ZOS390)
char *oldPath, *newPath;
int rc, newSize;
#if defined(J9ZOS390)
char *putenvPath;
int putenvSize;
#endif
oldPath = getenv("LIBPATH");
#ifdef DEBUG
printf("\nLIBPATH before = %s\n", oldPath ? oldPath : "<empty>");
#endif
newSize = (oldPath ? strlen(oldPath) : 0) + strlen(dir) + 2;
newPath = malloc(newSize);
if(!newPath) {
fprintf(stderr, "addToLibpath malloc(%d) 1 failed, aborting\n", newSize);
abort();
}
#if defined(AIXPPC)
if (oldPath) {
if (isPrepend) {
strcpy(newPath, dir);
strcat(newPath, ":");
strcat(newPath, oldPath);
} else {
strcpy(newPath, oldPath);
strcat(newPath, ":");
strcat(newPath, dir);
}
} else {
strcpy(newPath, dir);
}
#else
if (oldPath) {
strcpy(newPath, oldPath);
strcat(newPath, ":");
} else {
newPath[0] = '\0';
}
strcat(newPath, dir);
#endif
#if defined(J9ZOS390)
putenvSize = newSize + strlen("LIBPATH=");
putenvPath = malloc(putenvSize);
if(!putenvPath) {
fprintf(stderr, "addToLibpath malloc(%d) 2 failed, aborting\n", putenvSize);
abort();
}
strcpy(putenvPath,"LIBPATH=");
strcat(putenvPath, newPath);
rc = putenv(putenvPath);
free(putenvPath);
#else
rc = setenv("LIBPATH", newPath, 1);
#endif
#ifdef DEBUG
printf("\nLIBPATH after = %s\n", getenv("LIBPATH"));
#endif
free(newPath);
#endif
}
#if defined(AIXPPC)
static void
backupLibpath(J9LibpathBackup *libpathBackup, size_t origLibpathLen)
{
const char *curLibpath = getenv("LIBPATH");
libpathBackup->fullpath = NULL;
libpathBackup->j9prefixLen = 0;
if (NULL != curLibpath) {
libpathBackup->j9prefixLen = strlen(curLibpath) - origLibpathLen;
if (libpathBackup->j9prefixLen > 0) {
libpathBackup->fullpath = strdup(curLibpath);
if (NULL == libpathBackup->fullpath) {
fprintf(stderr, "backupLibpath: strdup() failed to allocate memory for the backup path\n");
abort();
}
}
}
}
#endif
#if defined(AIXPPC)
static void
freeBackupLibpath(J9LibpathBackup *libpathBackup)
{
if (NULL != libpathBackup->fullpath) {
free(libpathBackup->fullpath);
libpathBackup->fullpath = NULL;
}
libpathBackup->j9prefixLen = 0;
}
#endif
#if defined(AIXPPC)
static void
restoreLibpath(J9LibpathBackup *libpathBackup)
{
if ((NULL != libpathBackup->fullpath) && (libpathBackup->j9prefixLen > 0)) {
const char *curPath = getenv("LIBPATH");
if (NULL != curPath) {
const char *j9pathLoc = findInLibpath(curPath, libpathBackup->fullpath);
if (NULL != j9pathLoc) {
char *newPath = deleteDirsFromLibpath(curPath, j9pathLoc, libpathBackup->j9prefixLen);
#ifdef DEBUG
printf("restoreLibpath: old LIBPATH = <%s>\n", curPath);
printf("restoreLibpath: new LIBPATH = <%s>\n", newPath);
#endif
setLibpath(newPath);
free(newPath);
}
}
free(libpathBackup->fullpath);
libpathBackup->fullpath = NULL;
libpathBackup->j9prefixLen = 0;
}
}
#endif
#if defined(AIXPPC)
static const char *
findInLibpath(const char *libpath, const char *backupPath)
{
size_t backupPathLen = strlen(backupPath);
BOOLEAN leadingColon = FALSE;
BOOLEAN trailingColon = FALSE;
const char *libpathdir = libpath;
if (':' == backupPath[0]) {
leadingColon = TRUE;
}
if (':' == backupPath[backupPathLen - 1]) {
trailingColon = TRUE;
}
while (NULL != libpathdir) {
if (!leadingColon) {
while (':' == libpathdir[0]) {
libpathdir += 1;
}
}
if (0 == strncmp(libpathdir, backupPath, backupPathLen)) {
if (('\0' == libpathdir[backupPathLen]) || (':' == libpathdir[backupPathLen]) || trailingColon) {
return libpathdir;
}
}
libpathdir = strchr(libpathdir + 1, ':');
}
return NULL;
}
#endif
#if defined(AIXPPC)
static char *
deleteDirsFromLibpath(const char *const libpath, const char *const deleteStart, const size_t deleteLen)
{
char *newPath = NULL;
size_t preLen = deleteStart - libpath;
const char *postStart = deleteStart + deleteLen;
size_t postLen = strlen(postStart);
size_t delim = 0;
while ((preLen > 0) && (':' == libpath[preLen - 1])) {
preLen -= 1;
}
if (postLen > 0) {
while (':' == postStart[0]) {
postStart += 1;
postLen -= 1;
}
}
if ((preLen > 0) && (postLen > 0)) {
delim = 1;
}
newPath = malloc(preLen + delim + postLen + 1);
if (NULL == newPath) {
fprintf(stderr, "deleteDirsFromLibpath: malloc(%zu) failed, aborting\n", preLen + delim + postLen + 1);
abort();
}
memcpy(newPath, libpath, preLen);
if (delim > 0) {
newPath[preLen] = ':';
}
memcpy(newPath + preLen + delim, postStart, postLen);
newPath[preLen + delim + postLen] = '\0';
return newPath;
}
#endif
#if defined(AIXPPC) && defined(DEBUG_TEST)
static void
testBackupAndRestoreLibpath(void)
{
int failed = 0;
int passed = 0;
char *origLibpath = getenv("LIBPATH");
J9LibpathBackup bkp = {NULL, 0};
printf("testBackupAndRestoreLibpath:------------ BEGIN ------------------------\n");
printf("TESTCASE_1: Remove the path added by VM when restoring LIBPATH\n");
setLibpath("compressedrefs:/usr/lib");
backupLibpath(&bkp, strlen("/usr/lib"));
restoreLibpath(&bkp);
if (0 == strcmp(getenv("LIBPATH"), "/usr/lib")) {
printf("Test result: PASSED at </usr/lib>\n");
passed++;
} else {
fprintf(stderr, "Test result: FAILED at </usr/lib>: LIBPATH = <%s>\n", getenv("LIBPATH"));
failed++;
}
printf("TESTCASE_2: Ignore colons prefixing the backup path when restoring LIBPATH\n");
setLibpath("::abc");
backupLibpath(&bkp, strlen("abc"));
restoreLibpath(&bkp);
if (0 == strcmp(getenv("LIBPATH"), "abc")) {
printf("Test result: PASSED at <abc>\n");
passed++;
} else {
fprintf(stderr, "Test result: FAILED at <abc>: LIBPATH = <%s>\n", getenv("LIBPATH"));
failed++;
}
printf("TESTCASE_3: Set up libpath again with exactly the same path\n");
setLibpath("x:y");
backupLibpath(&bkp, 0);
setLibpath("x:y");
restoreLibpath(&bkp);
if (0 == strcmp(getenv("LIBPATH"), "")) {
printf("testcase_3: PASSED at <>\n");
passed++;
} else {
fprintf(stderr, "testcase_3: FAILED at <>: LIBPATH = <%s>\n", getenv("LIBPATH"));
failed++;
}
printf("TESTCASE_4: The backup path is followed by a single colon\n");
setLibpath("x:y");
backupLibpath(&bkp, 0);
setLibpath("x:y:");
restoreLibpath(&bkp);
if (0 == strcmp(getenv("LIBPATH"), "")) {
printf("testcase_4: PASSED at <>\n");
passed++;
} else {
fprintf(stderr, "testcase_4: FAILED at <>: LIBPATH = <%s>\n", getenv("LIBPATH"));
failed++;
}
printf("TESTCASE_5: The backup path is followed by multiple colons\n");
setLibpath("x:y");
backupLibpath(&bkp, 0);
setLibpath("x:y:::");
restoreLibpath(&bkp);
if (0 == strcmp(getenv("LIBPATH"), "")) {
printf("TESTCASE_5: PASSED at <>\n");
passed++;
} else {
fprintf(stderr, "TESTCASE_5: FAILED at <>: LIBPATH = <%s>\n", getenv("LIBPATH"));
failed++;
}
printf("TESTCASE_6: The backup path is followed by multiple paths\n");
setLibpath("x:y");
backupLibpath(&bkp, 0);
setLibpath("x:y:def:ghi");
restoreLibpath(&bkp);
if (0 == strcmp(getenv("LIBPATH"), "def:ghi")) {
printf("TESTCASE_6: PASSED at <def:ghi>\n");
passed++;
} else {
fprintf(stderr, "TESTCASE_6: FAILED at <def:ghi>: LIBPATH = <%s>\n", getenv("LIBPATH"));
failed++;
}
printf("TESTCASE_7: The backup path stays at the start except for a single colon\n");
setLibpath("x:y");
backupLibpath(&bkp, 0);
setLibpath(":x:y:def:ghi");
restoreLibpath(&bkp);
if (0 == strcmp(getenv("LIBPATH"), "def:ghi")) {
printf("TESTCASE_7: PASSED at <def:ghi>\n");
passed++;
} else {
fprintf(stderr, "TESTCASE_7: FAILED at <def:ghi>: LIBPATH = <%s>\n", getenv("LIBPATH"));
failed++;
}
printf("TESTCASE_8: The backup path stays at the start except for multiple colons\n");
setLibpath("x:y");
backupLibpath(&bkp, 0);
setLibpath(":::x:y:def:ghi");
restoreLibpath(&bkp);
if (0 == strcmp(getenv("LIBPATH"), "def:ghi")) {
printf("TESTCASE_8: PASSED at <def:ghi>\n");
passed++;
} else {
fprintf(stderr, "TESTCASE_8: FAILED at <def:ghi>: LIBPATH = <%s>\n", getenv("LIBPATH"));
failed++;
}
printf("TESTCASE_9: Partial match at the start\n");
setLibpath("x:y");
backupLibpath(&bkp, 0);
setLibpath("::x:ydef:ghi");
restoreLibpath(&bkp);
if (0 == strcmp(getenv("LIBPATH"), "::x:ydef:ghi")) {
printf("TESTCASE_9: PASSED at <::x:ydef:ghi>\n");
passed++;
} else {
fprintf(stderr, "TESTCASE_9: FAILED at <::x:ydef:ghi>: LIBPATH = <%s>\n", getenv("LIBPATH"));
failed++;
}
printf("TESTCASE_10: Partial match at the end\n");
setLibpath("x:y");
backupLibpath(&bkp, 0);
setLibpath("::abc:defx:y::");
restoreLibpath(&bkp);
if (0 == strcmp(getenv("LIBPATH"), "::abc:defx:y::")) {
printf("TESTCASE_10: PASSED at <::abc:defx:y::>\n");
passed++;
} else {
fprintf(stderr, "TESTCASE_10: FAILED at <::abc:defx:y::>: LIBPATH = <%s>\n", getenv("LIBPATH"));
failed++;
}
printf("TESTCASE_11: Partial match in the middle \n");
setLibpath("x:y");
backupLibpath(&bkp, 0);
setLibpath("::abc:def::x:yghi:jkl");
restoreLibpath(&bkp);
if (0 == strcmp(getenv("LIBPATH"), "::abc:def::x:yghi:jkl")) {
printf("TESTCASE_11: PASSED at <::abc:def::x:yghi:jkl>\n");
passed++;
} else {
fprintf(stderr, "TESTCASE_11: FAILED at <::abc:def::x:yghi:jkl>: LIBPATH = <%s>\n", getenv("LIBPATH"));
failed++;
}
printf("TESTCASE_12: The backup path stays at the end with a single colon ahead of it\n");
setLibpath("x:y");
backupLibpath(&bkp, 0);
setLibpath(":x:y");
restoreLibpath(&bkp);
if (0 == strcmp(getenv("LIBPATH"), "")) {
printf("TESTCASE_12: PASSED at <>\n");
passed++;
} else {
fprintf(stderr, "TESTCASE_12: FAILED at <>: LIBPATH = <%s>\n", getenv("LIBPATH"));
failed++;
}
printf("TESTCASE_13: The backup path stays at the end with multiple colons ahead of it\n");
setLibpath("x:y");
backupLibpath(&bkp, 0);
setLibpath("::x:y");
restoreLibpath(&bkp);
if (0 == strcmp(getenv("LIBPATH"), "")) {
printf("TESTCASE_13: PASSED at <>\n");
passed++;
} else {
fprintf(stderr, "TESTCASE_13: FAILED at <>: LIBPATH = <%s>\n", getenv("LIBPATH"));
failed++;
}
printf("TESTCASE_14: The backup path stays at the end with multiple paths ahead of it\n");
setLibpath("x:y");
backupLibpath(&bkp, 0);
setLibpath("abc:def:x:y");
restoreLibpath(&bkp);
if (0 == strcmp(getenv("LIBPATH"), "abc:def")) {
printf("TESTCASE_14: PASSED at <abc:def>\n");
passed++;
} else {
fprintf(stderr, "TESTCASE_14: FAILED at <abc:def>: LIBPATH = <%s>\n", getenv("LIBPATH"));
failed++;
}
printf("TESTCASE_15: The backup path stays at the end with multiple empty paths ahead of it\n");
setLibpath("x:y");
backupLibpath(&bkp, 0);
setLibpath("abc:::def:x:y");
restoreLibpath(&bkp);
if (0 == strcmp(getenv("LIBPATH"), "abc:::def")) {
printf("TESTCASE_15: PASSED at <abc:::def>\n");
passed++;
} else {
fprintf(stderr, "TESTCASE_15: FAILED at <abc:::def>: LIBPATH = <%s>\n", getenv("LIBPATH"));
failed++;
}
printf("TESTCASE_16: An empty path plus a single colon at the start stays ahead of the backup path\n");
setLibpath("x:y");
backupLibpath(&bkp, 0);
setLibpath(":abc::def:x:y");
restoreLibpath(&bkp);
if (0 == strcmp(getenv("LIBPATH"), ":abc::def")) {
printf("TESTCASE_16: PASSED at <:abc::def>\n");
passed++;
} else {
fprintf(stderr, "TESTCASE_16: FAILED at <:abc::def>: LIBPATH = <%s>\n", getenv("LIBPATH"));
failed++;
}
printf("TESTCASE_17: Multiple empty paths plus a single colon at the start stays ahead of the backup patht\n");
setLibpath("x:y");
backupLibpath(&bkp, 0);
setLibpath(":abc::def::x:y");
restoreLibpath(&bkp);
if (0 == strcmp(getenv("LIBPATH"), ":abc::def")) {
printf("TESTCASE_17: PASSED at <:abc::def>\n");
passed++;
} else {
fprintf(stderr, "TESTCASE_17: FAILED at <:abc::def>: LIBPATH = <%s>\n", getenv("LIBPATH"));
failed++;
}
printf("TESTCASE_18: The backup path stays at the end except for a single colon\n");
setLibpath("x:y");
backupLibpath(&bkp, 0);
setLibpath("abc:def:x:y:");
restoreLibpath(&bkp);
if (0 == strcmp(getenv("LIBPATH"), "abc:def")) {
printf("TESTCASE_18: PASSED at <abc:def>\n");
passed++;
} else {
fprintf(stderr, "TESTCASE_18: FAILED at <abc:def>: LIBPATH = <%s>\n", getenv("LIBPATH"));
failed++;
}
printf("TESTCASE_19: The backup path stays at the end except for an empty path\n");
setLibpath("x:y");
backupLibpath(&bkp, 0);
setLibpath("abc:def:x:y::");
restoreLibpath(&bkp);
if (0 == strcmp(getenv("LIBPATH"), "abc:def")) {
printf("TESTCASE_19: PASSED at <abc:def>\n");
passed++;
} else {
fprintf(stderr, "TESTCASE_19: FAILED at <abc:def>: LIBPATH = <%s>\n", getenv("LIBPATH"));
failed++;
}
printf("TESTCASE_20: The backup path comes with a trailing colon\n");
setLibpath("x:y:");
backupLibpath(&bkp, 0);
setLibpath("abc:x:y:ghi");
restoreLibpath(&bkp);
if (0 == strcmp(getenv("LIBPATH"), "abc:ghi")) {
printf("TESTCASE_20: PASSED at <abc:ghi>\n");
passed++;
} else {
fprintf(stderr, "TESTCASE_20: FAILED at <abc:ghi>: LIBPATH = <%s>\n", getenv("LIBPATH"));
failed++;
}
printf("TESTCASE_21: The backup path comes with a leading colon\n");
setLibpath(":x:y");
backupLibpath(&bkp, 0);
setLibpath("::abc:def::x:y:ghi");
restoreLibpath(&bkp);
if (0 == strcmp(getenv("LIBPATH"), "::abc:def:ghi")) {
printf("TESTCASE_21: PASSED at <::abc:def:ghi>\n");
passed++;
} else {
fprintf(stderr, "TESTCASE_21: FAILED at <::abc:def:ghi>: LIBPATH = <%s>\n", getenv("LIBPATH"));
failed++;
}
printf("TESTCASE_22: Delete from the start when restoring LIBPATH\n");
setLibpath("abc::def:xyz");
backupLibpath(&bkp, strlen("xyz"));
setLibpath("abc::def:xyz:morestuff");
restoreLibpath(&bkp);
if (0 == strcmp(getenv("LIBPATH"), "xyz:morestuff")) {
printf("TESTCASE_22: PASSED at <xyz:morestuff>\n");
passed++;
} else {
fprintf(stderr, "TESTCASE_22: FAILED at <xyz:morestuff>: LIBPATH = <%s>\n", getenv("LIBPATH"));
failed++;
}
printf("TESTCASE_23: Delete from the middle when restoring LIBPATH\n");
setLibpath("abc::def:xyz");
backupLibpath(&bkp, strlen("xyz"));
setLibpath(":stuff:abc::def:xyz:morestuff");
restoreLibpath(&bkp);
if (0 == strcmp(getenv("LIBPATH"), ":stuff:xyz:morestuff")) {
printf("TESTCASE_23: PASSED at <:stuff:xyz:morestuff>\n");
passed++;
} else {
fprintf(stderr, "TESTCASE_23: FAILED at <:stuff:xyz:morestuff>: LIBPATH = <%s>\n", getenv("LIBPATH"));
failed++;
}
printf("TESTCASE_24: Delete from the end when restoring LIBPATH\n");
setLibpath("abc::def:xyz");
backupLibpath(&bkp, strlen("xyz"));
setLibpath(":stuff:morestuff:abc::def:xyz");
restoreLibpath(&bkp);
if (0 == strcmp(getenv("LIBPATH"), ":stuff:morestuff:xyz")) {
printf("TESTCASE_24: PASSED at <:stuff:morestuff:xyz>\n");
passed++;
} else {
fprintf(stderr, "TESTCASE_24: FAILED at <:stuff:morestuff:xyz>: LIBPATH = <%s>\n", getenv("LIBPATH"));
failed++;
}
printf("TESTCASE_25: Ignore colons in the prefix when restoring LIBPATH\n");
setLibpath("abc::def::xyz");
backupLibpath(&bkp, strlen("xyz"));
setLibpath("stuff:abc::def::xyz:morestuff");
restoreLibpath(&bkp);
if (0 == strcmp(getenv("LIBPATH"), "stuff:xyz:morestuff")) {
printf("TESTCASE_25: PASSED at <stuff:xyz:morestuff>\n");
passed++;
} else {
fprintf(stderr, "TESTCASE_25: FAILED at <stuff:xyz:morestuff>: LIBPATH = <%s>\n", getenv("LIBPATH"));
failed++;
}
printf("TESTCASE_26: Skip colons from both start and end when restoring LIBPATH\n");
setLibpath("abc::def:");
backupLibpath(&bkp, 0);
setLibpath("::abc::def::");
restoreLibpath(&bkp);
if (0 == strcmp(getenv("LIBPATH"), "")) {
printf("TESTCASE_26: PASSED at <>\n");
passed++;
} else {
fprintf(stderr, "TESTCASE_26: FAILED at <>: LIBPATH = <%s>\n", getenv("LIBPATH"));
failed++;
}
printf("TESTCASE_27: Insert colon from the end when restoring LIBPATH\n");
setLibpath(":abc::def:xyz");
backupLibpath(&bkp, strlen("xyz"));
setLibpath("stuff:abc::def:xyz:morestuff");
restoreLibpath(&bkp);
if (0 == strcmp(getenv("LIBPATH"), "stuff:xyz:morestuff")) {
printf("TESTCASE_27: PASSED at <stuff:xyz:morestuff>\n");
passed++;
} else {
fprintf(stderr, "TESTCASE_27: FAILED at <stuff:xyz:morestuff>: LIBPATH = <%s>\n", getenv("LIBPATH"));
failed++;
}
printf("TESTCASE_28: Empty backup path before restoring LIBPATH\n");
setLibpath("");
backupLibpath(&bkp, 0);
setLibpath("stuff:abc::def:xyz:morestuff");
restoreLibpath(&bkp);
if (0 == strcmp(getenv("LIBPATH"), "stuff:abc::def:xyz:morestuff")) {
printf("TESTCASE_28: PASSED at <stuff:abc::def:xyz:morestuff>\n");
passed++;
} else {
fprintf(stderr, "TESTCASE_28: FAILED at <stuff:abc::def:xyz:morestuff>: LIBPATH = <%s>\n", getenv("LIBPATH"));
failed++;
}
printf("TESTCASE_29: Keep backup path and empty prefix when restoring LIBPATH\n");
setLibpath("abc:def");
backupLibpath(&bkp, strlen("abc:def"));
setLibpath("stuff:abc:def:xyz:morestuff");
restoreLibpath(&bkp);
if (0 == strcmp(getenv("LIBPATH"), "stuff:abc:def:xyz:morestuff")) {
printf("TESTCASE_29: PASSED at <stuff:abc:def:xyz:morestuff>\n");
passed++;
} else {
fprintf(stderr, "TESTCASE_29: FAILED at <stuff:abc:def:xyz:morestuff>: LIBPATH = <%s>\n", getenv("LIBPATH"));
failed++;
}
printf("TESTCASE_30: The length of current path is greater than the backup path when restoring LIBPATH\n");
setLibpath("abc:def:ghi");
backupLibpath(&bkp, 0);
setLibpath("abc:def");
restoreLibpath(&bkp);
if (0 == strcmp(getenv("LIBPATH"), "abc:def")) {
printf("TESTCASE_30: PASSED at <abc:def>\n");
passed++;
} else {
fprintf(stderr, "TESTCASE_30: FAILED at <abc:def>: LIBPATH = <%s>\n", getenv("LIBPATH"));
failed++;
}
printf("TESTCASE_31: The backup path is prefixed by multiple colons\n");
setLibpath(":::abc");
backupLibpath(&bkp, strlen("abc"));
setLibpath("abc");
restoreLibpath(&bkp);
if (0 == strcmp(getenv("LIBPATH"), "abc")) {
printf("TESTCASE_31: PASSED at <abc>\n");
passed++;
} else {
fprintf(stderr, "TESTCASE_31: FAILED at <abc>: LIBPATH = <%s>\n", getenv("LIBPATH"));
failed++;
}
printf("TESTCASE_32: Only VM prefix exists in the backup path when restoring LIBPATH\n");
setLibpath(":::abc");
backupLibpath(&bkp, 0);
setLibpath("abc");
restoreLibpath(&bkp);
if (0 == strcmp(getenv("LIBPATH"), "abc")) {
printf("TESTCASE_32: PASSED at <abc>\n");
passed++;
} else {
fprintf(stderr, "TESTCASE_32: FAILED at <abc>: LIBPATH = <%s>\n", getenv("LIBPATH"));
failed++;
}
printf("TESTCASE_33: Colons prefixing the backup LIBPATH is more than that of the current LIBPATH\n");
setLibpath(":::abc:xyz");
backupLibpath(&bkp, strlen("abc:xyz"));
setLibpath("def::abc:xyz");
restoreLibpath(&bkp);
if (0 == strcmp(getenv("LIBPATH"), "def::abc:xyz")) {
printf("TESTCASE_33: PASSED at <def::abc:xyz>\n");
passed++;
} else {
fprintf(stderr, "TESTCASE_33: FAILED at <def::abc:xyz>: LIBPATH = <%s>\n", getenv("LIBPATH"));
failed++;
}
printf("TESTCASE_34: Colons prefixing the backup LIBPATH is less than that of the current LIBPATH (1)\n");
setLibpath(":::abc:xyz");
backupLibpath(&bkp, strlen("abc:xyz"));
setLibpath("def:::abc:xyz");
restoreLibpath(&bkp);
if (0 == strcmp(getenv("LIBPATH"), "def:abc:xyz")) {
printf("TESTCASE_34: PASSED at <def:abc:xyz>\n");
passed++;
} else {
fprintf(stderr, "TESTCASE_34: FAILED at <def:abc:xyz>: LIBPATH = <%s>\n", getenv("LIBPATH"));
failed++;
}
printf("TESTCASE_35: Colons prefixing the backup LIBPATH is less than that of the current LIBPATH (2)\n");
setLibpath(":::abc:xyz");
backupLibpath(&bkp, strlen("abc:xyz"));
setLibpath("def::::abc:xyz");
restoreLibpath(&bkp);
if (0 == strcmp(getenv("LIBPATH"), "def:abc:xyz")) {
printf("TESTCASE_35: PASSED at <def:abc:xyz>\n");
passed++;
} else {
fprintf(stderr, "TESTCASE_35: FAILED at <def:abc:xyz>: LIBPATH = <%s>\n", getenv("LIBPATH"));
failed++;
}
printf("---------- TEST RESULTS ----------\n");
printf("Number of PASSED tests: %d\n", passed);
printf("Number of FAILED tests: %d\n", failed);
if (0 == failed) {
printf("testBackupAndRestoreLibpath:---- TEST_PASSED ---------\n");
} else {
printf("testBackupAndRestoreLibpath:---- TEST_FAILED ---------\n");
}
setLibpath(origLibpath);
}
#endif
#if defined(WIN32)
static jint
formatErrorMessage(int errorCode, char *inBuffer, jint inBufferLength)
{
size_t i=0;
int rc = 0, j=0;
size_t outLength, lastChar;
_TCHAR buffer[JVM_DEFAULT_ERROR_BUFFER_SIZE];
_TCHAR noCRLFbuffer[JVM_DEFAULT_ERROR_BUFFER_SIZE];
if (inBufferLength <= 1) {
if (inBufferLength == 1) {
inBuffer[0] = '\0';
}
return 0;
}
rc = FormatMessage( FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, NULL, errorCode, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), buffer, JVM_DEFAULT_ERROR_BUFFER_SIZE, NULL );
if (rc == 0) {
inBuffer[0] = '\0';
return 0;
}
j=0;
for (i = 0; i < _tcslen(buffer)+1 ; i++) {
if(buffer[i] == _TEXT('\n') ) {
noCRLFbuffer[j++]=_TEXT(' ');
} else if(buffer[i] == _TEXT('\r')) {
continue;
} else {
noCRLFbuffer[j++]=buffer[i];
}
}
lastChar = _tcslen(noCRLFbuffer)-1;
if(_istspace(noCRLFbuffer[lastChar])) {
noCRLFbuffer[lastChar] = _TEXT('\0');
}
#ifdef UNICODE
outLength = WideCharToMultiByte(CP_UTF8, 0, noCRLFbuffer, -1, inBuffer, inBufferLength-1, NULL, NULL);
#else
outLength = strlen(noCRLFbuffer)+1;
if(outLength > (size_t)inBufferLength) {
outLength = (size_t)inBufferLength;
}
strncpy(inBuffer, noCRLFbuffer, outLength);
inBuffer[inBufferLength-1]='\0';
#endif
Assert_SC_true(outLength <= I_32_MAX);
return (jint)outLength;
}
#endif
static UDATA
protectedStrerror(J9PortLibrary* portLib, void* savedErrno)
{
return (UDATA) strerror((int) (IDATA) savedErrno);
}
static UDATA
strerrorSignalHandler(struct J9PortLibrary* portLibrary, U_32 gpType, void* gpInfo, void* userData)
{
return J9PORT_SIG_EXCEPTION_RETURN;
}
static void
throwNewUnsatisfiedLinkError(JNIEnv *env, char *message)
{
jclass exceptionClass = (*env)->FindClass(env, "java/lang/UnsatisfiedLinkError");
if (NULL != exceptionClass) {
(*env)->ThrowNew(env, exceptionClass, message);
}
}
static void
truncatePath(char *inputPath) {
char *lastOccurence = strrchr(inputPath, DIR_SEPARATOR);
if (NULL != lastOccurence) {
*lastOccurence = '\0';
}
}
void JNICALL
JVM_OnExit(void (*func)(void))
{
J9SidecarExitFunction * newFunc;
Trc_SC_OnExit_Entry(func);
newFunc = (J9SidecarExitFunction *) malloc(sizeof(J9SidecarExitFunction));
if (newFunc) {
newFunc->func = func;
#if CALL_BUNDLED_FUNCTIONS_DIRECTLY
omrthread_monitor_enter(BFUjavaVM->vmThreadListMutex);
#else
f_monitorEnter(BFUjavaVM->vmThreadListMutex);
#endif
newFunc->next = BFUjavaVM->sidecarExitFunctions;
BFUjavaVM->sidecarExitFunctions = newFunc;
#if CALL_BUNDLED_FUNCTIONS_DIRECTLY
omrthread_monitor_exit(BFUjavaVM->vmThreadListMutex);
#else
f_monitorExit(BFUjavaVM->vmThreadListMutex);
#endif
BFUjavaVM->sidecarExitHook = &exitHook;
} else {
Trc_SC_OnExit_OutOfMemory();
}
Trc_SC_OnExit_Exit(newFunc);
}
void* JNICALL
JVM_LoadSystemLibrary(const char *libName)
{
#ifdef WIN32
UDATA dllHandle = 0;
size_t libNameLen = strlen(libName);
UDATA flags = 0;
Trc_SC_LoadSystemLibrary_Entry(libName);
if ((libNameLen <= 4) ||
('.' != libName[libNameLen - 4]) ||
('d' != j9_cmdla_tolower(libName[libNameLen - 3])) ||
('l' != j9_cmdla_tolower(libName[libNameLen - 2])) ||
('l' != j9_cmdla_tolower(libName[libNameLen - 1])))
{
flags = J9PORT_SLOPEN_DECORATE;
}
if (0 == j9util_open_system_library((char *)libName, &dllHandle, flags)) {
Trc_SC_LoadSystemLibrary_Exit(dllHandle);
return (void *)dllHandle;
}
#endif
#if defined(J9UNIX) || defined(J9ZOS390)
void *dllHandle = NULL;
Trc_SC_LoadSystemLibrary_Entry(libName);
#if defined(AIXPPC)
loadAndInit((char *)libName, L_RTLD_LOCAL, NULL);
#endif
dllHandle = dlopen((char *)libName, RTLD_LAZY);
if (NULL != dllHandle) {
Trc_SC_LoadSystemLibrary_Exit(dllHandle);
return dllHandle;
}
#endif
Trc_SC_LoadSystemLibrary_LoadFailed(libName);
if (NULL != BFUjavaVM) {
JNIEnv *env = NULL;
JavaVM *vm = (JavaVM *)BFUjavaVM;
(*vm)->GetEnv(vm, (void **)&env, JNI_VERSION_1_2);
if (NULL != env) {
char errMsg[512];
jio_snprintf(errMsg, sizeof(errMsg), "Failed to load library \"%s\"", libName);
errMsg[sizeof(errMsg) - 1] = '\0';
throwNewUnsatisfiedLinkError(env, errMsg);
}
}
Trc_SC_LoadSystemLibrary_Exit(NULL);
return NULL;
}
void * JNICALL
#if JAVA_SPEC_VERSION < 17
JVM_LoadLibrary(const char *libName)
#else
JVM_LoadLibrary(const char *libName, jboolean throwOnFailure)
#endif
{
void *result = NULL;
J9JavaVM *javaVM = (J9JavaVM *)BFUjavaVM;
PORT_ACCESS_FROM_JAVAVM(javaVM);
#if defined(WIN32)
char *libNameConverted = NULL;
UDATA libNameLen = strlen(libName);
UDATA libNameLenConverted = j9str_convert(J9STR_CODE_WINDEFAULTACP, J9STR_CODE_MUTF8, libName, libNameLen, NULL, 0);
if (libNameLenConverted > 0) {
libNameLenConverted += 1;
libNameConverted = j9mem_allocate_memory(libNameLenConverted, OMRMEM_CATEGORY_VM);
if (NULL != libNameConverted) {
libNameLenConverted = j9str_convert(J9STR_CODE_WINDEFAULTACP, J9STR_CODE_MUTF8, libName, libNameLen, libNameConverted, libNameLenConverted);
if (libNameLenConverted > 0) {
libName = libNameConverted;
}
}
}
if (libName == libNameConverted) {
#endif
Trc_SC_LoadLibrary_Entry(libName);
{
UDATA handle = 0;
UDATA flags = J9_ARE_ANY_BITS_SET(javaVM->extendedRuntimeFlags, J9_EXTENDED_RUNTIME_LAZY_SYMBOL_RESOLUTION) ? J9PORT_SLOPEN_LAZY : 0;
UDATA slOpenResult = j9sl_open_shared_library((char *)libName, &handle, flags);
Trc_SC_LoadLibrary_OpenShared(libName);
if (0 != slOpenResult) {
slOpenResult = j9sl_open_shared_library((char *)libName, &handle, flags | J9PORT_SLOPEN_DECORATE);
Trc_SC_LoadLibrary_OpenShared_Decorate(libName);
}
if (0 == slOpenResult) {
result = (void *)handle;
}
}
#if defined(WIN32)
}
if (NULL != libNameConverted) {
j9mem_free_memory(libNameConverted);
}
#endif
#if JAVA_SPEC_VERSION >= 17
if ((NULL == result) && throwOnFailure) {
JNIEnv *env = NULL;
JavaVM *vm = (JavaVM *)javaVM;
(*vm)->GetEnv(vm, (void **)&env, JNI_VERSION_1_2);
if (NULL != env) {
char errMsg[512];
jio_snprintf(errMsg, sizeof(errMsg), "Failed to load library \"%s\"", libName);
errMsg[sizeof(errMsg) - 1] = '\0';
throwNewUnsatisfiedLinkError(env, errMsg);
}
}
#endif
Trc_SC_LoadLibrary_Exit(result);
return result;
}
void* JNICALL
JVM_FindLibraryEntry(void* handle, const char *functionName)
{
void* result;
Trc_SC_FindLibraryEntry_Entry(handle, functionName);
#if defined(WIN32)
result = GetProcAddress ((HINSTANCE)handle, (LPCSTR)functionName);
#elif defined(J9UNIX) || defined(J9ZOS390)
result = (void*)dlsym( (void*)handle, (char *)functionName );
#else
#error "Please implement jvm.c:JVM_FindLibraryEntry(void* handle, const char *functionName)"
#endif
Trc_SC_FindLibraryEntry_Exit(result);
return result;
}
jint JNICALL
JVM_SetLength(jint fd, jlong length)
{
jint result;
Trc_SC_SetLength_Entry(fd, length);
if (fd == -1) {
Trc_SC_SetLength_bad_descriptor();
return -1;
}
#if defined(WIN32_IBMC)
printf("_JVM_SetLength@12 called but not yet implemented. Exiting.");
exit(43);
#elif defined(WIN32)
result = _chsize(fd, (long)length);
#elif defined(J9UNIX) && !defined(J9ZTPF) && !defined(OSX)
result = ftruncate64(fd, length);
#elif defined(J9ZOS390) || defined(J9ZTPF) || defined(OSX)
result = ftruncate(fd, length);
#else
#error "Please provide an implementation of jvm.c:JVM_SetLength(jint fd, jlong length)"
#endif
Trc_SC_SetLength_Exit(result);
return result;
}
jint JNICALL
JVM_Write(jint descriptor, const char* buffer, jint length)
{
PORT_ACCESS_FROM_JAVAVM(BFUjavaVM);
jint result = 0;
Trc_SC_Write_Entry(descriptor, buffer, length);
if (descriptor == -1) {
Trc_SC_Write_bad_descriptor();
return JVM_IO_ERR;
}
#ifndef J9ZOS390
if ( (descriptor == 1) || (descriptor == 2) ) {
IDATA retval = j9file_write(descriptor, (char *)buffer, length);
if(retval<0) {
result = -1;
} else {
result = (jint)retval;
Assert_SC_true(retval == (IDATA)result);
}
} else
#endif
{
do {
result = write(descriptor, buffer, length);
} while ((-1 == result) && (EINTR == errno));
}
Trc_SC_Write_Exit(result);
return result;
}
jint JNICALL
JVM_Close(jint descriptor)
{
jint result = 0;
Trc_SC_Close_Entry(descriptor);
if (descriptor == -1) {
Trc_SC_Close_bad_descriptor();
return JVM_IO_ERR;
}
if (descriptor >= 0 && descriptor <= 2) {
Trc_SC_Close_std_descriptor();
return 0;
}
result = close(descriptor);
Trc_SC_Close_Exit(result);
return result;
}
jint JNICALL
JVM_Available(jint descriptor, jlong* bytes)
{
jlong curr = 0;
jlong end = 0;
#if defined(J9UNIX) && !defined(J9ZTPF) && !defined(OSX)
struct stat64 tempStat;
#endif
#if defined(J9ZOS390) || defined(J9ZTPF) || defined(OSX)
struct stat tempStat;
#endif
#if defined(LINUX)
loff_t longResult = 0;
#endif
Trc_SC_Available_Entry(descriptor, bytes);
if (descriptor == -1) {
Trc_SC_Available_bad_descriptor();
*bytes = 0;
return JNI_FALSE;
}
#if defined(WIN32) && !defined(__IBMC__)
curr = _lseeki64(descriptor, 0, SEEK_CUR);
if (curr==-1L) {
if (descriptor == 0) {
DWORD result = 0;
if (GetNumberOfConsoleInputEvents(GetStdHandle(STD_INPUT_HANDLE), &result)) {
*bytes = result;
} else {
*bytes = 0;
}
Trc_SC_Available_Exit(1, *bytes);
return 1;
}
Trc_SC_Available_lseek_failed(descriptor);
return 0;
}
end = _lseeki64(descriptor, 0, SEEK_END);
_lseeki64(descriptor, curr, SEEK_SET);
#else
if (J9FSTAT(descriptor, &tempStat) == -1) {
Trc_SC_Available_fstat_failed(descriptor, errno);
*bytes = 0;
return 0;
}
else if (S_ISFIFO(tempStat.st_mode) || S_ISSOCK(tempStat.st_mode) || S_ISCHR(tempStat.st_mode)) {
int arg3FIONREAD = 0;
#if defined(J9ZOS390)
if (!S_ISSOCK(tempStat.st_mode)) {
*bytes = tempStat.st_size;
Trc_SC_Available_Exit(1, *bytes);
return 1;
}
#endif
if (ioctl(descriptor, FIONREAD, &(arg3FIONREAD)) == -1) {
if (descriptor == 0) {
*bytes = tempStat.st_size;
Trc_SC_Available_Exit(1, *bytes);
return 1;
}
#if (defined(LINUX) && !defined(J9ZTPF)) || defined(AIXPPC) || defined(J9ZOS390)
else {
struct pollfd pollOne;
int ret = 0;
pollOne.fd = descriptor;
pollOne.events = POLLRDNORM | POLLRDBAND | POLLPRI;
pollOne.revents = 0;
if (-1 != poll(&pollOne, 1, 0)) {
if(0 != (pollOne.events & pollOne.revents)) {
*bytes = 1;
Trc_SC_Available_Exit(1, *bytes);
return 1;
} else {
*bytes = 0;
Trc_SC_Available_Exit(1, *bytes);
return 1;
}
} else {
Trc_SC_Available_poll_failed(descriptor, errno);
*bytes = 0;
return 0;
}
}
#endif
Trc_SC_Available_ioctl_failed(descriptor, errno);
*bytes = 0;
return 0;
}
*bytes = (jlong) arg3FIONREAD;
Trc_SC_Available_Exit(1, *bytes);
return 1;
}
#if defined(LINUX) && !defined(J9VM_ENV_DATA64)
#if __GLIBC_PREREQ(2,4)
curr = lseek64(descriptor, 0, SEEK_CUR);
#else
curr = _llseek(descriptor, 0, 0, &longResult, SEEK_CUR);
if (0 == curr) {
curr = (jlong) longResult;
}
#endif
#else
curr = lseek(descriptor, 0, SEEK_CUR);
#endif
if (curr==-1L) {
if (descriptor == 0) {
*bytes = 0;
Trc_SC_Available_Exit(1, *bytes);
return 1;
}
Trc_SC_Available_lseek_failed(descriptor);
return 0;
}
end = tempStat.st_size;
#endif
*bytes = (end-curr);
Trc_SC_Available_Exit(1, *bytes);
return 1;
}
jlong JNICALL
JVM_Lseek(jint descriptor, jlong bytesToSeek, jint origin)
{
jlong result = 0;
#if defined (LINUX)
loff_t longResult = 0;
#endif
Trc_SC_Lseek_Entry(descriptor, bytesToSeek, origin);
if (descriptor == -1) {
Trc_SC_Lseek_bad_descriptor();
return JVM_IO_ERR;
}
#if defined(WIN32)
#ifdef __IBMC__
result = lseek(descriptor, (long) bytesToSeek, origin);
#else
result = _lseeki64(descriptor, bytesToSeek, origin);
#endif
#elif defined(J9UNIX) || defined(J9ZOS390)
#if defined(LINUX) && !defined(J9VM_ENV_DATA64)
#if __GLIBC_PREREQ(2,4)
result = lseek64(descriptor, bytesToSeek, origin);
#else
result = _llseek(descriptor, (unsigned long) ((bytesToSeek >> 32) & 0xFFFFFFFF), (unsigned long) (bytesToSeek & 0xFFFFFFFF), &longResult, origin);
if (0 == result) {
result = (jlong) longResult;
}
#endif
#else
result = lseek(descriptor, (off_t) bytesToSeek, origin);
#endif
#else
#error No JVM_Lseek provided
#endif
Trc_SC_Lseek_Exit(result);
return result;
}
jint JNICALL
JVM_Read(jint descriptor, char *buffer, jint bytesToRead)
{
PORT_ACCESS_FROM_JAVAVM(BFUjavaVM);
jint result = 0;
Trc_SC_Read_Entry(descriptor, buffer, bytesToRead);
if (descriptor == -1) {
Trc_SC_Read_bad_descriptor();
return -1;
}
#ifndef J9ZOS390
if (descriptor == 0) {
IDATA charsRead = j9tty_get_chars(buffer, bytesToRead);
result = (jint)charsRead;
Assert_SC_true(charsRead == (IDATA)result);
} else
#endif
{
do {
result = read(descriptor, buffer, bytesToRead);
} while ((-1 == result) && (EINTR == errno));
}
Trc_SC_Read_Exit(result, errno);
return result;
}
jint JNICALL
JVM_Open(const char* filename, jint flags, jint mode)
{
int errorVal = 0;
jint returnVal = 0;
#if defined(J9UNIX) && !defined(J9ZTPF) && !defined(OSX)
struct stat64 tempStat;
int doUnlink = 0;
#endif
#if defined(J9ZOS390) || defined(J9ZTPF) || defined(OSX)
struct stat tempStat;
int doUnlink = 0;
#endif
Trc_SC_Open_Entry(filename, flags, mode);
#define JVM_EEXIST -100
#ifdef WIN32
#ifdef __IBMC__
#define EXTRA_OPEN_FLAGS O_NOINHERIT | O_BINARY
#else
#define EXTRA_OPEN_FLAGS _O_NOINHERIT | _O_BINARY
#endif
#endif
#if defined(J9UNIX) || defined(J9ZOS390)
#if defined(OSX) || defined(J9ZTPF)
#define EXTRA_OPEN_FLAGS 0
#else
#define EXTRA_OPEN_FLAGS O_LARGEFILE
#endif
#ifndef O_DSYNC
#define O_DSYNC O_SYNC
#endif
doUnlink = (flags & O_TEMPORARY);
#if !defined(J9ZTPF)
flags &= (O_CREAT | O_APPEND | O_RDONLY | O_RDWR | O_TRUNC | O_WRONLY | O_EXCL | O_NOCTTY | O_NONBLOCK | O_NDELAY | O_SYNC | O_DSYNC);
#else
flags &= (O_CREAT | O_APPEND | O_RDONLY | O_RDWR | O_TRUNC | O_WRONLY | O_EXCL | O_NOCTTY | O_NONBLOCK | O_SYNC | O_DSYNC);
#endif
#endif
filename = JVM_NativePath((char *)filename);
#if defined(J9UNIX) || defined(J9ZOS390)
do {
errorVal = 0;
#endif
#ifdef J9OS_I5
returnVal = Xj9Open_JDK6((char *)filename, (flags | EXTRA_OPEN_FLAGS), mode);
#else
returnVal = open(filename, (flags | EXTRA_OPEN_FLAGS), mode);
#endif
if (-1 == returnVal) {
errorVal = errno;
}
#if defined(J9UNIX) || defined(J9ZOS390)
if ((returnVal>=0) && (J9FSTAT(returnVal, &tempStat)==-1)) {
Trc_SC_Open_fstat64(filename);
close(returnVal);
return -1;
}
if ((returnVal>=0) && S_ISDIR(tempStat.st_mode)) {
char buf[1];
Trc_SC_Open_isDirectory(filename);
errno = EISDIR;
close(returnVal);
return -1;
}
}
while ((-1 == returnVal) && ((EAGAIN == errorVal) || (EINTR == errorVal)));
if ((returnVal>=0) && doUnlink)
unlink(filename);
#endif
if (returnVal<0) {
Trc_SC_Open_error(filename, errorVal);
} else {
Trc_SC_Open_Exit(filename, returnVal);
}
if (returnVal>=0)
return returnVal;
else if (EEXIST == errorVal)
return JVM_EEXIST;
else
return -1;
}
jint JNICALL
JVM_Sync(jint descriptor)
{
jint result;
Trc_SC_Sync_Entry(descriptor);
if (descriptor == -1) {
Trc_SC_Sync_bad_descriptor();
return -1;
}
#if defined(WIN32)
#ifdef WIN32_IBMC
printf("_JVM_Sync@4 called but not yet implemented. Exiting.\n");
exit(44);
#else
result = _commit(descriptor);
#endif
#elif defined(J9UNIX) || defined(J9ZOS390)
result = fsync(descriptor);
#else
#error No JVM_Sync implementation
#endif
Trc_SC_Sync_Exit(result);
return result;
}
char* JNICALL
JVM_NativePath(char* path)
{
char * pathIndex;
size_t length = strlen(path);
Trc_SC_NativePath_Entry(path);
if (jclSeparator == '/') {
Trc_SC_NativePath_Exit(path);
return path;
}
pathIndex = path;
while (*pathIndex != '\0') {
if ((*pathIndex == '\\' || *pathIndex == '/') && (*pathIndex != jclSeparator))
*pathIndex = jclSeparator;
pathIndex++;
}
pathIndex = path;
while ((*pathIndex != '\0') && (*pathIndex == jclSeparator)) {
pathIndex++;
}
if ((pathIndex > path) && (length > (size_t)(pathIndex - path)) && (*(pathIndex + 1) == ':')) {
size_t newlen = length - (pathIndex - path);
memmove(path, pathIndex, newlen);
path[newlen] = '\0';
} else {
if ((pathIndex - path > 3) && (length > (size_t)(pathIndex - path))) {
size_t newlen = length - (pathIndex - path) + 2;
memmove(path, pathIndex - 2, newlen);
path[newlen] = '\0';
}
}
Trc_SC_NativePath_Exit(path);
return path;
}
static BOOLEAN
isSignalUsedForShutdown(jint sigNum)
{
return
#if defined(SIGHUP)
(SIGHUP == sigNum) ||
#endif
#if defined(SIGINT)
(SIGINT == sigNum) ||
#endif
#if defined(SIGTERM)
(SIGTERM == sigNum) ||
#endif
FALSE;
}
static BOOLEAN
isSignalReservedByJVM(jint sigNum)
{
return
#if defined(SIGFPE)
(SIGFPE == sigNum) ||
#endif
#if defined(SIGILL)
(SIGILL == sigNum) ||
#endif
#if defined(SIGSEGV)
(SIGSEGV == sigNum) ||
#endif
#if defined(SIGBUS)
(SIGBUS == sigNum) ||
#endif
#if defined(SIGTRAP)
(SIGTRAP == sigNum) ||
#endif
#if defined(SIGQUIT)
(SIGQUIT == sigNum) ||
#endif
#if defined(SIGBREAK)
(SIGBREAK == sigNum) ||
#endif
FALSE;
}
jboolean JNICALL
JVM_RaiseSignal(jint sigNum)
{
jboolean rc = JNI_FALSE;
J9JavaVM *javaVM = (J9JavaVM *)BFUjavaVM;
BOOLEAN isShutdownSignal = isSignalUsedForShutdown(sigNum);
BOOLEAN isSignalIgnored = FALSE;
int32_t isSignalIgnoredError = 0;
uint32_t portlibSignalFlag = 0;
PORT_ACCESS_FROM_JAVAVM(javaVM);
Trc_SC_RaiseSignal_Entry(sigNum);
portlibSignalFlag = j9sig_map_os_signal_to_portlib_signal(sigNum);
if (0 != portlibSignalFlag) {
isSignalIgnoredError = j9sig_is_signal_ignored(portlibSignalFlag, &isSignalIgnored);
}
if (isSignalReservedByJVM(sigNum)) {
} else if (J9_ARE_ALL_BITS_SET(javaVM->sigFlags, J9_SIG_XRS_ASYNC) && isShutdownSignal) {
} else if (isShutdownSignal && ((0 == isSignalIgnoredError) && isSignalIgnored)) {
} else {
raise(sigNum);
rc = JNI_TRUE;
}
Trc_SC_RaiseSignal_Exit(rc);
return rc;
}
void* JNICALL
JVM_RegisterSignal(jint sigNum, void *handler)
{
void *oldHandler = (void *)J9_SIG_ERR;
J9JavaVM *javaVM = (J9JavaVM *)BFUjavaVM;
J9InternalVMFunctions *vmFuncs = javaVM->internalVMFunctions;
J9VMThread *currentThread = vmFuncs->currentVMThread(javaVM);
BOOLEAN isShutdownSignal = isSignalUsedForShutdown(sigNum);
BOOLEAN isSignalIgnored = FALSE;
int32_t isSignalIgnoredError = 0;
uint32_t portlibSignalFlag = 0;
PORT_ACCESS_FROM_JAVAVM(javaVM);
Trc_SC_RegisterSignal_Entry(currentThread, sigNum, handler);
portlibSignalFlag = j9sig_map_os_signal_to_portlib_signal(sigNum);
if (0 != portlibSignalFlag) {
isSignalIgnoredError = j9sig_is_signal_ignored(portlibSignalFlag, &isSignalIgnored);
}
if (isSignalReservedByJVM(sigNum)) {
goto exit;
} else if (J9_ARE_ANY_BITS_SET(javaVM->sigFlags, J9_SIG_XRS_ASYNC) && isShutdownSignal) {
goto exit;
} else if (isShutdownSignal && ((0 == isSignalIgnoredError) && isSignalIgnored)) {
oldHandler = (void *)J9_SIG_IGNORED;
goto exit;
} else {
IDATA isHandlerRegistered = 0;
if ((void *)J9_PRE_DEFINED_HANDLER_CHECK == handler) {
isHandlerRegistered = vmFuncs->registerPredefinedHandler(javaVM, sigNum, &oldHandler);
} else {
isHandlerRegistered = vmFuncs->registerOSHandler(javaVM, sigNum, handler, &oldHandler);
}
if (0 != isHandlerRegistered) {
Trc_SC_RegisterSignal_FailedToRegisterHandler(currentThread, sigNum, handler, oldHandler);
}
}
if (j9sig_is_main_signal_handler(oldHandler)) {
oldHandler = (void *)J9_USE_OLD_JAVA_SIGNAL_HANDLER;
}
exit:
Trc_SC_RegisterSignal_Exit(currentThread, oldHandler);
return oldHandler;
}
jint JNICALL
JVM_FindSignal(const char *sigName)
{
const J9SignalMapping *mapping = NULL;
jint signalValue = J9_SIG_ERR;
BOOLEAN nameHasSigPrefix = FALSE;
const char *fullSigName = sigName;
#if !defined(WIN32)
char nameWithSIGPrefix[J9_SIGNAME_BUFFER_LENGTH] = {0};
#endif
Trc_SC_FindSignal_Entry(sigName);
if (NULL != sigName) {
size_t sigPrefixLength = sizeof(J9_SIG_PREFIX) - 1;
#if !defined(WIN32)
if (0 != strncmp(sigName, J9_SIG_PREFIX, sigPrefixLength)) {
size_t sigNameLength = sigPrefixLength + strlen(sigName) + 1;
if (sigNameLength <= J9_SIGNAME_BUFFER_LENGTH) {
strcpy(nameWithSIGPrefix, J9_SIG_PREFIX);
strcat(nameWithSIGPrefix, sigName);
fullSigName = nameWithSIGPrefix;
} else {
goto exit;
}
}
#endif
for (mapping = signalMap; NULL != mapping->signalName; mapping++) {
if (0 == strcmp(fullSigName, mapping->signalName)) {
signalValue = mapping->signalValue;
break;
}
}
}
#if !defined(WIN32)
exit:
#endif
Trc_SC_FindSignal_Exit(signalValue);
return signalValue;
}
jint JNICALL
JVM_GetLastErrorString(char* buffer, jint length)
{
int savedErrno = errno;
#ifdef WIN32
DWORD errorCode = GetLastError();
#endif
jint retVal = 0;
Trc_SC_GetLastErrorString_Entry(buffer, length);
memset(buffer, 0, length);
#ifdef WIN32
if (errorCode) {
retVal = formatErrorMessage(errorCode, buffer, length);
} else
#endif
if (savedErrno) {
PORT_ACCESS_FROM_JAVAVM(BFUjavaVM);
I_32 sigRC;
UDATA fnRC;
sigRC = j9sig_protect(protectedStrerror, (void *) (IDATA) savedErrno, strerrorSignalHandler, NULL, J9PORT_SIG_FLAG_SIGALLSYNC | J9PORT_SIG_FLAG_MAY_RETURN, &fnRC);
if (sigRC == 0) {
strncat(buffer, (char *) fnRC, (length-1));
retVal = (jint)strlen(buffer);
}
}
Trc_SC_GetLastErrorString_Exit(retVal, buffer);
return retVal;
}
jobject JNICALL
JVM_CurrentClassLoader(JNIEnv *env)
{
jobject result;
Trc_SC_CurrentClassLoader_Entry(env);
result = (*env)->CallStaticObjectMethod(env, jlClass, currentClassLoaderMID);
if ((*env)->ExceptionCheck(env)) {
result = NULL;
}
Trc_SC_CurrentClassLoader_Exit(env, result);
return result;
}
jclass JNICALL
JVM_CurrentLoadedClass(JNIEnv *env)
{
jobject result;
Trc_SC_CurrentLoadedClass_Entry(env);
result = (*env)->CallStaticObjectMethod(env, jlClass, currentLoadedClassMID);
if ((*env)->ExceptionCheck(env)) {
result = NULL;
}
Trc_SC_CurrentLoadedClass_Exit(env, result);
return result;
}
jint JNICALL
JVM_ClassLoaderDepth(JNIEnv *env)
{
jint result;
Trc_SC_ClassLoaderDepth_Entry(env);
result = (*env)->CallStaticIntMethod(env, jlClass, classLoaderDepthMID);
if ((*env)->ExceptionCheck(env)) {
result = -1;
}
Trc_SC_ClassLoaderDepth_Exit(env, result);
return result;
}
jint JNICALL
JVM_ClassDepth(JNIEnv *env, jstring name)
{
jint result;
Trc_SC_ClassDepth_Entry(env, name);
result = (*env)->CallStaticIntMethod(env, jlClass, classDepthMID, name);
if ((*env)->ExceptionCheck(env)) {
result = -1;
}
Trc_SC_ClassDepth_Exit(env, result);
return result;
}
void JNICALL
JVM_TraceInstructions(jboolean on)
{
Trc_SC_TraceInstructions(on);
}
void JNICALL
JVM_TraceMethodCalls(jboolean on)
{
Trc_SC_TraceMethodCalls(on);
}
void JNICALL
JVM_RawMonitorDestroy(void* mon)
{
Trc_SC_RawMonitorDestroy_Entry(mon);
#if CALL_BUNDLED_FUNCTIONS_DIRECTLY
omrthread_monitor_destroy((omrthread_monitor_t) mon);
#else
f_monitorDestroy((omrthread_monitor_t) mon);
#endif
Trc_SC_RawMonitorDestroy_Exit();
}
jint JNICALL
JVM_RawMonitorEnter(void* mon)
{
Trc_SC_RawMonitorEnter_Entry(mon);
#if CALL_BUNDLED_FUNCTIONS_DIRECTLY
omrthread_monitor_enter((omrthread_monitor_t)mon);
#else
f_monitorEnter((omrthread_monitor_t)mon);
#endif
Trc_SC_RawMonitorEnter_Exit();
return 0;
}
void JNICALL JVM_RawMonitorExit(void* mon) {
Trc_SC_RawMonitorExit_Entry(mon);
#if CALL_BUNDLED_FUNCTIONS_DIRECTLY
omrthread_monitor_exit((omrthread_monitor_t)mon);
#else
f_monitorExit((omrthread_monitor_t)mon);
#endif
Trc_SC_RawMonitorExit_Exit();
}
void* JNICALL
JVM_RawMonitorCreate(void)
{
omrthread_monitor_t newMonitor;
Trc_SC_RawMonitorCreate_Entry();
#if CALL_BUNDLED_FUNCTIONS_DIRECTLY
if(omrthread_monitor_init_with_name(&newMonitor, 0, "JVM_RawMonitor"))
#else
if(f_monitorInit(&newMonitor, 0, "JVM_RawMonitor"))
#endif
{
Trc_SC_RawMonitorCreate_Error();
printf("error initializing raw monitor\n");
exit(1);
}
Trc_SC_RawMonitorCreate_Exit(newMonitor);
return (void *) newMonitor;
}
void JNICALL JVM_MonitorWait(JNIEnv *env, jobject anObject, jlong timeout) {
Trc_SC_MonitorWait_Entry(env, anObject, timeout);
(*env)->CallVoidMethod(env, anObject, waitMID, timeout);
Trc_SC_MonitorWait_Exit(env);
}
void JNICALL JVM_MonitorNotify(JNIEnv *env, jobject anObject) {
Trc_SC_MonitorNotify_Entry(env, anObject);
(*env)->CallVoidMethod(env, anObject, notifyMID);
Trc_SC_MonitorNotify_Exit(env);
}
void JNICALL JVM_MonitorNotifyAll(JNIEnv *env, jobject anObject) {
Trc_SC_MonitorNotifyAll_Entry(env, anObject);
(*env)->CallVoidMethod(env, anObject, notifyAllMID);
Trc_SC_MonitorNotifyAll_Exit(env);
}
jint JNICALL
JVM_Accept(jint descriptor, struct sockaddr* address, int* length)
{
jint retVal;
Trc_SC_Accept_Entry(descriptor, address, length);
#if defined(AIXPPC)
{
int returnVal=0;
fd_set fdset;
struct timeval tval;
socklen_t socklen = (socklen_t)*length;
tval.tv_sec = 1;
tval.tv_usec = 0;
do {
FD_ZERO(&fdset);
FD_SET((u_int)descriptor, &fdset);
returnVal = select(descriptor+1, &fdset, 0, 0, &tval);
} while(returnVal == 0);
do {
retVal = accept(descriptor, address, &socklen);
} while ((-1 == retVal) && (EINTR == errno));
*length = (int)socklen;
}
#elif defined (WIN32)
{
SOCKET socketResult = accept(descriptor, address, length);
retVal = (jint)socketResult;
Assert_SC_true(socketResult == (SOCKET)retVal);
}
#else
{
socklen_t socklen = (socklen_t)*length;
do {
retVal = accept(descriptor, address, &socklen);
} while ((-1 == retVal) && (EINTR == errno));
*length = (int)socklen;
}
#endif
Trc_SC_Accept_Exit(retVal, *length);
return retVal;
}
jint JNICALL
JVM_Connect(jint descriptor, const struct sockaddr*address, int length)
{
jint retVal;
Trc_SC_Connect_Entry(descriptor, address, length);
#if defined (WIN32)
retVal = connect(descriptor, address, length);
#else
do {
retVal = connect(descriptor, address, length);
} while ((-1 == retVal) && (EINTR == errno));
#endif
Trc_SC_Connect_Exit(retVal);
return retVal;
}
jlong JNICALL
JVM_CurrentTimeMillis(JNIEnv *env, jint unused1)
{
jlong result;
if (env != NULL) {
PORT_ACCESS_FROM_ENV(env);
Trc_SC_CurrentTimeMillis_Entry(env, unused1);
result = (jlong) j9time_current_time_millis();
Trc_SC_CurrentTimeMillis_Exit(env, result);
} else {
PORT_ACCESS_FROM_JAVAVM(BFUjavaVM);
result = (jlong) j9time_current_time_millis();
}
return result;
}
jint JNICALL
JVM_InitializeSocketLibrary(void)
{
Trc_SC_InitializeSocketLibrary();
return 0;
}
jint JNICALL JVM_Listen(jint descriptor, jint count) {
jint retVal;
Trc_SC_Listen_Entry(descriptor, count);
retVal = listen(descriptor, count);
Trc_SC_Listen_Exit(retVal);
return retVal;
}
jint JNICALL
JVM_Recv(jint descriptor, char* buffer, jint length, jint flags)
{
jint retVal;
#ifdef AIXPPC
int returnVal=0;
fd_set fdset;
struct timeval tval;
#endif
Trc_SC_Recv_Entry(descriptor, buffer, length, flags);
#ifdef AIXPPC
tval.tv_sec = 1;
tval.tv_usec = 0;
do {
FD_ZERO(&fdset);
FD_SET((u_int)descriptor, &fdset);
returnVal = select(descriptor+1, &fdset, 0, 0, &tval);
} while(returnVal == 0);
#endif
#ifdef WIN32
retVal = recv(descriptor, buffer, (int)length, flags);
#else
do {
retVal = recv(descriptor, buffer, (size_t)length, flags);
} while ((-1 == retVal) && (EINTR == errno));
#endif
Trc_SC_Recv_Exit(retVal);
return retVal;
}
jint JNICALL
JVM_RecvFrom(jint descriptor, char* buffer, jint length, jint flags, struct sockaddr* fromAddr, int* fromLength)
{
jint retVal;
Trc_SC_RecvFrom_Entry(descriptor, buffer, length, flags, fromAddr, fromLength);
#if defined (WIN32)
retVal = recvfrom(descriptor, buffer, length, flags, fromAddr, fromLength);
#else
{
socklen_t address_len = (socklen_t)*fromLength;
do {
retVal = recvfrom(descriptor, buffer, (size_t)length, flags, fromAddr, &address_len);
} while ((-1 == retVal) && (EINTR == errno));
*fromLength = (int)address_len;
}
#endif
Trc_SC_RecvFrom_Exit(retVal, *fromLength);
return retVal;
}
jint JNICALL
JVM_Send(jint descriptor, const char* buffer, jint numBytes, jint flags)
{
jint retVal;
Trc_SC_Send_Entry(descriptor, buffer, numBytes, flags);
#if defined (WIN32)
retVal = send(descriptor, buffer, numBytes, flags);
#else
do {
retVal = send(descriptor, buffer, numBytes, flags);
} while ((-1 == retVal) && (EINTR == errno));
#endif
Trc_SC_Send_Exit(retVal);
return retVal;
}
jint JNICALL JVM_SendTo(jint descriptor, const char* buffer, jint length, jint flags, const struct sockaddr* toAddr, int toLength) {
jint retVal;
Trc_SC_SendTo_Entry(descriptor, buffer, length, flags, toAddr, toLength);
#if defined (WIN32)
retVal = sendto(descriptor, buffer, length, flags, toAddr, toLength);
#else
do {
retVal = sendto(descriptor, buffer, length, flags, toAddr, toLength);
} while ((-1 == retVal) && (EINTR == errno));
#endif
Trc_SC_SendTo_Exit(retVal);
return retVal;
}
jint JNICALL
JVM_Socket(jint domain, jint type, jint protocol)
{
jint result;
Trc_SC_Socket_Entry(domain, type, protocol);
#ifdef WIN32
{
SOCKET socketResult = socket(domain, type, protocol);
SetHandleInformation((HANDLE)socketResult, HANDLE_FLAG_INHERIT, HANDLE_FLAG_INHERIT);
result = (jint)socketResult;
Assert_SC_true(socketResult == (SOCKET)result);
}
#else
result = socket(domain, type, protocol);
#endif
Trc_SC_Socket_Exit(result);
return result;
}
jint JNICALL
JVM_SocketAvailable(jint descriptor, jint* result)
{
jint retVal = 0;
Trc_SC_SocketAvailable_Entry(descriptor, result);
#ifdef WIN32
Assert_SC_unreachable();
#endif
#if defined(J9UNIX) || defined(J9ZOS390)
if (0 <= descriptor) {
do {
retVal = ioctl(descriptor, FIONREAD, result);
} while ((-1 == retVal) && (EINTR == errno));
if (0 <= retVal) {
retVal = 1;
} else {
retVal = 0;
}
}
#endif
Trc_SC_SocketAvailable_Exit(retVal, *result);
return retVal;
}
jint JNICALL
JVM_SocketClose(jint descriptor)
{
jint retVal;
Trc_SC_SocketClose_Entry(descriptor);
if (descriptor<=0) {
Trc_SC_SocketClose_bad_descriptor();
return 1;
}
#if defined(WIN32)
(void)shutdown(descriptor, SD_SEND);
(void)closesocket(descriptor);
retVal = 1;
#else
do {
retVal = close(descriptor);
} while ((-1 == retVal) && (EINTR == errno));
#endif
Trc_SC_SocketClose_Exit(retVal);
return retVal;
}
jint JNICALL
JVM_Timeout(jint descriptor, jint timeout)
{
jint result = 0;
struct timeval tval;
#ifdef WIN32
struct fd_set fdset;
#endif
#if defined(J9UNIX) || defined(J9ZOS390)
jint returnVal = 0;
jint crazyCntr = 10;
fd_set fdset;
#endif
Trc_SC_Timeout_Entry(descriptor, timeout);
tval.tv_sec = timeout / 1000;
tval.tv_usec = (timeout % 1000) * 1000;
FD_ZERO(&fdset);
FD_SET((u_int)descriptor, &fdset);
#if defined(WIN32)
result = select(0, &fdset, 0, 0, &tval);
#elif defined(J9ZTPF)
if (-1 == timeout) {
result = select(0, &fdset, 0, 0, NULL);
} else {
result = select(0, &fdset, 0, 0, &tval);
}
#elif defined(J9UNIX) || defined(J9ZOS390)
do {
crazyCntr--;
returnVal = select(descriptor+1, &fdset, 0, 0, &tval);
if (returnVal==1 && !FD_ISSET((u_int)descriptor, &fdset)) {
result = 0;
break;
}
if (!(returnVal<0 && errno==EINTR)) {
result = returnVal;
break;
}
} while (crazyCntr);
#endif
Trc_SC_Timeout_Exit(result);
return result;
}
jboolean JNICALL
JVM_SupportsCX8(void)
{
Trc_SC_SupportsCX8();
return JNI_TRUE;
}
jboolean JNICALL
JVM_CX8Field(JNIEnv* env, jobject obj, jfieldID field, jlong oldval, jlong newval)
{
jboolean result = JNI_FALSE;
Trc_SC_CX8Field_Entry(env, obj, field, oldval, newval);
exit(230);
return result;
}
void JNICALL
JVM_RegisterUnsafeMethods(JNIEnv* env, jclass unsafeClz)
{
Trc_SC_RegisterUnsafeMethods(env);
}
jint JNICALL
JVM_ActiveProcessorCount(void)
{
PORT_ACCESS_FROM_JAVAVM(BFUjavaVM);
jint num;
Trc_SC_ActiveProcessorCount_Entry();
num = (jint)j9sysinfo_get_number_CPUs_by_type(J9PORT_CPU_TARGET);
if (num < 1) {
num = 1;
}
Trc_SC_ActiveProcessorCount_Exit(num);
return num;
}
J9Class* java_lang_Class_vmRef(JNIEnv* env, jobject clazz);
jstring JNICALL
#if JAVA_SPEC_VERSION < 11
JVM_GetClassName
#else
JVM_InitClassName
#endif
(JNIEnv *env, jclass theClass)
{
J9JavaVM* vm = ((J9VMThread*)env)->javaVM;
jstring result;
Trc_SC_GetClassName_Entry(env, theClass);
#ifdef J9VM_IVE_RAW_BUILD
{
J9Class* ramClass = java_lang_Class_vmRef(env, theClass);
J9ROMClass* romClass = ramClass->romClass;
PORT_ACCESS_FROM_JAVAVM(vm);
if (J9ROMCLASS_IS_ARRAY(romClass)) {
J9ArrayClass* arrayClass = (J9ArrayClass*) ramClass;
J9ArrayClass* elementClass = (J9ArrayClass*)arrayClass->leafComponentType;
UDATA arity = arrayClass->arity;
UDATA nameLength, prefixSkip;
J9UTF8* nameUTF;
char* name;
UDATA finalLength;
if (J9ROMCLASS_IS_PRIMITIVE_TYPE(elementClass->romClass)) {
nameUTF = J9ROMCLASS_CLASSNAME(elementClass->arrayClass->romClass);
arity -= 1;
nameLength = arity;
prefixSkip = arity;
} else {
nameUTF = J9ROMCLASS_CLASSNAME(elementClass->romClass);
nameLength = arity + 2;
prefixSkip = arity + 1;
}
finalLength = nameLength + J9UTF8_LENGTH(nameUTF) + 1;
name = (char*)j9mem_allocate_memory(nameLength + J9UTF8_LENGTH(nameUTF) + 1, OMRMEM_CATEGORY_VM);
if (NULL != name) {
memset(name,'[', nameLength);
memcpy(name+nameLength, J9UTF8_DATA(nameUTF), J9UTF8_LENGTH(nameUTF));
name[J9UTF8_LENGTH(nameUTF)] = 0;
}
return NULL;
} else {
J9UTF8* nameUTF = J9ROMCLASS_CLASSNAME(ramClass->romClass);
jobject result = NULL;
char* name = (char*)j9mem_allocate_memory(J9UTF8_LENGTH(nameUTF) + 1, OMRMEM_CATEGORY_VM);
if (NULL != name) {
memcpy(name, J9UTF8_DATA(nameUTF), J9UTF8_LENGTH(nameUTF));
name[J9UTF8_LENGTH(nameUTF)] = 0;
}
result = (*env)->NewStringUTF(env, name);
j9mem_free_memory(name);
#if JAVA_SPEC_VERSION >= 11
(*env)->SetObjectField(env, theClass, classNameFID, result);
if ((*env)->ExceptionCheck(env)) {
result = NULL;
}
#endif
return result;
}
}
#endif
result = (*env)->CallObjectMethod(env, theClass, getNameMID);
if ((*env)->ExceptionCheck(env)) {
result = NULL;
}
Trc_SC_GetClassName_Exit(env, result);
return result;
}
jclass JNICALL
JVM_FindClassFromCaller(JNIEnv* env, const char* arg1, jboolean arg2, jobject arg3, jclass arg4)
{
Assert_SC_true(!"JVM_FindClassFromCaller unimplemented");
return NULL;
}
jintArray JNICALL
JVM_GetResourceLookupCache(JNIEnv *env, jobject loader, const char *resource_name) {
return NULL;
}
jobjectArray JNICALL
JVM_GetResourceLookupCacheURLs(JNIEnv *env, jobject loader) {
return NULL;
}
jboolean JVM_KnownToNotExist(JNIEnv *env, jobject loader, const char *classname) {
return JNI_FALSE;
}
#if JAVA_SPEC_VERSION < 17
jint JNICALL
JVM_GetInterfaceVersion(void)
{
jint result = 4;
Trc_SC_GetInterfaceVersion_Entry();
if (J2SE_CURRENT_VERSION >= J2SE_V11) {
result = 6;
}
Trc_SC_GetInterfaceVersion_Exit(result);
return result;
}
#endif
jint JNICALL
JVM_Sleep(JNIEnv* env, jclass thread, jlong timeout)
{
Trc_SC_Sleep_Entry(env, thread, timeout);
(*env)->CallStaticVoidMethod(env, jlThread, sleepMID, timeout);
Trc_SC_Sleep_Exit(env);
return 0;
}
jint JNICALL
JVM_UcsOpen(const jchar* filename, jint flags, jint mode)
{
#ifdef WIN32
WCHAR *prefixStr;
DWORD prefixLen ;
DWORD fullPathLen, rc;
WCHAR* longFilename;
DWORD newFlags, disposition, attributes;
HANDLE hFile;
jint returnVal;
int isUNC = FALSE;
int isDosDevices = FALSE;
if (filename==NULL) {
Trc_SC_UcsOpen_nullName();
return -1;
}
Trc_SC_UcsOpen_Entry(filename, flags, mode);
if (filename[0] == L'\\' && filename[1] == L'\\') {
if (filename[2] == L'?') {
prefixStr = L"";
prefixLen = 0;
} else if (filename[2] == L'.' && filename[3] == L'\\') {
isDosDevices = TRUE;
prefixStr = L"";
prefixLen = 0;
} else {
isUNC = TRUE;
prefixStr = L"\\\\?\\UNC";
prefixLen = (sizeof(L"\\\\?\\UNC") / sizeof(WCHAR)) - 1;
}
} else {
prefixStr = L"\\\\?\\";
prefixLen = (sizeof(L"\\\\?\\") / sizeof(WCHAR)) - 1;
}
fullPathLen = GetFullPathNameW(filename, 0, NULL, NULL);
if (filename[0] == L'\0' || filename[1] == L'\0') fullPathLen += 3;
if (isDosDevices) fullPathLen += 4;
longFilename = malloc(sizeof(WCHAR) * (prefixLen+fullPathLen));
wcscpy(longFilename, prefixStr);
if (isUNC) prefixLen--;
rc = GetFullPathNameW(filename, fullPathLen, &longFilename[prefixLen], NULL);
if (!rc || rc >= fullPathLen) {
Trc_SC_UcsOpen_GetFullPathNameW(rc);
return -1;
}
if (isUNC) longFilename[prefixLen] = L'C';
if (!flags || (flags & O_RDONLY) || (flags == O_TEMPORARY))
newFlags = GENERIC_READ;
else if (flags & O_WRONLY)
newFlags = GENERIC_WRITE;
else if (flags & O_RDWR)
newFlags = (GENERIC_READ | GENERIC_WRITE);
if (flags & O_TRUNC)
disposition = CREATE_ALWAYS;
else if (flags & O_CREAT)
disposition = OPEN_ALWAYS;
else
disposition = OPEN_EXISTING;
if (flags & (O_SYNC | O_DSYNC))
attributes = FILE_FLAG_WRITE_THROUGH;
else
attributes = FILE_ATTRIBUTE_NORMAL;
if (flags & O_TEMPORARY)
attributes |= FILE_FLAG_DELETE_ON_CLOSE;
hFile = CreateFileW(longFilename, newFlags, mode, NULL, disposition, attributes, NULL);
returnVal = _open_osfhandle((UDATA)hFile, flags);
if (returnVal<0) {
Trc_SC_UcsOpen_error(returnVal);
} else {
Trc_SC_UcsOpen_Exit(returnVal);
}
free(longFilename);
if (returnVal>=0)
return returnVal;
else if (errno==EEXIST)
return JVM_EEXIST;
else
return -1;
#else
printf("JVM_UcsOpen is only supported on Win32 platforms\n");
return -1;
#endif
}
jclass JNICALL
JVM_ConstantPoolGetClassAt(JNIEnv *env, jobject anObject, jobject constantPool, jint index)
{
Trc_SC_ConstantPoolGetClassAt(env);
exit(207);
}
jclass JNICALL
JVM_ConstantPoolGetClassAtIfLoaded(JNIEnv *env, jobject anObject, jobject constantPool, jint index)
{
Trc_SC_ConstantPoolGetClassAtIfLoaded(env);
exit(208);
}
jdouble JNICALL
JVM_ConstantPoolGetDoubleAt(JNIEnv *env, jobject anObject, jobject constantPool, jint index)
{
Trc_SC_ConstantPoolGetDoubleAt(env);
exit(217);
}
jobject JNICALL
JVM_ConstantPoolGetFieldAt(JNIEnv *env, jobject anObject, jobject constantPool, jint index)
{
Trc_SC_ConstantPoolGetFieldAt(env);
exit(211);
}
jobject JNICALL
JVM_ConstantPoolGetFieldAtIfLoaded(JNIEnv *env, jobject anObject, jobject constantPool, jint index)
{
Trc_SC_ConstantPoolGetFieldAtIfLoaded(env);
exit(212);
}
jfloat JNICALL
JVM_ConstantPoolGetFloatAt(JNIEnv *env, jobject anObject, jobject constantPool, jint index)
{
Trc_SC_ConstantPoolGetFloatAt(env);
exit(216);
}
jint JNICALL
JVM_ConstantPoolGetIntAt(JNIEnv *env, jobject anObject, jobject constantPool, jint index)
{
Trc_SC_ConstantPoolGetIntAt(env);
exit(214);
}
jlong JNICALL
JVM_ConstantPoolGetLongAt(JNIEnv *env, jobject anObject, jobject constantPool, jint index)
{
Trc_SC_ConstantPoolGetLongAt(env);
exit(215);
}
jobjectArray JNICALL
JVM_ConstantPoolGetMemberRefInfoAt(JNIEnv *env, jobject anObject, jobject constantPool, jint index)
{
Trc_SC_ConstantPoolGetMemberRefInfoAt(env);
exit(213);
}
jobject JNICALL
JVM_ConstantPoolGetMethodAt(JNIEnv *env, jobject anObject, jobject constantPool, jint index)
{
Trc_SC_ConstantPoolGetMethodAt(env);
exit(209);
}
jobject JNICALL
JVM_ConstantPoolGetMethodAtIfLoaded(JNIEnv *env, jobject anObject, jobject constantPool, jint index)
{
Trc_SC_ConstantPoolGetMethodAtIfLoaded(env);
exit(210);
}
jint JNICALL
JVM_ConstantPoolGetSize(JNIEnv *env, jobject anObject, jobject constantPool)
{
Trc_SC_ConstantPoolGetSize(env);
exit(206);
}
jstring JNICALL
JVM_ConstantPoolGetStringAt(JNIEnv *env, jobject anObject, jobject constantPool, jint index)
{
Trc_SC_ConstantPoolGetStringAt(env);
exit(218);
}
jstring JNICALL
JVM_ConstantPoolGetUTF8At(JNIEnv *env, jobject anObject, jobject constantPool, jint index)
{
Trc_SC_ConstantPoolGetUTF8At(env);
exit(219);
}
jclass JNICALL
JVM_DefineClassWithSource(JNIEnv *env, const char * className, jobject classLoader, const jbyte * classArray, jsize length, jobject domain, const char * source)
{
J9VMThread* currentThread = (J9VMThread*) env;
J9JavaVM* vm = currentThread->javaVM;
J9InternalVMFunctions *vmFuncs = vm->internalVMFunctions;
J9ClassLoader* vmLoader;
j9object_t loaderObject;
jstring classNameString = (*env)->NewStringUTF(env,className);
vmFuncs->internalEnterVMFromJNI(currentThread);
loaderObject = J9_JNI_UNWRAP_REFERENCE(classLoader);
vmLoader = J9VMJAVALANGCLASSLOADER_VMREF(currentThread, loaderObject);
if (NULL == vmLoader) {
vmLoader = vmFuncs->internalAllocateClassLoader(vm, loaderObject);
if (NULL == vmLoader) {
vmFuncs->internalExitVMToJNI(currentThread);
return NULL;
}
}
vmFuncs->internalExitVMToJNI(currentThread);
return jvmDefineClassHelper(env, classLoader, classNameString, (jbyte*)classArray, 0, length, domain, 0);
}
jobjectArray JNICALL
JVM_DumpThreads(JNIEnv *env, jclass thread, jobjectArray threadArray)
{
Trc_SC_DumpThreads(env);
exit(224);
}
jobjectArray JNICALL
JVM_GetAllThreads(JNIEnv *env, jclass aClass)
{
Trc_SC_GetAllThreads(env);
exit(223);
}
jbyteArray JNICALL
JVM_GetClassAnnotations(JNIEnv *env, jclass target)
{
Trc_SC_GetClassAnnotations(env);
exit(221);
}
jobject JNICALL
JVM_GetClassConstantPool(JNIEnv *env, jclass target)
{
Trc_SC_GetClassConstantPool(env);
exit(205);
}
jstring JNICALL
JVM_GetClassSignature(JNIEnv *env, jclass target)
{
Trc_SC_GetClassSignature(env);
exit(220);
}
jobjectArray JNICALL
JVM_GetEnclosingMethodInfo(JNIEnv *env, jclass theClass)
{
Trc_SC_GetEnclosingMethodInfo(env);
exit(204);
}
static jint JNICALL
managementVMIVersion(JNIEnv *env)
{
return JNI_VERSION_1_8;
}
typedef struct ManagementVMI {
void * unused1;
void * unused2;
jint (JNICALL *getManagementVMIVersion)(JNIEnv *env);
} ManagementVMI;
static ManagementVMI globalManagementVMI = {NULL, NULL, &managementVMIVersion};
void* JNICALL
JVM_GetManagement(jint version)
{
Trc_SC_GetManagement();
return &globalManagementVMI;
}
jlong JNICALL
JVM_NanoTime(JNIEnv *env, jclass aClass)
{
jlong ticks, freq;
PORT_ACCESS_FROM_JAVAVM(BFUjavaVM);
Trc_SC_NanoTime(env);
ticks = j9time_hires_clock();
freq = j9time_hires_frequency();
if ( freq == 1000000000L ) {
return ticks;
} else if ( freq < 1000000000L ) {
return ticks * (1000000000L / freq);
} else {
return ticks / (freq / 1000000000L);
}
}
struct J9PortLibrary*
JNICALL JVM_GetPortLibrary(void)
{
return &j9portLibrary;
}
jint JNICALL
JVM_ExpandFdTable(jint fd)
{
return 0;
}
void JNICALL
JVM_ZipHook(JNIEnv *env, const char* filename, jint newState)
{
#ifdef J9VM_OPT_ZIP_SUPPORT
VMI_ACCESS_FROM_ENV(env);
J9JavaVM *vm = (J9JavaVM*)((J9VMThread*)env)->javaVM;
J9HookInterface ** hook = (*VMI)->GetZipFunctions(VMI)->zip_getZipHookInterface(VMI);
if (hook != NULL) {
UDATA state;
switch (newState) {
case JVM_ZIP_HOOK_STATE_OPEN :
state = J9ZIP_STATE_OPEN;
break;
case JVM_ZIP_HOOK_STATE_CLOSED :
state = J9ZIP_STATE_CLOSED;
break;
case JVM_ZIP_HOOK_STATE_RESET :
state = J9ZIP_STATE_RESET;
break;
default :
state = 0;
}
if (state) {
struct J9VMZipLoadEvent eventData;
eventData.portlib = vm->portLibrary;
eventData.userData = vm;
eventData.zipfile = NULL;
eventData.newState = state;
eventData.cpPath = (U_8*)filename;
eventData.returnCode = 0;
(*hook)->J9HookDispatch(hook, J9HOOK_VM_ZIP_LOAD, &eventData);
}
}
#endif
}
void * JNICALL
JVM_RawAllocate(size_t size, const char * callsite)
{
return j9portLibrary.omrPortLibrary.mem_allocate_memory(&j9portLibrary.omrPortLibrary, (UDATA) size, (char *) ((callsite == NULL) ? J9_GET_CALLSITE() : callsite), J9MEM_CATEGORY_SUN_JCL);
}
void * JNICALL
JVM_RawRealloc(void * ptr, size_t size, const char * callsite)
{
return j9portLibrary.omrPortLibrary.mem_reallocate_memory(&j9portLibrary.omrPortLibrary, ptr, (UDATA) size, callsite, J9MEM_CATEGORY_SUN_JCL);
}
void * JNICALL
JVM_RawCalloc(size_t nmemb, size_t size, const char * callsite)
{
size_t byteSize = nmemb * size;
void * mem = JVM_RawAllocate(byteSize, callsite);
if (mem != NULL) {
memset(mem, 0, byteSize);
}
return mem;
}
void * JNICALL
JVM_RawAllocateInCategory(size_t size, const char * callsite, jint category)
{
return j9portLibrary.omrPortLibrary.mem_allocate_memory(&j9portLibrary.omrPortLibrary, (UDATA) size, (char *) ((callsite == NULL) ? J9_GET_CALLSITE() : callsite), category);
}
void * JNICALL
JVM_RawReallocInCategory(void * ptr, size_t size, const char * callsite, jint category)
{
return j9portLibrary.omrPortLibrary.mem_reallocate_memory(&j9portLibrary.omrPortLibrary, ptr, (UDATA) size, callsite, category);
}
void * JNICALL
JVM_RawCallocInCategory(size_t nmemb, size_t size, const char * callsite, jint category)
{
size_t byteSize = nmemb * size;
void * mem = JVM_RawAllocateInCategory(byteSize, callsite, category);
if (mem != NULL) {
memset(mem, 0, byteSize);
}
return mem;
}
void JNICALL
JVM_RawFree(void * ptr)
{
j9portLibrary.omrPortLibrary.mem_free_memory(&j9portLibrary.omrPortLibrary, ptr);
}
jboolean JNICALL
JVM_IsNaN(jdouble dbl)
{
Trc_SC_IsNaN(*(jlong*)&dbl);
return IS_NAN_DBL(dbl);
}
jint JNICALL
JVM_Startup(JavaVM* vm, JNIEnv* env)
{
return JNI_OK;
}
#if defined(J9ZOS390)
static BOOLEAN
setZOSThrWeight(void)
{
BOOLEAN success = FALSE;
const UDATA jvmZOSTW = checkZOSThrWeightEnvVar();
if (ZOS_THR_WEIGHT_NOT_FOUND != jvmZOSTW) {
omrthread_t thandle = NULL;
IDATA trc = 0;
#if CALL_BUNDLED_FUNCTIONS_DIRECTLY
trc = omrthread_attach_ex(&thandle, J9THREAD_ATTR_DEFAULT);
#else
trc = f_threadAttachEx(&thandle, J9THREAD_ATTR_DEFAULT);
#endif
if (0 == trc) {
UDATA * gtw = NULL;
#if CALL_BUNDLED_FUNCTIONS_DIRECTLY
gtw = omrthread_global("thread_weight");
#else
gtw = f_threadGlobal("thread_weight");
#endif
if (NULL != gtw) {
if (ZOS_THR_WEIGHT_HEAVY == jvmZOSTW) {
*gtw = (UDATA)"heavy";
} else {
*gtw = (UDATA)"medium";
}
success = TRUE;
}
#if CALL_BUNDLED_FUNCTIONS_DIRECTLY
omrthread_detach(thandle);
#else
f_threadDetach(thandle);
#endif
}
} else {
success = TRUE;
}
return success;
}
static UDATA
checkZOSThrWeightEnvVar(void)
{
UDATA retVal = ZOS_THR_WEIGHT_NOT_FOUND;
#pragma convlit(suspend)
#undef getenv
const char * const val = getenv("JAVA_THREAD_MODEL");
if (NULL != val) {
if (0 == strcmp(val, "HEAVY")) {
#pragma convlit(resume)
retVal = ZOS_THR_WEIGHT_HEAVY;
} else {
retVal = ZOS_THR_WEIGHT_MEDIUM;
}
}
return retVal;
}
#endif
void JNICALL
JVM_BeforeHalt()
{
}