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