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) {
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) {
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 bool SharedPathsMiscInfo::check(jint type, const char* path) {
145 assert(UseSharedSpaces, "runtime only");
146 switch (type) {
147 case BOOT_PATH:
148 {
149 //
150 // - Archive contains boot classes only - relaxed boot path check:
151 // Extra path elements appended to the boot path at runtime are allowed.
152 //
153 // - Archive contains application or platform classes - strict boot path check:
154 // Validate the entire runtime boot path, which must be compactible
155 // with the dump time boot path. Appending boot path at runtime is not
156 // allowed.
157 //
158
159 bool relaxed_check = !FileMapInfo::current_info()->header()->has_platform_or_app_classes();
160 char* runtime_boot_path;
161 ResourceMark rm;
162 if (relaxed_check) {
163 // only check the begining portion of the runtime boot path, up to
164 // the length of the dump time boot path
165 size_t len = strlen(path);
166 runtime_boot_path = NEW_RESOURCE_ARRAY(char, len + 1);
167 strncpy(runtime_boot_path, Arguments::get_sysclasspath(), len);
168 runtime_boot_path[len] = '\0';
169 } else {
170 // check the full runtime boot path
171 runtime_boot_path = Arguments::get_sysclasspath();
172 }
173
174 // Do a quick check first with a simple
175 // strcmp(dump_time_boot_path, runtime_boot_path). If the paths are the
176 // same, the check has succeeded.
177 if (os::file_name_strcmp(path, runtime_boot_path) == 0) {
178 break; // ok
179 }
180
181 // The paths are different.
182 //
183 // - The first entry in boot path is the modules_image (guaranteed by
184 // ClassLoader::setup_boot_search_path()). Skip the first entry. The
185 // path of the runtime modules_image may be different from the dump
186 // time path (e.g. the JDK image is copied to a different location
187 // after generating the shared archive), which is acceptable. For most
188 // common cases, the dump time boot path might contain modules_image only.
189 // - The rest of the 'runtime_boot_path' and 'dump_time_boot_path' strings
190 // must be the same.
191 size_t path_sep_len = strlen(os::path_separator());
192 char* rp = strstr(runtime_boot_path, os::path_separator());
193 if (rp != NULL) {
194 rp += path_sep_len;
195 }
196
197 char* dp = strstr((char*)path, os::path_separator());
198 if (dp != NULL) {
199 dp ++;
200 }
201
202 if (dp == NULL && rp == NULL) {
203 break; // ok, both runtime and dump time boot paths have modules_images only
204 } else if (dp == NULL && rp != NULL && relaxed_check) {
205 break; // ok, relaxed check, runtime has extra boot append path entries
206 } else if (dp != NULL && rp != NULL) {
207 if (os::file_name_strcmp(dp, rp) == 0) {
208 break; // ok, runtime and dump time paths match
209 }
210 }
211
212 // The paths are different
213 return fail("[BOOT classpath mismatch, actual =",
214 Arguments::get_sysclasspath());
215 }
216 break;
217 case NON_EXIST:
218 {
219 struct stat st;
220 if (os::stat(path, &st) == 0) {
221 // The file actually exists
222 // But we want it to not exist -> fail
223 return fail("File must not exist");
224 }
225 }
226 break;
227 case APP_PATH:
228 {
229 // Prefix is OK: E.g., dump with -cp foo.jar, but run with -cp foo.jar:bar.jar
230 size_t len = strlen(path);
231 const char *appcp = Arguments::get_appclasspath();
232 assert(appcp != NULL, "NULL app classpath");
233 size_t appcp_len = strlen(appcp);
234 if (appcp_len < len) {
|