filemap.cpp revision 0
/*
* Copyright 2003-2006 Sun Microsystems, Inc. All Rights Reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
* CA 95054 USA or visit www.sun.com if you need additional information or
* have any questions.
*
*/
# include "incls/_precompiled.incl"
# include "incls/_filemap.cpp.incl"
# include <errno.h>
#ifndef O_BINARY // if defined (Win32) use binary files.
#define O_BINARY 0 // otherwise do nothing.
#endif
extern address JVM_FunctionAtStart();
extern address JVM_FunctionAtEnd();
// Complain and stop. All error conditions occuring during the writing of
// an archive file should stop the process. Unrecoverable errors during
// the reading of the archive file should stop the process.
// This occurs very early during initialization: tty is not initialized.
"An error has occured while processing the"
" shared archive file.\n");
}
}
// Complain and continue. Recoverable errors during the reading of the
// archive file may continue (with sharing disabled).
//
// If we continue, then disable shared spaces and close the file.
if (RequireSharedSpaces) {
}
UseSharedSpaces = false;
close();
}
// Fill in the fileMapInfo structure with data about this VM instance.
// The following fields are for sanity checks for whether this archive
// will function correctly with this JVM and the bootclasspath it's
// invoked with.
// JVM version string ... changes on each build.
} else {
fail_stop("JVM Ident field for shared archive is too long"
}
// Build checks on classpath and jar files
if (cpe->is_jar_file()) {
}
// Jar file - record timestamp and file size.
// If we can't access a jar file in the boot path, then we can't
// make assumptions about where classes get loaded from.
}
} else {
// If directories appear in boot classpath, they must be empty to
// avoid having to verify each individual class file.
}
}
}
}
// Read the FileMapInfo information from the file.
if (n != sizeof(struct FileMapHeader)) {
fail_continue("Unable to read the file header.");
return false;
}
fail_continue("The shared archive file has the wrong version.");
return false;
}
_file_offset = (long)n;
return true;
}
// Read the FileMapInfo information from the file.
bool FileMapInfo::open_for_read() {
if (fd < 0) {
// Not locating the shared archive is ok.
fail_continue("Specified shared archive not found.");
} else {
fail_continue("Failed to open shared archive file (%s).",
}
return false;
}
_file_open = true;
return true;
}
// Write the FileMapInfo information to the file.
void FileMapInfo::open_for_write() {
if (PrintSharedSpaces) {
}
// Remove the existing file in case another process has it open.
if (fd < 0) {
}
_file_offset = 0;
_file_open = true;
}
// Write the header to the file, seek to the next allocation boundary.
void FileMapInfo::write_header() {
}
// Dump shared spaces to file.
}
// Dump region to file.
bool allow_exec) {
if (_file_open) {
if (PrintSharedSpaces) {
}
} else {
}
}
// Dump bytes to file -- at the current file position.
if (_file_open) {
if (n != nbytes) {
// It is dangerous to leave the corrupted shared archive file around,
// close and remove the file. See bug 6372906.
close();
}
}
_file_offset += nbytes;
}
// Align file position to an allocation unit boundary.
void FileMapInfo::align_file_position() {
if (new_file_offset != _file_offset) {
if (_file_open) {
// Seek one byte back from the target and write a byte to insure
// that the written file is the correct length.
_file_offset -= 1;
}
char zero = 0;
}
}
}
// Dump bytes to file -- at the current file position.
}
// Close the shared archive file. This does NOT unmap mapped regions.
void FileMapInfo::close() {
if (_file_open) {
fail_stop("Unable to close the shared archive file.");
}
_file_open = false;
_fd = -1;
}
}
// Memory map a shared space from the archive file.
fail_continue("Shared space base address does not match.");
return false;
}
}
space->set_saved_mark();
}
return result;
}
// Remap the shared readonly space to shared readwrite, private.
if (!si->_read_only) {
// the space is already readwrite so we are done
return true;
}
if (!open_for_read()) {
return false;
}
si->_allow_exec);
close();
return false;
}
fail_continue("Unable to remap shared readonly space at required address.");
return false;
}
si->_read_only = false;
return true;
}
// Memory map a region in the address space.
return map_region(i, true);
}
// Memory map a region in the address space.
char *requested_addr = 0;
if (address_must_match) {
}
si->_allow_exec);
fail_continue("Unable to map shared space.");
return NULL;
}
if (address_must_match) {
fail_continue("Unable to map shared space at required address.");
return NULL;
}
} else {
}
return base;
}
// Unmap a memory region in the address space.
void FileMapInfo::unmap_region(int i) {
fail_stop("Unable to unmap shared space.");
}
}
if (!check) {
}
}
// Open the shared archive file, read and validate the header
// information (version, boot classpath, etc.). If initialization
// fails, shared spaces are disabled and the file is closed. [See
// fail_continue.]
bool FileMapInfo::initialize() {
fail_continue("Tool agent requires sharing to be disabled.");
return false;
}
if (!open_for_read()) {
return false;
}
if (!validate()) {
return false;
}
return true;
}
bool FileMapInfo::validate() {
fail_continue("The shared archive file is the wrong version.");
return false;
}
fail_continue("The shared archive file has a bad magic number.");
return false;
}
JVM_IDENT_MAX-1) != 0) {
fail_continue("The shared archive file was created by a different"
" version or build of HotSpot.");
return false;
}
// Cannot verify interpreter yet, as it can only be created after the GC
// heap has been initialized.
fail_continue("Too many jar files to share.");
return false;
}
// Build checks on classpath and jar files
int num_jars_now = 0;
if (cpe->is_jar_file()) {
// Jar file - verify timestamp and file size.
return false;
}
fail_continue("A jar file is not the one used while building"
" the shared archive file.");
return false;
}
}
++num_jars_now;
} else {
// If directories appear in boot classpath, they must be empty to
// avoid having to verify each individual class file.
return false;
}
}
}
fail_continue("The number of jar files in the boot classpath is"
" less than the number the shared archive was created with.");
return false;
}
return true;
}
// The following method is provided to see whether a given pointer
// falls in the mapped shared space.
// Param:
// p, The given pointer
// Return:
// True if the p is within the mapped shared space, otherwise, false.
bool FileMapInfo::is_in_shared_space(const void* p) {
for (int i = 0; i < CompactingPermGenGen::n_regions; i++) {
return true;
}
}
return false;
}