diff src/share/vm/memory/filemap.cpp @ 20527:8cb56c8cb30d

Merge
author jiangli
date Mon, 15 Sep 2014 16:39:00 -0400
parents 6e0cb14ce59b ca6d25be853b
children 0558eb13dcf3
line wrap: on
line diff
--- a/src/share/vm/memory/filemap.cpp	Wed Sep 10 09:05:31 2014 -0700
+++ b/src/share/vm/memory/filemap.cpp	Mon Sep 15 16:39:00 2014 -0400
@@ -314,7 +314,6 @@
     fail_continue("The shared archive file has the wrong version.");
     return false;
   }
-  _file_offset = (long)n;
 
   size_t info_size = _header->_paths_misc_info_size;
   _paths_misc_info = NEW_C_HEAP_ARRAY_RETURN_NULL(char, info_size, mtClass);
@@ -330,6 +329,14 @@
     return false;
   }
 
+  size_t len = lseek(fd, 0, SEEK_END);
+  struct FileMapInfo::FileMapHeader::space_info* si =
+    &_header->_space[MetaspaceShared::mc];
+  if (si->_file_offset >= len || len - si->_file_offset < si->_used) {
+    fail_continue("The shared archive file has been truncated.");
+    return false;
+  }
+
   _file_offset += (long)n;
   return true;
 }
@@ -430,6 +437,7 @@
   si->_capacity = capacity;
   si->_read_only = read_only;
   si->_allow_exec = allow_exec;
+  si->_crc = ClassLoader::crc32(0, base, (jint)size);
   write_bytes_aligned(base, (int)size);
 }
 
@@ -454,14 +462,15 @@
 // Align file position to an allocation unit boundary.
 
 void FileMapInfo::align_file_position() {
-  long new_file_offset = align_size_up(_file_offset, os::vm_allocation_granularity());
+  size_t new_file_offset = align_size_up(_file_offset,
+                                         os::vm_allocation_granularity());
   if (new_file_offset != _file_offset) {
     _file_offset = new_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;
-      if (lseek(_fd, _file_offset, SEEK_SET) < 0) {
+      if (lseek(_fd, (long)_file_offset, SEEK_SET) < 0) {
         fail_stop("Unable to seek.", NULL);
       }
       char zero = 0;
@@ -568,6 +577,19 @@
   return base;
 }
 
+bool FileMapInfo::verify_region_checksum(int i) {
+  if (!VerifySharedSpaces) {
+    return true;
+  }
+  const char* buf = _header->_space[i]._base;
+  size_t sz = _header->_space[i]._used;
+  int crc = ClassLoader::crc32(0, buf, (jint)sz);
+  if (crc != _header->_space[i]._crc) {
+    fail_continue("Checksum verification failed.");
+    return false;
+  }
+  return true;
+}
 
 // Unmap a memory region in the address space.
 
@@ -628,13 +650,31 @@
   return true;
 }
 
+int FileMapInfo::FileMapHeader::compute_crc() {
+  char* header = data();
+  // start computing from the field after _crc
+  char* buf = (char*)&_crc + sizeof(int);
+  size_t sz = data_size() - (buf - header);
+  int crc = ClassLoader::crc32(0, buf, (jint)sz);
+  return crc;
+}
+
+int FileMapInfo::compute_header_crc() {
+  return _header->compute_crc();
+}
+
 bool FileMapInfo::FileMapHeader::validate() {
+  if (_magic != (int)0xf00baba2) {
+    FileMapInfo::fail_continue("The shared archive file has a bad magic number.");
+    return false;
+  }
+  if (VerifySharedSpaces && compute_crc() != _crc) {
+    fail_continue("Header checksum verification failed.");
+    return false;
+  }
   if (_version != current_version()) {
     FileMapInfo::fail_continue("The shared archive file is the wrong version.");
-    return false;
-  }
-  if (_magic != (int)0xf00baba2) {
-    FileMapInfo::fail_continue("The shared archive file has a bad magic number.");
+
     return false;
   }
   char header_version[JVM_IDENT_MAX];