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