namespace mirror { class ClassLoader; class DexCache;
} // namespace mirror
namespace verifier {
class MethodVerifier; class RegType; class RegTypeCache; struct ScopedNewLine; class VerifierDeps;
// A mapping from a dex pc to the register line statuses as they are immediately prior to the // execution of that instruction. class PcToRegisterLineTable { public: explicit PcToRegisterLineTable(ArenaAllocator& allocator);
~PcToRegisterLineTable();
// Initialize the RegisterTable. Every instruction address can have a different set of information // about what's in which register, but for verification purposes we only need to store it at // branch target addresses (because we merge into that). void Init(InstructionFlags* flags,
uint32_t insns_size,
uint16_t registers_size,
ArenaAllocator& allocator,
uint32_t interesting_dex_pc);
// Calculates the type information at the given `dex_pc`. // No classes will be loaded.
EXPORT static MethodVerifier* CalculateVerificationInfo(Thread* self,
RegTypeCache* reg_types,
ArtMethod* method,
Handle<mirror::DexCache> dex_cache,
uint32_t dex_pc)
REQUIRES_SHARED(Locks::mutator_lock_);
// Log for verification information.
ScopedNewLine LogVerifyInfo();
// Information structure for a lock held at a certain point in time. struct DexLockInfo { // The registers aliasing the lock.
std::set<uint32_t> dex_registers; // The dex PC of the monitor-enter instruction.
uint32_t dex_pc;
explicit DexLockInfo(uint32_t dex_pc_in) {
dex_pc = dex_pc_in;
}
}; // Fills 'monitor_enter_dex_pcs' with the dex pcs of the monitor-enter instructions corresponding // to the locks held at 'dex_pc' in method 'm'. // Note: this is the only situation where the verifier will visit quickened instructions. staticvoid FindLocksAtDexPc(ArtMethod* m,
uint32_t dex_pc,
std::vector<DexLockInfo>* monitor_enter_dex_pcs,
uint32_t api_level)
REQUIRES_SHARED(Locks::mutator_lock_);
// Verification result for method(s). Includes a (maximum) failure kind, and (the union of) // all failure types. struct FailureData : ValueObject {
FailureKind kind = FailureKind::kNoFailure;
uint32_t types = 0U;
// Merge src into this. Uses the most severe failure kind, and the union of types. void Merge(const FailureData& src);
};
// Can a variable with type `lhs` be assigned a value with type `rhs`? // Note: Object and interface types may always be assigned to one another, see // comment on `ClassJoin()`. bool IsAssignableFrom(const RegType& lhs, const RegType& rhs) const
REQUIRES_SHARED(Locks::mutator_lock_);
// Can a variable with type `lhs` be assigned a value with type `rhs`? // Variant of IsAssignableFrom that doesn't allow assignment to an interface from an Object. bool IsStrictlyAssignableFrom(const RegType& lhs, const RegType& rhs) const
REQUIRES_SHARED(Locks::mutator_lock_);
// Implementation helper for `IsAssignableFrom()` and `IsStrictlyAssignableFrom()`. bool AssignableFrom(const RegType& lhs, const RegType& rhs, bool strict) const
REQUIRES_SHARED(Locks::mutator_lock_);
// For VerifierDepsTest. TODO: Refactor.
// Run verification on the method. Returns true if verification completes and false if the input // has an irrecoverable corruption. virtualbool Verify() REQUIRES_SHARED(Locks::mutator_lock_) = 0; static MethodVerifier* CreateVerifier(Thread* self,
RegTypeCache* reg_types,
VerifierDeps* verifier_deps,
Handle<mirror::DexCache> dex_cache, const dex::ClassDef& class_def, const dex::CodeItem* code_item,
uint32_t method_idx,
uint32_t access_flags, bool verify_to_dump,
uint32_t api_level)
REQUIRES_SHARED(Locks::mutator_lock_);
// The thread we're verifying on.
Thread* const self_;
// Arena allocator.
ArenaAllocator allocator_;
RegTypeCache& reg_types_; // TODO: Change to a pointer in a separate CL.
PcToRegisterLineTable reg_table_;
// Storage for the register status we're currently working on.
RegisterLineArenaUniquePtr work_line_;
// The address of the instruction we're currently working on, note that this is in 2 byte // quantities
uint32_t work_insn_idx_;
// Storage for the register status we're saving for later.
RegisterLineArenaUniquePtr saved_line_;
const uint32_t dex_method_idx_; // The method we're working on. const DexFile* const dex_file_; // The dex file containing the method. const dex::ClassDef& class_def_; // The class being verified. const CodeItemDataAccessor code_item_accessor_;
// Instruction widths and flags, one entry per code unit. // Owned, but not unique_ptr since insn_flags_ are allocated in arenas.
ArenaUniquePtr<InstructionFlags[]> insn_flags_;
// The types of any error that occurs and associated error messages. using MessageOStream =
std::basic_ostringstream<char, std::char_traits<char>, ArenaAllocatorAdapter<char>>; struct VerifyErrorAndMessage {
VerifyErrorAndMessage(VerifyError e, const std::string& location, ArenaAllocatorAdapter<char> a)
: error(e), message(location, std::ios_base::ate, a) {}
VerifyError error;
MessageOStream message;
};
ArenaList<VerifyErrorAndMessage> failures_;
struct { // Is there a pending hard failure? bool have_pending_hard_failure_ : 1;
// Is there a pending runtime throw failure? A runtime throw failure is when an instruction // would fail at runtime throwing an exception. Such an instruction causes the following code // to be unreachable. This is set by Fail and used to ensure we don't process unreachable // instructions that would hard fail the verification. // Note: this flag is reset after processing each instruction. bool have_pending_runtime_throw_failure_ : 1;
} flags_;
// Whether the `MethodVerifer` can load classes. bool can_load_classes_ : 1;
} const const_flags_;
// Bitset of the encountered failure types. Bits are according to the values in VerifyError.
uint32_t encountered_failure_types_;
// Info message log use primarily for verifier diagnostics.
std::optional<std::ostringstream> info_messages_;
// The verifier deps object we are going to report type assigability // constraints to. Can be null for runtime verification.
VerifierDeps* verifier_deps_;
// Link, for the method verifier root linked list.
MethodVerifier* link_;
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 und die Messung sind noch experimentell.