< prev index next >

src/hotspot/share/classfile/verifier.hpp

Print this page




  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 #ifndef SHARE_CLASSFILE_VERIFIER_HPP
  26 #define SHARE_CLASSFILE_VERIFIER_HPP
  27 
  28 #include "classfile/verificationType.hpp"
  29 #include "oops/klass.hpp"
  30 #include "oops/method.hpp"
  31 #include "runtime/handles.hpp"
  32 #include "utilities/exceptions.hpp"
  33 #include "utilities/growableArray.hpp"

  34 
  35 // The verifier class
  36 class Verifier : AllStatic {
  37  public:
  38   enum {
  39     STACKMAP_ATTRIBUTE_MAJOR_VERSION    = 50,
  40     INVOKEDYNAMIC_MAJOR_VERSION         = 51,
  41     NO_RELAX_ACCESS_CTRL_CHECK_VERSION  = 52,
  42     DYNAMICCONSTANT_MAJOR_VERSION       = 55
  43   };
  44 
  45   // Verify the bytecodes for a class.
  46   static bool verify(InstanceKlass* klass, bool should_verify_class, TRAPS);
  47 
  48   static void log_end_verification(outputStream* st, const char* klassName, Symbol* exception_name, TRAPS);
  49 
  50   // Return false if the class is loaded by the bootstrap loader,
  51   // or if defineClass was called requesting skipping verification
  52   // -Xverify:all overrides this value
  53   static bool should_verify_for(oop class_loader, bool should_verify_class);


 229 
 230 #ifdef ASSERT
 231   void print_on(outputStream* str) const {
 232     str->print("error_context(%d, %d,", _bci, _fault);
 233     _type.print_on(str);
 234     str->print(",");
 235     _expected.print_on(str);
 236     str->print(")");
 237   }
 238 #endif
 239 
 240  private:
 241   void location_details(outputStream* ss, const Method* method) const;
 242   void reason_details(outputStream* ss) const;
 243   void frame_details(outputStream* ss) const;
 244   void bytecode_details(outputStream* ss, const Method* method) const;
 245   void handler_details(outputStream* ss, const Method* method) const;
 246   void stackmap_details(outputStream* ss, const Method* method) const;
 247 };
 248 

























 249 // A new instance of this class is created for each class being verified
 250 class ClassVerifier : public StackObj {
 251  private:
 252   Thread* _thread;
 253 
 254   Symbol* _previous_symbol;          // cache of the previously looked up symbol
 255   GrowableArray<Symbol*>* _symbols;  // keep a list of symbols created
 256 
 257   Symbol* _exception_type;
 258   char* _message;
 259 


 260   ErrorContext _error_context;  // contains information about an error
 261 
 262   void verify_method(const methodHandle& method, TRAPS);
 263   char* generate_code_data(const methodHandle& m, u4 code_length, TRAPS);
 264   void verify_exception_handler_table(u4 code_length, char* code_data,
 265                                       int& min, int& max, TRAPS);
 266   void verify_local_variable_table(u4 code_length, char* code_data, TRAPS);
 267 
 268   VerificationType cp_ref_index_to_type(
 269       int index, const constantPoolHandle& cp, TRAPS) {
 270     return cp_index_to_type(cp->klass_ref_index_at(index), cp, THREAD);
 271   }
 272 
 273   bool is_protected_access(
 274     InstanceKlass* this_class, Klass* target_class,
 275     Symbol* field_name, Symbol* field_sig, bool is_method);
 276 
 277   void verify_cp_index(u2 bci, const constantPoolHandle& cp, int index, TRAPS);
 278   void verify_cp_type(u2 bci, int index, const constantPoolHandle& cp,
 279       unsigned int types, TRAPS);


 366     BYTECODE_OFFSET = 1,
 367     NEW_OFFSET = 2
 368   };
 369 
 370   // constructor
 371   ClassVerifier(InstanceKlass* klass, TRAPS);
 372 
 373   // destructor
 374   ~ClassVerifier();
 375 
 376   Thread* thread()             { return _thread; }
 377   const methodHandle& method() { return _method; }
 378   InstanceKlass* current_class() const { return _klass; }
 379   VerificationType current_type() const { return _this_type; }
 380 
 381   // Verifies the class.  If a verify or class file format error occurs,
 382   // the '_exception_name' symbols will set to the exception name and
 383   // the message_buffer will be filled in with the exception message.
 384   void verify_class(TRAPS);
 385 








 386   // Return status modes
 387   Symbol* result() const { return _exception_type; }
 388   bool has_error() const { return result() != NULL; }
 389   char* exception_message() {
 390     stringStream ss;
 391     ss.print("%s", _message);
 392     _error_context.details(&ss, _method());
 393     return ss.as_string();
 394   }
 395 
 396   // Called when verify or class format errors are encountered.
 397   // May throw an exception based upon the mode.
 398   void verify_error(ErrorContext ctx, const char* fmt, ...) ATTRIBUTE_PRINTF(3, 4);
 399   void class_format_error(const char* fmt, ...) ATTRIBUTE_PRINTF(2, 3);
 400 
 401   Klass* load_class(Symbol* name, TRAPS);








 402 
 403   int change_sig_to_verificationType(
 404     SignatureStream* sig_type, VerificationType* inference_type, TRAPS);
 405 
 406   VerificationType cp_index_to_type(int index, const constantPoolHandle& cp, TRAPS) {
 407     return VerificationType::reference_type(cp->klass_name_at(index));
 408   }
 409 
 410   // Keep a list of temporary symbols created during verification because
 411   // their reference counts need to be decremented when the verifier object
 412   // goes out of scope.  Since these symbols escape the scope in which they're
 413   // created, we can't use a TempNewSymbol.
 414   Symbol* create_temporary_symbol(const Symbol* s, int begin, int end, TRAPS);
 415   Symbol* create_temporary_symbol(const char *s, int length, TRAPS);
 416   Symbol* create_temporary_symbol(Symbol* s) {
 417     if (s == _previous_symbol) {
 418       return s;
 419     }
 420     if (!s->is_permanent()) {
 421       s->increment_refcount();




  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 #ifndef SHARE_CLASSFILE_VERIFIER_HPP
  26 #define SHARE_CLASSFILE_VERIFIER_HPP
  27 
  28 #include "classfile/verificationType.hpp"
  29 #include "oops/klass.hpp"
  30 #include "oops/method.hpp"
  31 #include "runtime/handles.hpp"
  32 #include "utilities/exceptions.hpp"
  33 #include "utilities/growableArray.hpp"
  34 #include "utilities/resourceHash.hpp"
  35 
  36 // The verifier class
  37 class Verifier : AllStatic {
  38  public:
  39   enum {
  40     STACKMAP_ATTRIBUTE_MAJOR_VERSION    = 50,
  41     INVOKEDYNAMIC_MAJOR_VERSION         = 51,
  42     NO_RELAX_ACCESS_CTRL_CHECK_VERSION  = 52,
  43     DYNAMICCONSTANT_MAJOR_VERSION       = 55
  44   };
  45 
  46   // Verify the bytecodes for a class.
  47   static bool verify(InstanceKlass* klass, bool should_verify_class, TRAPS);
  48 
  49   static void log_end_verification(outputStream* st, const char* klassName, Symbol* exception_name, TRAPS);
  50 
  51   // Return false if the class is loaded by the bootstrap loader,
  52   // or if defineClass was called requesting skipping verification
  53   // -Xverify:all overrides this value
  54   static bool should_verify_for(oop class_loader, bool should_verify_class);


 230 
 231 #ifdef ASSERT
 232   void print_on(outputStream* str) const {
 233     str->print("error_context(%d, %d,", _bci, _fault);
 234     _type.print_on(str);
 235     str->print(",");
 236     _expected.print_on(str);
 237     str->print(")");
 238   }
 239 #endif
 240 
 241  private:
 242   void location_details(outputStream* ss, const Method* method) const;
 243   void reason_details(outputStream* ss) const;
 244   void frame_details(outputStream* ss) const;
 245   void bytecode_details(outputStream* ss, const Method* method) const;
 246   void handler_details(outputStream* ss, const Method* method) const;
 247   void stackmap_details(outputStream* ss, const Method* method) const;
 248 };
 249 
 250 class sig_as_verification_types : public ResourceObj {
 251  private:
 252   int _num_args;  // Number of arguments, not including return type.
 253   GrowableArray<VerificationType>* _sig_verif_types;
 254 
 255  public:
 256 
 257   sig_as_verification_types(GrowableArray<VerificationType>* sig_verif_types) :
 258     _num_args(0), _sig_verif_types(sig_verif_types) {
 259   }
 260 
 261   int num_args() const { return _num_args; }
 262   void set_num_args(int num_args) { _num_args = num_args; }
 263 
 264   GrowableArray<VerificationType>* sig_verif_types() { return _sig_verif_types; }
 265   void set_sig_verif_types(GrowableArray<VerificationType>* sig_verif_types) {
 266     _sig_verif_types = sig_verif_types;
 267   }
 268 
 269 };
 270 
 271 typedef ResourceHashtable<int, sig_as_verification_types*,
 272                           primitive_hash<int>, primitive_equals<int>, 71>
 273                           method_signatures_table_type;
 274 
 275 // A new instance of this class is created for each class being verified
 276 class ClassVerifier : public StackObj {
 277  private:
 278   Thread* _thread;
 279 
 280   Symbol* _previous_symbol;          // cache of the previously looked up symbol
 281   GrowableArray<Symbol*>* _symbols;  // keep a list of symbols created
 282 
 283   Symbol* _exception_type;
 284   char* _message;
 285 
 286   method_signatures_table_type* _method_signatures_table;
 287 
 288   ErrorContext _error_context;  // contains information about an error
 289 
 290   void verify_method(const methodHandle& method, TRAPS);
 291   char* generate_code_data(const methodHandle& m, u4 code_length, TRAPS);
 292   void verify_exception_handler_table(u4 code_length, char* code_data,
 293                                       int& min, int& max, TRAPS);
 294   void verify_local_variable_table(u4 code_length, char* code_data, TRAPS);
 295 
 296   VerificationType cp_ref_index_to_type(
 297       int index, const constantPoolHandle& cp, TRAPS) {
 298     return cp_index_to_type(cp->klass_ref_index_at(index), cp, THREAD);
 299   }
 300 
 301   bool is_protected_access(
 302     InstanceKlass* this_class, Klass* target_class,
 303     Symbol* field_name, Symbol* field_sig, bool is_method);
 304 
 305   void verify_cp_index(u2 bci, const constantPoolHandle& cp, int index, TRAPS);
 306   void verify_cp_type(u2 bci, int index, const constantPoolHandle& cp,
 307       unsigned int types, TRAPS);


 394     BYTECODE_OFFSET = 1,
 395     NEW_OFFSET = 2
 396   };
 397 
 398   // constructor
 399   ClassVerifier(InstanceKlass* klass, TRAPS);
 400 
 401   // destructor
 402   ~ClassVerifier();
 403 
 404   Thread* thread()             { return _thread; }
 405   const methodHandle& method() { return _method; }
 406   InstanceKlass* current_class() const { return _klass; }
 407   VerificationType current_type() const { return _this_type; }
 408 
 409   // Verifies the class.  If a verify or class file format error occurs,
 410   // the '_exception_name' symbols will set to the exception name and
 411   // the message_buffer will be filled in with the exception message.
 412   void verify_class(TRAPS);
 413 
 414   // Loops through the constant pool looking for method signatures and stores
 415   // them in the method signatures table.
 416   void init_method_sigs_table(method_signatures_table_type* method_sig_table, TRAPS);
 417 
 418   // Translates signature entries into verificationTypes and saves them in the
 419   // growable array.
 420   void translate_signature(Symbol* const method_sig, sig_as_verification_types* sig_verif_types, TRAPS);
 421 
 422   // Return status modes
 423   Symbol* result() const { return _exception_type; }
 424   bool has_error() const { return result() != NULL; }
 425   char* exception_message() {
 426     stringStream ss;
 427     ss.print("%s", _message);
 428     _error_context.details(&ss, _method());
 429     return ss.as_string();
 430   }
 431 
 432   // Called when verify or class format errors are encountered.
 433   // May throw an exception based upon the mode.
 434   void verify_error(ErrorContext ctx, const char* fmt, ...) ATTRIBUTE_PRINTF(3, 4);
 435   void class_format_error(const char* fmt, ...) ATTRIBUTE_PRINTF(2, 3);
 436 
 437   Klass* load_class(Symbol* name, TRAPS);
 438 
 439   method_signatures_table_type* method_signatures_table() const {
 440     return _method_signatures_table;
 441   }
 442 
 443   void set_method_signatures_table(method_signatures_table_type* method_signatures_table) {
 444     _method_signatures_table = method_signatures_table;
 445   }
 446 
 447   int change_sig_to_verificationType(
 448     SignatureStream* sig_type, VerificationType* inference_type, TRAPS);
 449 
 450   VerificationType cp_index_to_type(int index, const constantPoolHandle& cp, TRAPS) {
 451     return VerificationType::reference_type(cp->klass_name_at(index));
 452   }
 453 
 454   // Keep a list of temporary symbols created during verification because
 455   // their reference counts need to be decremented when the verifier object
 456   // goes out of scope.  Since these symbols escape the scope in which they're
 457   // created, we can't use a TempNewSymbol.
 458   Symbol* create_temporary_symbol(const Symbol* s, int begin, int end, TRAPS);
 459   Symbol* create_temporary_symbol(const char *s, int length, TRAPS);
 460   Symbol* create_temporary_symbol(Symbol* s) {
 461     if (s == _previous_symbol) {
 462       return s;
 463     }
 464     if (!s->is_permanent()) {
 465       s->increment_refcount();


< prev index next >