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