src/share/vm/classfile/verifier.hpp

changeset 3992
4ee06e614636
parent 2708
1d1603768966
child 4037
da91efe96a93
     1.1 --- a/src/share/vm/classfile/verifier.hpp	Mon Aug 06 09:34:40 2012 -0700
     1.2 +++ b/src/share/vm/classfile/verifier.hpp	Mon Aug 06 15:54:45 2012 -0400
     1.3 @@ -1,5 +1,5 @@
     1.4  /*
     1.5 - * Copyright (c) 1998, 2011, Oracle and/or its affiliates. All rights reserved.
     1.6 + * Copyright (c) 1998, 2012, Oracle and/or its affiliates. All rights reserved.
     1.7   * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
     1.8   *
     1.9   * This code is free software; you can redistribute it and/or modify it
    1.10 @@ -88,18 +88,178 @@
    1.11  #define CHECK_VERIFY_(verifier, result) \
    1.12    CHECK_(result)); if ((verifier)->has_error()) return (result); (0
    1.13  
    1.14 +class TypeOrigin VALUE_OBJ_CLASS_SPEC {
    1.15 + private:
    1.16 +  typedef enum {
    1.17 +    CF_LOCALS,  // Comes from the current frame locals
    1.18 +    CF_STACK,   // Comes from the current frame expression stack
    1.19 +    SM_LOCALS,  // Comes from stackmap locals
    1.20 +    SM_STACK,   // Comes from stackmap expression stack
    1.21 +    CONST_POOL, // Comes from the constant pool
    1.22 +    SIG,        // Comes from method signature
    1.23 +    IMPLICIT,   // Comes implicitly from code or context
    1.24 +    BAD_INDEX,  // No type, but the index is bad
    1.25 +    FRAME_ONLY, // No type, context just contains the frame
    1.26 +    NONE
    1.27 +  } Origin;
    1.28 +
    1.29 +  Origin _origin;
    1.30 +  u2 _index;              // local, stack, or constant pool index
    1.31 +  StackMapFrame* _frame;  // source frame if CF or SM
    1.32 +  VerificationType _type; // The actual type
    1.33 +
    1.34 +  TypeOrigin(
    1.35 +      Origin origin, u2 index, StackMapFrame* frame, VerificationType type)
    1.36 +      : _origin(origin), _index(index), _frame(frame), _type(type) {}
    1.37 +
    1.38 + public:
    1.39 +  TypeOrigin() : _origin(NONE), _index(0), _frame(NULL) {}
    1.40 +
    1.41 +  static TypeOrigin null();
    1.42 +  static TypeOrigin local(u2 index, StackMapFrame* frame);
    1.43 +  static TypeOrigin stack(u2 index, StackMapFrame* frame);
    1.44 +  static TypeOrigin sm_local(u2 index, StackMapFrame* frame);
    1.45 +  static TypeOrigin sm_stack(u2 index, StackMapFrame* frame);
    1.46 +  static TypeOrigin cp(u2 index, VerificationType vt);
    1.47 +  static TypeOrigin signature(VerificationType vt);
    1.48 +  static TypeOrigin bad_index(u2 index);
    1.49 +  static TypeOrigin implicit(VerificationType t);
    1.50 +  static TypeOrigin frame(StackMapFrame* frame);
    1.51 +
    1.52 +  void reset_frame();
    1.53 +  void details(outputStream* ss) const;
    1.54 +  void print_frame(outputStream* ss) const;
    1.55 +  const StackMapFrame* frame() const { return _frame; }
    1.56 +  bool is_valid() const { return _origin != NONE; }
    1.57 +  u2 index() const { return _index; }
    1.58 +
    1.59 +#ifdef ASSERT
    1.60 +  void print_on(outputStream* str) const;
    1.61 +#endif
    1.62 +};
    1.63 +
    1.64 +class ErrorContext VALUE_OBJ_CLASS_SPEC {
    1.65 + private:
    1.66 +  typedef enum {
    1.67 +    INVALID_BYTECODE,     // There was a problem with the bytecode
    1.68 +    WRONG_TYPE,           // Type value was not as expected
    1.69 +    FLAGS_MISMATCH,       // Frame flags are not assignable
    1.70 +    BAD_CP_INDEX,         // Invalid constant pool index
    1.71 +    BAD_LOCAL_INDEX,      // Invalid local index
    1.72 +    LOCALS_SIZE_MISMATCH, // Frames have differing local counts
    1.73 +    STACK_SIZE_MISMATCH,  // Frames have different stack sizes
    1.74 +    STACK_OVERFLOW,       // Attempt to push onto a full expression stack
    1.75 +    STACK_UNDERFLOW,      // Attempt to pop and empty expression stack
    1.76 +    MISSING_STACKMAP,     // No stackmap for this location and there should be
    1.77 +    BAD_STACKMAP,         // Format error in stackmap
    1.78 +    NO_FAULT,             // No error
    1.79 +    UNKNOWN
    1.80 +  } FaultType;
    1.81 +
    1.82 +  int _bci;
    1.83 +  FaultType _fault;
    1.84 +  TypeOrigin _type;
    1.85 +  TypeOrigin _expected;
    1.86 +
    1.87 +  ErrorContext(int bci, FaultType fault) :
    1.88 +      _bci(bci), _fault(fault)  {}
    1.89 +  ErrorContext(int bci, FaultType fault, TypeOrigin type) :
    1.90 +      _bci(bci), _fault(fault), _type(type)  {}
    1.91 +  ErrorContext(int bci, FaultType fault, TypeOrigin type, TypeOrigin exp) :
    1.92 +      _bci(bci), _fault(fault), _type(type), _expected(exp)  {}
    1.93 +
    1.94 + public:
    1.95 +  ErrorContext() : _bci(-1), _fault(NO_FAULT) {}
    1.96 +
    1.97 +  static ErrorContext bad_code(u2 bci) {
    1.98 +    return ErrorContext(bci, INVALID_BYTECODE);
    1.99 +  }
   1.100 +  static ErrorContext bad_type(u2 bci, TypeOrigin type) {
   1.101 +    return ErrorContext(bci, WRONG_TYPE, type);
   1.102 +  }
   1.103 +  static ErrorContext bad_type(u2 bci, TypeOrigin type, TypeOrigin exp) {
   1.104 +    return ErrorContext(bci, WRONG_TYPE, type, exp);
   1.105 +  }
   1.106 +  static ErrorContext bad_flags(u2 bci, StackMapFrame* frame) {
   1.107 +    return ErrorContext(bci, FLAGS_MISMATCH, TypeOrigin::frame(frame));
   1.108 +  }
   1.109 +  static ErrorContext bad_flags(u2 bci, StackMapFrame* cur, StackMapFrame* sm) {
   1.110 +    return ErrorContext(bci, FLAGS_MISMATCH,
   1.111 +                        TypeOrigin::frame(cur), TypeOrigin::frame(sm));
   1.112 +  }
   1.113 +  static ErrorContext bad_cp_index(u2 bci, u2 index) {
   1.114 +    return ErrorContext(bci, BAD_CP_INDEX, TypeOrigin::bad_index(index));
   1.115 +  }
   1.116 +  static ErrorContext bad_local_index(u2 bci, u2 index) {
   1.117 +    return ErrorContext(bci, BAD_LOCAL_INDEX, TypeOrigin::bad_index(index));
   1.118 +  }
   1.119 +  static ErrorContext locals_size_mismatch(
   1.120 +      u2 bci, StackMapFrame* frame0, StackMapFrame* frame1) {
   1.121 +    return ErrorContext(bci, LOCALS_SIZE_MISMATCH,
   1.122 +        TypeOrigin::frame(frame0), TypeOrigin::frame(frame1));
   1.123 +  }
   1.124 +  static ErrorContext stack_size_mismatch(
   1.125 +      u2 bci, StackMapFrame* frame0, StackMapFrame* frame1) {
   1.126 +    return ErrorContext(bci, STACK_SIZE_MISMATCH,
   1.127 +        TypeOrigin::frame(frame0), TypeOrigin::frame(frame1));
   1.128 +  }
   1.129 +  static ErrorContext stack_overflow(u2 bci, StackMapFrame* frame) {
   1.130 +    return ErrorContext(bci, STACK_OVERFLOW, TypeOrigin::frame(frame));
   1.131 +  }
   1.132 +  static ErrorContext stack_underflow(u2 bci, StackMapFrame* frame) {
   1.133 +    return ErrorContext(bci, STACK_UNDERFLOW, TypeOrigin::frame(frame));
   1.134 +  }
   1.135 +  static ErrorContext missing_stackmap(u2 bci) {
   1.136 +    return ErrorContext(bci, MISSING_STACKMAP);
   1.137 +  }
   1.138 +  static ErrorContext bad_stackmap(int index, StackMapFrame* frame) {
   1.139 +    return ErrorContext(0, BAD_STACKMAP, TypeOrigin::frame(frame));
   1.140 +  }
   1.141 +
   1.142 +  bool is_valid() const { return _fault != NO_FAULT; }
   1.143 +  int bci() const { return _bci; }
   1.144 +
   1.145 +  void reset_frames() {
   1.146 +    _type.reset_frame();
   1.147 +    _expected.reset_frame();
   1.148 +  }
   1.149 +
   1.150 +  void details(outputStream* ss, methodOop method) const;
   1.151 +
   1.152 +#ifdef ASSERT
   1.153 +  void print_on(outputStream* str) const {
   1.154 +    str->print("error_context(%d, %d,", _bci, _fault);
   1.155 +    _type.print_on(str);
   1.156 +    str->print(",");
   1.157 +    _expected.print_on(str);
   1.158 +    str->print(")");
   1.159 +  }
   1.160 +#endif
   1.161 +
   1.162 + private:
   1.163 +  void location_details(outputStream* ss, methodOop method) const;
   1.164 +  void reason_details(outputStream* ss) const;
   1.165 +  void frame_details(outputStream* ss) const;
   1.166 +  void bytecode_details(outputStream* ss, methodOop method) const;
   1.167 +  void handler_details(outputStream* ss, methodOop method) const;
   1.168 +  void stackmap_details(outputStream* ss, methodOop method) const;
   1.169 +};
   1.170 +
   1.171  // A new instance of this class is created for each class being verified
   1.172  class ClassVerifier : public StackObj {
   1.173   private:
   1.174    Thread* _thread;
   1.175 +  GrowableArray<Symbol*>* _symbols;  // keep a list of symbols created
   1.176 +
   1.177    Symbol* _exception_type;
   1.178    char* _message;
   1.179 -  size_t _message_buffer_len;
   1.180 -  GrowableArray<Symbol*>* _symbols;  // keep a list of symbols created
   1.181 +
   1.182 +  ErrorContext _error_context;  // contains information about an error
   1.183  
   1.184    void verify_method(methodHandle method, TRAPS);
   1.185    char* generate_code_data(methodHandle m, u4 code_length, TRAPS);
   1.186 -  void verify_exception_handler_table(u4 code_length, char* code_data, int& min, int& max, TRAPS);
   1.187 +  void verify_exception_handler_table(u4 code_length, char* code_data,
   1.188 +                                      int& min, int& max, TRAPS);
   1.189    void verify_local_variable_table(u4 code_length, char* code_data, TRAPS);
   1.190  
   1.191    VerificationType cp_ref_index_to_type(
   1.192 @@ -111,10 +271,10 @@
   1.193      instanceKlassHandle this_class, klassOop target_class,
   1.194      Symbol* field_name, Symbol* field_sig, bool is_method);
   1.195  
   1.196 -  void verify_cp_index(constantPoolHandle cp, int index, TRAPS);
   1.197 -  void verify_cp_type(
   1.198 -    int index, constantPoolHandle cp, unsigned int types, TRAPS);
   1.199 -  void verify_cp_class_type(int index, constantPoolHandle cp, TRAPS);
   1.200 +  void verify_cp_index(u2 bci, constantPoolHandle cp, int index, TRAPS);
   1.201 +  void verify_cp_type(u2 bci, int index, constantPoolHandle cp,
   1.202 +      unsigned int types, TRAPS);
   1.203 +  void verify_cp_class_type(u2 bci, int index, constantPoolHandle cp, TRAPS);
   1.204  
   1.205    u2 verify_stackmap_table(
   1.206      u2 stackmap_index, u2 bci, StackMapFrame* current_frame,
   1.207 @@ -137,7 +297,7 @@
   1.208      constantPoolHandle cp, TRAPS);
   1.209  
   1.210    void verify_invoke_init(
   1.211 -    RawBytecodeStream* bcs, VerificationType ref_class_type,
   1.212 +    RawBytecodeStream* bcs, u2 ref_index, VerificationType ref_class_type,
   1.213      StackMapFrame* current_frame, u4 code_length, bool* this_uninit,
   1.214      constantPoolHandle cp, TRAPS);
   1.215  
   1.216 @@ -147,10 +307,11 @@
   1.217      constantPoolHandle cp, TRAPS);
   1.218  
   1.219    VerificationType get_newarray_type(u2 index, u2 bci, TRAPS);
   1.220 -  void verify_anewarray(
   1.221 -    u2 index, constantPoolHandle cp, StackMapFrame* current_frame, TRAPS);
   1.222 +  void verify_anewarray(u2 bci, u2 index, constantPoolHandle cp,
   1.223 +      StackMapFrame* current_frame, TRAPS);
   1.224    void verify_return_value(
   1.225 -    VerificationType return_type, VerificationType type, u2 offset, TRAPS);
   1.226 +      VerificationType return_type, VerificationType type, u2 offset,
   1.227 +      StackMapFrame* current_frame, TRAPS);
   1.228  
   1.229    void verify_iload (u2 index, StackMapFrame* current_frame, TRAPS);
   1.230    void verify_lload (u2 index, StackMapFrame* current_frame, TRAPS);
   1.231 @@ -189,7 +350,7 @@
   1.232    };
   1.233  
   1.234    // constructor
   1.235 -  ClassVerifier(instanceKlassHandle klass, char* msg, size_t msg_len, TRAPS);
   1.236 +  ClassVerifier(instanceKlassHandle klass, TRAPS);
   1.237  
   1.238    // destructor
   1.239    ~ClassVerifier();
   1.240 @@ -207,13 +368,17 @@
   1.241    // Return status modes
   1.242    Symbol* result() const { return _exception_type; }
   1.243    bool has_error() const { return result() != NULL; }
   1.244 +  char* exception_message() {
   1.245 +    stringStream ss;
   1.246 +    ss.print(_message);
   1.247 +    _error_context.details(&ss, _method());
   1.248 +    return ss.as_string();
   1.249 +  }
   1.250  
   1.251    // Called when verify or class format errors are encountered.
   1.252    // May throw an exception based upon the mode.
   1.253 -  void verify_error(u2 offset, const char* fmt, ...);
   1.254 -  void verify_error(const char* fmt, ...);
   1.255 +  void verify_error(ErrorContext ctx, const char* fmt, ...);
   1.256    void class_format_error(const char* fmt, ...);
   1.257 -  void format_error_message(const char* fmt, int offset, va_list args);
   1.258  
   1.259    klassOop load_class(Symbol* name, TRAPS);
   1.260  
   1.261 @@ -228,10 +393,11 @@
   1.262    // their reference counts need to be decrememented when the verifier object
   1.263    // goes out of scope.  Since these symbols escape the scope in which they're
   1.264    // created, we can't use a TempNewSymbol.
   1.265 -  Symbol* create_temporary_symbol(const Symbol* s, int begin, int end, TRAPS);
   1.266 +  Symbol* create_temporary_symbol(
   1.267 +      const Symbol* s, int begin, int end, TRAPS);
   1.268    Symbol* create_temporary_symbol(const char *s, int length, TRAPS);
   1.269  
   1.270 -  static bool _verify_verbose;  // for debugging
   1.271 +  TypeOrigin ref_ctx(const char* str, TRAPS);
   1.272  };
   1.273  
   1.274  inline int ClassVerifier::change_sig_to_verificationType(

mercurial