/* * Copyright (c) 1998, 2021, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * version 2 for more details (a copy is included in the LICENSE file that * accompanied this code). * * You should have received a copy of the GNU General Public License version * 2 along with this work; if not, write to the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA * or visit www.oracle.com if you need additional information or have any * questions. *
*/
// Return false if the class is loaded by the bootstrap loader, // or if defineClass was called requesting skipping verification // -Xverify:all overrides this value staticbool should_verify_for(oop class_loader, bool should_verify_class);
// Relax certain access checks to enable some broken 1.1 apps to run on 1.2. staticbool relax_access_for(oop class_loader);
// Print output for class+resolve staticvoid trace_class_resolution(Klass* resolve_class, InstanceKlass* verify_class);
class RawBytecodeStream; class StackMapFrame; class StackMapTable;
// Summary of verifier's memory usage: // StackMapTable is stack allocated. // StackMapFrame are resource allocated. There is only one ResourceMark // for each class verification, which is created at the top level. // There is one mutable StackMapFrame (current_frame) which is updated // by abstract bytecode interpretation. frame_in_exception_handler() returns // a frame that has a mutable one-item stack (ready for pushing the // catch type exception object). All the other StackMapFrame's // are immutable (including their locals and stack arrays) after // their constructions. // locals/stack arrays in StackMapFrame are resource allocated. // locals/stack arrays can be shared between StackMapFrame's, except // the mutable StackMapFrame (current_frame).
// These macros are used similarly to CHECK macros but also check // the status of the verifier and return if that has an error. #define CHECK_VERIFY(verifier) \
CHECK); if ((verifier)->has_error()) return; ((void)0 #define CHECK_VERIFY_(verifier, result) \
CHECK_(result)); if ((verifier)->has_error()) return (result); ((void)0
class TypeOrigin { private: typedefenum {
CF_LOCALS, // Comes from the current frame locals
CF_STACK, // Comes from the current frame expression stack
SM_LOCALS, // Comes from stackmap locals
SM_STACK, // Comes from stackmap expression stack
CONST_POOL, // Comes from the constant pool
SIG, // Comes from method signature
IMPLICIT, // Comes implicitly from code or context
BAD_INDEX, // No type, but the index is bad
FRAME_ONLY, // No type, context just contains the frame
NONE
} Origin;
Origin _origin;
u2 _index; // local, stack, or constant pool index
StackMapFrame* _frame; // source frame if CF or SM
VerificationType _type; // The actual type
class ErrorContext { private: typedefenum {
INVALID_BYTECODE, // There was a problem with the bytecode
WRONG_TYPE, // Type value was not as expected
FLAGS_MISMATCH, // Frame flags are not assignable
BAD_CP_INDEX, // Invalid constant pool index
BAD_LOCAL_INDEX, // Invalid local index
LOCALS_SIZE_MISMATCH, // Frames have differing local counts
STACK_SIZE_MISMATCH, // Frames have different stack sizes
STACK_OVERFLOW, // Attempt to push onto a full expression stack
STACK_UNDERFLOW, // Attempt to pop and empty expression stack
MISSING_STACKMAP, // No stackmap for this location and there should be
BAD_STACKMAP, // Format error in stackmap
NO_FAULT, // No error
UNKNOWN
} FaultType;
int _bci;
FaultType _fault;
TypeOrigin _type;
TypeOrigin _expected;
class sig_as_verification_types : public ResourceObj { private: int _num_args; // Number of arguments, not including return type.
GrowableArray<VerificationType>* _sig_verif_types;
// This hashtable is indexed by the Utf8 constant pool indexes pointed to // by constant pool (Interface)Method_refs' NameAndType signature entries. typedef ResourceHashtable<int, sig_as_verification_types*, 1007>
method_signatures_table_type;
// A new instance of this class is created for each class being verified class ClassVerifier : public StackObj { private:
Thread* _thread;
Symbol* _previous_symbol; // cache of the previously looked up symbol
GrowableArray<Symbol*>* _symbols; // keep a list of symbols created
// Used by ends_in_athrow() to push all handlers that contain bci onto the // handler_stack, if the handler has not already been pushed on the stack. void push_handlers(ExceptionTable* exhandlers,
GrowableArray<u4>* handler_list,
GrowableArray<u4>* handler_stack,
u4 bci);
// Returns true if all paths starting with start_bc_offset end in athrow // bytecode or loop. bool ends_in_athrow(u4 start_bc_offset);
InstanceKlass* _klass; // the class being verified
methodHandle _method; // current method being verified
VerificationType _this_type; // the verification type of the current class
// Some recursive calls from the verifier to the name resolver // can cause the current class to be re-verified and rewritten. // If this happens, the original verification should not continue, // because constant pool indexes will have changed. // The rewriter is preceded by the verifier. If the verifier throws // an error, rewriting is prevented. Also, rewriting always precedes // bytecode execution or compilation. Thus, is_rewritten implies // that a class has been verified and prepared for execution. bool was_recursively_verified() { return _klass->is_rewritten(); }
// Verifies the class. If a verify or class file format error occurs, // the '_exception_name' symbols will set to the exception name and // the message_buffer will be filled in with the exception message. void verify_class(TRAPS);
// Translates method signature entries into verificationTypes and saves them // in the growable array. void translate_signature(Symbol* const method_sig, sig_as_verification_types* sig_verif_types);
// Initializes a sig_as_verification_types entry and puts it in the hash table. void create_method_sig_entry(sig_as_verification_types* sig_verif_types, int sig_index);
// Called when verify or class format errors are encountered. // May throw an exception based upon the mode. void verify_error(ErrorContext ctx, constchar* fmt, ...) ATTRIBUTE_PRINTF(3, 4); void class_format_error(constchar* fmt, ...) ATTRIBUTE_PRINTF(2, 3);
// Keep a list of temporary symbols created during verification because // their reference counts need to be decremented when the verifier object // goes out of scope. Since these symbols escape the scope in which they're // created, we can't use a TempNewSymbol.
Symbol* create_temporary_symbol(constchar *s, int length);
Symbol* create_temporary_symbol(Symbol* s) { if (s == _previous_symbol) { return s;
} if (!s->is_permanent()) {
s->increment_refcount(); if (_symbols == NULL) {
_symbols = new GrowableArray<Symbol*>(50, 0, NULL);
}
_symbols->push(s);
}
_previous_symbol = s; return s;
}
TypeOrigin ref_ctx(constchar* str);
};
inlineint ClassVerifier::change_sig_to_verificationType(
SignatureStream* sig_type, VerificationType* inference_type) {
BasicType bt = sig_type->type(); switch (bt) { case T_OBJECT: case T_ARRAY:
{
Symbol* name = sig_type->as_symbol(); // Create another symbol to save as signature stream unreferences this symbol.
Symbol* name_copy = create_temporary_symbol(name);
assert(name_copy == name, "symbols don't match");
*inference_type =
VerificationType::reference_type(name_copy); return 1;
} case T_LONG:
*inference_type = VerificationType::long_type();
*++inference_type = VerificationType::long2_type(); return 2; case T_DOUBLE:
*inference_type = VerificationType::double_type();
*++inference_type = VerificationType::double2_type(); return 2; case T_INT: case T_BOOLEAN: case T_BYTE: case T_CHAR: case T_SHORT:
*inference_type = VerificationType::integer_type(); return 1; case T_FLOAT:
*inference_type = VerificationType::float_type(); return 1; default:
ShouldNotReachHere(); return 1;
}
}
#endif// SHARE_CLASSFILE_VERIFIER_HPP
¤ Dauer der Verarbeitung: 0.2 Sekunden
(vorverarbeitet)
¤
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung ist noch experimentell.