138 } 139 } 140 va_end(ap); 141 } 142 143 // Fill in the fileMapInfo structure with data about this VM instance. 144 145 // This method copies the vm version info into header_version. If the version is too 146 // long then a truncated version, which has a hash code appended to it, is copied. 147 // 148 // Using a template enables this method to verify that header_version is an array of 149 // length JVM_IDENT_MAX. This ensures that the code that writes to the CDS file and 150 // the code that reads the CDS file will both use the same size buffer. Hence, will 151 // use identical truncation. This is necessary for matching of truncated versions. 152 template <int N> static void get_header_version(char (&header_version) [N]) { 153 assert(N == JVM_IDENT_MAX, "Bad header_version size"); 154 155 const char *vm_version = VM_Version::internal_vm_info_string(); 156 const int version_len = (int)strlen(vm_version); 157 158 if (version_len < (JVM_IDENT_MAX-1)) { 159 strcpy(header_version, vm_version); 160 161 } else { 162 // Get the hash value. Use a static seed because the hash needs to return the same 163 // value over multiple jvm invocations. 164 unsigned int hash = AltHashing::murmur3_32(8191, (const jbyte*)vm_version, version_len); 165 166 // Truncate the ident, saving room for the 8 hex character hash value. 167 strncpy(header_version, vm_version, JVM_IDENT_MAX-9); 168 169 // Append the hash code as eight hex digits. 170 sprintf(&header_version[JVM_IDENT_MAX-9], "%08x", hash); 171 header_version[JVM_IDENT_MAX-1] = 0; // Null terminate. 172 } 173 } 174 175 FileMapInfo::FileMapInfo(bool is_static) { 176 memset((void*)this, 0, sizeof(FileMapInfo)); 177 _is_static = is_static; 178 size_t header_size; 179 if (is_static) { 180 assert(_current_info == NULL, "must be singleton"); // not thread safe 181 _current_info = this; 182 header_size = sizeof(FileMapHeader); 183 } else { 184 assert(_dynamic_archive_info == NULL, "must be singleton"); // not thread safe 185 _dynamic_archive_info = this; 186 header_size = sizeof(DynamicArchiveHeader); 187 } 188 _header = (FileMapHeader*)os::malloc(header_size, mtInternal); 189 memset((void*)_header, 0, header_size); 190 _header->_header_size = header_size; 191 _header->_version = INVALID_CDS_ARCHIVE_VERSION; 192 _header->_has_platform_or_app_classes = true; 874 } 875 876 os::free(dynamic_header); 877 os::close(fd); 878 return true; 879 } 880 881 void FileMapInfo::restore_shared_path_table() { 882 _shared_path_table = _current_info->_header->_shared_path_table; 883 } 884 885 // Read the FileMapInfo information from the file. 886 887 bool FileMapInfo::init_from_file(int fd, bool is_static) { 888 size_t sz = is_static ? sizeof(FileMapHeader) : sizeof(DynamicArchiveHeader); 889 size_t n = os::read(fd, _header, (unsigned int)sz); 890 if (n != sz) { 891 fail_continue("Unable to read the file header."); 892 return false; 893 } 894 if (_header->_version != CURRENT_CDS_ARCHIVE_VERSION) { 895 fail_continue("The shared archive file has the wrong version."); 896 return false; 897 } 898 _file_offset = n; 899 900 size_t info_size = _header->_paths_misc_info_size; 901 _paths_misc_info = NEW_C_HEAP_ARRAY(char, info_size, mtClass); 902 n = os::read(fd, _paths_misc_info, (unsigned int)info_size); 903 if (n != info_size) { 904 fail_continue("Unable to read the shared path info header."); 905 FREE_C_HEAP_ARRAY(char, _paths_misc_info); 906 _paths_misc_info = NULL; 907 return false; 908 } 909 _file_offset += n + _header->_base_archive_name_size; // accounts for the size of _base_archive_name 910 911 if (is_static) { 912 if (_header->_magic != CDS_ARCHIVE_MAGIC) { 913 fail_continue("Incorrect static archive magic number"); 914 return false; 915 } 916 // just checking the last region is sufficient since the archive is written 917 // in sequential order 918 size_t len = lseek(fd, 0, SEEK_END); 919 CDSFileMapRegion* si = space_at(MetaspaceShared::last_valid_region); 920 // The last space might be empty 921 if (si->_file_offset > len || len - si->_file_offset < si->_used) { 922 fail_continue("The shared archive file has been truncated."); 923 return false; 924 } 925 926 SharedBaseAddress = _header->_shared_base_address; 927 } 928 929 return true; 930 } 931 932 933 // Read the FileMapInfo information from the file. 934 bool FileMapInfo::open_for_read(const char* path) { 935 if (_file_open) { 1733 if (HeapShared::is_heap_region(idx)) { 1734 assert(DumpSharedSpaces, "The following doesn't work at runtime"); 1735 return si->_used > 0 ? 1736 (char*)start_address_as_decoded_with_current_oop_encoding_mode(si) : NULL; 1737 } else { 1738 return si->_addr._base; 1739 } 1740 } 1741 1742 int FileMapHeader::compute_crc() { 1743 char* start = (char*)this; 1744 // start computing from the field after _crc 1745 char* buf = (char*)&_crc + sizeof(_crc); 1746 size_t sz = _header_size - (buf - start); 1747 int crc = ClassLoader::crc32(0, buf, (jint)sz); 1748 return crc; 1749 } 1750 1751 // This function should only be called during run time with UseSharedSpaces enabled. 1752 bool FileMapHeader::validate() { 1753 if (VerifySharedSpaces && compute_crc() != _crc) { 1754 FileMapInfo::fail_continue("Header checksum verification failed."); 1755 return false; 1756 } 1757 1758 if (!Arguments::has_jimage()) { 1759 FileMapInfo::fail_continue("The shared archive file cannot be used with an exploded module build."); 1760 return false; 1761 } 1762 1763 if (_version != CURRENT_CDS_ARCHIVE_VERSION) { 1764 FileMapInfo::fail_continue("The shared archive file is the wrong version."); 1765 return false; 1766 } 1767 if (_magic != CDS_ARCHIVE_MAGIC && _magic != CDS_DYNAMIC_ARCHIVE_MAGIC) { 1768 FileMapInfo::fail_continue("The shared archive file has a bad magic number."); 1769 return false; 1770 } 1771 char header_version[JVM_IDENT_MAX]; 1772 get_header_version(header_version); 1773 if (strncmp(_jvm_ident, header_version, JVM_IDENT_MAX-1) != 0) { 1774 log_info(class, path)("expected: %s", header_version); 1775 log_info(class, path)("actual: %s", _jvm_ident); 1776 FileMapInfo::fail_continue("The shared archive file was created by a different" 1777 " version or build of HotSpot"); 1778 return false; 1779 } 1780 if (_obj_alignment != ObjectAlignmentInBytes) { 1781 FileMapInfo::fail_continue("The shared archive file's ObjectAlignmentInBytes of %d" 1782 " does not equal the current ObjectAlignmentInBytes of " INTX_FORMAT ".", 1783 _obj_alignment, ObjectAlignmentInBytes); 1784 return false; 1785 } 1786 if (_compact_strings != CompactStrings) { 1787 FileMapInfo::fail_continue("The shared archive file's CompactStrings setting (%s)" 1788 " does not equal the current CompactStrings setting (%s).", 1789 _compact_strings ? "enabled" : "disabled", 1790 CompactStrings ? "enabled" : "disabled"); 1791 return false; 1792 } 1793 1794 // This must be done after header validation because it might change the 1795 // header data 1796 const char* prop = Arguments::get_property("java.system.class.loader"); 1797 if (prop != NULL) { 1798 warning("Archived non-system classes are disabled because the " 1799 "java.system.class.loader property is specified (value = \"%s\"). " | 138 } 139 } 140 va_end(ap); 141 } 142 143 // Fill in the fileMapInfo structure with data about this VM instance. 144 145 // This method copies the vm version info into header_version. If the version is too 146 // long then a truncated version, which has a hash code appended to it, is copied. 147 // 148 // Using a template enables this method to verify that header_version is an array of 149 // length JVM_IDENT_MAX. This ensures that the code that writes to the CDS file and 150 // the code that reads the CDS file will both use the same size buffer. Hence, will 151 // use identical truncation. This is necessary for matching of truncated versions. 152 template <int N> static void get_header_version(char (&header_version) [N]) { 153 assert(N == JVM_IDENT_MAX, "Bad header_version size"); 154 155 const char *vm_version = VM_Version::internal_vm_info_string(); 156 const int version_len = (int)strlen(vm_version); 157 158 memset(header_version, 0, JVM_IDENT_MAX); 159 160 if (version_len < (JVM_IDENT_MAX-1)) { 161 strcpy(header_version, vm_version); 162 163 } else { 164 // Get the hash value. Use a static seed because the hash needs to return the same 165 // value over multiple jvm invocations. 166 unsigned int hash = AltHashing::murmur3_32(8191, (const jbyte*)vm_version, version_len); 167 168 // Truncate the ident, saving room for the 8 hex character hash value. 169 strncpy(header_version, vm_version, JVM_IDENT_MAX-9); 170 171 // Append the hash code as eight hex digits. 172 sprintf(&header_version[JVM_IDENT_MAX-9], "%08x", hash); 173 header_version[JVM_IDENT_MAX-1] = 0; // Null terminate. 174 } 175 176 assert(header_version[JVM_IDENT_MAX-1] == 0, "must be"); 177 } 178 179 FileMapInfo::FileMapInfo(bool is_static) { 180 memset((void*)this, 0, sizeof(FileMapInfo)); 181 _is_static = is_static; 182 size_t header_size; 183 if (is_static) { 184 assert(_current_info == NULL, "must be singleton"); // not thread safe 185 _current_info = this; 186 header_size = sizeof(FileMapHeader); 187 } else { 188 assert(_dynamic_archive_info == NULL, "must be singleton"); // not thread safe 189 _dynamic_archive_info = this; 190 header_size = sizeof(DynamicArchiveHeader); 191 } 192 _header = (FileMapHeader*)os::malloc(header_size, mtInternal); 193 memset((void*)_header, 0, header_size); 194 _header->_header_size = header_size; 195 _header->_version = INVALID_CDS_ARCHIVE_VERSION; 196 _header->_has_platform_or_app_classes = true; 878 } 879 880 os::free(dynamic_header); 881 os::close(fd); 882 return true; 883 } 884 885 void FileMapInfo::restore_shared_path_table() { 886 _shared_path_table = _current_info->_header->_shared_path_table; 887 } 888 889 // Read the FileMapInfo information from the file. 890 891 bool FileMapInfo::init_from_file(int fd, bool is_static) { 892 size_t sz = is_static ? sizeof(FileMapHeader) : sizeof(DynamicArchiveHeader); 893 size_t n = os::read(fd, _header, (unsigned int)sz); 894 if (n != sz) { 895 fail_continue("Unable to read the file header."); 896 return false; 897 } 898 899 if (!Arguments::has_jimage()) { 900 FileMapInfo::fail_continue("The shared archive file cannot be used with an exploded module build."); 901 return false; 902 } 903 904 unsigned int expected_magic = is_static ? CDS_ARCHIVE_MAGIC : CDS_DYNAMIC_ARCHIVE_MAGIC; 905 if (_header->_magic != expected_magic) { 906 log_info(cds)("_magic expected: 0x%08x", expected_magic); 907 log_info(cds)(" actual: 0x%08x", _header->_magic); 908 FileMapInfo::fail_continue("The shared archive file has a bad magic number."); 909 return false; 910 } 911 912 if (_header->_version != CURRENT_CDS_ARCHIVE_VERSION) { 913 log_info(cds)("_version expected: %d", CURRENT_CDS_ARCHIVE_VERSION); 914 log_info(cds)(" actual: %d", _header->_version); 915 fail_continue("The shared archive file has the wrong version."); 916 return false; 917 } 918 919 if (_header->_header_size != sz) { 920 log_info(cds)("_header_size expected: " SIZE_FORMAT, sz); 921 log_info(cds)(" actual: " SIZE_FORMAT, _header->_header_size); 922 FileMapInfo::fail_continue("The shared archive file has an incorrect header size."); 923 return false; 924 } 925 926 if (_header->_jvm_ident[JVM_IDENT_MAX-1] != 0) { 927 FileMapInfo::fail_continue("JVM version identifier is corrupted."); 928 return false; 929 } 930 931 char header_version[JVM_IDENT_MAX]; 932 get_header_version(header_version); 933 if (strncmp(_header->_jvm_ident, header_version, JVM_IDENT_MAX-1) != 0) { 934 log_info(cds)("_jvm_ident expected: %s", header_version); 935 log_info(cds)(" actual: %s", _header->_jvm_ident); 936 FileMapInfo::fail_continue("The shared archive file was created by a different" 937 " version or build of HotSpot"); 938 return false; 939 } 940 941 if (VerifySharedSpaces) { 942 int expected_crc = _header->compute_crc(); 943 if (expected_crc != _header->_crc) { 944 log_info(cds)("_crc expected: %d", expected_crc); 945 log_info(cds)(" actual: %d", _header->_crc); 946 FileMapInfo::fail_continue("Header checksum verification failed."); 947 return false; 948 } 949 } 950 951 _file_offset = n; 952 953 size_t info_size = _header->_paths_misc_info_size; 954 _paths_misc_info = NEW_C_HEAP_ARRAY(char, info_size, mtClass); 955 n = os::read(fd, _paths_misc_info, (unsigned int)info_size); 956 if (n != info_size) { 957 fail_continue("Unable to read the shared path info header."); 958 FREE_C_HEAP_ARRAY(char, _paths_misc_info); 959 _paths_misc_info = NULL; 960 return false; 961 } 962 _file_offset += n + _header->_base_archive_name_size; // accounts for the size of _base_archive_name 963 964 if (is_static) { 965 // just checking the last region is sufficient since the archive is written 966 // in sequential order 967 size_t len = lseek(fd, 0, SEEK_END); 968 CDSFileMapRegion* si = space_at(MetaspaceShared::last_valid_region); 969 // The last space might be empty 970 if (si->_file_offset > len || len - si->_file_offset < si->_used) { 971 fail_continue("The shared archive file has been truncated."); 972 return false; 973 } 974 975 SharedBaseAddress = _header->_shared_base_address; 976 } 977 978 return true; 979 } 980 981 982 // Read the FileMapInfo information from the file. 983 bool FileMapInfo::open_for_read(const char* path) { 984 if (_file_open) { 1782 if (HeapShared::is_heap_region(idx)) { 1783 assert(DumpSharedSpaces, "The following doesn't work at runtime"); 1784 return si->_used > 0 ? 1785 (char*)start_address_as_decoded_with_current_oop_encoding_mode(si) : NULL; 1786 } else { 1787 return si->_addr._base; 1788 } 1789 } 1790 1791 int FileMapHeader::compute_crc() { 1792 char* start = (char*)this; 1793 // start computing from the field after _crc 1794 char* buf = (char*)&_crc + sizeof(_crc); 1795 size_t sz = _header_size - (buf - start); 1796 int crc = ClassLoader::crc32(0, buf, (jint)sz); 1797 return crc; 1798 } 1799 1800 // This function should only be called during run time with UseSharedSpaces enabled. 1801 bool FileMapHeader::validate() { 1802 1803 if (_obj_alignment != ObjectAlignmentInBytes) { 1804 FileMapInfo::fail_continue("The shared archive file's ObjectAlignmentInBytes of %d" 1805 " does not equal the current ObjectAlignmentInBytes of " INTX_FORMAT ".", 1806 _obj_alignment, ObjectAlignmentInBytes); 1807 return false; 1808 } 1809 if (_compact_strings != CompactStrings) { 1810 FileMapInfo::fail_continue("The shared archive file's CompactStrings setting (%s)" 1811 " does not equal the current CompactStrings setting (%s).", 1812 _compact_strings ? "enabled" : "disabled", 1813 CompactStrings ? "enabled" : "disabled"); 1814 return false; 1815 } 1816 1817 // This must be done after header validation because it might change the 1818 // header data 1819 const char* prop = Arguments::get_property("java.system.class.loader"); 1820 if (prop != NULL) { 1821 warning("Archived non-system classes are disabled because the " 1822 "java.system.class.loader property is specified (value = \"%s\"). " |