1 | /* |
2 | * Copyright (c) 2014, 2019, Oracle and/or its affiliates. All rights reserved. |
3 | * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. |
4 | * |
5 | * This code is free software; you can redistribute it and/or modify it |
6 | * under the terms of the GNU General Public License version 2 only, as |
7 | * published by the Free Software Foundation. |
8 | * |
9 | * This code is distributed in the hope that it will be useful, but WITHOUT |
10 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or |
11 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License |
12 | * version 2 for more details (a copy is included in the LICENSE file that |
13 | * accompanied this code). |
14 | * |
15 | * You should have received a copy of the GNU General Public License version |
16 | * 2 along with this work; if not, write to the Free Software Foundation, |
17 | * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. |
18 | * |
19 | * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA |
20 | * or visit www.oracle.com if you need additional information or have any |
21 | * questions. |
22 | * |
23 | */ |
24 | |
25 | #ifndef SHARE_CLASSFILE_SHAREDPATHSMISCINFO_HPP |
26 | #define SHARE_CLASSFILE_SHAREDPATHSMISCINFO_HPP |
27 | |
28 | #include "classfile/classLoader.hpp" |
29 | #include "runtime/os.hpp" |
30 | |
31 | class outputStream; |
32 | // During dumping time, when processing class paths, we build up the dump-time |
33 | // classpath. The JAR files that exist are stored in the list ClassLoader::_first_append_entry. |
34 | // However, we need to store other "misc" information for run-time checking, such as |
35 | // |
36 | // + The values of Arguments::get_sysclasspath() used during dumping. |
37 | // |
38 | // + The class path elements specified during dumping but did not exist -- |
39 | // these elements must also be specified at run time, and they also must not |
40 | // exist at run time. |
41 | // |
42 | // These misc items are stored in a linear buffer in SharedPathsMiscInfo. |
43 | // The storage format is stream oriented to minimize its size. |
44 | // |
45 | // When writing the information to the archive file, SharedPathsMiscInfo is stored in |
46 | // the archive file header. At run-time, this information is used only during initialization |
47 | // (accessed using read() instead of mmap()), and is deallocated afterwards to save space. |
48 | // |
49 | // The SharedPathsMiscInfo class is used for both creating the the information (during |
50 | // dumping time) and validation (at run time). Different constructors are used in the |
51 | // two situations. See below. |
52 | |
53 | class SharedPathsMiscInfo : public CHeapObj<mtClass> { |
54 | private: |
55 | int _app_offset; |
56 | protected: |
57 | char* _buf_start; |
58 | char* _cur_ptr; |
59 | char* _end_ptr; |
60 | int _buf_size; |
61 | bool _allocated; // was _buf_start allocated by me? |
62 | void ensure_size(size_t needed_bytes); |
63 | void add_path(const char* path, int type); |
64 | |
65 | void write(const void* ptr, size_t size); |
66 | bool read(void* ptr, size_t size); |
67 | |
68 | protected: |
69 | static bool fail(const char* msg, const char* name = NULL); |
70 | bool check(jint type, const char* path, bool is_static); |
71 | |
72 | public: |
73 | enum { |
74 | INITIAL_BUF_SIZE = 128 |
75 | }; |
76 | // This constructor is used when creating the misc information (during dump) |
77 | SharedPathsMiscInfo(); |
78 | // This constructor is used when validating the misc info (during run time) |
79 | SharedPathsMiscInfo(char *buff, int size) { |
80 | _app_offset = 0; |
81 | _cur_ptr = _buf_start = buff; |
82 | _end_ptr = _buf_start + size; |
83 | _buf_size = size; |
84 | _allocated = false; |
85 | } |
86 | ~SharedPathsMiscInfo(); |
87 | |
88 | int get_used_bytes() { |
89 | return _cur_ptr - _buf_start; |
90 | } |
91 | void* buffer() { |
92 | return _buf_start; |
93 | } |
94 | |
95 | // writing -- |
96 | |
97 | // The path must not exist at run-time |
98 | void add_nonexist_path(const char* path) { |
99 | add_path(path, NON_EXIST); |
100 | } |
101 | |
102 | // The path must exist, and must contain exactly <num_entries> files/dirs |
103 | void add_boot_classpath(const char* path) { |
104 | add_path(path, BOOT_PATH); |
105 | } |
106 | |
107 | void add_app_classpath(const char* path) { |
108 | add_path(path, APP_PATH); |
109 | } |
110 | void record_app_offset() { |
111 | _app_offset = get_used_bytes(); |
112 | } |
113 | void pop_app() { |
114 | _cur_ptr = _buf_start + _app_offset; |
115 | write_jint(0); |
116 | } |
117 | |
118 | int write_jint(jint num) { |
119 | write(&num, sizeof(num)); |
120 | return 0; |
121 | } |
122 | void write_time(time_t t) { |
123 | write(&t, sizeof(t)); |
124 | } |
125 | void write_long(long l) { |
126 | write(&l, sizeof(l)); |
127 | } |
128 | |
129 | bool dump_to_file(int fd) { |
130 | int n = get_used_bytes(); |
131 | return (os::write(fd, _buf_start, n) == (size_t)n); |
132 | } |
133 | |
134 | // reading -- |
135 | |
136 | private: |
137 | enum { |
138 | BOOT_PATH = 1, |
139 | APP_PATH = 2, |
140 | NON_EXIST = 3 |
141 | }; |
142 | |
143 | const char* type_name(int type) { |
144 | switch (type) { |
145 | case BOOT_PATH: return "BOOT" ; |
146 | case APP_PATH: return "APP" ; |
147 | case NON_EXIST: return "NON_EXIST" ; |
148 | default: ShouldNotReachHere(); return "?" ; |
149 | } |
150 | } |
151 | |
152 | void print_path(outputStream* os, int type, const char* path); |
153 | |
154 | bool read_jint(jint *ptr) { |
155 | return read(ptr, sizeof(jint)); |
156 | } |
157 | bool read_long(long *ptr) { |
158 | return read(ptr, sizeof(long)); |
159 | } |
160 | bool read_time(time_t *ptr) { |
161 | return read(ptr, sizeof(time_t)); |
162 | } |
163 | |
164 | public: |
165 | bool check(bool is_static); |
166 | }; |
167 | |
168 | #endif // SHARE_CLASSFILE_SHAREDPATHSMISCINFO_HPP |
169 | |