src/os/aix/vm/loadlib_aix.cpp

changeset 0
f90c822e73f8
     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 +

mercurial