< prev index next >

src/share/vm/classfile/imageFile.cpp

Print this page


   1 /*
   2  * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
   3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   4  *
   5  * This code is free software; you can redistribute it and/or modify it
   6  * under the terms of the GNU General Public License version 2 only, as
   7  * published by the Free Software Foundation.
   8  *
   9  * This code is distributed in the hope that it will be useful, but WITHOUT
  10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  11  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  12  * version 2 for more details (a copy is included in the LICENSE file that
  13  * accompanied this code).
  14  *
  15  * You should have received a copy of the GNU General Public License version
  16  * 2 along with this work; if not, write to the Free Software Foundation,
  17  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  18  *
  19  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  20  * or visit www.oracle.com if you need additional information or have any
  21  * questions.
  22  *
  23  */
  24 
  25 #include "precompiled.hpp"

  26 #include "classfile/imageFile.hpp"



  27 #include "runtime/os.inline.hpp"
  28 #include "utilities/bytes.hpp"

  29 
  30 
  31 // Compute the Perfect Hashing hash code for the supplied string.
  32 u4 ImageStrings::hash_code(const char* string, u4 seed) {






  33   u1* bytes = (u1*)string;
  34 
  35   // Compute hash code.
  36   for (u1 byte = *bytes++; byte; byte = *bytes++) {
  37     seed = (seed * HASH_MULTIPLIER) ^ byte;
  38   }
  39 
  40   // Ensure the result is unsigned.
  41   return seed & 0x7FFFFFFF;
  42 }
  43 
  44 // Test to see if string begins with start.  If so returns remaining portion
  45 // of string.  Otherwise, NULL.
































  46 const char* ImageStrings::starts_with(const char* string, const char* start) {
  47   char ch1, ch2;
  48 
  49   // Match up the strings the best we can.
  50   while ((ch1 = *string) && (ch2 = *start)) {
  51     if (ch1 != ch2) {
  52       // Mismatch, return NULL.
  53       return NULL;
  54     }
  55 
  56     string++, start++;
  57   }
  58 
  59   // Return remainder of string.
  60   return string;
  61 }
  62 
  63 ImageLocation::ImageLocation(u1* data) {



  64   // Deflate the attribute stream into an array of attributes.
  65   memset(_attributes, 0, sizeof(_attributes));
  66   u1 byte;
  67 
  68   while ((byte = *data) != ATTRIBUTE_END) {

  69     u1 kind = attribute_kind(byte);


  70     u1 n = attribute_length(byte);
  71     assert(kind < ATTRIBUTE_COUNT, "invalid image location attribute");
  72     _attributes[kind] = attribute_value(data + 1, n);

  73     data += n + 1;
  74   }
  75 }
  76 
  77 ImageFile::ImageFile(const char* name) {


























































































































































































  78   // Copy the image file name.
  79   _name = NEW_C_HEAP_ARRAY(char, strlen(name)+1, mtClass);
  80   strcpy(_name, name);
  81 
  82   // Initialize for a closed file.
  83   _fd = -1;
  84   _memory_mapped = true;
  85   _index_data = NULL;
  86 }
  87 
  88 ImageFile::~ImageFile() {

  89   // Ensure file is closed.
  90   close();
  91 
  92   // Free up name.

  93   FREE_C_HEAP_ARRAY(char, _name);


  94 }
  95 
  96 bool ImageFile::open() {

  97   // If file exists open for reading.
  98   struct stat st;
  99   if (os::stat(_name, &st) != 0 ||
 100     (st.st_mode & S_IFREG) != S_IFREG ||
 101     (_fd = os::open(_name, 0, O_RDONLY)) == -1) {
 102     return false;
 103   }
 104 
 105   // Read image file header and verify.
 106   u8 header_size = sizeof(ImageHeader);
 107   if (os::read(_fd, &_header, header_size) != header_size ||
 108     _header._magic != IMAGE_MAGIC ||
 109     _header._major_version != MAJOR_VERSION ||
 110     _header._minor_version != MINOR_VERSION) {


 111     close();
 112     return false;
 113   }
 114 
 115   // Memory map index.
 116   _index_size = index_size();
 117   _index_data = (u1*)os::map_memory(_fd, _name, 0, NULL, _index_size, true, false);
 118 
 119   // Failing that, read index into C memory.
 120   if (_index_data == NULL) {
 121     _memory_mapped = false;
 122     _index_data = NEW_RESOURCE_ARRAY(u1, _index_size);
 123 
 124     if (os::seek_to_file_offset(_fd, 0) == -1) {
 125       close();
 126       return false;
 127     }
 128 
 129     if (os::read(_fd, _index_data, _index_size) != _index_size) {
 130       close();
 131       return false;
 132     }
 133 
 134     return true;
 135   }
 136 
 137 // Used to advance a pointer, unstructured.
 138 #undef nextPtr
 139 #define nextPtr(base, fromType, count, toType) (toType*)((fromType*)(base) + (count))
 140   // Pull tables out from the index.
 141   _redirect_table = nextPtr(_index_data, u1, header_size, s4);
 142   _offsets_table = nextPtr(_redirect_table, s4, _header._location_count, u4);
 143   _location_bytes = nextPtr(_offsets_table, u4, _header._location_count, u1);
 144   _string_bytes = nextPtr(_location_bytes, u1, _header._locations_size, u1);
 145 #undef nextPtr
 146 




 147   // Successful open.
 148   return true;
 149 }
 150 
 151 void ImageFile::close() {

 152   // Dealllocate the index.
 153   if (_index_data) {
 154     if (_memory_mapped) {
 155       os::unmap_memory((char*)_index_data, _index_size);
 156     } else {
 157       FREE_RESOURCE_ARRAY(u1, _index_data, _index_size);
 158     }
 159 
 160     _index_data = NULL;
 161   }
 162 
 163   // close file.
 164   if (_fd != -1) {
 165     os::close(_fd);
 166     _fd = -1;
 167   }
 168 
 169 }
 170 
 171 // Return the attribute stream for a named resourced.
 172 u1* ImageFile::find_location_data(const char* path) const {
 173   // Compute hash.
 174   u4 hash = ImageStrings::hash_code(path) % _header._location_count;
 175   s4 redirect = _redirect_table[hash];
 176 
 177   if (!redirect) {
 178     return NULL;










 179   }


 180 
 181   u4 index;
 182 
 183   if (redirect < 0) {
 184     // If no collision.
 185     index = -redirect - 1;
 186   } else {
 187     // If collision, recompute hash code.
 188     index = ImageStrings::hash_code(path, redirect) % _header._location_count;












 189   }
 190 
 191   assert(index < _header._location_count, "index exceeds location count");
 192   u4 offset = _offsets_table[index];
 193   assert(offset < _header._locations_size, "offset exceeds location attributes size");
 194 
 195   if (offset == 0) {
 196     return NULL;




 197   }
 198 
 199   return _location_bytes + offset;
 200 }
 201 
 202 // Verify that a found location matches the supplied path.
 203 bool ImageFile::verify_location(ImageLocation& location, const char* path) const {
 204   // Retrieve each path component string.
 205   ImageStrings strings(_string_bytes, _header._strings_size);
 206   // Match a path with each subcomponent without concatenation (copy).
 207   // Match up path parent.
































 208   const char* parent = location.get_attribute(ImageLocation::ATTRIBUTE_PARENT, strings);
 209   const char* next = ImageStrings::starts_with(path, parent);
 210   // Continue only if a complete match.
 211   if (!next) return false;
 212   // Match up path base.



 213   const char* base = location.get_attribute(ImageLocation::ATTRIBUTE_BASE, strings);
 214   next = ImageStrings::starts_with(next, base);
 215   // Continue only if a complete match.
 216   if (!next) return false;
 217   // Match up path extension.
 218   const char* extension = location.get_attribute(ImageLocation::ATTRIBUTE_EXTENSION, strings);
 219   next = ImageStrings::starts_with(next, extension);
 220 




 221   // True only if complete match and no more characters.
 222   return next && *next == '\0';
 223 }
 224 
 225 // Return the resource for the supplied location.
 226 u1* ImageFile::get_resource(ImageLocation& location) const {
 227   // Retrieve the byte offset and size of the resource.
 228   u8 offset = _index_size + location.get_attribute(ImageLocation::ATTRIBUTE_OFFSET);
 229   u8 size = location.get_attribute(ImageLocation::ATTRIBUTE_UNCOMPRESSED);
 230   u8 compressed_size = location.get_attribute(ImageLocation::ATTRIBUTE_COMPRESSED);
 231   u8 read_size = compressed_size ? compressed_size : size;
 232 
 233   // Allocate space for the resource.
 234   u1* data = NEW_RESOURCE_ARRAY(u1, read_size);
 235 
 236   bool is_read = os::read_at(_fd, data, read_size, offset) == read_size;



 237   guarantee(is_read, "error reading from image or short read");
 238 
 239   // If not compressed, just return the data.
 240   if (!compressed_size) {
 241     return data;
 242   }
 243 
 244   u1* uncompressed = NEW_RESOURCE_ARRAY(u1, size);
 245   char* msg = NULL;
 246   jboolean res = ClassLoader::decompress(data, compressed_size, uncompressed, size, &msg);
 247   if (!res) warning("decompression failed due to %s\n", msg);
 248   guarantee(res, "decompression failed");
 249 
 250   return uncompressed;
 251 }
 252 
 253 void ImageFile::get_resource(const char* path, u1*& buffer, u8& size) const {
 254   buffer = NULL;
 255   size = 0;
 256   u1* data = find_location_data(path);
 257   if (data) {
 258     ImageLocation location(data);
 259     if (verify_location(location, path)) {
 260       size = location.get_attribute(ImageLocation::ATTRIBUTE_UNCOMPRESSED);
 261       buffer = get_resource(location);
 262     }
 263   }
 264 }
 265 
 266 GrowableArray<const char*>* ImageFile::packages(const char* name) {
 267   char entry[JVM_MAXPATHLEN];
 268   bool overflow = jio_snprintf(entry, sizeof(entry), "%s/packages.offsets", name) == -1;
 269   guarantee(!overflow, "package name overflow");
 270 
 271   u1* buffer;
 272   u8 size;
 273 
 274   get_resource(entry, buffer, size);
 275   guarantee(buffer, "missing module packages reource");
 276   ImageStrings strings(_string_bytes, _header._strings_size);
 277   GrowableArray<const char*>* pkgs = new GrowableArray<const char*>();
 278   int count = size / 4;
 279   for (int i = 0; i < count; i++) {
 280     u4 offset = Bytes::get_Java_u4(buffer + (i*4));
 281     const char* p = strings.get(offset);
 282     pkgs->append(p);
 283   }
 284 
 285   return pkgs;
 286 }
   1 /*
   2  * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
   3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   4  *
   5  * This code is free software; you can redistribute it and/or modify it
   6  * under the terms of the GNU General Public License version 2 only, as
   7  * published by the Free Software Foundation.
   8  *
   9  * This code is distributed in the hope that it will be useful, but WITHOUT
  10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  11  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  12  * version 2 for more details (a copy is included in the LICENSE file that
  13  * accompanied this code).
  14  *
  15  * You should have received a copy of the GNU General Public License version
  16  * 2 along with this work; if not, write to the Free Software Foundation,
  17  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  18  *
  19  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  20  * or visit www.oracle.com if you need additional information or have any
  21  * questions.
  22  *
  23  */
  24 
  25 #include "precompiled.hpp"
  26 #include "classfile/imageDecompressor.hpp"
  27 #include "classfile/imageFile.hpp"
  28 #include "memory/resourceArea.hpp"
  29 #include "runtime/mutex.hpp"
  30 #include "runtime/mutexLocker.hpp"
  31 #include "runtime/os.inline.hpp"
  32 #include "utilities/endian.hpp"
  33 #include "utilities/growableArray.hpp"
  34 
  35 // Image files are an alternate file format for storing classes and resources. The
  36 // goal is to supply file access which is faster and smaller than the jar format.
  37 //
  38 // (More detailed nodes in the header.)
  39 //
  40 
  41 // Compute the Perfect Hashing hash code for the supplied UTF-8 string.
  42 s4 ImageStrings::hash_code(const char* string, s4 seed) {
  43   // Access bytes as unsigned.
  44   u1* bytes = (u1*)string;

  45   // Compute hash code.
  46   for (u1 byte = *bytes++; byte; byte = *bytes++) {
  47     seed = (seed * HASH_MULTIPLIER) ^ byte;
  48   }
  49   // Ensure the result is not signed.

  50   return seed & 0x7FFFFFFF;
  51 }
  52 
  53 // Match up a string in a perfect hash table.  Result still needs validation
  54 // for precise match (false positive.)
  55 s4 ImageStrings::find(Endian* endian, const char* name, s4* redirect, u4 length) {
  56   // If the table is empty, then short cut.
  57   if (redirect == NULL || length == 0) {
  58     return NOT_FOUND;
  59   }
  60   // Compute the basic perfect hash for name.
  61   s4 hash_code = ImageStrings::hash_code(name);
  62   // Modulo table size.
  63   s4 index = hash_code % length;
  64   // Get redirect entry.
  65   //   value == 0 then not found
  66   //   value < 0 then -1 - value is true index
  67   //   value > 0 then value is seed for recomputing hash.
  68   s4 value = endian->get(redirect[index]);
  69   // if recompute is required.
  70   if (value > 0) {
  71     // Entry collision value, need to recompute hash.
  72     hash_code = ImageStrings::hash_code(name, value);
  73     // Modulo table size.
  74     return hash_code % length;
  75   } else if (value < 0) {
  76     // Compute direct index.
  77     return -1 - value;
  78   }
  79   // No entry found.
  80   return NOT_FOUND;
  81 }
  82 
  83 // Test to see if UTF-8 string begins with the start UTF-8 string.  If so,
  84 // return non-NULL address of remaining portion of string.  Otherwise, return
  85 // NULL.  Used to test sections of a path without copying from image string
  86 // table.
  87 const char* ImageStrings::starts_with(const char* string, const char* start) {
  88   char ch1, ch2;

  89   // Match up the strings the best we can.
  90   while ((ch1 = *string) && (ch2 = *start)) {
  91     if (ch1 != ch2) {
  92       // Mismatch, return NULL.
  93       return NULL;
  94     }
  95     // Next characters.
  96     string++, start++;
  97   }

  98   // Return remainder of string.
  99   return string;
 100 }
 101 
 102 // Inflates the attribute stream into individual values stored in the long
 103 // array _attributes. This allows an attribute value to be quickly accessed by
 104 // direct indexing.  Unspecified values default to zero (from constructor.)
 105 void ImageLocation::set_data(u1* data) {
 106   // Deflate the attribute stream into an array of attributes.

 107   u1 byte;
 108   // Repeat until end header is found.
 109   while ((byte = *data)) {
 110     // Extract kind from header byte.
 111     u1 kind = attribute_kind(byte);
 112     guarantee(kind < ATTRIBUTE_COUNT, "invalid image location attribute");
 113     // Extract length of data (in bytes).
 114     u1 n = attribute_length(byte);
 115     // Read value (most significant first.)
 116     _attributes[kind] = attribute_value(data + 1, n);
 117     // Position to next attribute by skipping attribute header and data bytes.
 118     data += n + 1;
 119   }
 120 }
 121 
 122 // Zero all attribute values.
 123 void ImageLocation::clear_data() {
 124   // Set defaults to zero.
 125   memset(_attributes, 0, sizeof(_attributes));
 126 }
 127 
 128 // ImageModuleData constructor maps out sub-tables for faster access.
 129 ImageModuleData::ImageModuleData(const ImageFileReader* image_file,
 130         const char* module_data_name) :
 131     _image_file(image_file),
 132     _endian(image_file->endian()),
 133     _strings(image_file->get_strings()) {
 134   // Retrieve the resource containing the module data for the image file.
 135   ImageLocation location;
 136   bool found = image_file->find_location(module_data_name, location);
 137   guarantee(found, "missing module data");
 138   u8 data_size = location.get_attribute(ImageLocation::ATTRIBUTE_UNCOMPRESSED);
 139   _data = (u1*)NEW_C_HEAP_ARRAY(char, data_size, mtClass);
 140   _image_file->get_resource(location, _data);
 141   // Map out the header.
 142   _header = (Header*)_data;
 143   // Get the package to module entry count.
 144   u4 ptm_count = _header->ptm_count(_endian);
 145   // Get the module to package entry count.
 146   u4 mtp_count = _header->mtp_count(_endian);
 147   // Compute the offset of the package to module perfect hash redirect.
 148   u4 ptm_redirect_offset = sizeof(Header);
 149   // Compute the offset of the package to module data.
 150   u4 ptm_data_offset = ptm_redirect_offset + ptm_count * sizeof(s4);
 151   // Compute the offset of the module to package perfect hash redirect.
 152   u4 mtp_redirect_offset = ptm_data_offset + ptm_count * sizeof(PTMData);
 153   // Compute the offset of the module to package data.
 154   u4 mtp_data_offset = mtp_redirect_offset + mtp_count * sizeof(s4);
 155   // Compute the offset of the module to package tables.
 156   u4 mtp_packages_offset = mtp_data_offset + mtp_count * sizeof(MTPData);
 157   // Compute the address of the package to module perfect hash redirect.
 158   _ptm_redirect = (s4*)(_data + ptm_redirect_offset);
 159   // Compute the address of the package to module data.
 160   _ptm_data = (PTMData*)(_data + ptm_data_offset);
 161   // Compute the address of the module to package perfect hash redirect.
 162   _mtp_redirect = (s4*)(_data + mtp_redirect_offset);
 163   // Compute the address of the module to package data.
 164   _mtp_data = (MTPData*)(_data + mtp_data_offset);
 165   // Compute the address of the module to package tables.
 166   _mtp_packages = (s4*)(_data + mtp_packages_offset);
 167 }
 168 
 169 // Release module data resource.
 170 ImageModuleData::~ImageModuleData() {
 171   if (_data != NULL) {
 172     FREE_C_HEAP_ARRAY(u1, _data);
 173   }
 174 }
 175 
 176 // Return the name of the module data resource.  Ex. "./lib/modules/file.jimage"
 177 // yields "file.jdata"
 178 void ImageModuleData::module_data_name(char* buffer, const char* image_file_name) {
 179   // Locate the last slash in the file name path.
 180   const char* slash = strrchr(image_file_name, os::file_separator()[0]);
 181   // Trim the path to name and extension.
 182   const char* name = slash != NULL ? slash + 1 : (char *)image_file_name;
 183   // Locate the extension period.
 184   const char* dot = strrchr(name, '.');
 185   guarantee(dot, "missing extension on jimage name");
 186   // Trim to only base name.
 187   int length = dot - name;
 188   strncpy(buffer, name, length);
 189   buffer[length] = '\0';
 190   // Append extension.
 191   strcat(buffer, ".jdata");
 192 }
 193 
 194 // Return the module in which a package resides.  Returns NULL if not found.
 195 const char* ImageModuleData::package_to_module(const char* package_name) {
 196   // Search the package to module table.
 197   s4 index = ImageStrings::find(_endian, package_name, _ptm_redirect,
 198                                   _header->ptm_count(_endian));
 199   // If entry is found.
 200   if (index != ImageStrings::NOT_FOUND) {
 201     // Retrieve the package to module entry.
 202     PTMData* data = _ptm_data + index;
 203     // Verify that it is the correct data.
 204     if (strcmp(package_name, get_string(data->name_offset(_endian))) != 0) {
 205       return NULL;
 206     }
 207     // Return the module name.
 208     return get_string(data->module_name_offset(_endian));
 209   }
 210   return NULL;
 211 }
 212 
 213 // Returns all the package names in a module.  Returns NULL if module not found.
 214 GrowableArray<const char*>* ImageModuleData::module_to_packages(const char* module_name) {
 215   // Search the module to package table.
 216   s4 index = ImageStrings::find(_endian, module_name, _mtp_redirect,
 217                                   _header->mtp_count(_endian));
 218   // If entry is found.
 219   if (index != ImageStrings::NOT_FOUND) {
 220     // Retrieve the module to package entry.
 221     MTPData* data = _mtp_data + index;
 222     // Verify that it is the correct data.
 223     if (strcmp(module_name, get_string(data->name_offset(_endian))) != 0) {
 224       return NULL;
 225     }
 226     // Construct an array of all the package entries.
 227     GrowableArray<const char*>* packages = new GrowableArray<const char*>();
 228     s4 package_offset = data->package_offset(_endian);
 229     for (u4 i = 0; i < data->package_count(_endian); i++) {
 230       u4 package_name_offset = mtp_package(package_offset + i);
 231       const char* package_name = get_string(package_name_offset);
 232       packages->append(package_name);
 233     }
 234     return packages;
 235   }
 236   return NULL;
 237 }
 238 
 239 // Table to manage multiple opens of an image file.
 240 GrowableArray<ImageFileReader*>* ImageFileReader::_reader_table =
 241   new(ResourceObj::C_HEAP, mtInternal) GrowableArray<ImageFileReader*>(2, true);
 242 
 243 // Open an image file, reuse structure if file already open.
 244 ImageFileReader* ImageFileReader::open(const char* name, bool big_endian) {
 245   // Lock out _reader_table.
 246   MutexLocker ml(ImageFileReaderTable_lock);
 247   ImageFileReader* reader;
 248   // Search for an exist image file.
 249   for (int i = 0; i < _reader_table->length(); i++) {
 250     // Retrieve table entry.
 251     reader = _reader_table->at(i);
 252     // If name matches, then reuse (bump up use count.)
 253     if (strcmp(reader->name(), name) == 0) {
 254       reader->inc_use();
 255       return reader;
 256     }
 257   }
 258   // Need a new image reader.
 259   reader = new ImageFileReader(name, big_endian);
 260   bool opened = reader->open();
 261   // If failed to open.
 262   if (!opened) {
 263     delete reader;
 264     return NULL;
 265   }
 266   // Bump use count and add to table.
 267   reader->inc_use();
 268   _reader_table->append(reader);
 269   return reader;
 270 }
 271 
 272 // Close an image file if the file is not in use elsewhere.
 273 void ImageFileReader::close(ImageFileReader *reader) {
 274   // Lock out _reader_table.
 275   MutexLocker ml(ImageFileReaderTable_lock);
 276   // If last use then remove from table and then close.
 277   if (reader->dec_use()) {
 278     _reader_table->remove(reader);
 279     delete reader;
 280   }
 281 }
 282 
 283 // Return an id for the specifed ImageFileReader.
 284 u8 ImageFileReader::readerToID(ImageFileReader *reader) {
 285   // ID is just the cloaked reader address.
 286   return (u8)reader;
 287 }
 288 
 289 // Validate the image id.
 290 bool ImageFileReader::idCheck(u8 id) {
 291   // Make sure the ID is a managed (_reader_table) reader.
 292   MutexLocker ml(ImageFileReaderTable_lock);
 293   return _reader_table->contains((ImageFileReader*)id);
 294 }
 295 
 296 // Return an id for the specifed ImageFileReader.
 297 ImageFileReader* ImageFileReader::idToReader(u8 id) {
 298 #ifdef PRODUCT
 299   // Fast convert.
 300   return (ImageFileReader*)id;
 301 #else
 302   // Do a slow check before fast convert.
 303   return idCheck(id) ? (ImageFileReader*)id : NULL;
 304 #endif
 305 }
 306 
 307 // Constructor intializes to a closed state.
 308 ImageFileReader::ImageFileReader(const char* name, bool big_endian) {
 309   // Copy the image file name.
 310   _name = NEW_C_HEAP_ARRAY(char, strlen(name) + 1, mtClass);
 311   strcpy(_name, name);

 312   // Initialize for a closed file.
 313   _fd = -1;
 314   _endian = Endian::get_handler(big_endian);
 315   _index_data = NULL;
 316 }
 317 
 318 // Close image and free up data structures.
 319 ImageFileReader::~ImageFileReader() {
 320   // Ensure file is closed.
 321   close();

 322   // Free up name.
 323   if (_name != NULL) {
 324     FREE_C_HEAP_ARRAY(char, _name);
 325     _name = NULL;
 326   }
 327 }
 328 
 329 // Open image file for read access.
 330 bool ImageFileReader::open() {
 331   // If file exists open for reading.
 332   struct stat st;
 333   if (os::stat(_name, &st) != 0 ||
 334     (st.st_mode & S_IFREG) != S_IFREG ||
 335     (_fd = os::open(_name, 0, O_RDONLY)) == -1) {
 336     return false;
 337   }
 338   // Retrieve the file size.
 339   _file_size = (u8)st.st_size;
 340   // Read image file header and verify it has a valid header.
 341   size_t header_size = sizeof(ImageHeader);
 342   if (_file_size < header_size ||
 343     !read_at((u1*)&_header, header_size, 0) ||
 344     _header.magic(_endian) != IMAGE_MAGIC ||
 345     _header.major_version(_endian) != MAJOR_VERSION ||
 346     _header.minor_version(_endian) != MINOR_VERSION) {
 347     close();
 348     return false;
 349   }
 350   // Size of image index.

 351   _index_size = index_size();
 352   // Make sure file is large enough to contain the index.
 353   if (_file_size < _index_size) {







 354     return false;
 355   }
 356   // Determine how much of the image is memory mapped.
 357   off_t map_size = (off_t)(MemoryMapImage ? _file_size : _index_size);
 358   // Memory map image (minimally the index.)
 359   _index_data = (u1*)os::map_memory(_fd, _name, 0, NULL, map_size, true, false);
 360   guarantee(_index_data, "image file not memory mapped");
 361   // Retrieve length of index perfect hash table.
 362   u4 length = table_length();
 363   // Compute offset of the perfect hash table redirect table.
 364   u4 redirect_table_offset = (u4)header_size;
 365   // Compute offset of index attribute offsets.
 366   u4 offsets_table_offset = redirect_table_offset + length * sizeof(s4);
 367   // Compute offset of index location attribute data.
 368   u4 location_bytes_offset = offsets_table_offset + length * sizeof(u4);
 369   // Compute offset of index string table.
 370   u4 string_bytes_offset = location_bytes_offset + locations_size();
 371   // Compute address of the perfect hash table redirect table.
 372   _redirect_table = (s4*)(_index_data + redirect_table_offset);
 373   // Compute address of index attribute offsets.
 374   _offsets_table = (u4*)(_index_data + offsets_table_offset);
 375   // Compute address of index location attribute data.
 376   _location_bytes = _index_data + location_bytes_offset;
 377   // Compute address of index string table.
 378   _string_bytes = _index_data + string_bytes_offset;
 379   // Successful open.
 380   return true;
 381 }
 382 
 383 // Close image file.
 384 void ImageFileReader::close() {
 385   // Dealllocate the index.
 386   if (_index_data != NULL) {

 387     os::unmap_memory((char*)_index_data, _index_size);




 388     _index_data = NULL;
 389   }
 390   // Close file.

 391   if (_fd != -1) {
 392     os::close(_fd);
 393     _fd = -1;
 394   }

 395 }
 396 
 397 // Read directly from the file.
 398 bool ImageFileReader::read_at(u1* data, u8 size, u8 offset) const {
 399   return os::read_at(_fd, data, size, offset) == size;
 400 }
 401 
 402 // Find the location attributes associated with the path.  Returns true if
 403 // the location is found, false otherwise.
 404 bool ImageFileReader::find_location(const char* path, ImageLocation& location) const {
 405   // Locate the entry in the index perfect hash table.
 406   s4 index = ImageStrings::find(_endian, path, _redirect_table, table_length());
 407   // If is found.
 408   if (index != ImageStrings::NOT_FOUND) {
 409     // Get address of first byte of location attribute stream.
 410     u1* data = get_location_data(index);
 411     // Expand location attributes.
 412     location.set_data(data);
 413     // Make sure result is not a false positive.
 414     return verify_location(location, path);
 415   }
 416   return false;
 417 }
 418 
 419 // Assemble the location path from the string fragments indicated in the location attributes.
 420 void ImageFileReader::location_path(ImageLocation& location, char* path, size_t max) const {
 421   // Manage the image string table.
 422   ImageStrings strings(_string_bytes, _header.strings_size(_endian));
 423   // Position to first character of the path buffer.
 424   char* next = path;
 425   // Temp for string length.
 426   size_t length;
 427   // Get module string.
 428   const char* module = location.get_attribute(ImageLocation::ATTRIBUTE_MODULE, strings);
 429   // If module string is not empty string.
 430   if (*module != '\0') {
 431     // Get length of module name.
 432     length = strlen(module);
 433     // Make sure there is no buffer overflow.
 434     guarantee(next - path + length + 2 < max, "buffer overflow");
 435     // Append '/module/'.
 436     *next++ = '/';
 437     strcpy(next, module); next += length;
 438     *next++ = '/';
 439   }
 440   // Get parent (package) string.
 441   const char* parent = location.get_attribute(ImageLocation::ATTRIBUTE_PARENT, strings);
 442   // If parent string is not empty string.
 443   if (*parent != '\0') {
 444     // Get length of module string.
 445     length = strlen(parent);
 446     // Make sure there is no buffer overflow.
 447     guarantee(next - path + length + 1 < max, "buffer overflow");
 448     // Append 'patent/' .
 449     strcpy(next, parent); next += length;
 450     *next++ = '/';
 451   }
 452   // Get base name string.
 453   const char* base = location.get_attribute(ImageLocation::ATTRIBUTE_BASE, strings);
 454   // Get length of base name.
 455   length = strlen(base);
 456   // Make sure there is no buffer overflow.
 457   guarantee(next - path + length < max, "buffer overflow");
 458   // Append base name.
 459   strcpy(next, base); next += length;
 460   // Get extension string.
 461   const char* extension = location.get_attribute(ImageLocation::ATTRIBUTE_EXTENSION, strings);
 462   // If extension string is not empty string.
 463   if (*extension != '\0') {
 464     // Get length of extension string.
 465     length = strlen(extension);
 466     // Make sure there is no buffer overflow.
 467     guarantee(next - path + length + 1 < max, "buffer overflow");
 468     // Append '.extension' .
 469     *next++ = '.';
 470     strcpy(next, extension); next += length;
 471   }
 472   // Make sure there is no buffer overflow.
 473   guarantee((size_t)(next - path) < max, "buffer overflow");
 474   // Terminate string.
 475   *next = '\0';
 476 }
 477 
 478 // Verify that a found location matches the supplied path (without copying.)
 479 bool ImageFileReader::verify_location(ImageLocation& location, const char* path) const {
 480   // Manage the image string table.
 481   ImageStrings strings(_string_bytes, _header.strings_size(_endian));
 482   // Position to first character of the path string.
 483   const char* next = path;
 484   // Get module name string.
 485   const char* module = location.get_attribute(ImageLocation::ATTRIBUTE_MODULE, strings);
 486   // If module string is not empty.
 487   if (*module != '\0') {
 488     // Compare '/module/' .
 489     if (*next++ != '/') return false;
 490     if (!(next = ImageStrings::starts_with(next, module))) return false;
 491     if (*next++ != '/') return false;
 492   }
 493   // Get parent (package) string
 494   const char* parent = location.get_attribute(ImageLocation::ATTRIBUTE_PARENT, strings);
 495   // If parent string is not empty string.
 496   if (*parent != '\0') {
 497     // Compare 'parent/' .
 498     if (!(next = ImageStrings::starts_with(next, parent))) return false;
 499     if (*next++ != '/') return false;
 500   }
 501   // Get base name string.
 502   const char* base = location.get_attribute(ImageLocation::ATTRIBUTE_BASE, strings);
 503   // Compare with basne name.
 504   if (!(next = ImageStrings::starts_with(next, base))) return false;
 505   // Get extension string.

 506   const char* extension = location.get_attribute(ImageLocation::ATTRIBUTE_EXTENSION, strings);
 507   // If extension is not empty.
 508   if (*extension != '\0') {
 509     // Compare '.extension' .
 510     if (*next++ != '.') return false;
 511     if (!(next = ImageStrings::starts_with(next, extension))) return false;
 512   }
 513   // True only if complete match and no more characters.
 514   return *next == '\0';
 515 }
 516 
 517 // Return the resource data for the supplied location.
 518 void ImageFileReader::get_resource(ImageLocation& location, u1* uncompressed_data) const {
 519   // Retrieve the byte offset and size of the resource.
 520   u8 offset = location.get_attribute(ImageLocation::ATTRIBUTE_OFFSET);
 521   u8 uncompressed_size = location.get_attribute(ImageLocation::ATTRIBUTE_UNCOMPRESSED);
 522   u8 compressed_size = location.get_attribute(ImageLocation::ATTRIBUTE_COMPRESSED);
 523   if (compressed_size != 0) {
 524     ResourceMark rm;
 525     u1* compressed_data;
 526     // If not memory mapped read in bytes.
 527     if (!MemoryMapImage) {
 528       // Allocate buffer for compression.
 529       compressed_data = NEW_RESOURCE_ARRAY(u1, compressed_size);
 530       // Read bytes from offset beyond the image index.
 531       bool is_read = read_at(compressed_data, compressed_size, _index_size + offset);
 532       guarantee(is_read, "error reading from image or short read");
 533     } else {
 534       compressed_data = get_data_address() + offset;























 535     }
 536     // Get image string table.
 537     const ImageStrings strings = get_strings();
 538     // Decompress resource.
 539     ImageDecompressor::decompress_resource(compressed_data, uncompressed_data, uncompressed_size,
 540             &strings, false);
 541   } else {
 542     // Read bytes from offset beyond the image index.
 543     bool is_read = read_at(uncompressed_data, uncompressed_size, _index_size + offset);
 544     guarantee(is_read, "error reading from image or short read");










 545   }


 546 }
< prev index next >