< prev index next >

src/hotspot/os/aix/os_aix.cpp

Print this page

  96 #include <stdint.h>
  97 #include <stdio.h>
  98 #include <string.h>
  99 #include <unistd.h>
 100 #include <sys/ioctl.h>
 101 #include <sys/ipc.h>
 102 #include <sys/mman.h>
 103 #include <sys/resource.h>
 104 #include <sys/select.h>
 105 #include <sys/shm.h>
 106 #include <sys/socket.h>
 107 #include <sys/stat.h>
 108 #include <sys/sysinfo.h>
 109 #include <sys/systemcfg.h>
 110 #include <sys/time.h>
 111 #include <sys/times.h>
 112 #include <sys/types.h>
 113 #include <sys/utsname.h>
 114 #include <sys/vminfo.h>
 115 




 116 // Missing prototypes for various system APIs.
 117 extern "C"
 118 int mread_real_time(timebasestruct_t *t, size_t size_of_timebasestruct_t);
 119 
 120 #if !defined(_AIXVERSION_610)
 121 extern "C" int getthrds64(pid_t, struct thrdentry64*, int, tid64_t*, int);
 122 extern "C" int getprocs64(procentry64*, int, fdsinfo*, int, pid_t*, int);
 123 extern "C" int getargs(procsinfo*, int, char*, int);
 124 #endif
 125 
 126 #define MAX_PATH (2 * K)
 127 
 128 // for timer info max values which include all bits
 129 #define ALL_64_BITS CONST64(0xFFFFFFFFFFFFFFFF)
 130 // for multipage initialization error analysis (in 'g_multipage_error')
 131 #define ERROR_MP_OS_TOO_OLD                          100
 132 #define ERROR_MP_EXTSHM_ACTIVE                       101
 133 #define ERROR_MP_VMGETINFO_FAILED                    102
 134 #define ERROR_MP_VMGETINFO_CLAIMS_NO_SUPPORT_FOR_64K 103
 135 

1085 
1086   // Resolve function ptr literals first.
1087   addr = resolve_function_descriptor_to_code_pointer(addr);
1088   if (!addr) {
1089     return false;
1090   }
1091 
1092   address  base = nullptr;
1093   if (!AixSymbols::get_module_name_and_base(addr, buf, buflen, &base)
1094       || base == nullptr) {
1095     return false;
1096   }
1097   assert(addr >= base && addr <= base + INT_MAX, "address not in library text range");
1098   if (offset != nullptr) {
1099     *offset = addr - base;
1100   }
1101 
1102   return true;
1103 }
1104 
1105 void *os::dll_load(const char *filename, char *ebuf, int ebuflen) {
1106 
1107   log_info(os)("attempting shared library load of %s", filename);
1108 
1109   if (ebuf && ebuflen > 0) {
1110     ebuf[0] = '\0';
1111     ebuf[ebuflen - 1] = '\0';
1112   }
1113 
1114   if (!filename || strlen(filename) == 0) {
1115     if (ebuf != nullptr && ebuflen > 0) {
1116       ::strncpy(ebuf, "dll_load: empty filename specified", ebuflen - 1);
1117     }
1118     return nullptr;
1119   }
1120 
1121   // RTLD_LAZY has currently the same behavior as RTLD_NOW
1122   // The dl is loaded immediately with all its dependants.
1123   int dflags = RTLD_LAZY;
1124   // check for filename ending with ')', it indicates we want to load
1125   // a MEMBER module that is a member of an archive.
1126   int flen = strlen(filename);
1127   if (flen > 0 && filename[flen - 1] == ')') {
1128     dflags |= RTLD_MEMBER;

1134   if (result != nullptr) {
1135     Events::log_dll_message(nullptr, "Loaded shared library %s", filename);
1136     // Reload dll cache. Don't do this in signal handling.
1137     LoadedLibraries::reload();
1138     log_info(os)("shared library load of %s was successful", filename);
1139     return result;
1140   } else {
1141     // error analysis when dlopen fails
1142     if (error_report == nullptr) {
1143       error_report = "dlerror returned no error description";
1144     }
1145     if (ebuf != nullptr && ebuflen > 0) {
1146       snprintf(ebuf, ebuflen - 1, "%s, LIBPATH=%s, LD_LIBRARY_PATH=%s : %s",
1147                filename, ::getenv("LIBPATH"), ::getenv("LD_LIBRARY_PATH"), error_report);
1148     }
1149     Events::log_dll_message(nullptr, "Loading shared library %s failed, %s", filename, error_report);
1150     log_info(os)("shared library load of %s failed, %s", filename, error_report);
1151   }
1152   return nullptr;
1153 }




















1154 
1155 void os::print_dll_info(outputStream *st) {
1156   st->print_cr("Dynamic libraries:");
1157   LoadedLibraries::print(st);
1158 }
1159 
1160 void os::get_summary_os_info(char* buf, size_t buflen) {
1161   // There might be something more readable than uname results for AIX.
1162   struct utsname name;
1163   uname(&name);
1164   snprintf(buf, buflen, "%s %s", name.release, name.version);
1165 }
1166 
1167 int os::get_loaded_modules_info(os::LoadedModulesCallbackFunc callback, void *param) {
1168 
1169   if (!LoadedLibraries::for_each(callback, param)) {
1170     return -1;
1171   }
1172 
1173   return 0;

2478 // on, e.g., Win32.
2479 void
2480 os::os_exception_wrapper(java_call_t f, JavaValue* value, const methodHandle& method,
2481                          JavaCallArguments* args, JavaThread* thread) {
2482   f(value, method, args, thread);
2483 }
2484 
2485 // This code originates from JDK's sysOpen and open64_w
2486 // from src/solaris/hpi/src/system_md.c
2487 
2488 int os::open(const char *path, int oflag, int mode) {
2489 
2490   if (strlen(path) > MAX_PATH - 1) {
2491     errno = ENAMETOOLONG;
2492     return -1;
2493   }
2494   // AIX 7.X now supports O_CLOEXEC too, like modern Linux; but we have to be careful, see
2495   // IV90804: OPENING A FILE IN AFS WITH O_CLOEXEC FAILS WITH AN EINVAL ERROR APPLIES TO AIX 7100-04 17/04/14 PTF PECHANGE
2496   int oflag_with_o_cloexec = oflag | O_CLOEXEC;
2497 
2498   int fd = ::open64(path, oflag_with_o_cloexec, mode);
2499   if (fd == -1) {
2500     // we might fail in the open call when O_CLOEXEC is set, so try again without (see IV90804)
2501     fd = ::open64(path, oflag, mode);
2502     if (fd == -1) {
2503       return -1;
2504     }
2505   }
2506 
2507   // If the open succeeded, the file might still be a directory.
2508   {
2509     struct stat64 buf64;
2510     int ret = ::fstat64(fd, &buf64);
2511     int st_mode = buf64.st_mode;
2512 
2513     if (ret != -1) {
2514       if ((st_mode & S_IFMT) == S_IFDIR) {
2515         errno = EISDIR;
2516         ::close(fd);
2517         return -1;
2518       }
2519     } else {
2520       ::close(fd);
2521       return -1;
2522     }
2523   }
2524 
2525   // All file descriptors that are opened in the JVM and not
2526   // specifically destined for a subprocess should have the
2527   // close-on-exec flag set. If we don't set it, then careless 3rd
2528   // party native code might fork and exec without closing all
2529   // appropriate file descriptors (e.g. as we do in closeDescriptors in
2530   // UNIXProcess.c), and this in turn might:

2544         O_CLOEXEC_is_known_to_work = 1;
2545       } else { // it does not work
2546         ::fcntl(fd, F_SETFD, flags | FD_CLOEXEC);
2547         O_CLOEXEC_is_known_to_work = -1;
2548       }
2549     }
2550   } else if (O_CLOEXEC_is_known_to_work == -1) {
2551     int flags = ::fcntl(fd, F_GETFD);
2552     if (flags != -1) {
2553       ::fcntl(fd, F_SETFD, flags | FD_CLOEXEC);
2554     }
2555   }
2556 
2557   return fd;
2558 }
2559 
2560 // create binary file, rewriting existing file if required
2561 int os::create_binary_file(const char* path, bool rewrite_existing) {
2562   int oflags = O_WRONLY | O_CREAT;
2563   oflags |= rewrite_existing ? O_TRUNC : O_EXCL;
2564   return ::open64(path, oflags, S_IREAD | S_IWRITE);
2565 }
2566 
2567 // return current position of file pointer
2568 jlong os::current_file_offset(int fd) {
2569   return (jlong)::lseek64(fd, (off64_t)0, SEEK_CUR);
2570 }
2571 
2572 // move file pointer to the specified offset
2573 jlong os::seek_to_file_offset(int fd, jlong offset) {
2574   return (jlong)::lseek64(fd, (off64_t)offset, SEEK_SET);
2575 }
2576 
2577 // Map a block of memory.
2578 char* os::pd_map_memory(int fd, const char* file_name, size_t file_offset,
2579                         char *addr, size_t bytes, bool read_only,
2580                         bool allow_exec) {
2581   int prot;
2582   int flags = MAP_PRIVATE;
2583 
2584   if (read_only) {
2585     prot = PROT_READ;
2586     flags = MAP_SHARED;
2587   } else {
2588     prot = PROT_READ | PROT_WRITE;
2589     flags = MAP_PRIVATE;
2590   }
2591 
2592   if (allow_exec) {
2593     prot |= PROT_EXEC;
2594   }

  96 #include <stdint.h>
  97 #include <stdio.h>
  98 #include <string.h>
  99 #include <unistd.h>
 100 #include <sys/ioctl.h>
 101 #include <sys/ipc.h>
 102 #include <sys/mman.h>
 103 #include <sys/resource.h>
 104 #include <sys/select.h>
 105 #include <sys/shm.h>
 106 #include <sys/socket.h>
 107 #include <sys/stat.h>
 108 #include <sys/sysinfo.h>
 109 #include <sys/systemcfg.h>
 110 #include <sys/time.h>
 111 #include <sys/times.h>
 112 #include <sys/types.h>
 113 #include <sys/utsname.h>
 114 #include <sys/vminfo.h>
 115 
 116 #ifndef _LARGE_FILES
 117 #error Hotspot on AIX must be compiled with -D_LARGE_FILES
 118 #endif
 119 
 120 // Missing prototypes for various system APIs.
 121 extern "C"
 122 int mread_real_time(timebasestruct_t *t, size_t size_of_timebasestruct_t);
 123 
 124 #if !defined(_AIXVERSION_610)
 125 extern "C" int getthrds64(pid_t, struct thrdentry64*, int, tid64_t*, int);
 126 extern "C" int getprocs64(procentry64*, int, fdsinfo*, int, pid_t*, int);
 127 extern "C" int getargs(procsinfo*, int, char*, int);
 128 #endif
 129 
 130 #define MAX_PATH (2 * K)
 131 
 132 // for timer info max values which include all bits
 133 #define ALL_64_BITS CONST64(0xFFFFFFFFFFFFFFFF)
 134 // for multipage initialization error analysis (in 'g_multipage_error')
 135 #define ERROR_MP_OS_TOO_OLD                          100
 136 #define ERROR_MP_EXTSHM_ACTIVE                       101
 137 #define ERROR_MP_VMGETINFO_FAILED                    102
 138 #define ERROR_MP_VMGETINFO_CLAIMS_NO_SUPPORT_FOR_64K 103
 139 

1089 
1090   // Resolve function ptr literals first.
1091   addr = resolve_function_descriptor_to_code_pointer(addr);
1092   if (!addr) {
1093     return false;
1094   }
1095 
1096   address  base = nullptr;
1097   if (!AixSymbols::get_module_name_and_base(addr, buf, buflen, &base)
1098       || base == nullptr) {
1099     return false;
1100   }
1101   assert(addr >= base && addr <= base + INT_MAX, "address not in library text range");
1102   if (offset != nullptr) {
1103     *offset = addr - base;
1104   }
1105 
1106   return true;
1107 }
1108 
1109 static void* dll_load_library(const char *filename, char *ebuf, int ebuflen) {
1110 
1111   log_info(os)("attempting shared library load of %s", filename);

1112   if (ebuf && ebuflen > 0) {
1113     ebuf[0] = '\0';
1114     ebuf[ebuflen - 1] = '\0';
1115   }
1116 
1117   if (!filename || strlen(filename) == 0) {
1118     if (ebuf != nullptr && ebuflen > 0) {
1119       ::strncpy(ebuf, "dll_load: empty filename specified", ebuflen - 1);
1120     }
1121     return nullptr;
1122   }
1123 
1124   // RTLD_LAZY has currently the same behavior as RTLD_NOW
1125   // The dl is loaded immediately with all its dependants.
1126   int dflags = RTLD_LAZY;
1127   // check for filename ending with ')', it indicates we want to load
1128   // a MEMBER module that is a member of an archive.
1129   int flen = strlen(filename);
1130   if (flen > 0 && filename[flen - 1] == ')') {
1131     dflags |= RTLD_MEMBER;

1137   if (result != nullptr) {
1138     Events::log_dll_message(nullptr, "Loaded shared library %s", filename);
1139     // Reload dll cache. Don't do this in signal handling.
1140     LoadedLibraries::reload();
1141     log_info(os)("shared library load of %s was successful", filename);
1142     return result;
1143   } else {
1144     // error analysis when dlopen fails
1145     if (error_report == nullptr) {
1146       error_report = "dlerror returned no error description";
1147     }
1148     if (ebuf != nullptr && ebuflen > 0) {
1149       snprintf(ebuf, ebuflen - 1, "%s, LIBPATH=%s, LD_LIBRARY_PATH=%s : %s",
1150                filename, ::getenv("LIBPATH"), ::getenv("LD_LIBRARY_PATH"), error_report);
1151     }
1152     Events::log_dll_message(nullptr, "Loading shared library %s failed, %s", filename, error_report);
1153     log_info(os)("shared library load of %s failed, %s", filename, error_report);
1154   }
1155   return nullptr;
1156 }
1157 // Load library named <filename>
1158 // If filename matches <name>.so, and loading fails, repeat with <name>.a.
1159 void *os::dll_load(const char *filename, char *ebuf, int ebuflen) {
1160   void* result = nullptr;
1161   char* const file_path = strdup(filename);
1162   char* const pointer_to_dot = strrchr(file_path, '.');
1163   const char old_extension[] = ".so";
1164   const char new_extension[] = ".a";
1165   STATIC_ASSERT(sizeof(old_extension) >= sizeof(new_extension));
1166   // First try to load the existing file.
1167   result = dll_load_library(filename, ebuf, ebuflen);
1168   // If the load fails,we try to reload by changing the extension to .a for .so files only.
1169   // Shared object in .so format dont have braces, hence they get removed for archives with members.
1170   if (result == nullptr && pointer_to_dot != nullptr && strcmp(pointer_to_dot, old_extension) == 0) {
1171     snprintf(pointer_to_dot, sizeof(old_extension), "%s", new_extension);
1172     result = dll_load_library(file_path, ebuf, ebuflen);
1173   }
1174   FREE_C_HEAP_ARRAY(char, file_path);
1175   return result;
1176 }
1177 
1178 void os::print_dll_info(outputStream *st) {
1179   st->print_cr("Dynamic libraries:");
1180   LoadedLibraries::print(st);
1181 }
1182 
1183 void os::get_summary_os_info(char* buf, size_t buflen) {
1184   // There might be something more readable than uname results for AIX.
1185   struct utsname name;
1186   uname(&name);
1187   snprintf(buf, buflen, "%s %s", name.release, name.version);
1188 }
1189 
1190 int os::get_loaded_modules_info(os::LoadedModulesCallbackFunc callback, void *param) {
1191 
1192   if (!LoadedLibraries::for_each(callback, param)) {
1193     return -1;
1194   }
1195 
1196   return 0;

2501 // on, e.g., Win32.
2502 void
2503 os::os_exception_wrapper(java_call_t f, JavaValue* value, const methodHandle& method,
2504                          JavaCallArguments* args, JavaThread* thread) {
2505   f(value, method, args, thread);
2506 }
2507 
2508 // This code originates from JDK's sysOpen and open64_w
2509 // from src/solaris/hpi/src/system_md.c
2510 
2511 int os::open(const char *path, int oflag, int mode) {
2512 
2513   if (strlen(path) > MAX_PATH - 1) {
2514     errno = ENAMETOOLONG;
2515     return -1;
2516   }
2517   // AIX 7.X now supports O_CLOEXEC too, like modern Linux; but we have to be careful, see
2518   // IV90804: OPENING A FILE IN AFS WITH O_CLOEXEC FAILS WITH AN EINVAL ERROR APPLIES TO AIX 7100-04 17/04/14 PTF PECHANGE
2519   int oflag_with_o_cloexec = oflag | O_CLOEXEC;
2520 
2521   int fd = ::open(path, oflag_with_o_cloexec, mode);
2522   if (fd == -1) {
2523     // we might fail in the open call when O_CLOEXEC is set, so try again without (see IV90804)
2524     fd = ::open(path, oflag, mode);
2525     if (fd == -1) {
2526       return -1;
2527     }
2528   }
2529 
2530   // If the open succeeded, the file might still be a directory.
2531   {
2532     struct stat buf64;
2533     int ret = ::fstat(fd, &buf64);
2534     int st_mode = buf64.st_mode;
2535 
2536     if (ret != -1) {
2537       if ((st_mode & S_IFMT) == S_IFDIR) {
2538         errno = EISDIR;
2539         ::close(fd);
2540         return -1;
2541       }
2542     } else {
2543       ::close(fd);
2544       return -1;
2545     }
2546   }
2547 
2548   // All file descriptors that are opened in the JVM and not
2549   // specifically destined for a subprocess should have the
2550   // close-on-exec flag set. If we don't set it, then careless 3rd
2551   // party native code might fork and exec without closing all
2552   // appropriate file descriptors (e.g. as we do in closeDescriptors in
2553   // UNIXProcess.c), and this in turn might:

2567         O_CLOEXEC_is_known_to_work = 1;
2568       } else { // it does not work
2569         ::fcntl(fd, F_SETFD, flags | FD_CLOEXEC);
2570         O_CLOEXEC_is_known_to_work = -1;
2571       }
2572     }
2573   } else if (O_CLOEXEC_is_known_to_work == -1) {
2574     int flags = ::fcntl(fd, F_GETFD);
2575     if (flags != -1) {
2576       ::fcntl(fd, F_SETFD, flags | FD_CLOEXEC);
2577     }
2578   }
2579 
2580   return fd;
2581 }
2582 
2583 // create binary file, rewriting existing file if required
2584 int os::create_binary_file(const char* path, bool rewrite_existing) {
2585   int oflags = O_WRONLY | O_CREAT;
2586   oflags |= rewrite_existing ? O_TRUNC : O_EXCL;
2587   return ::open(path, oflags, S_IREAD | S_IWRITE);
2588 }
2589 
2590 // return current position of file pointer
2591 jlong os::current_file_offset(int fd) {
2592   return (jlong)::lseek(fd, (off_t)0, SEEK_CUR);
2593 }
2594 
2595 // move file pointer to the specified offset
2596 jlong os::seek_to_file_offset(int fd, jlong offset) {
2597   return (jlong)::lseek(fd, (off_t)offset, SEEK_SET);
2598 }
2599 
2600 // Map a block of memory.
2601 char* os::pd_map_memory(int fd, const char* file_name, size_t file_offset,
2602                         char *addr, size_t bytes, bool read_only,
2603                         bool allow_exec) {
2604   int prot;
2605   int flags = MAP_PRIVATE;
2606 
2607   if (read_only) {
2608     prot = PROT_READ;
2609     flags = MAP_SHARED;
2610   } else {
2611     prot = PROT_READ | PROT_WRITE;
2612     flags = MAP_PRIVATE;
2613   }
2614 
2615   if (allow_exec) {
2616     prot |= PROT_EXEC;
2617   }
< prev index next >