Path: blob/master/runtime/exelib/common/libargs.c
6000 views
/*******************************************************************************1* Copyright (c) 1991, 2020 IBM Corp. and others2*3* This program and the accompanying materials are made available under4* the terms of the Eclipse Public License 2.0 which accompanies this5* distribution and is available at https://www.eclipse.org/legal/epl-2.0/6* or the Apache License, Version 2.0 which accompanies this distribution and7* is available at https://www.apache.org/licenses/LICENSE-2.0.8*9* This Source Code may also be made available under the following10* Secondary Licenses when the conditions for such availability set11* forth in the Eclipse Public License, v. 2.0 are satisfied: GNU12* General Public License, version 2 with the GNU Classpath13* Exception [1] and GNU General Public License, version 2 with the14* OpenJDK Assembly Exception [2].15*16* [1] https://www.gnu.org/software/classpath/license.html17* [2] http://openjdk.java.net/legal/assembly-exception.html18*19* SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 OR GPL-2.0 WITH Classpath-exception-2.0 OR LicenseRef-GPL-2.0 WITH Assembly-exception20*******************************************************************************/2122/*------------------------------------------------------------------23* libargs. : handle VM init args24*------------------------------------------------------------------*/2526#include <stdio.h>27#include <stdlib.h>28#include <string.h>29#include <jni.h>30#include "j9.h"31#include "j9port.h"32#include "j9lib.h"33#include "j9exelibnls.h"34#include "exelib_internal.h"35#include "util_api.h"3637/*------------------------------------------------------------------38*39*------------------------------------------------------------------*/40#if defined(LOGGING)41#define LOG(x) printf x42#else43#define LOG(x)44#endif45/*------------------------------------------------------------------46*47*------------------------------------------------------------------*/4849typedef struct J9LinkedString {50struct J9LinkedString *next;51char data[1];52} J9LinkedString;5354typedef struct {55I_32 size;56I_32 count;57JavaVMOption *vmOptions;58J9PortLibrary *portLib;59J9LinkedString *strings;60} J9VMOptionsTable;6162#define J9CMD_EXACT_MATCH 063#define J9CMD_PARTIAL_MATCH 164typedef struct J9CmdLineAction {65char *cmdLineName;66UDATA partialMatch;67char *internalName;68I_32 (*actionFunction)(J9PortLibrary *portLib, int *argc, char *argv[], void **vmOptionsTable, struct J9CmdLineAction *);69} J9CmdLineAction;7071I_32 vmOptionsTableAddExeName(void **vmOptionsTable, char *argv0);72int vmOptionsTableGetCount(void **vmOptionsTable);73I_32 vmOptionsTableInit(J9PortLibrary *portLib, void **vmOptionsTable, int initialCount);74I_32 vmOptionsTableAddOptionWithCopy(void **vmOptionsTable, char *optionString, void *extraInfo);75I_32 vmOptionsTableAddOption(void **vmOptionsTable, char *optionString, void *extraInfo);76JavaVMOption *vmOptionsTableGetOptions(void **vmOptionsTable);77void vmOptionsTableDestroy(void **vmOptionsTable);7879static char *allocString(J9VMOptionsTable *table, UDATA size);80static I_32 cmdline_get_jcl(J9PortLibrary *portLib, int *argc, char *argv[], void **vmOptionsTable, J9CmdLineAction *action);81static I_32 copyTable(J9PortLibrary *portLib, J9VMOptionsTable *table, J9VMOptionsTable *oldTable);82static I_32 buildNewTable(J9PortLibrary *portLib, int initialCount, J9VMOptionsTable *oldTable, J9VMOptionsTable **newTable);8384#define NO_DEFAULT_VALUE 085#define PRIVATE_OPTION NULL8687/*------------------------------------------------------------------88*89*------------------------------------------------------------------*/9091#if defined(J9VM_INTERP_VERBOSE)92static char *verboseOptions[] = {93"\n -verbose[:{class",94"|gcterse",95"|gc",96#ifdef J9VM_OPT_DYNAMIC_LOAD_SUPPORT97"|dynload",98#endif99"|sizes",100"|stack|debug}]\n"101};102#endif /* J9VM_INTERP_VERBOSE */103104/*------------------------------------------------------------------105* create a new table with specified size106*------------------------------------------------------------------*/107I_32108vmOptionsTableInit(J9PortLibrary *portLib, void **vmOptionsTable, int initialCount)109{110return buildNewTable(portLib, initialCount, NULL, (J9VMOptionsTable **)vmOptionsTable);111}112113/*------------------------------------------------------------------114* destroy the table115*------------------------------------------------------------------*/116void117vmOptionsTableDestroy(void **vmOptionsTable)118{119J9VMOptionsTable *table = *vmOptionsTable;120J9PortLibrary *portLib = table->portLib;121J9LinkedString *this = table->strings;122PORT_ACCESS_FROM_PORT(portLib);123124/* free the linked list of strings */125while (NULL != this) {126J9LinkedString *next = this->next;127j9mem_free_memory(this);128this = next;129}130131j9mem_free_memory(table);132}133134/*------------------------------------------------------------------135* get the number of options in the table136*------------------------------------------------------------------*/137int138vmOptionsTableGetCount(void **vmOptionsTable)139{140J9VMOptionsTable *table = *vmOptionsTable;141142return table->count;143}144145/*------------------------------------------------------------------146*147*------------------------------------------------------------------*/148JavaVMOption *149vmOptionsTableGetOptions(void **vmOptionsTable)150{151J9VMOptionsTable *table = *vmOptionsTable;152153return table->vmOptions;154}155156/*------------------------------------------------------------------157*158*------------------------------------------------------------------*/159I_32160vmOptionsTableAddOption(void **vmOptionsTable, char *optionString, void *extraInfo)161{162J9VMOptionsTable *table = *vmOptionsTable;163J9VMOptionsTable *newTable = NULL;164165if (table->count == table->size) {166I_32 returnCode = buildNewTable(table->portLib, table->size * 2, table, &newTable);167if (J9CMDLINE_OK != returnCode) {168return returnCode;169}170171vmOptionsTableDestroy(vmOptionsTable);172table = newTable;173*vmOptionsTable = table;174}175176table->vmOptions[table->count].optionString = optionString;177table->vmOptions[table->count].extraInfo = extraInfo;178179table->count++;180return J9CMDLINE_OK;181}182183/*------------------------------------------------------------------184*185*------------------------------------------------------------------*/186I_32187vmOptionsTableAddExeName(void **vmOptionsTable, char *argv0)188{189J9VMOptionsTable *table = *vmOptionsTable;190PORT_ACCESS_FROM_PORT(table->portLib);191char *value = NULL;192char *define = NULL;193#define EXE_PROPERTY "-Dcom.ibm.oti.vm.exe="194195if (j9sysinfo_get_executable_name(argv0, &value)) {196return J9CMDLINE_GENERIC_ERROR;197}198199define = allocString(*vmOptionsTable, sizeof(EXE_PROPERTY) + strlen(value)); /* sizeof() includes room for the terminating \0 */200if (NULL == define) {201j9mem_free_memory(value);202return J9CMDLINE_OUT_OF_MEMORY;203}204205strcpy(define, EXE_PROPERTY);206strcat(define, value);207/* Do /not/ delete executable name string; system-owned. */208return vmOptionsTableAddOption(vmOptionsTable, define, NULL);209}210211static char *212allocString(J9VMOptionsTable *table, UDATA size)213{214PORT_ACCESS_FROM_PORT(table->portLib);215J9LinkedString *node = j9mem_allocate_memory(size + sizeof(J9LinkedString *), OMRMEM_CATEGORY_VM);216217if (NULL == node) {218return NULL;219}220221node->next = table->strings;222table->strings = node;223224return node->data;225}226227/*------------------------------------------------------------------228* create a new table, copying from old if valid229*------------------------------------------------------------------*/230static I_32231buildNewTable(J9PortLibrary *portLib, int initialCount, J9VMOptionsTable *oldTable, J9VMOptionsTable **newTable)232{233J9VMOptionsTable *table = NULL;234int mallocSize = sizeof(J9VMOptionsTable) + (sizeof(JavaVMOption) * initialCount);235I_32 returnCode = 0;236237PORT_ACCESS_FROM_PORT(portLib);238239LOG(("buildNewTable(%d,%p)\n", initialCount, oldTable));240LOG(("buildNewtable(): malloc size = %d\n", mallocSize));241242table = j9mem_allocate_memory(mallocSize, OMRMEM_CATEGORY_VM);243if (NULL == table) {244return J9CMDLINE_OUT_OF_MEMORY;245}246*newTable = table;247248table->size = initialCount;249table->count = 0;250table->portLib = portLib;251table->vmOptions = (JavaVMOption *) (((char *) table) + sizeof(J9VMOptionsTable));252table->strings = NULL;253254LOG(("buildNewtable(): table: %#010X\n",table));255LOG(("buildNewtable(): options: %#010X\n",table->vmOptions));256257if (NULL == oldTable) {258return J9CMDLINE_OK;259}260261LOG(("buildNewtable(): copying table\n"));262returnCode = copyTable(table->portLib, table, oldTable);263if (J9CMDLINE_OK != returnCode) {264return returnCode;265}266267LOG(("buildNewtable(): table->size = %d\n",table->size));268return J9CMDLINE_OK;269}270271/*------------------------------------------------------------------272* create a new table, copying from old if valid273*------------------------------------------------------------------*/274static I_32275copyTable(J9PortLibrary *portLib, J9VMOptionsTable *table, J9VMOptionsTable *oldTable)276{277int i = 0;278279LOG(("copyTable(%p, %p, %d)\n", table, oldTable, copyCount));280281table->strings = oldTable->strings;282oldTable->strings = NULL;283table->count = oldTable->count;284285for (i = 0; i < oldTable->count; i++) {286table->vmOptions[i].optionString = oldTable->vmOptions[i].optionString;287table->vmOptions[i].extraInfo = oldTable->vmOptions[i].extraInfo;288}289290LOG(("copyTable(): table->count = %d\n",table->count));291292return J9CMDLINE_OK;293}294295/*------------------------------------------------------------------296*297*------------------------------------------------------------------*/298I_32299vmOptionsTableAddOptionWithCopy(void **vmOptionsTable, char *optionString, void *extraInfo)300{301char *copyOptionString = allocString(*vmOptionsTable, strlen(optionString) + 1);302303if (NULL == copyOptionString) {304return J9CMDLINE_OUT_OF_MEMORY;305}306strcpy(copyOptionString, optionString);307return vmOptionsTableAddOption(vmOptionsTable, copyOptionString, extraInfo);308}309310#if defined(WIN32)311/* On Windows, the subdirectory containing the redirector hasn't changed with Java versions. */312#define J9JAVA_REDIRECTOR_SUBDIR "\\bin\\j9vm\\"313#elif (JAVA_SPEC_VERSION >= 10) || ((JAVA_SPEC_VERSION == 9) && defined(OPENJ9_BUILD)) || defined(OSX)314/* On other platforms, the subdirectory containing the redirector is common in recent Java versions. */315#define J9JAVA_REDIRECTOR_SUBDIR "/lib/j9vm/"316#else /* WIN32 */317/* In Java 8 and early versions of Java 9, the path depends on the platform architecture. */318#if defined(J9HAMMER)319#define JVM_ARCH_DIR "amd64"320#elif defined(J9ARM)321#define JVM_ARCH_DIR "arm"322#elif defined(J9AARCH64)323#define JVM_ARCH_DIR "aarch64"324#elif defined(J9X86)325#define JVM_ARCH_DIR "i386"326#elif defined(S39064) || defined(J9ZOS39064)327#define JVM_ARCH_DIR "s390x"328#elif defined(S390) || defined(J9ZOS390)329#define JVM_ARCH_DIR "s390"330#elif defined(RS6000) || defined(LINUXPPC)331#if !defined(PPC64)332#define JVM_ARCH_DIR "ppc"333#elif defined(J9VM_ENV_LITTLE_ENDIAN)334#define JVM_ARCH_DIR "ppc64le"335#else /* J9VM_ENV_LITTLE_ENDIAN */336#define JVM_ARCH_DIR "ppc64"337#endif /* PPC64 */338#elif defined(RISCV64)339#define JVM_ARCH_DIR "riscv64"340#else341#error "Must define an architecture"342#endif343#define J9JAVA_REDIRECTOR_SUBDIR "/lib/" JVM_ARCH_DIR "/j9vm/"344#endif /* WIN32 */345346#define JAVAHOMEDIR "-Djava.home="347#define JAVAHOMEDIR_LEN (sizeof(JAVAHOMEDIR) - 1)348349/**350* This function scans for -Djava.home=xxx/jre. If found, it uses it to construct a path351* to redirector jvm.dll and put it in the passed in char buffer:352* --> [java.home]/bin/j9vm/353* This function is meant to be used by thrstatetest and shrtest so the test can be invoked354* in a sdk shape independent way.355*/356BOOLEAN357cmdline_fetchRedirectorDllDir(struct j9cmdlineOptions *args, char *result)358{359char *tmpresult = NULL;360struct j9cmdlineOptions *arg = args;361int argc = arg->argc;362char **argv = arg->argv;363int i = 0;364365/* Find the last -Djava.home= in the args */366for (i = 0; i < argc; i++) {367char *javaHomeDir = strstr(argv[i], JAVAHOMEDIR);368if (NULL != javaHomeDir) {369tmpresult = javaHomeDir + JAVAHOMEDIR_LEN;370}371}372373if (NULL == tmpresult) {374printf("ERROR: -Djava.home was not specified on command line.\n");375return FALSE;376}377378strcpy(result, tmpresult);379strcat(result, J9JAVA_REDIRECTOR_SUBDIR);380381return TRUE;382}383384385