iklam@7089: /* ccheung@8184: * Copyright (c) 2014, 2015, Oracle and/or its affiliates. All rights reserved. iklam@7089: * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. iklam@7089: * iklam@7089: * This code is free software; you can redistribute it and/or modify it iklam@7089: * under the terms of the GNU General Public License version 2 only, as iklam@7089: * published by the Free Software Foundation. iklam@7089: * iklam@7089: * This code is distributed in the hope that it will be useful, but WITHOUT iklam@7089: * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or iklam@7089: * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License iklam@7089: * version 2 for more details (a copy is included in the LICENSE file that iklam@7089: * accompanied this code). iklam@7089: * iklam@7089: * You should have received a copy of the GNU General Public License version iklam@7089: * 2 along with this work; if not, write to the Free Software Foundation, iklam@7089: * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. iklam@7089: * iklam@7089: * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA iklam@7089: * or visit www.oracle.com if you need additional information or have any iklam@7089: * questions. iklam@7089: * iklam@7089: */ iklam@7089: iklam@7089: #ifndef SHARE_VM_CLASSFILE_SHAREDPATHSMISCINFO_HPP iklam@7089: #define SHARE_VM_CLASSFILE_SHAREDPATHSMISCINFO_HPP iklam@7089: iklam@7089: #include "runtime/os.hpp" iklam@7089: iklam@7089: // During dumping time, when processing class paths, we build up the dump-time iklam@7089: // classpath. The JAR files that exist are stored in the list ClassLoader::_first_entry. iklam@7089: // However, we need to store other "misc" information for run-time checking, such as iklam@7089: // iklam@7089: // + The values of Arguments::get_sysclasspath() used during dumping. iklam@7089: // iklam@7089: // + The meta-index file(s) used during dumping (incl modification time and size) iklam@7089: // iklam@7089: // + The class path elements specified during dumping but did not exist -- iklam@7089: // these elements must also be specified at run time, and they also must not iklam@7089: // exist at run time. iklam@7089: // iklam@7089: // These misc items are stored in a linear buffer in SharedPathsMiscInfo. iklam@7089: // The storage format is stream oriented to minimize its size. iklam@7089: // iklam@7089: // When writing the information to the archive file, SharedPathsMiscInfo is stored in iklam@7089: // the archive file header. At run-time, this information is used only during initialization iklam@7089: // (accessed using read() instead of mmap()), and is deallocated afterwards to save space. iklam@7089: // iklam@7089: // The SharedPathsMiscInfo class is used for both creating the the information (during iklam@7089: // dumping time) and validation (at run time). Different constructors are used in the iklam@7089: // two situations. See below. iklam@7089: iklam@7089: class SharedPathsMiscInfo : public CHeapObj { iklam@7089: protected: iklam@7089: char* _buf_start; iklam@7089: char* _cur_ptr; iklam@7089: char* _end_ptr; iklam@7089: int _buf_size; iklam@7089: bool _allocated; // was _buf_start allocated by me? iklam@7089: void ensure_size(size_t needed_bytes); iklam@7089: void add_path(const char* path, int type); iklam@7089: iklam@7089: void write(const void* ptr, size_t size); iklam@7089: bool read(void* ptr, size_t size); iklam@7089: iklam@7089: static void trace_class_path(const char* msg, const char* name = NULL) { ccheung@8184: ClassLoader::trace_class_path(tty, msg, name); iklam@7089: } iklam@7089: protected: iklam@7089: static bool fail(const char* msg, const char* name = NULL); iklam@7089: virtual bool check(jint type, const char* path); iklam@7089: iklam@7089: public: iklam@7089: enum { iklam@7089: INITIAL_BUF_SIZE = 128 iklam@7089: }; iklam@7089: // This constructor is used when creating the misc information (during dump) iklam@7089: SharedPathsMiscInfo() { iklam@7089: _buf_size = INITIAL_BUF_SIZE; iklam@7089: _cur_ptr = _buf_start = NEW_C_HEAP_ARRAY(char, _buf_size, mtClass); iklam@7089: _allocated = true; iklam@7089: } iklam@7089: // This constructor is used when validating the misc info (during run time) iklam@7089: SharedPathsMiscInfo(char *buff, int size) { iklam@7089: _cur_ptr = _buf_start = buff; iklam@7089: _end_ptr = _buf_start + size; iklam@7089: _buf_size = size; iklam@7089: _allocated = false; iklam@7089: } iklam@7089: ~SharedPathsMiscInfo() { iklam@7089: if (_allocated) { iklam@7089: FREE_C_HEAP_ARRAY(char, _buf_start, mtClass); iklam@7089: } iklam@7089: } iklam@7089: int get_used_bytes() { iklam@7089: return _cur_ptr - _buf_start; iklam@7089: } iklam@7089: void* buffer() { iklam@7089: return _buf_start; iklam@7089: } iklam@7089: iklam@7089: // writing -- iklam@7089: iklam@7089: // The path must not exist at run-time iklam@7089: void add_nonexist_path(const char* path) { iklam@7089: add_path(path, NON_EXIST); iklam@7089: } iklam@7089: iklam@7089: // The path must exist and have required size and modification time iklam@7089: void add_required_file(const char* path) { iklam@7089: add_path(path, REQUIRED); iklam@7089: iklam@7089: struct stat st; iklam@7089: if (os::stat(path, &st) != 0) { iklam@7089: assert(0, "sanity"); iklam@7089: ClassLoader::exit_with_path_failure("failed to os::stat(%s)", path); // should not happen iklam@7089: } iklam@7089: write_time(st.st_mtime); iklam@7089: write_long(st.st_size); iklam@7089: } iklam@7089: iklam@7089: // The path must exist, and must contain exactly files/dirs iklam@7089: void add_boot_classpath(const char* path) { iklam@7089: add_path(path, BOOT); iklam@7089: } iklam@7089: int write_jint(jint num) { iklam@7089: write(&num, sizeof(num)); iklam@7089: return 0; iklam@7089: } iklam@7089: void write_time(time_t t) { iklam@7089: write(&t, sizeof(t)); iklam@7089: } iklam@7089: void write_long(long l) { iklam@7089: write(&l, sizeof(l)); iklam@7089: } iklam@7089: iklam@7089: bool dump_to_file(int fd) { iklam@7089: int n = get_used_bytes(); iklam@7089: return (os::write(fd, _buf_start, n) == (size_t)n); iklam@7089: } iklam@7089: iklam@7089: // reading -- iklam@7089: iklam@7089: enum { iklam@7089: BOOT = 1, iklam@7089: NON_EXIST = 2, iklam@7089: REQUIRED = 3 iklam@7089: }; iklam@7089: iklam@7089: virtual const char* type_name(int type) { iklam@7089: switch (type) { iklam@7089: case BOOT: return "BOOT"; iklam@7089: case NON_EXIST: return "NON_EXIST"; iklam@7089: case REQUIRED: return "REQUIRED"; iklam@7089: default: ShouldNotReachHere(); return "?"; iklam@7089: } iklam@7089: } iklam@7089: iklam@7089: virtual void print_path(outputStream* out, int type, const char* path) { iklam@7089: switch (type) { iklam@7089: case BOOT: iklam@7089: out->print("Expecting -Dsun.boot.class.path=%s", path); iklam@7089: break; iklam@7089: case NON_EXIST: iklam@7089: out->print("Expecting that %s does not exist", path); iklam@7089: break; iklam@7089: case REQUIRED: iklam@7090: out->print("Expecting that file %s must exist and is not altered", path); iklam@7089: break; iklam@7089: default: iklam@7089: ShouldNotReachHere(); iklam@7089: } iklam@7089: } iklam@7089: iklam@7089: bool check(); iklam@7089: bool read_jint(jint *ptr) { iklam@7089: return read(ptr, sizeof(jint)); iklam@7089: } iklam@7089: bool read_long(long *ptr) { iklam@7089: return read(ptr, sizeof(long)); iklam@7089: } iklam@7089: bool read_time(time_t *ptr) { iklam@7089: return read(ptr, sizeof(time_t)); iklam@7089: } iklam@7089: }; iklam@7089: iklam@7089: #endif // SHARE_VM_CLASSFILE_SHAREDPATHSMISCINFO_HPP