< prev index next >

src/java.base/share/native/libjimage/imageFile.cpp

Print this page

  1 /*
  2  * Copyright (c) 2015, 2023, Oracle and/or its affiliates. All rights reserved.
  3  *
  4  * Redistribution and use in source and binary forms, with or without
  5  * modification, are permitted provided that the following conditions
  6  * are met:
  7  *
  8  *   - Redistributions of source code must retain the above copyright
  9  *     notice, this list of conditions and the following disclaimer.
 10  *
 11  *   - Redistributions in binary form must reproduce the above copyright
 12  *     notice, this list of conditions and the following disclaimer in the
 13  *     documentation and/or other materials provided with the distribution.
 14  *
 15  *   - Neither the name of Oracle nor the names of its
 16  *     contributors may be used to endorse or promote products derived
 17  *     from this software without specific prior written permission.
 18  *
 19  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
 20  * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
 21  * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 22  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR

131         u1 kind = attribute_kind(byte);
132         assert(kind < ATTRIBUTE_COUNT && "invalid image location attribute");
133         if (kind == ATTRIBUTE_END) {
134             break;
135         }
136         // Extract length of data (in bytes).
137         u1 n = attribute_length(byte);
138         // Read value (most significant first.)
139         _attributes[kind] = attribute_value(data + 1, n);
140         // Position to next attribute by skipping attribute header and data bytes.
141         data += n + 1;
142     }
143 }
144 
145 // Zero all attribute values.
146 void ImageLocation::clear_data() {
147     // Set defaults to zero.
148     memset(_attributes, 0, sizeof(_attributes));
149 }
150 
151 // ImageModuleData constructor maps out sub-tables for faster access.
152 ImageModuleData::ImageModuleData(const ImageFileReader* image_file) :
153         _image_file(image_file),
154         _endian(image_file->endian()) {
155 }
156 
157 // Release module data resource.
158 ImageModuleData::~ImageModuleData() {
159 }
160 
161 
162 // Return the module in which a package resides.    Returns NULL if not found.
163 const char* ImageModuleData::package_to_module(const char* package_name) {
164     // replace all '/' by '.'
165     char* replaced = new char[(int) strlen(package_name) + 1];
166     assert(replaced != NULL && "allocation failed");
167     int i;
168     for (i = 0; package_name[i] != '\0'; i++) {
169       replaced[i] = package_name[i] == '/' ? '.' : package_name[i];
170     }
171     replaced[i] = '\0';
172 
173     // build path /packages/<package_name>
174     const char* radical = "/packages/";
175     char* path = new char[(int) strlen(radical) + (int) strlen(package_name) + 1];
176     assert(path != NULL && "allocation failed");
177     strcpy(path, radical);
178     strcat(path, replaced);
179     delete[] replaced;
180 
181     // retrieve package location
182     ImageLocation location;
183     bool found = _image_file->find_location(path, location);
184     delete[] path;
185     if (!found) {
186         return NULL;
187     }
188 
189     // retrieve offsets to module name
190     int size = (int)location.get_attribute(ImageLocation::ATTRIBUTE_UNCOMPRESSED);
191     u1* content = new u1[size];
192     assert(content != NULL && "allocation failed");
193     _image_file->get_resource(location, content);
194     u1* ptr = content;
195     // sequence of sizeof(8) isEmpty|offset. Use the first module that is not empty.
196     u4 offset = 0;
197     for (i = 0; i < size; i+=8) {
198         u4 isEmpty = _endian->get(*((u4*)ptr));
199         ptr += 4;
200         if (!isEmpty) {
201             offset = _endian->get(*((u4*)ptr));
202             break;
203         }
204         ptr += 4;
205     }
206     delete[] content;
207     return _image_file->get_strings().get(offset);
208 }
209 
210 // Manage a table of open image files.  This table allows multiple access points
211 // to share an open image.
212 ImageFileReaderTable::ImageFileReaderTable() : _count(0), _max(_growth) {
213     _table = static_cast<ImageFileReader**>(calloc(_max, sizeof(ImageFileReader*)));
214     assert(_table != NULL && "allocation failed");
215 }
216 
217 // Add a new image entry to the table.
218 void ImageFileReaderTable::add(ImageFileReader* image) {
219     if (_count == _max) {
220         _max += _growth;
221         _table = static_cast<ImageFileReader**>(realloc(_table, _max * sizeof(ImageFileReader*)));
222     }
223     _table[_count++] = image;
224 }
225 
226 // Remove an image entry from the table.
227 void ImageFileReaderTable::remove(ImageFileReader* image) {
228     for (u4 i = 0; i < _count; i++) {
229         if (_table[i] == image) {

323 // Return an id for the specified ImageFileReader.
324 u8 ImageFileReader::reader_to_ID(ImageFileReader *reader) {
325     // ID is just the cloaked reader address.
326     return (u8)reader;
327 }
328 
329 // Validate the image id.
330 bool ImageFileReader::id_check(u8 id) {
331     // Make sure the ID is a managed (_reader_table) reader.
332     SimpleCriticalSectionLock cs(&_reader_table_lock);
333     return _reader_table.contains((ImageFileReader*)id);
334 }
335 
336 // Return an id for the specified ImageFileReader.
337 ImageFileReader* ImageFileReader::id_to_reader(u8 id) {
338     assert(id_check(id) && "invalid image id");
339     return (ImageFileReader*)id;
340 }
341 
342 // Constructor initializes to a closed state.
343 ImageFileReader::ImageFileReader(const char* name, bool big_endian) :
344     _module_data(NULL) {
345     // Copy the image file name.
346      int len = (int) strlen(name) + 1;
347     _name = new char[len];
348     assert(_name != NULL  && "allocation failed");
349     strncpy(_name, name, len);
350     // Initialize for a closed file.
351     _fd = -1;
352     _endian = Endian::get_handler(big_endian);
353     _index_data = NULL;
354 }
355 
356 // Close image and free up data structures.
357 ImageFileReader::~ImageFileReader() {
358     // Ensure file is closed.
359     close();
360     // Free up name.
361     if (_name) {
362         delete[] _name;
363         _name = NULL;
364     }
365 
366     if (_module_data != NULL) {
367         delete _module_data;
368     }
369 }
370 
371 // Open image file for read access.
372 bool ImageFileReader::open() {
373     // If file exists open for reading.
374     _fd = osSupport::openReadOnly(_name);
375     if (_fd == -1) {
376         return false;
377     }
378     // Retrieve the file size.
379     _file_size = osSupport::size(_name);
380     // Read image file header and verify it has a valid header.
381     size_t header_size = sizeof(ImageHeader);
382     if (_file_size < header_size ||
383         !read_at((u1*)&_header, header_size, 0) ||
384         _header.magic(_endian) != IMAGE_MAGIC ||
385         _header.major_version(_endian) != MAJOR_VERSION ||
386         _header.minor_version(_endian) != MINOR_VERSION) {
387         close();
388         return false;

397     _index_data = (u1*)osSupport::map_memory(_fd, _name, 0, (size_t)map_size());
398     assert(_index_data && "image file not memory mapped");
399     // Retrieve length of index perfect hash table.
400     u4 length = table_length();
401     // Compute offset of the perfect hash table redirect table.
402     u4 redirect_table_offset = (u4)header_size;
403     // Compute offset of index attribute offsets.
404     u4 offsets_table_offset = redirect_table_offset + length * (u4)sizeof(s4);
405     // Compute offset of index location attribute data.
406     u4 location_bytes_offset = offsets_table_offset + length * (u4)sizeof(u4);
407     // Compute offset of index string table.
408     u4 string_bytes_offset = location_bytes_offset + locations_size();
409     // Compute address of the perfect hash table redirect table.
410     _redirect_table = (s4*)(_index_data + redirect_table_offset);
411     // Compute address of index attribute offsets.
412     _offsets_table = (u4*)(_index_data + offsets_table_offset);
413     // Compute address of index location attribute data.
414     _location_bytes = _index_data + location_bytes_offset;
415     // Compute address of index string table.
416     _string_bytes = _index_data + string_bytes_offset;
417 
418     // Initialize the module data
419     _module_data = new ImageModuleData(this);
420     // Successful open (if memory allocation succeeded).
421     return _module_data != NULL;
422 }
423 
424 // Close image file.
425 void ImageFileReader::close() {
426     // Deallocate the index.
427     if (_index_data) {
428         osSupport::unmap_memory((char*)_index_data, (size_t)map_size());
429         _index_data = NULL;
430     }
431     // Close file.
432     if (_fd != -1) {
433         osSupport::close(_fd);
434         _fd = -1;
435     }
436 
437     if (_module_data != NULL) {
438         delete _module_data;
439         _module_data = NULL;
440     }
441 }
442 
443 // Read directly from the file.
444 bool ImageFileReader::read_at(u1* data, u8 size, u8 offset) const {
445     return (u8)osSupport::read(_fd, (char*)data, size, offset) == size;
446 }
447 
448 // Find the location attributes associated with the path.    Returns true if
449 // the location is found, false otherwise.
450 bool ImageFileReader::find_location(const char* path, ImageLocation& location) const {
451     // Locate the entry in the index perfect hash table.
452     s4 index = ImageStrings::find(_endian, path, _redirect_table, table_length());
453     // If is found.
454     if (index != ImageStrings::NOT_FOUND) {
455         // Get address of first byte of location attribute stream.
456         u1* data = get_location_data(index);
457         // Expand location attributes.
458         location.set_data(data);
459         // Make sure result is not a false positive.
460         return verify_location(location, path);

550             bool is_read = read_at(compressed_data, compressed_size, _index_size + offset);
551             assert(is_read && "error reading from image or short read");
552         } else {
553             compressed_data = get_data_address() + offset;
554         }
555         // Get image string table.
556         const ImageStrings strings = get_strings();
557         // Decompress resource.
558         ImageDecompressor::decompress_resource(compressed_data, uncompressed_data, uncompressed_size,
559                         &strings, _endian);
560         // If not memory mapped then release temporary buffer.
561         if (!memory_map_image) {
562                 delete[] compressed_data;
563         }
564     } else {
565         // Read bytes from offset beyond the image index.
566         bool is_read = read_at(uncompressed_data, uncompressed_size, _index_size + offset);
567         assert(is_read && "error reading from image or short read");
568     }
569 }
570 
571 // Return the ImageModuleData for this image
572 ImageModuleData * ImageFileReader::get_image_module_data() {
573     return _module_data;
574 }

  1 /*
  2  * Copyright (c) 2015, 2025, Oracle and/or its affiliates. All rights reserved.
  3  *
  4  * Redistribution and use in source and binary forms, with or without
  5  * modification, are permitted provided that the following conditions
  6  * are met:
  7  *
  8  *   - Redistributions of source code must retain the above copyright
  9  *     notice, this list of conditions and the following disclaimer.
 10  *
 11  *   - Redistributions in binary form must reproduce the above copyright
 12  *     notice, this list of conditions and the following disclaimer in the
 13  *     documentation and/or other materials provided with the distribution.
 14  *
 15  *   - Neither the name of Oracle nor the names of its
 16  *     contributors may be used to endorse or promote products derived
 17  *     from this software without specific prior written permission.
 18  *
 19  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
 20  * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
 21  * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 22  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR

131         u1 kind = attribute_kind(byte);
132         assert(kind < ATTRIBUTE_COUNT && "invalid image location attribute");
133         if (kind == ATTRIBUTE_END) {
134             break;
135         }
136         // Extract length of data (in bytes).
137         u1 n = attribute_length(byte);
138         // Read value (most significant first.)
139         _attributes[kind] = attribute_value(data + 1, n);
140         // Position to next attribute by skipping attribute header and data bytes.
141         data += n + 1;
142     }
143 }
144 
145 // Zero all attribute values.
146 void ImageLocation::clear_data() {
147     // Set defaults to zero.
148     memset(_attributes, 0, sizeof(_attributes));
149 }
150 



























































151 // Manage a table of open image files.  This table allows multiple access points
152 // to share an open image.
153 ImageFileReaderTable::ImageFileReaderTable() : _count(0), _max(_growth) {
154     _table = static_cast<ImageFileReader**>(calloc(_max, sizeof(ImageFileReader*)));
155     assert(_table != NULL && "allocation failed");
156 }
157 
158 // Add a new image entry to the table.
159 void ImageFileReaderTable::add(ImageFileReader* image) {
160     if (_count == _max) {
161         _max += _growth;
162         _table = static_cast<ImageFileReader**>(realloc(_table, _max * sizeof(ImageFileReader*)));
163     }
164     _table[_count++] = image;
165 }
166 
167 // Remove an image entry from the table.
168 void ImageFileReaderTable::remove(ImageFileReader* image) {
169     for (u4 i = 0; i < _count; i++) {
170         if (_table[i] == image) {

264 // Return an id for the specified ImageFileReader.
265 u8 ImageFileReader::reader_to_ID(ImageFileReader *reader) {
266     // ID is just the cloaked reader address.
267     return (u8)reader;
268 }
269 
270 // Validate the image id.
271 bool ImageFileReader::id_check(u8 id) {
272     // Make sure the ID is a managed (_reader_table) reader.
273     SimpleCriticalSectionLock cs(&_reader_table_lock);
274     return _reader_table.contains((ImageFileReader*)id);
275 }
276 
277 // Return an id for the specified ImageFileReader.
278 ImageFileReader* ImageFileReader::id_to_reader(u8 id) {
279     assert(id_check(id) && "invalid image id");
280     return (ImageFileReader*)id;
281 }
282 
283 // Constructor initializes to a closed state.
284 ImageFileReader::ImageFileReader(const char* name, bool big_endian) {

285     // Copy the image file name.
286      int len = (int) strlen(name) + 1;
287     _name = new char[len];
288     assert(_name != NULL  && "allocation failed");
289     strncpy(_name, name, len);
290     // Initialize for a closed file.
291     _fd = -1;
292     _endian = Endian::get_handler(big_endian);
293     _index_data = NULL;
294 }
295 
296 // Close image and free up data structures.
297 ImageFileReader::~ImageFileReader() {
298     // Ensure file is closed.
299     close();
300     // Free up name.
301     if (_name) {
302         delete[] _name;
303         _name = NULL;
304     }




305 }
306 
307 // Open image file for read access.
308 bool ImageFileReader::open() {
309     // If file exists open for reading.
310     _fd = osSupport::openReadOnly(_name);
311     if (_fd == -1) {
312         return false;
313     }
314     // Retrieve the file size.
315     _file_size = osSupport::size(_name);
316     // Read image file header and verify it has a valid header.
317     size_t header_size = sizeof(ImageHeader);
318     if (_file_size < header_size ||
319         !read_at((u1*)&_header, header_size, 0) ||
320         _header.magic(_endian) != IMAGE_MAGIC ||
321         _header.major_version(_endian) != MAJOR_VERSION ||
322         _header.minor_version(_endian) != MINOR_VERSION) {
323         close();
324         return false;

333     _index_data = (u1*)osSupport::map_memory(_fd, _name, 0, (size_t)map_size());
334     assert(_index_data && "image file not memory mapped");
335     // Retrieve length of index perfect hash table.
336     u4 length = table_length();
337     // Compute offset of the perfect hash table redirect table.
338     u4 redirect_table_offset = (u4)header_size;
339     // Compute offset of index attribute offsets.
340     u4 offsets_table_offset = redirect_table_offset + length * (u4)sizeof(s4);
341     // Compute offset of index location attribute data.
342     u4 location_bytes_offset = offsets_table_offset + length * (u4)sizeof(u4);
343     // Compute offset of index string table.
344     u4 string_bytes_offset = location_bytes_offset + locations_size();
345     // Compute address of the perfect hash table redirect table.
346     _redirect_table = (s4*)(_index_data + redirect_table_offset);
347     // Compute address of index attribute offsets.
348     _offsets_table = (u4*)(_index_data + offsets_table_offset);
349     // Compute address of index location attribute data.
350     _location_bytes = _index_data + location_bytes_offset;
351     // Compute address of index string table.
352     _string_bytes = _index_data + string_bytes_offset;
353     return true;




354 }
355 
356 // Close image file.
357 void ImageFileReader::close() {
358     // Deallocate the index.
359     if (_index_data) {
360         osSupport::unmap_memory((char*)_index_data, (size_t)map_size());
361         _index_data = NULL;
362     }
363     // Close file.
364     if (_fd != -1) {
365         osSupport::close(_fd);
366         _fd = -1;
367     }





368 }
369 
370 // Read directly from the file.
371 bool ImageFileReader::read_at(u1* data, u8 size, u8 offset) const {
372     return (u8)osSupport::read(_fd, (char*)data, size, offset) == size;
373 }
374 
375 // Find the location attributes associated with the path.    Returns true if
376 // the location is found, false otherwise.
377 bool ImageFileReader::find_location(const char* path, ImageLocation& location) const {
378     // Locate the entry in the index perfect hash table.
379     s4 index = ImageStrings::find(_endian, path, _redirect_table, table_length());
380     // If is found.
381     if (index != ImageStrings::NOT_FOUND) {
382         // Get address of first byte of location attribute stream.
383         u1* data = get_location_data(index);
384         // Expand location attributes.
385         location.set_data(data);
386         // Make sure result is not a false positive.
387         return verify_location(location, path);

477             bool is_read = read_at(compressed_data, compressed_size, _index_size + offset);
478             assert(is_read && "error reading from image or short read");
479         } else {
480             compressed_data = get_data_address() + offset;
481         }
482         // Get image string table.
483         const ImageStrings strings = get_strings();
484         // Decompress resource.
485         ImageDecompressor::decompress_resource(compressed_data, uncompressed_data, uncompressed_size,
486                         &strings, _endian);
487         // If not memory mapped then release temporary buffer.
488         if (!memory_map_image) {
489                 delete[] compressed_data;
490         }
491     } else {
492         // Read bytes from offset beyond the image index.
493         bool is_read = read_at(uncompressed_data, uncompressed_size, _index_size + offset);
494         assert(is_read && "error reading from image or short read");
495     }
496 }





< prev index next >