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 }
|