1 /* 2 * Copyright (c) 2015, 2020, 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 #include "precompiled.hpp" 26 #include "jvm.h" 27 #include "jimage.hpp" 28 #include "classfile/classListParser.hpp" 29 #include "classfile/classLoaderExt.hpp" 30 #include "classfile/symbolTable.hpp" 31 #include "classfile/systemDictionary.hpp" 32 #include "classfile/systemDictionaryShared.hpp" 33 #include "logging/log.hpp" 34 #include "logging/logTag.hpp" 35 #include "memory/metaspaceShared.hpp" 36 #include "memory/resourceArea.hpp" 37 #include "runtime/handles.inline.hpp" 38 #include "runtime/javaCalls.hpp" 39 #include "utilities/defaultStream.hpp" 40 #include "utilities/hashtable.inline.hpp" 41 #include "utilities/macros.hpp" 42 43 ClassListParser* ClassListParser::_instance = NULL; 44 45 ClassListParser::ClassListParser(const char* file) { 46 assert(_instance == NULL, "must be singleton"); 47 _instance = this; 48 _classlist_file = file; 49 _file = NULL; 50 // Use os::open() because neither fopen() nor os::fopen() 51 // can handle long path name on Windows. 52 int fd = os::open(file, O_RDONLY, S_IREAD); 53 if (fd != -1) { 54 // Obtain a File* from the file descriptor so that fgets() 55 // can be used in parse_one_line() 56 _file = os::open(fd, "r"); 57 } 58 if (_file == NULL) { 59 char errmsg[JVM_MAXPATHLEN]; 60 os::lasterror(errmsg, JVM_MAXPATHLEN); 61 vm_exit_during_initialization("Loading classlist failed", errmsg); 62 } 63 _line_no = 0; 64 _interfaces = new (ResourceObj::C_HEAP, mtClass) GrowableArray<int>(10, true); 65 } 66 67 ClassListParser::~ClassListParser() { 68 if (_file) { 69 fclose(_file); 70 } 71 _instance = NULL; 72 } 73 74 bool ClassListParser::parse_one_line() { 75 for (;;) { 76 if (fgets(_line, sizeof(_line), _file) == NULL) { 77 return false; 78 } 79 ++ _line_no; 80 _line_len = (int)strlen(_line); 81 if (_line_len > _max_allowed_line_len) { 82 error("input line too long (must be no longer than %d chars)", _max_allowed_line_len); 83 } 84 if (*_line == '#') { // comment 85 continue; 86 } 87 break; 88 } 89 90 _id = _unspecified; 91 _super = _unspecified; 92 _interfaces->clear(); 93 _source = NULL; 94 _interfaces_specified = false; 95 96 { 97 int len = (int)strlen(_line); 98 int i; 99 // Replace \t\r\n with ' ' 100 for (i=0; i<len; i++) { 101 if (_line[i] == '\t' || _line[i] == '\r' || _line[i] == '\n') { 102 _line[i] = ' '; 103 } 104 } 105 106 // Remove trailing newline/space 107 while (len > 0) { 108 if (_line[len-1] == ' ') { 109 _line[len-1] = '\0'; 110 len --; 111 } else { 112 break; 113 } 114 } 115 _line_len = len; 116 _class_name = _line; 117 } 118 119 if ((_token = strchr(_line, ' ')) == NULL) { 120 // No optional arguments are specified. 121 return true; 122 } 123 124 // Mark the end of the name, and go to the next input char 125 *_token++ = '\0'; 126 127 while (*_token) { 128 skip_whitespaces(); 129 130 if (parse_int_option("id:", &_id)) { 131 continue; 132 } else if (parse_int_option("super:", &_super)) { 133 check_already_loaded("Super class", _super); 134 continue; 135 } else if (skip_token("interfaces:")) { 136 int i; 137 while (try_parse_int(&i)) { 138 check_already_loaded("Interface", i); 139 _interfaces->append(i); 140 } 141 } else if (skip_token("source:")) { 142 skip_whitespaces(); 143 _source = _token; 144 char* s = strchr(_token, ' '); 145 if (s == NULL) { 146 break; // end of input line 147 } else { 148 *s = '\0'; // mark the end of _source 149 _token = s+1; 150 } 151 } else { 152 error("Unknown input"); 153 } 154 } 155 156 // if src is specified 157 // id super interfaces must all be specified 158 // loader may be specified 159 // else 160 // # the class is loaded from classpath 161 // id may be specified 162 // super, interfaces, loader must not be specified 163 return true; 164 } 165 166 void ClassListParser::skip_whitespaces() { 167 while (*_token == ' ' || *_token == '\t') { 168 _token ++; 169 } 170 } 171 172 void ClassListParser::skip_non_whitespaces() { 173 while (*_token && *_token != ' ' && *_token != '\t') { 174 _token ++; 175 } 176 } 177 178 void ClassListParser::parse_int(int* value) { 179 skip_whitespaces(); 180 if (sscanf(_token, "%i", value) == 1) { 181 skip_non_whitespaces(); 182 if (*value < 0) { 183 error("Error: negative integers not allowed (%d)", *value); 184 } 185 } else { 186 error("Error: expected integer"); 187 } 188 } 189 190 bool ClassListParser::try_parse_int(int* value) { 191 skip_whitespaces(); 192 if (sscanf(_token, "%i", value) == 1) { 193 skip_non_whitespaces(); 194 return true; 195 } 196 return false; 197 } 198 199 bool ClassListParser::skip_token(const char* option_name) { 200 size_t len = strlen(option_name); 201 if (strncmp(_token, option_name, len) == 0) { 202 _token += len; 203 return true; 204 } else { 205 return false; 206 } 207 } 208 209 bool ClassListParser::parse_int_option(const char* option_name, int* value) { 210 if (skip_token(option_name)) { 211 if (*value != _unspecified) { 212 error("%s specified twice", option_name); 213 } else { 214 parse_int(value); 215 return true; 216 } 217 } 218 return false; 219 } 220 221 void ClassListParser::print_specified_interfaces() { 222 const int n = _interfaces->length(); 223 jio_fprintf(defaultStream::error_stream(), "Currently specified interfaces[%d] = {\n", n); 224 for (int i=0; i<n; i++) { 225 InstanceKlass* k = lookup_class_by_id(_interfaces->at(i)); 226 jio_fprintf(defaultStream::error_stream(), " %4d = %s\n", _interfaces->at(i), k->name()->as_klass_external_name()); 227 } 228 jio_fprintf(defaultStream::error_stream(), "}\n"); 229 } 230 231 void ClassListParser::print_actual_interfaces(InstanceKlass* ik) { 232 int n = ik->local_interfaces()->length(); 233 jio_fprintf(defaultStream::error_stream(), "Actual interfaces[%d] = {\n", n); 234 for (int i = 0; i < n; i++) { 235 InstanceKlass* e = ik->local_interfaces()->at(i); 236 jio_fprintf(defaultStream::error_stream(), " %s\n", e->name()->as_klass_external_name()); 237 } 238 jio_fprintf(defaultStream::error_stream(), "}\n"); 239 } 240 241 void ClassListParser::error(const char* msg, ...) { 242 va_list ap; 243 va_start(ap, msg); 244 int error_index = _token - _line; 245 if (error_index >= _line_len) { 246 error_index = _line_len - 1; 247 } 248 if (error_index < 0) { 249 error_index = 0; 250 } 251 252 jio_fprintf(defaultStream::error_stream(), 253 "An error has occurred while processing class list file %s %d:%d.\n", 254 _classlist_file, _line_no, (error_index + 1)); 255 jio_vfprintf(defaultStream::error_stream(), msg, ap); 256 257 if (_line_len <= 0) { 258 jio_fprintf(defaultStream::error_stream(), "\n"); 259 } else { 260 jio_fprintf(defaultStream::error_stream(), ":\n"); 261 for (int i=0; i<_line_len; i++) { 262 char c = _line[i]; 263 if (c == '\0') { 264 jio_fprintf(defaultStream::error_stream(), "%s", " "); 265 } else { 266 jio_fprintf(defaultStream::error_stream(), "%c", c); 267 } 268 } 269 jio_fprintf(defaultStream::error_stream(), "\n"); 270 for (int i=0; i<error_index; i++) { 271 jio_fprintf(defaultStream::error_stream(), "%s", " "); 272 } 273 jio_fprintf(defaultStream::error_stream(), "^\n"); 274 } 275 276 vm_exit_during_initialization("class list format error.", NULL); 277 va_end(ap); 278 } 279 280 // This function is used for loading classes for customized class loaders 281 // during archive dumping. 282 InstanceKlass* ClassListParser::load_class_from_source(Symbol* class_name, TRAPS) { 283 #if !(defined(_LP64) && (defined(LINUX) || defined(__APPLE__))) 284 // The only supported platforms are: (1) Linux/64-bit and (2) Solaris/64-bit and 285 // (3) MacOSX/64-bit 286 // This #if condition should be in sync with the areCustomLoadersSupportedForCDS 287 // method in test/lib/jdk/test/lib/Platform.java. 288 error("AppCDS custom class loaders not supported on this platform"); 289 #endif 290 291 if (!is_super_specified()) { 292 error("If source location is specified, super class must be also specified"); 293 } 294 if (!is_id_specified()) { 295 error("If source location is specified, id must be also specified"); 296 } 297 if (strncmp(_class_name, "java/", 5) == 0) { 298 log_info(cds)("Prohibited package for non-bootstrap classes: %s.class from %s", 299 _class_name, _source); 300 return NULL; 301 } 302 303 InstanceKlass* k = ClassLoaderExt::load_class(class_name, _source, CHECK_NULL); 304 305 if (k != NULL) { 306 if (k->local_interfaces()->length() != _interfaces->length()) { 307 print_specified_interfaces(); 308 print_actual_interfaces(k); 309 error("The number of interfaces (%d) specified in class list does not match the class file (%d)", 310 _interfaces->length(), k->local_interfaces()->length()); 311 } 312 313 bool added = SystemDictionaryShared::add_unregistered_class(k, CHECK_NULL); 314 if (!added) { 315 // We allow only a single unregistered class for each unique name. 316 error("Duplicated class %s", _class_name); 317 } 318 319 // This tells JVM_FindLoadedClass to not find this class. 320 k->set_shared_classpath_index(UNREGISTERED_INDEX); 321 k->clear_shared_class_loader_type(); 322 } 323 324 return k; 325 } 326 327 Klass* ClassListParser::load_current_class(TRAPS) { 328 TempNewSymbol class_name_symbol = SymbolTable::new_symbol(_class_name); 329 330 Klass* klass = NULL; 331 if (!is_loading_from_source()) { 332 // Load classes for the boot/platform/app loaders only. 333 if (is_super_specified()) { 334 error("If source location is not specified, super class must not be specified"); 335 } 336 if (are_interfaces_specified()) { 337 error("If source location is not specified, interface(s) must not be specified"); 338 } 339 340 bool non_array = !Signature::is_array(class_name_symbol); 341 342 JavaValue result(T_OBJECT); 343 if (non_array) { 344 // At this point, we are executing in the context of the boot loader. We 345 // cannot call Class.forName because that is context dependent and 346 // would load only classes for the boot loader. 347 // 348 // Instead, let's call java_system_loader().loadClass() directly, which will 349 // delegate to the correct loader (boot, platform or app) depending on 350 // the class name. 351 352 Handle s = java_lang_String::create_from_symbol(class_name_symbol, CHECK_NULL); 353 // ClassLoader.loadClass() wants external class name format, i.e., convert '/' chars to '.' 354 Handle ext_class_name = java_lang_String::externalize_classname(s, CHECK_NULL); 355 Handle loader = Handle(THREAD, SystemDictionary::java_system_loader()); 356 357 JavaCalls::call_virtual(&result, 358 loader, //SystemDictionary::java_system_loader(), 359 SystemDictionary::ClassLoader_klass(), 360 vmSymbols::loadClass_name(), 361 vmSymbols::string_class_signature(), 362 ext_class_name, 363 THREAD); // <-- failure is handled below 364 } else { 365 // array classes are not supported in class list. 366 THROW_NULL(vmSymbols::java_lang_ClassNotFoundException()); 367 } 368 assert(result.get_type() == T_OBJECT, "just checking"); 369 oop obj = (oop) result.get_jobject(); 370 if (!HAS_PENDING_EXCEPTION && (obj != NULL)) { 371 klass = java_lang_Class::as_Klass(obj); 372 } else { // load classes in bootclasspath/a 373 if (HAS_PENDING_EXCEPTION) { 374 CLEAR_PENDING_EXCEPTION; 375 } 376 377 if (non_array) { 378 Klass* k = SystemDictionary::resolve_or_null(class_name_symbol, CHECK_NULL); 379 if (k != NULL) { 380 klass = k; 381 } else { 382 if (!HAS_PENDING_EXCEPTION) { 383 THROW_NULL(vmSymbols::java_lang_ClassNotFoundException()); 384 } 385 } 386 } 387 } 388 } else { 389 // If "source:" tag is specified, all super class and super interfaces must be specified in the 390 // class list file. 391 klass = load_class_from_source(class_name_symbol, CHECK_NULL); 392 } 393 394 if (klass != NULL && klass->is_instance_klass() && is_id_specified()) { 395 InstanceKlass* ik = InstanceKlass::cast(klass); 396 int id = this->id(); 397 SystemDictionaryShared::update_shared_entry(ik, id); 398 InstanceKlass** old_ptr = table()->lookup(id); 399 if (old_ptr != NULL) { 400 error("Duplicated ID %d for class %s", id, _class_name); 401 } 402 table()->add(id, ik); 403 } 404 405 return klass; 406 } 407 408 bool ClassListParser::is_loading_from_source() { 409 return (_source != NULL); 410 } 411 412 InstanceKlass* ClassListParser::lookup_class_by_id(int id) { 413 InstanceKlass** klass_ptr = table()->lookup(id); 414 if (klass_ptr == NULL) { 415 error("Class ID %d has not been defined", id); 416 } 417 assert(*klass_ptr != NULL, "must be"); 418 return *klass_ptr; 419 } 420 421 422 InstanceKlass* ClassListParser::lookup_super_for_current_class(Symbol* super_name) { 423 if (!is_loading_from_source()) { 424 return NULL; 425 } 426 427 InstanceKlass* k = lookup_class_by_id(super()); 428 if (super_name != k->name()) { 429 error("The specified super class %s (id %d) does not match actual super class %s", 430 k->name()->as_klass_external_name(), super(), 431 super_name->as_klass_external_name()); 432 } 433 return k; 434 } 435 436 InstanceKlass* ClassListParser::lookup_interface_for_current_class(Symbol* interface_name) { 437 if (!is_loading_from_source()) { 438 return NULL; 439 } 440 441 const int n = _interfaces->length(); 442 if (n == 0) { 443 error("Class %s implements the interface %s, but no interface has been specified in the input line", 444 _class_name, interface_name->as_klass_external_name()); 445 ShouldNotReachHere(); 446 } 447 448 int i; 449 for (i=0; i<n; i++) { 450 InstanceKlass* k = lookup_class_by_id(_interfaces->at(i)); 451 if (interface_name == k->name()) { 452 return k; 453 } 454 } 455 456 // interface_name is not specified by the "interfaces:" keyword. 457 print_specified_interfaces(); 458 error("The interface %s implemented by class %s does not match any of the specified interface IDs", 459 interface_name->as_klass_external_name(), _class_name); 460 ShouldNotReachHere(); 461 return NULL; 462 }