Wed, 31 Jan 2018 19:24:57 -0500
8189170: Add option to disable stack overflow checking in primordial thread for use with JNI_CreateJavaJVM
Reviewed-by: dcubed
aoqi@0 | 1 | /* |
aoqi@0 | 2 | * Copyright 2012, 2013 SAP AG. All rights reserved. |
aoqi@0 | 3 | * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. |
aoqi@0 | 4 | * |
aoqi@0 | 5 | * This code is free software; you can redistribute it and/or modify it |
aoqi@0 | 6 | * under the terms of the GNU General Public License version 2 only, as |
aoqi@0 | 7 | * published by the Free Software Foundation. |
aoqi@0 | 8 | * |
aoqi@0 | 9 | * This code is distributed in the hope that it will be useful, but WITHOUT |
aoqi@0 | 10 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or |
aoqi@0 | 11 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License |
aoqi@0 | 12 | * version 2 for more details (a copy is included in the LICENSE file that |
aoqi@0 | 13 | * accompanied this code). |
aoqi@0 | 14 | * |
aoqi@0 | 15 | * You should have received a copy of the GNU General Public License version |
aoqi@0 | 16 | * 2 along with this work; if not, write to the Free Software Foundation, |
aoqi@0 | 17 | * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. |
aoqi@0 | 18 | * |
aoqi@0 | 19 | * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA |
aoqi@0 | 20 | * or visit www.oracle.com if you need additional information or have any |
aoqi@0 | 21 | * questions. |
aoqi@0 | 22 | * |
aoqi@0 | 23 | */ |
aoqi@0 | 24 | |
aoqi@0 | 25 | |
aoqi@0 | 26 | // Implementation of LoadedLibraries and friends |
aoqi@0 | 27 | |
aoqi@0 | 28 | // Ultimately this just uses loadquery() |
aoqi@0 | 29 | // See: |
aoqi@0 | 30 | // http://publib.boulder.ibm.com/infocenter/pseries/v5r3/index.jsp |
aoqi@0 | 31 | // ?topic=/com.ibm.aix.basetechref/doc/basetrf1/loadquery.htm |
aoqi@0 | 32 | |
aoqi@0 | 33 | #ifndef __STDC_FORMAT_MACROS |
aoqi@0 | 34 | #define __STDC_FORMAT_MACROS |
aoqi@0 | 35 | #endif |
aoqi@0 | 36 | // 'allocation.inline.hpp' triggers the inclusion of 'inttypes.h' which defines macros |
aoqi@0 | 37 | // required by the definitions in 'globalDefinitions.hpp'. But these macros in 'inttypes.h' |
aoqi@0 | 38 | // are only defined if '__STDC_FORMAT_MACROS' is defined! |
aoqi@0 | 39 | #include "memory/allocation.inline.hpp" |
aoqi@0 | 40 | #include "oops/oop.inline.hpp" |
aoqi@0 | 41 | #include "runtime/threadCritical.hpp" |
aoqi@0 | 42 | #include "utilities/debug.hpp" |
aoqi@0 | 43 | #include "utilities/ostream.hpp" |
aoqi@0 | 44 | #include "loadlib_aix.hpp" |
aoqi@0 | 45 | #include "porting_aix.hpp" |
aoqi@0 | 46 | |
aoqi@0 | 47 | // For loadquery() |
aoqi@0 | 48 | #include <sys/ldr.h> |
aoqi@0 | 49 | |
aoqi@0 | 50 | /////////////////////////////////////////////////////////////////////////////// |
aoqi@0 | 51 | // Implementation for LoadedLibraryModule |
aoqi@0 | 52 | |
aoqi@0 | 53 | // output debug info |
aoqi@0 | 54 | void LoadedLibraryModule::print(outputStream* os) const { |
aoqi@0 | 55 | os->print("%15.15s: text: " INTPTR_FORMAT " - " INTPTR_FORMAT |
aoqi@0 | 56 | ", data: " INTPTR_FORMAT " - " INTPTR_FORMAT " ", |
aoqi@0 | 57 | shortname, text_from, text_to, data_from, data_to); |
aoqi@0 | 58 | os->print(" %s", fullpath); |
aoqi@0 | 59 | if (strlen(membername) > 0) { |
aoqi@0 | 60 | os->print("(%s)", membername); |
aoqi@0 | 61 | } |
aoqi@0 | 62 | os->cr(); |
aoqi@0 | 63 | } |
aoqi@0 | 64 | |
aoqi@0 | 65 | |
aoqi@0 | 66 | /////////////////////////////////////////////////////////////////////////////// |
aoqi@0 | 67 | // Implementation for LoadedLibraries |
aoqi@0 | 68 | |
aoqi@0 | 69 | // class variables |
aoqi@0 | 70 | LoadedLibraryModule LoadedLibraries::tab[MAX_MODULES]; |
aoqi@0 | 71 | int LoadedLibraries::num_loaded = 0; |
aoqi@0 | 72 | |
aoqi@0 | 73 | // Checks whether the address p points to any of the loaded code segments. |
aoqi@0 | 74 | // If it does, returns the LoadedLibraryModule entry. If not, returns NULL. |
aoqi@0 | 75 | // static |
aoqi@0 | 76 | const LoadedLibraryModule* LoadedLibraries::find_for_text_address(const unsigned char* p) { |
aoqi@0 | 77 | |
aoqi@0 | 78 | if (num_loaded == 0) { |
aoqi@0 | 79 | reload(); |
aoqi@0 | 80 | } |
aoqi@0 | 81 | for (int i = 0; i < num_loaded; i++) { |
aoqi@0 | 82 | if (tab[i].is_in_text(p)) { |
aoqi@0 | 83 | return &tab[i]; |
aoqi@0 | 84 | } |
aoqi@0 | 85 | } |
aoqi@0 | 86 | return NULL; |
aoqi@0 | 87 | } |
aoqi@0 | 88 | |
aoqi@0 | 89 | // Checks whether the address p points to any of the loaded data segments. |
aoqi@0 | 90 | // If it does, returns the LoadedLibraryModule entry. If not, returns NULL. |
aoqi@0 | 91 | // static |
aoqi@0 | 92 | const LoadedLibraryModule* LoadedLibraries::find_for_data_address(const unsigned char* p) { |
aoqi@0 | 93 | if (num_loaded == 0) { |
aoqi@0 | 94 | reload(); |
aoqi@0 | 95 | } |
aoqi@0 | 96 | for (int i = 0; i < num_loaded; i++) { |
aoqi@0 | 97 | if (tab[i].is_in_data(p)) { |
aoqi@0 | 98 | return &tab[i]; |
aoqi@0 | 99 | } |
aoqi@0 | 100 | } |
aoqi@0 | 101 | return NULL; |
aoqi@0 | 102 | } |
aoqi@0 | 103 | |
aoqi@0 | 104 | // Rebuild the internal table of LoadedLibraryModule objects |
aoqi@0 | 105 | // static |
aoqi@0 | 106 | void LoadedLibraries::reload() { |
aoqi@0 | 107 | |
aoqi@0 | 108 | ThreadCritical cs; |
aoqi@0 | 109 | |
aoqi@0 | 110 | // discard old content |
aoqi@0 | 111 | num_loaded = 0; |
aoqi@0 | 112 | |
aoqi@0 | 113 | // Call loadquery(L_GETINFO..) to get a list of all loaded Dlls from AIX. |
aoqi@0 | 114 | size_t buf_size = 4096; |
aoqi@0 | 115 | char* loadquery_buf = AllocateHeap(buf_size, mtInternal); |
aoqi@0 | 116 | |
aoqi@0 | 117 | while(loadquery(L_GETINFO, loadquery_buf, buf_size) == -1) { |
aoqi@0 | 118 | if (errno == ENOMEM) { |
aoqi@0 | 119 | buf_size *= 2; |
aoqi@0 | 120 | loadquery_buf = ReallocateHeap(loadquery_buf, buf_size, mtInternal); |
aoqi@0 | 121 | } else { |
aoqi@0 | 122 | FreeHeap(loadquery_buf); |
aoqi@0 | 123 | // Ensure that the uintptr_t pointer is valid |
aoqi@0 | 124 | assert(errno != EFAULT, "loadquery: Invalid uintptr_t in info buffer."); |
aoqi@0 | 125 | fprintf(stderr, "loadquery failed (%d %s)", errno, strerror(errno)); |
aoqi@0 | 126 | return; |
aoqi@0 | 127 | } |
aoqi@0 | 128 | } |
aoqi@0 | 129 | |
aoqi@0 | 130 | // Iterate over the loadquery result. For details see sys/ldr.h on AIX. |
aoqi@0 | 131 | const struct ld_info* p = (struct ld_info*) loadquery_buf; |
aoqi@0 | 132 | |
aoqi@0 | 133 | // Ensure we have all loaded libs. |
aoqi@0 | 134 | bool all_loaded = false; |
aoqi@0 | 135 | while(num_loaded < MAX_MODULES) { |
aoqi@0 | 136 | LoadedLibraryModule& mod = tab[num_loaded]; |
aoqi@0 | 137 | mod.text_from = (const unsigned char*) p->ldinfo_textorg; |
aoqi@0 | 138 | mod.text_to = (const unsigned char*) (((char*)p->ldinfo_textorg) + p->ldinfo_textsize); |
aoqi@0 | 139 | mod.data_from = (const unsigned char*) p->ldinfo_dataorg; |
aoqi@0 | 140 | mod.data_to = (const unsigned char*) (((char*)p->ldinfo_dataorg) + p->ldinfo_datasize); |
aoqi@0 | 141 | sprintf(mod.fullpath, "%.*s", sizeof(mod.fullpath), p->ldinfo_filename); |
aoqi@0 | 142 | // do we have a member name as well (see ldr.h)? |
aoqi@0 | 143 | const char* p_mbr_name = p->ldinfo_filename + strlen(p->ldinfo_filename) + 1; |
aoqi@0 | 144 | if (*p_mbr_name) { |
aoqi@0 | 145 | sprintf(mod.membername, "%.*s", sizeof(mod.membername), p_mbr_name); |
aoqi@0 | 146 | } else { |
aoqi@0 | 147 | mod.membername[0] = '\0'; |
aoqi@0 | 148 | } |
aoqi@0 | 149 | |
aoqi@0 | 150 | // fill in the short name |
aoqi@0 | 151 | const char* p_slash = strrchr(mod.fullpath, '/'); |
aoqi@0 | 152 | if (p_slash) { |
aoqi@0 | 153 | sprintf(mod.shortname, "%.*s", sizeof(mod.shortname), p_slash + 1); |
aoqi@0 | 154 | } else { |
aoqi@0 | 155 | sprintf(mod.shortname, "%.*s", sizeof(mod.shortname), mod.fullpath); |
aoqi@0 | 156 | } |
aoqi@0 | 157 | num_loaded ++; |
aoqi@0 | 158 | |
aoqi@0 | 159 | // next entry... |
aoqi@0 | 160 | if (p->ldinfo_next) { |
aoqi@0 | 161 | p = (struct ld_info*)(((char*)p) + p->ldinfo_next); |
aoqi@0 | 162 | } else { |
aoqi@0 | 163 | all_loaded = true; |
aoqi@0 | 164 | break; |
aoqi@0 | 165 | } |
aoqi@0 | 166 | } |
aoqi@0 | 167 | |
aoqi@0 | 168 | FreeHeap(loadquery_buf); |
aoqi@0 | 169 | |
aoqi@0 | 170 | // Ensure we have all loaded libs |
aoqi@0 | 171 | assert(all_loaded, "loadquery returned more entries then expected. Please increase MAX_MODULES"); |
aoqi@0 | 172 | |
aoqi@0 | 173 | } // end LoadedLibraries::reload() |
aoqi@0 | 174 | |
aoqi@0 | 175 | |
aoqi@0 | 176 | // output loaded libraries table |
aoqi@0 | 177 | //static |
aoqi@0 | 178 | void LoadedLibraries::print(outputStream* os) { |
aoqi@0 | 179 | |
aoqi@0 | 180 | for (int i = 0; i < num_loaded; i++) { |
aoqi@0 | 181 | tab[i].print(os); |
aoqi@0 | 182 | } |
aoqi@0 | 183 | |
aoqi@0 | 184 | } |
aoqi@0 | 185 |