1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/src/os/aix/vm/loadlib_aix.cpp Wed Apr 27 01:25:04 2016 +0800 1.3 @@ -0,0 +1,185 @@ 1.4 +/* 1.5 + * Copyright 2012, 2013 SAP AG. All rights reserved. 1.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 1.7 + * 1.8 + * This code is free software; you can redistribute it and/or modify it 1.9 + * under the terms of the GNU General Public License version 2 only, as 1.10 + * published by the Free Software Foundation. 1.11 + * 1.12 + * This code is distributed in the hope that it will be useful, but WITHOUT 1.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 1.14 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 1.15 + * version 2 for more details (a copy is included in the LICENSE file that 1.16 + * accompanied this code). 1.17 + * 1.18 + * You should have received a copy of the GNU General Public License version 1.19 + * 2 along with this work; if not, write to the Free Software Foundation, 1.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 1.21 + * 1.22 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 1.23 + * or visit www.oracle.com if you need additional information or have any 1.24 + * questions. 1.25 + * 1.26 + */ 1.27 + 1.28 + 1.29 +// Implementation of LoadedLibraries and friends 1.30 + 1.31 +// Ultimately this just uses loadquery() 1.32 +// See: 1.33 +// http://publib.boulder.ibm.com/infocenter/pseries/v5r3/index.jsp 1.34 +// ?topic=/com.ibm.aix.basetechref/doc/basetrf1/loadquery.htm 1.35 + 1.36 +#ifndef __STDC_FORMAT_MACROS 1.37 +#define __STDC_FORMAT_MACROS 1.38 +#endif 1.39 +// 'allocation.inline.hpp' triggers the inclusion of 'inttypes.h' which defines macros 1.40 +// required by the definitions in 'globalDefinitions.hpp'. But these macros in 'inttypes.h' 1.41 +// are only defined if '__STDC_FORMAT_MACROS' is defined! 1.42 +#include "memory/allocation.inline.hpp" 1.43 +#include "oops/oop.inline.hpp" 1.44 +#include "runtime/threadCritical.hpp" 1.45 +#include "utilities/debug.hpp" 1.46 +#include "utilities/ostream.hpp" 1.47 +#include "loadlib_aix.hpp" 1.48 +#include "porting_aix.hpp" 1.49 + 1.50 +// For loadquery() 1.51 +#include <sys/ldr.h> 1.52 + 1.53 +/////////////////////////////////////////////////////////////////////////////// 1.54 +// Implementation for LoadedLibraryModule 1.55 + 1.56 +// output debug info 1.57 +void LoadedLibraryModule::print(outputStream* os) const { 1.58 + os->print("%15.15s: text: " INTPTR_FORMAT " - " INTPTR_FORMAT 1.59 + ", data: " INTPTR_FORMAT " - " INTPTR_FORMAT " ", 1.60 + shortname, text_from, text_to, data_from, data_to); 1.61 + os->print(" %s", fullpath); 1.62 + if (strlen(membername) > 0) { 1.63 + os->print("(%s)", membername); 1.64 + } 1.65 + os->cr(); 1.66 +} 1.67 + 1.68 + 1.69 +/////////////////////////////////////////////////////////////////////////////// 1.70 +// Implementation for LoadedLibraries 1.71 + 1.72 +// class variables 1.73 +LoadedLibraryModule LoadedLibraries::tab[MAX_MODULES]; 1.74 +int LoadedLibraries::num_loaded = 0; 1.75 + 1.76 +// Checks whether the address p points to any of the loaded code segments. 1.77 +// If it does, returns the LoadedLibraryModule entry. If not, returns NULL. 1.78 +// static 1.79 +const LoadedLibraryModule* LoadedLibraries::find_for_text_address(const unsigned char* p) { 1.80 + 1.81 + if (num_loaded == 0) { 1.82 + reload(); 1.83 + } 1.84 + for (int i = 0; i < num_loaded; i++) { 1.85 + if (tab[i].is_in_text(p)) { 1.86 + return &tab[i]; 1.87 + } 1.88 + } 1.89 + return NULL; 1.90 +} 1.91 + 1.92 +// Checks whether the address p points to any of the loaded data segments. 1.93 +// If it does, returns the LoadedLibraryModule entry. If not, returns NULL. 1.94 +// static 1.95 +const LoadedLibraryModule* LoadedLibraries::find_for_data_address(const unsigned char* p) { 1.96 + if (num_loaded == 0) { 1.97 + reload(); 1.98 + } 1.99 + for (int i = 0; i < num_loaded; i++) { 1.100 + if (tab[i].is_in_data(p)) { 1.101 + return &tab[i]; 1.102 + } 1.103 + } 1.104 + return NULL; 1.105 +} 1.106 + 1.107 +// Rebuild the internal table of LoadedLibraryModule objects 1.108 +// static 1.109 +void LoadedLibraries::reload() { 1.110 + 1.111 + ThreadCritical cs; 1.112 + 1.113 + // discard old content 1.114 + num_loaded = 0; 1.115 + 1.116 + // Call loadquery(L_GETINFO..) to get a list of all loaded Dlls from AIX. 1.117 + size_t buf_size = 4096; 1.118 + char* loadquery_buf = AllocateHeap(buf_size, mtInternal); 1.119 + 1.120 + while(loadquery(L_GETINFO, loadquery_buf, buf_size) == -1) { 1.121 + if (errno == ENOMEM) { 1.122 + buf_size *= 2; 1.123 + loadquery_buf = ReallocateHeap(loadquery_buf, buf_size, mtInternal); 1.124 + } else { 1.125 + FreeHeap(loadquery_buf); 1.126 + // Ensure that the uintptr_t pointer is valid 1.127 + assert(errno != EFAULT, "loadquery: Invalid uintptr_t in info buffer."); 1.128 + fprintf(stderr, "loadquery failed (%d %s)", errno, strerror(errno)); 1.129 + return; 1.130 + } 1.131 + } 1.132 + 1.133 + // Iterate over the loadquery result. For details see sys/ldr.h on AIX. 1.134 + const struct ld_info* p = (struct ld_info*) loadquery_buf; 1.135 + 1.136 + // Ensure we have all loaded libs. 1.137 + bool all_loaded = false; 1.138 + while(num_loaded < MAX_MODULES) { 1.139 + LoadedLibraryModule& mod = tab[num_loaded]; 1.140 + mod.text_from = (const unsigned char*) p->ldinfo_textorg; 1.141 + mod.text_to = (const unsigned char*) (((char*)p->ldinfo_textorg) + p->ldinfo_textsize); 1.142 + mod.data_from = (const unsigned char*) p->ldinfo_dataorg; 1.143 + mod.data_to = (const unsigned char*) (((char*)p->ldinfo_dataorg) + p->ldinfo_datasize); 1.144 + sprintf(mod.fullpath, "%.*s", sizeof(mod.fullpath), p->ldinfo_filename); 1.145 + // do we have a member name as well (see ldr.h)? 1.146 + const char* p_mbr_name = p->ldinfo_filename + strlen(p->ldinfo_filename) + 1; 1.147 + if (*p_mbr_name) { 1.148 + sprintf(mod.membername, "%.*s", sizeof(mod.membername), p_mbr_name); 1.149 + } else { 1.150 + mod.membername[0] = '\0'; 1.151 + } 1.152 + 1.153 + // fill in the short name 1.154 + const char* p_slash = strrchr(mod.fullpath, '/'); 1.155 + if (p_slash) { 1.156 + sprintf(mod.shortname, "%.*s", sizeof(mod.shortname), p_slash + 1); 1.157 + } else { 1.158 + sprintf(mod.shortname, "%.*s", sizeof(mod.shortname), mod.fullpath); 1.159 + } 1.160 + num_loaded ++; 1.161 + 1.162 + // next entry... 1.163 + if (p->ldinfo_next) { 1.164 + p = (struct ld_info*)(((char*)p) + p->ldinfo_next); 1.165 + } else { 1.166 + all_loaded = true; 1.167 + break; 1.168 + } 1.169 + } 1.170 + 1.171 + FreeHeap(loadquery_buf); 1.172 + 1.173 + // Ensure we have all loaded libs 1.174 + assert(all_loaded, "loadquery returned more entries then expected. Please increase MAX_MODULES"); 1.175 + 1.176 +} // end LoadedLibraries::reload() 1.177 + 1.178 + 1.179 +// output loaded libraries table 1.180 +//static 1.181 +void LoadedLibraries::print(outputStream* os) { 1.182 + 1.183 + for (int i = 0; i < num_loaded; i++) { 1.184 + tab[i].print(os); 1.185 + } 1.186 + 1.187 +} 1.188 +