< prev index next >
src/hotspot/share/memory/filemap.cpp
Print this page
@@ -23,12 +23,12 @@
*/
#include "precompiled.hpp"
#include "jvm.h"
#include "classfile/classLoader.inline.hpp"
+#include "classfile/classLoaderExt.hpp"
#include "classfile/compactHashtable.inline.hpp"
-#include "classfile/sharedClassUtil.hpp"
#include "classfile/stringTable.hpp"
#include "classfile/symbolTable.hpp"
#include "classfile/systemDictionaryShared.hpp"
#include "classfile/altHashing.hpp"
#include "logging/log.hpp"
@@ -157,12 +157,13 @@
assert(_current_info == NULL, "must be singleton"); // not thread safe
_current_info = this;
memset((void*)this, 0, sizeof(FileMapInfo));
_file_offset = 0;
_file_open = false;
- _header = SharedClassUtil::allocate_file_map_header();
+ _header = new FileMapHeader();
_header->_version = _invalid_version;
+ _header->_has_platform_or_app_classes = true;
}
FileMapInfo::~FileMapInfo() {
assert(_current_info == this, "must be singleton"); // not thread safe
_current_info = NULL;
@@ -171,11 +172,11 @@
void FileMapInfo::populate_header(size_t alignment) {
_header->populate(this, alignment);
}
size_t FileMapInfo::FileMapHeader::data_size() {
- return SharedClassUtil::file_map_header_size() - sizeof(FileMapInfo::FileMapHeaderBase);
+ return sizeof(FileMapHeader) - sizeof(FileMapInfo::FileMapHeaderBase);
}
void FileMapInfo::FileMapHeader::populate(FileMapInfo* mapinfo, size_t alignment) {
_magic = 0xf00baba2;
_version = _current_version;
@@ -196,10 +197,18 @@
// will function correctly with this JVM and the bootclasspath it's
// invoked with.
// JVM version string ... changes on each build.
get_header_version(_jvm_ident);
+
+ ClassLoaderExt::finalize_shared_paths_misc_info();
+ _app_class_paths_start_index = ClassLoaderExt::app_class_paths_start_index();
+ _app_module_paths_start_index = ClassLoaderExt::app_module_paths_start_index();
+
+ _verify_local = BytecodeVerificationLocal;
+ _verify_remote = BytecodeVerificationRemote;
+ _has_platform_or_app_classes = ClassLoaderExt::has_platform_or_app_classes();
}
void SharedClassPathEntry::init(const char* name, TRAPS) {
_timestamp = 0;
_filesize = 0;
@@ -276,11 +285,11 @@
ClassPathEntry* jrt = ClassLoader::get_jrt_entry();
assert(jrt != NULL,
"No modular java runtime image present when allocating the CDS classpath entry table");
- size_t entry_size = SharedClassUtil::shared_class_path_entry_size(); // assert ( should be 8 byte aligned??)
+ size_t entry_size = sizeof(SharedClassPathEntry); // assert ( should be 8 byte aligned??)
int num_boot_classpath_entries = ClassLoader::num_boot_classpath_entries();
int num_app_classpath_entries = ClassLoader::num_app_classpath_entries();
int num_module_path_entries = ClassLoader::num_module_path_entries();
int num_entries = num_boot_classpath_entries + num_app_classpath_entries + num_module_path_entries;
size_t bytes = entry_size * num_entries;
@@ -297,11 +306,11 @@
log_info(class, path)("add main shared path (%s) %s", type, cpe->name());
SharedClassPathEntry* ent = shared_path(i);
ent->init(cpe->name(), THREAD);
if (cpe != jrt) { // No need to do jimage.
EXCEPTION_MARK; // The following call should never throw, but would exit VM on error.
- SharedClassUtil::update_shared_classpath(cpe, ent, THREAD);
+ update_shared_classpath(cpe, ent, THREAD);
}
cpe = ClassLoader::get_next_boot_classpath_entry(cpe);
i++;
}
assert(i == num_boot_classpath_entries,
@@ -312,11 +321,11 @@
while (acpe != NULL) {
log_info(class, path)("add app shared path %s", acpe->name());
SharedClassPathEntry* ent = shared_path(i);
ent->init(acpe->name(), THREAD);
EXCEPTION_MARK;
- SharedClassUtil::update_shared_classpath(acpe, ent, THREAD);
+ update_shared_classpath(acpe, ent, THREAD);
acpe = acpe->next();
i++;
}
// 3. module path
@@ -324,11 +333,11 @@
while (mpe != NULL) {
log_info(class, path)("add module path %s",mpe->name());
SharedClassPathEntry* ent = shared_path(i);
ent->init(mpe->name(), THREAD);
EXCEPTION_MARK;
- SharedClassUtil::update_shared_classpath(mpe, ent, THREAD);
+ update_shared_classpath(mpe, ent, THREAD);
mpe = mpe->next();
i++;
}
assert(i == num_entries, "number of shared path entry mismatch");
}
@@ -358,26 +367,103 @@
if (has_nonempty_dir) {
ClassLoader::exit_with_path_failure("Cannot have non-empty directory in paths", NULL);
}
}
+class ManifestStream: public ResourceObj {
+ private:
+ u1* _buffer_start; // Buffer bottom
+ u1* _buffer_end; // Buffer top (one past last element)
+ u1* _current; // Current buffer position
+
+ public:
+ // Constructor
+ ManifestStream(u1* buffer, int length) : _buffer_start(buffer),
+ _current(buffer) {
+ _buffer_end = buffer + length;
+ }
+
+ static bool is_attr(u1* attr, const char* name) {
+ return strncmp((const char*)attr, name, strlen(name)) == 0;
+ }
+
+ static char* copy_attr(u1* value, size_t len) {
+ char* buf = NEW_RESOURCE_ARRAY(char, len + 1);
+ strncpy(buf, (char*)value, len);
+ buf[len] = 0;
+ return buf;
+ }
+
+ // The return value indicates if the JAR is signed or not
+ bool check_is_signed() {
+ u1* attr = _current;
+ bool isSigned = false;
+ while (_current < _buffer_end) {
+ if (*_current == '\n') {
+ *_current = '\0';
+ u1* value = (u1*)strchr((char*)attr, ':');
+ if (value != NULL) {
+ assert(*(value+1) == ' ', "Unrecognized format" );
+ if (strstr((char*)attr, "-Digest") != NULL) {
+ isSigned = true;
+ break;
+ }
+ }
+ *_current = '\n'; // restore
+ attr = _current + 1;
+ }
+ _current ++;
+ }
+ return isSigned;
+ }
+};
+
+void FileMapInfo::update_shared_classpath(ClassPathEntry *cpe, SharedClassPathEntry* ent, TRAPS) {
+ ClassLoaderData* loader_data = ClassLoaderData::the_null_class_loader_data();
+ ResourceMark rm(THREAD);
+ jint manifest_size;
+ bool isSigned;
+
+ if (cpe->is_jar_file()) {
+ char* manifest = ClassLoaderExt::read_manifest(cpe, &manifest_size, CHECK);
+ if (manifest != NULL) {
+ ManifestStream* stream = new ManifestStream((u1*)manifest,
+ manifest_size);
+ isSigned = stream->check_is_signed();
+ if (isSigned) {
+ ent->set_is_signed(true);
+ } else {
+ // Copy the manifest into the shared archive
+ manifest = ClassLoaderExt::read_raw_manifest(cpe, &manifest_size, CHECK);
+ Array<u1>* buf = MetadataFactory::new_array<u1>(loader_data,
+ manifest_size,
+ THREAD);
+ char* p = (char*)(buf->data());
+ memcpy(p, manifest, manifest_size);
+ ent->set_manifest(buf);
+ ent->set_is_signed(false);
+ }
+ }
+ }
+}
+
+
bool FileMapInfo::validate_shared_path_table() {
assert(UseSharedSpaces, "runtime only");
_validating_shared_path_table = true;
_shared_path_table = _header->_shared_path_table;
_shared_path_entry_size = _header->_shared_path_entry_size;
_shared_path_table_size = _header->_shared_path_table_size;
- FileMapHeaderExt* header = (FileMapHeaderExt*)FileMapInfo::current_info()->header();
- int module_paths_start_index = header->_app_module_paths_start_index;
+ int module_paths_start_index = _header->_app_module_paths_start_index;
// If the shared archive contain app or platform classes, validate all entries
// in the shared path table. Otherwise, only validate the boot path entries (with
// entry index < _app_class_paths_start_index).
- int count = header->has_platform_or_app_classes() ?
- _shared_path_table_size : header->_app_class_paths_start_index;
+ int count = _header->has_platform_or_app_classes() ?
+ _shared_path_table_size : _header->_app_class_paths_start_index;
for (int i=0; i<count; i++) {
if (i < module_paths_start_index) {
if (shared_path(i)->validate()) {
log_info(class, path)("ok");
@@ -1076,10 +1162,30 @@
_compact_strings ? "enabled" : "disabled",
CompactStrings ? "enabled" : "disabled");
return false;
}
+ // This must be done after header validation because it might change the
+ // header data
+ const char* prop = Arguments::get_property("java.system.class.loader");
+ if (prop != NULL) {
+ warning("Archived non-system classes are disabled because the "
+ "java.system.class.loader property is specified (value = \"%s\"). "
+ "To use archived non-system classes, this property must be not be set", prop);
+ _has_platform_or_app_classes = false;
+ }
+
+ // For backwards compatibility, we don't check the verification setting
+ // if the archive only contains system classes.
+ if (_has_platform_or_app_classes &&
+ ((!_verify_local && BytecodeVerificationLocal) ||
+ (!_verify_remote && BytecodeVerificationRemote))) {
+ FileMapInfo::fail_continue("The shared archive file was created with less restrictive "
+ "verification setting than the current setting.");
+ return false;
+ }
+
return true;
}
bool FileMapInfo::validate_header() {
bool status = _header->validate();
< prev index next >