src/solaris/bin/java_md_solinux.c

Print this page
rev 7983 : 8024854: Basic changes and files to build the class library on AIX
Contributed-by: luchsh@linux.vnet.ibm.com, spoole@linux.vnet.ibm.com, thomas.stuefe@sap.com
Reviewed-by:
   1 /*
   2  * Copyright (c) 1998, 2012, Oracle and/or its affiliates. All rights reserved.
   3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   4  *
   5  * This code is free software; you can redistribute it and/or modify it
   6  * under the terms of the GNU General Public License version 2 only, as
   7  * published by the Free Software Foundation.  Oracle designates this
   8  * particular file as subject to the "Classpath" exception as provided
   9  * by Oracle in the LICENSE file that accompanied this code.
  10  *
  11  * This code is distributed in the hope that it will be useful, but WITHOUT
  12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  14  * version 2 for more details (a copy is included in the LICENSE file that
  15  * accompanied this code).
  16  *
  17  * You should have received a copy of the GNU General Public License version
  18  * 2 along with this work; if not, write to the Free Software Foundation,
  19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  20  *
  21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  22  * or visit www.oracle.com if you need additional information or have any


  24  */
  25 
  26 #include "java.h"
  27 #include "jvm_md.h"
  28 #include <dirent.h>
  29 #include <dlfcn.h>
  30 #include <fcntl.h>
  31 #include <inttypes.h>
  32 #include <stdio.h>
  33 #include <string.h>
  34 #include <stdlib.h>
  35 #include <sys/stat.h>
  36 #include <unistd.h>
  37 #include <sys/types.h>
  38 #include "manifest_info.h"
  39 #include "version_comp.h"
  40 
  41 
  42 #define JVM_DLL "libjvm.so"
  43 #define JAVA_DLL "libjava.so"



  44 #define LD_LIBRARY_PATH "LD_LIBRARY_PATH"

  45 
  46 /* help jettison the LD_LIBRARY_PATH settings in the future */
  47 #ifndef SETENV_REQUIRED
  48 #define SETENV_REQUIRED
  49 #endif
  50 /*
  51  * If a processor / os combination has the ability to run binaries of
  52  * two data models and cohabitation of jre/jdk bits with both data
  53  * models is supported, then DUAL_MODE is defined.  When DUAL_MODE is
  54  * defined, the architecture names for the narrow and wide version of
  55  * the architecture are defined in LIBARCH64NAME and LIBARCH32NAME.
  56  * Currently  only Solaris on sparc/sparcv9 and i586/amd64 is DUAL_MODE;
  57  * linux i586/amd64 could be defined as DUAL_MODE but that is not the
  58  * current policy.
  59  */
  60 
  61 #ifdef __solaris__
  62 #  define DUAL_MODE
  63 #  ifndef LIBARCH32NAME
  64 #    error "The macro LIBARCH32NAME was not defined on the compile line"


 271             if (JvmExists(path)) {
 272                 JLI_MemFree(envpath);
 273                 return JNI_TRUE;
 274             }
 275         }
 276     }
 277     JLI_MemFree(envpath);
 278     return JNI_FALSE;
 279 }
 280 
 281 /*
 282  * Test whether the environment variable needs to be set, see flowchart.
 283  */
 284 static jboolean
 285 RequiresSetenv(int wanted, const char *jvmpath) {
 286     char jpath[PATH_MAX + 1];
 287     char *llp;
 288     char *dmllp = NULL;
 289     char *p; /* a utility pointer */
 290 





 291     llp = getenv("LD_LIBRARY_PATH");
 292 #ifdef __solaris__
 293     dmllp = (CURRENT_DATA_MODEL == 32)
 294             ? getenv("LD_LIBRARY_PATH_32")
 295             : getenv("LD_LIBRARY_PATH_64");
 296 #endif /* __solaris__ */
 297     /* no environment variable is a good environment variable */
 298     if (llp == NULL && dmllp == NULL) {
 299         return JNI_FALSE;
 300     }
 301 #ifdef __linux
 302     /*
 303      * On linux, if a binary is running as sgid or suid, glibc sets
 304      * LD_LIBRARY_PATH to the empty string for security purposes. (In contrast,
 305      * on Solaris the LD_LIBRARY_PATH variable for a privileged binary does not
 306      * lose its settings; but the dynamic linker does apply more scrutiny to the
 307      * path.) The launcher uses the value of LD_LIBRARY_PATH to prevent an exec
 308      * loop, here and further downstream. Therefore, if we are running sgid or
 309      * suid, this function's setting of LD_LIBRARY_PATH will be ineffective and
 310      * we should case a return from the calling function.  Getting the right


 582                 default:
 583                     JLI_ReportErrorMessage(JRE_ERROR3, __LINE__);
 584                     exit(1); /* unknown value in wanted */
 585                     break;
 586             }
 587 
 588             /*
 589              * If dmpath is NULL, the relevant data model specific variable is
 590              * not set and normal LD_LIBRARY_PATH should be used.
 591              */
 592             if (dmpath == NULL) {
 593                 runpath = getenv("LD_LIBRARY_PATH");
 594             } else {
 595                 runpath = dmpath;
 596             }
 597 #else /* ! __solaris__ */
 598             /*
 599              * If not on Solaris, assume only a single LD_LIBRARY_PATH
 600              * variable.
 601              */
 602             runpath = getenv("LD_LIBRARY_PATH");
 603 #endif /* __solaris__ */
 604 
 605             /* runpath contains current effective LD_LIBRARY_PATH setting */
 606 
 607             jvmpath = JLI_StringDup(jvmpath);
 608             new_runpath = JLI_MemAlloc(((runpath != NULL) ? JLI_StrLen(runpath) : 0) +
 609                     2 * JLI_StrLen(jrepath) + 2 * JLI_StrLen(arch) +




 610                     JLI_StrLen(jvmpath) + 52);
 611             newpath = new_runpath + JLI_StrLen("LD_LIBRARY_PATH=");
 612 
 613 
 614             /*
 615              * Create desired LD_LIBRARY_PATH value for target data model.
 616              */
 617             {
 618                 /* remove the name of the .so from the JVM path */
 619                 lastslash = JLI_StrRChr(jvmpath, '/');
 620                 if (lastslash)
 621                     *lastslash = '\0';
 622 
 623                 sprintf(new_runpath, "LD_LIBRARY_PATH="
 624                         "%s:"
 625                         "%s/lib/%s:"



 626                         "%s/../lib/%s",
 627                         jvmpath,
 628 #ifdef DUAL_MODE
 629                         jrepath, GetArchPath(wanted),
 630                         jrepath, GetArchPath(wanted)
 631 #else /* !DUAL_MODE */
 632                         jrepath, arch,



 633                         jrepath, arch
 634 #endif /* DUAL_MODE */
 635                         );
 636 
 637 
 638                 /*
 639                  * Check to make sure that the prefix of the current path is the
 640                  * desired environment variable setting, though the RequiresSetenv
 641                  * checks if the desired runpath exists, this logic does a more
 642                  * comprehensive check.
 643                  */
 644                 if (runpath != NULL &&
 645                         JLI_StrNCmp(newpath, runpath, JLI_StrLen(newpath)) == 0 &&
 646                         (runpath[JLI_StrLen(newpath)] == 0 || runpath[JLI_StrLen(newpath)] == ':') &&
 647                         (running == wanted) /* data model does not have to be changed */
 648 #ifdef __solaris__
 649                         && (dmpath == NULL) /* data model specific variables not set  */
 650 #endif /* __solaris__ */
 651                         ) {
 652                     JLI_MemFree(newargv);


 966         void* sym = dlsym(hSplashLib, name);
 967         return sym;
 968     } else {
 969         return NULL;
 970     }
 971 }
 972 
 973 void SplashFreeLibrary() {
 974     if (hSplashLib) {
 975         dlclose(hSplashLib);
 976         hSplashLib = NULL;
 977     }
 978 }
 979 
 980 /*
 981  * Block current thread and continue execution in a new thread
 982  */
 983 int
 984 ContinueInNewThread0(int (JNICALL *continuation)(void *), jlong stack_size, void * args) {
 985     int rslt;
 986 #ifdef __linux__
 987     pthread_t tid;
 988     pthread_attr_t attr;
 989     pthread_attr_init(&attr);
 990     pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE);
 991 
 992     if (stack_size > 0) {
 993       pthread_attr_setstacksize(&attr, stack_size);
 994     }
 995 
 996     if (pthread_create(&tid, &attr, (void *(*)(void*))continuation, (void*)args) == 0) {
 997       void * tmp;
 998       pthread_join(tid, &tmp);
 999       rslt = (int)tmp;
1000     } else {
1001      /*
1002       * Continue execution in current thread if for some reason (e.g. out of
1003       * memory/LWP)  a new thread can't be created. This will likely fail
1004       * later in continuation as JNI_CreateJavaVM needs to create quite a
1005       * few new threads, anyway, just give it a try..
1006       */
1007       rslt = continuation(args);
1008     }
1009 
1010     pthread_attr_destroy(&attr);
1011 #else /* ! __linux__ */
1012     thread_t tid;
1013     long flags = 0;
1014     if (thr_create(NULL, stack_size, (void *(*)(void *))continuation, args, flags, &tid) == 0) {
1015       void * tmp;
1016       thr_join(tid, NULL, &tmp);
1017       rslt = (int)tmp;
1018     } else {
1019       /* See above. Continue in current thread if thr_create() failed */
1020       rslt = continuation(args);
1021     }
1022 #endif /* __linux__ */
1023     return rslt;
1024 }
1025 
1026 /* Coarse estimation of number of digits assuming the worst case is a 64-bit pid. */
1027 #define MAX_PID_STR_SZ   20
1028 
1029 void SetJavaLauncherPlatformProps() {
1030    /* Linux only */
1031 #ifdef __linux__
1032     const char *substr = "-Dsun.java.launcher.pid=";
1033     char *pid_prop_str = (char *)JLI_MemAlloc(JLI_StrLen(substr) + MAX_PID_STR_SZ + 1);
1034     sprintf(pid_prop_str, "%s%d", substr, getpid());
1035     AddOption(pid_prop_str, NULL);
1036 #endif /* __linux__ */
1037 }
1038 
1039 int
1040 JVMInit(InvocationFunctions* ifn, jlong threadStackSize,
1041         int argc, char **argv,
1042         int mode, char *what, int ret)


   1 /*
   2  * Copyright (c) 1998, 2013, Oracle and/or its affiliates. All rights reserved.
   3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   4  *
   5  * This code is free software; you can redistribute it and/or modify it
   6  * under the terms of the GNU General Public License version 2 only, as
   7  * published by the Free Software Foundation.  Oracle designates this
   8  * particular file as subject to the "Classpath" exception as provided
   9  * by Oracle in the LICENSE file that accompanied this code.
  10  *
  11  * This code is distributed in the hope that it will be useful, but WITHOUT
  12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  14  * version 2 for more details (a copy is included in the LICENSE file that
  15  * accompanied this code).
  16  *
  17  * You should have received a copy of the GNU General Public License version
  18  * 2 along with this work; if not, write to the Free Software Foundation,
  19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  20  *
  21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  22  * or visit www.oracle.com if you need additional information or have any


  24  */
  25 
  26 #include "java.h"
  27 #include "jvm_md.h"
  28 #include <dirent.h>
  29 #include <dlfcn.h>
  30 #include <fcntl.h>
  31 #include <inttypes.h>
  32 #include <stdio.h>
  33 #include <string.h>
  34 #include <stdlib.h>
  35 #include <sys/stat.h>
  36 #include <unistd.h>
  37 #include <sys/types.h>
  38 #include "manifest_info.h"
  39 #include "version_comp.h"
  40 
  41 
  42 #define JVM_DLL "libjvm.so"
  43 #define JAVA_DLL "libjava.so"
  44 #ifdef AIX
  45 #define LD_LIBRARY_PATH "LIBPATH"
  46 #else
  47 #define LD_LIBRARY_PATH "LD_LIBRARY_PATH"
  48 #endif
  49 
  50 /* help jettison the LD_LIBRARY_PATH settings in the future */
  51 #ifndef SETENV_REQUIRED
  52 #define SETENV_REQUIRED
  53 #endif
  54 /*
  55  * If a processor / os combination has the ability to run binaries of
  56  * two data models and cohabitation of jre/jdk bits with both data
  57  * models is supported, then DUAL_MODE is defined.  When DUAL_MODE is
  58  * defined, the architecture names for the narrow and wide version of
  59  * the architecture are defined in LIBARCH64NAME and LIBARCH32NAME.
  60  * Currently  only Solaris on sparc/sparcv9 and i586/amd64 is DUAL_MODE;
  61  * linux i586/amd64 could be defined as DUAL_MODE but that is not the
  62  * current policy.
  63  */
  64 
  65 #ifdef __solaris__
  66 #  define DUAL_MODE
  67 #  ifndef LIBARCH32NAME
  68 #    error "The macro LIBARCH32NAME was not defined on the compile line"


 275             if (JvmExists(path)) {
 276                 JLI_MemFree(envpath);
 277                 return JNI_TRUE;
 278             }
 279         }
 280     }
 281     JLI_MemFree(envpath);
 282     return JNI_FALSE;
 283 }
 284 
 285 /*
 286  * Test whether the environment variable needs to be set, see flowchart.
 287  */
 288 static jboolean
 289 RequiresSetenv(int wanted, const char *jvmpath) {
 290     char jpath[PATH_MAX + 1];
 291     char *llp;
 292     char *dmllp = NULL;
 293     char *p; /* a utility pointer */
 294 
 295 #ifdef AIX
 296     /* We always have to set the LIBPATH on AIX because ld doesn't support $ORIGIN. */
 297     return JNI_TRUE;
 298 #endif
 299 
 300     llp = getenv("LD_LIBRARY_PATH");
 301 #ifdef __solaris__
 302     dmllp = (CURRENT_DATA_MODEL == 32)
 303             ? getenv("LD_LIBRARY_PATH_32")
 304             : getenv("LD_LIBRARY_PATH_64");
 305 #endif /* __solaris__ */
 306     /* no environment variable is a good environment variable */
 307     if (llp == NULL && dmllp == NULL) {
 308         return JNI_FALSE;
 309     }
 310 #ifdef __linux
 311     /*
 312      * On linux, if a binary is running as sgid or suid, glibc sets
 313      * LD_LIBRARY_PATH to the empty string for security purposes. (In contrast,
 314      * on Solaris the LD_LIBRARY_PATH variable for a privileged binary does not
 315      * lose its settings; but the dynamic linker does apply more scrutiny to the
 316      * path.) The launcher uses the value of LD_LIBRARY_PATH to prevent an exec
 317      * loop, here and further downstream. Therefore, if we are running sgid or
 318      * suid, this function's setting of LD_LIBRARY_PATH will be ineffective and
 319      * we should case a return from the calling function.  Getting the right


 591                 default:
 592                     JLI_ReportErrorMessage(JRE_ERROR3, __LINE__);
 593                     exit(1); /* unknown value in wanted */
 594                     break;
 595             }
 596 
 597             /*
 598              * If dmpath is NULL, the relevant data model specific variable is
 599              * not set and normal LD_LIBRARY_PATH should be used.
 600              */
 601             if (dmpath == NULL) {
 602                 runpath = getenv("LD_LIBRARY_PATH");
 603             } else {
 604                 runpath = dmpath;
 605             }
 606 #else /* ! __solaris__ */
 607             /*
 608              * If not on Solaris, assume only a single LD_LIBRARY_PATH
 609              * variable.
 610              */
 611             runpath = getenv(LD_LIBRARY_PATH);
 612 #endif /* __solaris__ */
 613 
 614             /* runpath contains current effective LD_LIBRARY_PATH setting */
 615 
 616             jvmpath = JLI_StringDup(jvmpath);
 617             new_runpath = JLI_MemAlloc(((runpath != NULL) ? JLI_StrLen(runpath) : 0) +
 618                     2 * JLI_StrLen(jrepath) + 2 * JLI_StrLen(arch) +
 619 #ifdef AIX
 620                     /* On AIX we additionally need 'jli' in the path because ld doesn't support $ORIGIN. */
 621                     JLI_StrLen(jrepath) + JLI_StrLen(arch) + JLI_StrLen("/lib//jli:") +
 622 #endif
 623                     JLI_StrLen(jvmpath) + 52);
 624             newpath = new_runpath + JLI_StrLen(LD_LIBRARY_PATH "=");
 625 
 626 
 627             /*
 628              * Create desired LD_LIBRARY_PATH value for target data model.
 629              */
 630             {
 631                 /* remove the name of the .so from the JVM path */
 632                 lastslash = JLI_StrRChr(jvmpath, '/');
 633                 if (lastslash)
 634                     *lastslash = '\0';
 635 
 636                 sprintf(new_runpath, LD_LIBRARY_PATH "="
 637                         "%s:"
 638                         "%s/lib/%s:"
 639 #ifdef AIX
 640                         "%s/lib/%s/jli:" /* Needed on AIX because ld doesn't support $ORIGIN. */
 641 #endif
 642                         "%s/../lib/%s",
 643                         jvmpath,
 644 #ifdef DUAL_MODE
 645                         jrepath, GetArchPath(wanted),
 646                         jrepath, GetArchPath(wanted)
 647 #else /* !DUAL_MODE */
 648                         jrepath, arch,
 649 #ifdef AIX
 650                         jrepath, arch,
 651 #endif
 652                         jrepath, arch
 653 #endif /* DUAL_MODE */
 654                         );
 655 
 656 
 657                 /*
 658                  * Check to make sure that the prefix of the current path is the
 659                  * desired environment variable setting, though the RequiresSetenv
 660                  * checks if the desired runpath exists, this logic does a more
 661                  * comprehensive check.
 662                  */
 663                 if (runpath != NULL &&
 664                         JLI_StrNCmp(newpath, runpath, JLI_StrLen(newpath)) == 0 &&
 665                         (runpath[JLI_StrLen(newpath)] == 0 || runpath[JLI_StrLen(newpath)] == ':') &&
 666                         (running == wanted) /* data model does not have to be changed */
 667 #ifdef __solaris__
 668                         && (dmpath == NULL) /* data model specific variables not set  */
 669 #endif /* __solaris__ */
 670                         ) {
 671                     JLI_MemFree(newargv);


 985         void* sym = dlsym(hSplashLib, name);
 986         return sym;
 987     } else {
 988         return NULL;
 989     }
 990 }
 991 
 992 void SplashFreeLibrary() {
 993     if (hSplashLib) {
 994         dlclose(hSplashLib);
 995         hSplashLib = NULL;
 996     }
 997 }
 998 
 999 /*
1000  * Block current thread and continue execution in a new thread
1001  */
1002 int
1003 ContinueInNewThread0(int (JNICALL *continuation)(void *), jlong stack_size, void * args) {
1004     int rslt;
1005 #ifndef __solaris__
1006     pthread_t tid;
1007     pthread_attr_t attr;
1008     pthread_attr_init(&attr);
1009     pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE);
1010 
1011     if (stack_size > 0) {
1012       pthread_attr_setstacksize(&attr, stack_size);
1013     }
1014 
1015     if (pthread_create(&tid, &attr, (void *(*)(void*))continuation, (void*)args) == 0) {
1016       void * tmp;
1017       pthread_join(tid, &tmp);
1018       rslt = (int)tmp;
1019     } else {
1020      /*
1021       * Continue execution in current thread if for some reason (e.g. out of
1022       * memory/LWP)  a new thread can't be created. This will likely fail
1023       * later in continuation as JNI_CreateJavaVM needs to create quite a
1024       * few new threads, anyway, just give it a try..
1025       */
1026       rslt = continuation(args);
1027     }
1028 
1029     pthread_attr_destroy(&attr);
1030 #else /* SOLARIS */
1031     thread_t tid;
1032     long flags = 0;
1033     if (thr_create(NULL, stack_size, (void *(*)(void *))continuation, args, flags, &tid) == 0) {
1034       void * tmp;
1035       thr_join(tid, NULL, &tmp);
1036       rslt = (int)tmp;
1037     } else {
1038       /* See above. Continue in current thread if thr_create() failed */
1039       rslt = continuation(args);
1040     }
1041 #endif /* !SOLARIS */
1042     return rslt;
1043 }
1044 
1045 /* Coarse estimation of number of digits assuming the worst case is a 64-bit pid. */
1046 #define MAX_PID_STR_SZ   20
1047 
1048 void SetJavaLauncherPlatformProps() {
1049    /* Linux only */
1050 #ifdef __linux__
1051     const char *substr = "-Dsun.java.launcher.pid=";
1052     char *pid_prop_str = (char *)JLI_MemAlloc(JLI_StrLen(substr) + MAX_PID_STR_SZ + 1);
1053     sprintf(pid_prop_str, "%s%d", substr, getpid());
1054     AddOption(pid_prop_str, NULL);
1055 #endif /* __linux__ */
1056 }
1057 
1058 int
1059 JVMInit(InvocationFunctions* ifn, jlong threadStackSize,
1060         int argc, char **argv,
1061         int mode, char *what, int ret)