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