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