src/solaris/bin/java_md_solinux.c

Print this page
rev 8822 : 8024854: PPC64: Basic changes and files to build the class library on AIX
Reviewed-by: alanb, prr, sla, chegar, michaelm, mullan, art
Contributed-by: luchsh@linux.vnet.ibm.com, spoole@linux.vnet.ibm.com, thomas.stuefe@sap.com


  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 #  ifndef LIBARCH32NAME
  63 #    error "The macro LIBARCH32NAME was not defined on the compile line"
  64 #  endif


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





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


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




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



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



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


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




  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 #  ifndef LIBARCH32NAME
  67 #    error "The macro LIBARCH32NAME was not defined on the compile line"
  68 #  endif


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


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


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