• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2011 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 #ifndef ART_RUNTIME_VERIFIER_METHOD_VERIFIER_H_
18 #define ART_RUNTIME_VERIFIER_METHOD_VERIFIER_H_
19 
20 #include <memory>
21 #include <sstream>
22 #include <vector>
23 
24 #include <android-base/logging.h>
25 
26 #include "base/arena_allocator.h"
27 #include "base/macros.h"
28 #include "base/scoped_arena_containers.h"
29 #include "base/value_object.h"
30 #include "dex/code_item_accessors.h"
31 #include "dex/dex_file_types.h"
32 #include "dex/method_reference.h"
33 #include "handle.h"
34 #include "instruction_flags.h"
35 #include "reg_type_cache.h"
36 #include "register_line.h"
37 #include "verifier_enums.h"
38 
39 namespace art {
40 
41 class ClassLinker;
42 class CompilerCallbacks;
43 class DexFile;
44 class Instruction;
45 struct ReferenceMap2Visitor;
46 class Thread;
47 class VariableIndentationOutputStream;
48 
49 namespace dex {
50 struct ClassDef;
51 struct CodeItem;
52 }  // namespace dex
53 
54 namespace mirror {
55 class DexCache;
56 }  // namespace mirror
57 
58 namespace verifier {
59 
60 class MethodVerifier;
61 class RegisterLine;
62 using RegisterLineArenaUniquePtr = std::unique_ptr<RegisterLine, RegisterLineArenaDelete>;
63 class RegType;
64 struct ScopedNewLine;
65 
66 // We don't need to store the register data for many instructions, because we either only need
67 // it at branch points (for verification) or GC points and branches (for verification +
68 // type-precise register analysis).
69 enum RegisterTrackingMode {
70   kTrackRegsBranches,
71   kTrackCompilerInterestPoints,
72   kTrackRegsAll,
73 };
74 
75 // A class used by the verifier to tell users about what options need to be set for given methods.
76 class VerifierCallback {
77  public:
~VerifierCallback()78   virtual ~VerifierCallback() {}
79   virtual void SetDontCompile(ArtMethod* method, bool value)
80       REQUIRES_SHARED(Locks::mutator_lock_) = 0;
81   virtual void SetMustCountLocks(ArtMethod* method, bool value)
82       REQUIRES_SHARED(Locks::mutator_lock_) = 0;
83 };
84 
85 // A mapping from a dex pc to the register line statuses as they are immediately prior to the
86 // execution of that instruction.
87 class PcToRegisterLineTable {
88  public:
89   explicit PcToRegisterLineTable(ScopedArenaAllocator& allocator);
90   ~PcToRegisterLineTable();
91 
92   // Initialize the RegisterTable. Every instruction address can have a different set of information
93   // about what's in which register, but for verification purposes we only need to store it at
94   // branch target addresses (because we merge into that).
95   void Init(RegisterTrackingMode mode,
96             InstructionFlags* flags,
97             uint32_t insns_size,
98             uint16_t registers_size,
99             ScopedArenaAllocator& allocator,
100             RegTypeCache* reg_types);
101 
IsInitialized()102   bool IsInitialized() const {
103     return !register_lines_.empty();
104   }
105 
GetLine(size_t idx)106   RegisterLine* GetLine(size_t idx) const {
107     return register_lines_[idx].get();
108   }
109 
110  private:
111   ScopedArenaVector<RegisterLineArenaUniquePtr> register_lines_;
112 
113   DISALLOW_COPY_AND_ASSIGN(PcToRegisterLineTable);
114 };
115 
116 // The verifier
117 class MethodVerifier {
118  public:
119   static MethodVerifier* VerifyMethodAndDump(Thread* self,
120                                              VariableIndentationOutputStream* vios,
121                                              uint32_t method_idx,
122                                              const DexFile* dex_file,
123                                              Handle<mirror::DexCache> dex_cache,
124                                              Handle<mirror::ClassLoader> class_loader,
125                                              const dex::ClassDef& class_def,
126                                              const dex::CodeItem* code_item, ArtMethod* method,
127                                              uint32_t method_access_flags,
128                                              uint32_t api_level)
129       REQUIRES_SHARED(Locks::mutator_lock_);
130 
131   // Calculates the verification information for every instruction of the given method. The given
132   // dex-cache and class-loader will be used for lookups. No classes will be loaded. If verification
133   // fails hard nullptr will be returned. This should only be used if one needs to examine what the
134   // verifier believes about the registers of a given method.
135   static MethodVerifier* CalculateVerificationInfo(Thread* self,
136                                                    ArtMethod* method,
137                                                    Handle<mirror::DexCache> dex_cache,
138                                                    Handle<mirror::ClassLoader> class_loader)
139       REQUIRES_SHARED(Locks::mutator_lock_);
140 
GetDexFile()141   const DexFile& GetDexFile() const {
142     DCHECK(dex_file_ != nullptr);
143     return *dex_file_;
144   }
145 
GetRegTypeCache()146   RegTypeCache* GetRegTypeCache() {
147     return &reg_types_;
148   }
149 
150   // Log a verification failure.
151   std::ostream& Fail(VerifyError error, bool pending_exc = true);
152 
153   // Log for verification information.
154   ScopedNewLine LogVerifyInfo();
155 
156   // Information structure for a lock held at a certain point in time.
157   struct DexLockInfo {
158     // The registers aliasing the lock.
159     std::set<uint32_t> dex_registers;
160     // The dex PC of the monitor-enter instruction.
161     uint32_t dex_pc;
162 
DexLockInfoDexLockInfo163     explicit DexLockInfo(uint32_t dex_pc_in) {
164       dex_pc = dex_pc_in;
165     }
166   };
167   // Fills 'monitor_enter_dex_pcs' with the dex pcs of the monitor-enter instructions corresponding
168   // to the locks held at 'dex_pc' in method 'm'.
169   // Note: this is the only situation where the verifier will visit quickened instructions.
170   static void FindLocksAtDexPc(ArtMethod* m,
171                                uint32_t dex_pc,
172                                std::vector<DexLockInfo>* monitor_enter_dex_pcs,
173                                uint32_t api_level)
174       REQUIRES_SHARED(Locks::mutator_lock_);
175 
176   static void Init(ClassLinker* class_linker) REQUIRES_SHARED(Locks::mutator_lock_);
177   static void Shutdown();
178 
179   virtual ~MethodVerifier();
180 
181   static void VisitStaticRoots(RootVisitor* visitor)
182       REQUIRES_SHARED(Locks::mutator_lock_);
183   void VisitRoots(RootVisitor* visitor, const RootInfo& roots)
184       REQUIRES_SHARED(Locks::mutator_lock_);
185 
186   // Accessors used by the compiler via CompilerCallback
CodeItem()187   const CodeItemDataAccessor& CodeItem() const {
188     return code_item_accessor_;
189   }
190   RegisterLine* GetRegLine(uint32_t dex_pc);
191   ALWAYS_INLINE const InstructionFlags& GetInstructionFlags(size_t index) const;
192 
193   MethodReference GetMethodReference() const;
194   bool HasCheckCasts() const;
195   bool HasFailures() const;
HasInstructionThatWillThrow()196   bool HasInstructionThatWillThrow() const {
197     return flags_.have_any_pending_runtime_throw_failure_;
198   }
199 
200   virtual const RegType& ResolveCheckedClass(dex::TypeIndex class_idx)
201       REQUIRES_SHARED(Locks::mutator_lock_) = 0;
202 
GetEncounteredFailureTypes()203   uint32_t GetEncounteredFailureTypes() {
204     return encountered_failure_types_;
205   }
206 
GetClassLinker()207   ClassLinker* GetClassLinker() {
208     return class_linker_;
209   }
210 
IsAotMode()211   bool IsAotMode() const {
212     return flags_.aot_mode_;
213   }
214 
215  protected:
216   MethodVerifier(Thread* self,
217                  ClassLinker* class_linker,
218                  ArenaPool* arena_pool,
219                  const DexFile* dex_file,
220                  const dex::CodeItem* code_item,
221                  uint32_t dex_method_idx,
222                  bool can_load_classes,
223                  bool allow_thread_suspension,
224                  bool allow_soft_failures,
225                  bool aot_mode)
226       REQUIRES_SHARED(Locks::mutator_lock_);
227 
228   // Verification result for method(s). Includes a (maximum) failure kind, and (the union of)
229   // all failure types.
230   struct FailureData : ValueObject {
231     FailureKind kind = FailureKind::kNoFailure;
232     uint32_t types = 0U;
233 
234     // Merge src into this. Uses the most severe failure kind, and the union of types.
235     void Merge(const FailureData& src);
236   };
237 
238   /*
239    * Perform verification on a single method.
240    *
241    * We do this in three passes:
242    *  (1) Walk through all code units, determining instruction locations,
243    *      widths, and other characteristics.
244    *  (2) Walk through all code units, performing static checks on
245    *      operands.
246    *  (3) Iterate through the method, checking type safety and looking
247    *      for code flow problems.
248    */
249   static FailureData VerifyMethod(Thread* self,
250                                   ClassLinker* class_linker,
251                                   ArenaPool* arena_pool,
252                                   uint32_t method_idx,
253                                   const DexFile* dex_file,
254                                   Handle<mirror::DexCache> dex_cache,
255                                   Handle<mirror::ClassLoader> class_loader,
256                                   const dex::ClassDef& class_def_idx,
257                                   const dex::CodeItem* code_item,
258                                   ArtMethod* method,
259                                   uint32_t method_access_flags,
260                                   CompilerCallbacks* callbacks,
261                                   VerifierCallback* verifier_callback,
262                                   bool allow_soft_failures,
263                                   HardFailLogMode log_level,
264                                   bool need_precise_constants,
265                                   uint32_t api_level,
266                                   bool aot_mode,
267                                   std::string* hard_failure_msg)
268       REQUIRES_SHARED(Locks::mutator_lock_);
269 
270   template <bool kVerifierDebug>
271   static FailureData VerifyMethod(Thread* self,
272                                   ClassLinker* class_linker,
273                                   ArenaPool* arena_pool,
274                                   uint32_t method_idx,
275                                   const DexFile* dex_file,
276                                   Handle<mirror::DexCache> dex_cache,
277                                   Handle<mirror::ClassLoader> class_loader,
278                                   const dex::ClassDef& class_def_idx,
279                                   const dex::CodeItem* code_item,
280                                   ArtMethod* method,
281                                   uint32_t method_access_flags,
282                                   CompilerCallbacks* callbacks,
283                                   VerifierCallback* verifier_callback,
284                                   bool allow_soft_failures,
285                                   HardFailLogMode log_level,
286                                   bool need_precise_constants,
287                                   uint32_t api_level,
288                                   bool aot_mode,
289                                   std::string* hard_failure_msg)
290       REQUIRES_SHARED(Locks::mutator_lock_);
291 
292   // For VerifierDepsTest. TODO: Refactor.
293 
294   // Run verification on the method. Returns true if verification completes and false if the input
295   // has an irrecoverable corruption.
296   virtual bool Verify() REQUIRES_SHARED(Locks::mutator_lock_) = 0;
297   static MethodVerifier* CreateVerifier(Thread* self,
298                                         const DexFile* dex_file,
299                                         Handle<mirror::DexCache> dex_cache,
300                                         Handle<mirror::ClassLoader> class_loader,
301                                         const dex::ClassDef& class_def,
302                                         const dex::CodeItem* code_item,
303                                         uint32_t method_idx,
304                                         ArtMethod* method,
305                                         uint32_t access_flags,
306                                         bool can_load_classes,
307                                         bool allow_soft_failures,
308                                         bool need_precise_constants,
309                                         bool verify_to_dump,
310                                         bool allow_thread_suspension,
311                                         uint32_t api_level)
312       REQUIRES_SHARED(Locks::mutator_lock_);
313 
314   // The thread we're verifying on.
315   Thread* const self_;
316 
317   // Arena allocator.
318   ArenaStack arena_stack_;
319   ScopedArenaAllocator allocator_;
320 
321   RegTypeCache reg_types_;
322 
323   PcToRegisterLineTable reg_table_;
324 
325   // Storage for the register status we're currently working on.
326   RegisterLineArenaUniquePtr work_line_;
327 
328   // The address of the instruction we're currently working on, note that this is in 2 byte
329   // quantities
330   uint32_t work_insn_idx_;
331 
332   // Storage for the register status we're saving for later.
333   RegisterLineArenaUniquePtr saved_line_;
334 
335   const uint32_t dex_method_idx_;  // The method we're working on.
336   const DexFile* const dex_file_;  // The dex file containing the method.
337   const CodeItemDataAccessor code_item_accessor_;
338 
339   // Instruction widths and flags, one entry per code unit.
340   // Owned, but not unique_ptr since insn_flags_ are allocated in arenas.
341   ArenaUniquePtr<InstructionFlags[]> insn_flags_;
342 
343   // The types of any error that occurs.
344   std::vector<VerifyError> failures_;
345   // Error messages associated with failures.
346   std::vector<std::ostringstream*> failure_messages_;
347   struct {
348     // Is there a pending hard failure?
349     bool have_pending_hard_failure_ : 1;
350 
351     // Is there a pending runtime throw failure? A runtime throw failure is when an instruction
352     // would fail at runtime throwing an exception. Such an instruction causes the following code
353     // to be unreachable. This is set by Fail and used to ensure we don't process unreachable
354     // instructions that would hard fail the verification.
355     // Note: this flag is reset after processing each instruction.
356     bool have_pending_runtime_throw_failure_ : 1;
357 
358     // Is there a pending experimental failure?
359     bool have_pending_experimental_failure_ : 1;
360 
361     // A version of the above that is not reset and thus captures if there were *any* throw
362     // failures.
363     bool have_any_pending_runtime_throw_failure_ : 1;
364 
365     // Verify in AoT mode?
366     bool aot_mode_ : 1;
367   } flags_;
368 
369   // Info message log use primarily for verifier diagnostics.
370   std::ostringstream info_messages_;
371 
372   // Bitset of the encountered failure types. Bits are according to the values in VerifyError.
373   uint32_t encountered_failure_types_;
374 
375   const bool can_load_classes_;
376 
377   // Converts soft failures to hard failures when false. Only false when the compiler isn't
378   // running and the verifier is called from the class linker.
379   const bool allow_soft_failures_;
380 
381   // Indicates the method being verified contains at least one check-cast or aput-object
382   // instruction. Aput-object operations implicitly check for array-store exceptions, similar to
383   // check-cast.
384   bool has_check_casts_;
385 
386   // Classlinker to use when resolving.
387   ClassLinker* class_linker_;
388 
389   // Link, for the method verifier root linked list.
390   MethodVerifier* link_;
391 
392   friend class art::Thread;
393   friend class ClassVerifier;
394   friend class VerifierDepsTest;
395 
396   DISALLOW_COPY_AND_ASSIGN(MethodVerifier);
397 };
398 
399 }  // namespace verifier
400 }  // namespace art
401 
402 #endif  // ART_RUNTIME_VERIFIER_METHOD_VERIFIER_H_
403