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 #include "precompiled.hpp"
26 #include "classfile/classLoader.hpp"
27 #include "classfile/sharedPathsMiscInfo.hpp"
28 #include "logging/log.hpp"
29 #include "logging/logStream.hpp"
30 #include "memory/allocation.inline.hpp"
31 #include "memory/metaspaceShared.hpp"
32 #include "memory/resourceArea.hpp"
33 #include "runtime/arguments.hpp"
34 #include "runtime/os.inline.hpp"
35 #include "utilities/ostream.hpp"
36
37 SharedPathsMiscInfo::SharedPathsMiscInfo() {
38 _app_offset = 0;
39 _buf_size = INITIAL_BUF_SIZE;
40 _cur_ptr = _buf_start = NEW_C_HEAP_ARRAY(char, _buf_size, mtClass);
41 _allocated = true;
42 }
43
44 SharedPathsMiscInfo::~SharedPathsMiscInfo() {
45 if (_allocated) {
46 FREE_C_HEAP_ARRAY(char, _buf_start);
47 }
48 }
49
50 void SharedPathsMiscInfo::add_path(const char* path, int type) {
123 }
124 LogTarget(Info, class, path) lt;
125 if (lt.is_enabled()) {
126 lt.print("type=%s ", type_name(type));
127 LogStream ls(lt);
128 print_path(&ls, type, path);
129 ls.cr();
130 }
131 if (!check(type, path)) {
132 if (!PrintSharedArchiveAndExit) {
133 return false;
134 }
135 } else {
136 ClassLoader::trace_class_path("ok");
137 }
138 }
139
140 return true;
141 }
142
143 bool SharedPathsMiscInfo::check(jint type, const char* path) {
144 switch (type) {
145 case BOOT_PATH:
146 // In the future we should perform the check based on the content of the mapped archive.
147 if (os::file_name_strcmp(path, Arguments::get_sysclasspath()) != 0) {
148 return fail("[BOOT classpath mismatch, actual =", Arguments::get_sysclasspath());
149 }
150 break;
151 case NON_EXIST:
152 {
153 struct stat st;
154 if (os::stat(path, &st) == 0) {
155 // The file actually exists
156 // But we want it to not exist -> fail
157 return fail("File must not exist");
158 }
159 }
160 break;
161 case APP_PATH:
162 {
163 // Prefix is OK: E.g., dump with -cp foo.jar, but run with -cp foo.jar:bar.jar
164 size_t len = strlen(path);
165 const char *appcp = Arguments::get_appclasspath();
166 assert(appcp != NULL, "NULL app classpath");
167 size_t appcp_len = strlen(appcp);
168 if (appcp_len < len) {
|
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 #include "precompiled.hpp"
26 #include "classfile/classLoader.hpp"
27 #include "classfile/sharedPathsMiscInfo.hpp"
28 #include "logging/log.hpp"
29 #include "logging/logStream.hpp"
30 #include "memory/allocation.inline.hpp"
31 #include "memory/filemap.hpp"
32 #include "memory/metaspaceShared.hpp"
33 #include "memory/resourceArea.hpp"
34 #include "runtime/arguments.hpp"
35 #include "runtime/os.inline.hpp"
36 #include "utilities/ostream.hpp"
37
38 SharedPathsMiscInfo::SharedPathsMiscInfo() {
39 _app_offset = 0;
40 _buf_size = INITIAL_BUF_SIZE;
41 _cur_ptr = _buf_start = NEW_C_HEAP_ARRAY(char, _buf_size, mtClass);
42 _allocated = true;
43 }
44
45 SharedPathsMiscInfo::~SharedPathsMiscInfo() {
46 if (_allocated) {
47 FREE_C_HEAP_ARRAY(char, _buf_start);
48 }
49 }
50
51 void SharedPathsMiscInfo::add_path(const char* path, int type) {
124 }
125 LogTarget(Info, class, path) lt;
126 if (lt.is_enabled()) {
127 lt.print("type=%s ", type_name(type));
128 LogStream ls(lt);
129 print_path(&ls, type, path);
130 ls.cr();
131 }
132 if (!check(type, path)) {
133 if (!PrintSharedArchiveAndExit) {
134 return false;
135 }
136 } else {
137 ClassLoader::trace_class_path("ok");
138 }
139 }
140
141 return true;
142 }
143
144 char* skip_first_path_entry(const char* path) {
145 size_t path_sep_len = strlen(os::path_separator());
146 char* p = strstr((char*)path, os::path_separator());
147 if (p != NULL) {
148 p += path_sep_len;
149 }
150 return p;
151 }
152
153 bool SharedPathsMiscInfo::check(jint type, const char* path) {
154 assert(UseSharedSpaces, "runtime only");
155 switch (type) {
156 case BOOT_PATH:
157 {
158 //
159 // - Archive contains boot classes only - relaxed boot path check:
160 // Extra path elements appended to the boot path at runtime are allowed.
161 //
162 // - Archive contains application or platform classes - strict boot path check:
163 // Validate the entire runtime boot path, which must be compactible
164 // with the dump time boot path. Appending boot path at runtime is not
165 // allowed.
166 //
167
168 // The first entry in boot path is the modules_image (guaranteed by
169 // ClassLoader::setup_boot_search_path()). Skip the first entry. The
170 // path of the runtime modules_image may be different from the dump
171 // time path (e.g. the JDK image is copied to a different location
172 // after generating the shared archive), which is acceptable. For most
173 // common cases, the dump time boot path might contain modules_image only.
174 char* runtime_boot_path = Arguments::get_sysclasspath();
175 char* rp = skip_first_path_entry(runtime_boot_path);
176 char* dp = skip_first_path_entry(path);
177
178 bool relaxed_check = !FileMapInfo::current_info()->header()->has_platform_or_app_classes();
179 if (dp == NULL && rp == NULL) {
180 break; // ok, both runtime and dump time boot paths have modules_images only
181 } else if (dp == NULL && rp != NULL && relaxed_check) {
182 break; // ok, relaxed check, runtime has extra boot append path entries
183 } else if (dp != NULL && rp != NULL) {
184 ResourceMark rm;
185 char* checked_rp;
186 if (relaxed_check) {
187 // only check the leading entries in the runtime boot path, up to
188 // the length of the dump time boot path
189 size_t len = strlen(dp);
190 checked_rp = NEW_RESOURCE_ARRAY(char, len + 1);
191 strncpy(checked_rp, rp, len);
192 checked_rp[len] = '\0';
193 } else {
194 checked_rp = rp;
195 }
196
197 if (os::file_name_strcmp(dp, checked_rp) == 0) {
198 break; // ok, runtime and dump time paths match
199 }
200 }
201
202 // The paths are different
203 return fail("[BOOT classpath mismatch, actual =", runtime_boot_path);
204 }
205 break;
206 case NON_EXIST:
207 {
208 struct stat st;
209 if (os::stat(path, &st) == 0) {
210 // The file actually exists
211 // But we want it to not exist -> fail
212 return fail("File must not exist");
213 }
214 }
215 break;
216 case APP_PATH:
217 {
218 // Prefix is OK: E.g., dump with -cp foo.jar, but run with -cp foo.jar:bar.jar
219 size_t len = strlen(path);
220 const char *appcp = Arguments::get_appclasspath();
221 assert(appcp != NULL, "NULL app classpath");
222 size_t appcp_len = strlen(appcp);
223 if (appcp_len < len) {
|