• 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 mapping from a dex pc to the register line statuses as they are immediately prior to the
76 // execution of that instruction.
77 class PcToRegisterLineTable {
78  public:
79   explicit PcToRegisterLineTable(ScopedArenaAllocator& allocator);
80   ~PcToRegisterLineTable();
81 
82   // Initialize the RegisterTable. Every instruction address can have a different set of information
83   // about what's in which register, but for verification purposes we only need to store it at
84   // branch target addresses (because we merge into that).
85   void Init(RegisterTrackingMode mode,
86             InstructionFlags* flags,
87             uint32_t insns_size,
88             uint16_t registers_size,
89             ScopedArenaAllocator& allocator,
90             RegTypeCache* reg_types);
91 
IsInitialized()92   bool IsInitialized() const {
93     return !register_lines_.empty();
94   }
95 
GetLine(size_t idx)96   RegisterLine* GetLine(size_t idx) const {
97     return register_lines_[idx].get();
98   }
99 
100  private:
101   ScopedArenaVector<RegisterLineArenaUniquePtr> register_lines_;
102 
103   DISALLOW_COPY_AND_ASSIGN(PcToRegisterLineTable);
104 };
105 
106 // The verifier
107 class MethodVerifier {
108  public:
109   static MethodVerifier* VerifyMethodAndDump(Thread* self,
110                                              VariableIndentationOutputStream* vios,
111                                              uint32_t method_idx,
112                                              const DexFile* dex_file,
113                                              Handle<mirror::DexCache> dex_cache,
114                                              Handle<mirror::ClassLoader> class_loader,
115                                              const dex::ClassDef& class_def,
116                                              const dex::CodeItem* code_item, ArtMethod* method,
117                                              uint32_t method_access_flags,
118                                              uint32_t api_level)
119       REQUIRES_SHARED(Locks::mutator_lock_);
120 
GetDexFile()121   const DexFile& GetDexFile() const {
122     DCHECK(dex_file_ != nullptr);
123     return *dex_file_;
124   }
125 
GetRegTypeCache()126   RegTypeCache* GetRegTypeCache() {
127     return &reg_types_;
128   }
129 
130   // Log a verification failure.
131   std::ostream& Fail(VerifyError error);
132 
133   // Log for verification information.
134   ScopedNewLine LogVerifyInfo();
135 
136   // Information structure for a lock held at a certain point in time.
137   struct DexLockInfo {
138     // The registers aliasing the lock.
139     std::set<uint32_t> dex_registers;
140     // The dex PC of the monitor-enter instruction.
141     uint32_t dex_pc;
142 
DexLockInfoDexLockInfo143     explicit DexLockInfo(uint32_t dex_pc_in) {
144       dex_pc = dex_pc_in;
145     }
146   };
147   // Fills 'monitor_enter_dex_pcs' with the dex pcs of the monitor-enter instructions corresponding
148   // to the locks held at 'dex_pc' in method 'm'.
149   // Note: this is the only situation where the verifier will visit quickened instructions.
150   static void FindLocksAtDexPc(ArtMethod* m,
151                                uint32_t dex_pc,
152                                std::vector<DexLockInfo>* monitor_enter_dex_pcs,
153                                uint32_t api_level)
154       REQUIRES_SHARED(Locks::mutator_lock_);
155 
156   static void Init() REQUIRES_SHARED(Locks::mutator_lock_);
157   static void Shutdown();
158 
159   virtual ~MethodVerifier();
160 
161   static void VisitStaticRoots(RootVisitor* visitor)
162       REQUIRES_SHARED(Locks::mutator_lock_);
163   void VisitRoots(RootVisitor* visitor, const RootInfo& roots)
164       REQUIRES_SHARED(Locks::mutator_lock_);
165 
166   // Accessors used by the compiler via CompilerCallback
CodeItem()167   const CodeItemDataAccessor& CodeItem() const {
168     return code_item_accessor_;
169   }
170   RegisterLine* GetRegLine(uint32_t dex_pc);
171   ALWAYS_INLINE const InstructionFlags& GetInstructionFlags(size_t index) const;
172 
173   MethodReference GetMethodReference() const;
174   bool HasCheckCasts() const;
175   bool HasFailures() const;
HasInstructionThatWillThrow()176   bool HasInstructionThatWillThrow() const {
177     return have_any_pending_runtime_throw_failure_;
178   }
179 
180   virtual const RegType& ResolveCheckedClass(dex::TypeIndex class_idx)
181       REQUIRES_SHARED(Locks::mutator_lock_) = 0;
182 
GetEncounteredFailureTypes()183   uint32_t GetEncounteredFailureTypes() {
184     return encountered_failure_types_;
185   }
186 
187  protected:
188   MethodVerifier(Thread* self,
189                  const DexFile* dex_file,
190                  const dex::CodeItem* code_item,
191                  uint32_t dex_method_idx,
192                  bool can_load_classes,
193                  bool allow_thread_suspension,
194                  bool allow_soft_failures)
195       REQUIRES_SHARED(Locks::mutator_lock_);
196 
197   // Verification result for method(s). Includes a (maximum) failure kind, and (the union of)
198   // all failure types.
199   struct FailureData : ValueObject {
200     FailureKind kind = FailureKind::kNoFailure;
201     uint32_t types = 0U;
202 
203     // Merge src into this. Uses the most severe failure kind, and the union of types.
204     void Merge(const FailureData& src);
205   };
206 
207   /*
208    * Perform verification on a single method.
209    *
210    * We do this in three passes:
211    *  (1) Walk through all code units, determining instruction locations,
212    *      widths, and other characteristics.
213    *  (2) Walk through all code units, performing static checks on
214    *      operands.
215    *  (3) Iterate through the method, checking type safety and looking
216    *      for code flow problems.
217    */
218   static FailureData VerifyMethod(Thread* self,
219                                   uint32_t method_idx,
220                                   const DexFile* dex_file,
221                                   Handle<mirror::DexCache> dex_cache,
222                                   Handle<mirror::ClassLoader> class_loader,
223                                   const dex::ClassDef& class_def_idx,
224                                   const dex::CodeItem* code_item,
225                                   ArtMethod* method,
226                                   uint32_t method_access_flags,
227                                   CompilerCallbacks* callbacks,
228                                   bool allow_soft_failures,
229                                   HardFailLogMode log_level,
230                                   bool need_precise_constants,
231                                   uint32_t api_level,
232                                   std::string* hard_failure_msg)
233       REQUIRES_SHARED(Locks::mutator_lock_);
234 
235   template <bool kVerifierDebug>
236   static FailureData VerifyMethod(Thread* self,
237                                   uint32_t method_idx,
238                                   const DexFile* dex_file,
239                                   Handle<mirror::DexCache> dex_cache,
240                                   Handle<mirror::ClassLoader> class_loader,
241                                   const dex::ClassDef& class_def_idx,
242                                   const dex::CodeItem* code_item,
243                                   ArtMethod* method,
244                                   uint32_t method_access_flags,
245                                   CompilerCallbacks* callbacks,
246                                   bool allow_soft_failures,
247                                   HardFailLogMode log_level,
248                                   bool need_precise_constants,
249                                   uint32_t api_level,
250                                   std::string* hard_failure_msg)
251       REQUIRES_SHARED(Locks::mutator_lock_);
252 
253   // For VerifierDepsTest. TODO: Refactor.
254 
255   // Run verification on the method. Returns true if verification completes and false if the input
256   // has an irrecoverable corruption.
257   virtual bool Verify() REQUIRES_SHARED(Locks::mutator_lock_) = 0;
258   static MethodVerifier* CreateVerifier(Thread* self,
259                                         const DexFile* dex_file,
260                                         Handle<mirror::DexCache> dex_cache,
261                                         Handle<mirror::ClassLoader> class_loader,
262                                         const dex::ClassDef& class_def,
263                                         const dex::CodeItem* code_item,
264                                         uint32_t method_idx,
265                                         ArtMethod* method,
266                                         uint32_t access_flags,
267                                         bool can_load_classes,
268                                         bool allow_soft_failures,
269                                         bool need_precise_constants,
270                                         bool verify_to_dump,
271                                         bool allow_thread_suspension,
272                                         uint32_t api_level)
273       REQUIRES_SHARED(Locks::mutator_lock_);
274 
275   // The thread we're verifying on.
276   Thread* const self_;
277 
278   // Arena allocator.
279   ArenaStack arena_stack_;
280   ScopedArenaAllocator allocator_;
281 
282   RegTypeCache reg_types_;
283 
284   PcToRegisterLineTable reg_table_;
285 
286   // Storage for the register status we're currently working on.
287   RegisterLineArenaUniquePtr work_line_;
288 
289   // The address of the instruction we're currently working on, note that this is in 2 byte
290   // quantities
291   uint32_t work_insn_idx_;
292 
293   // Storage for the register status we're saving for later.
294   RegisterLineArenaUniquePtr saved_line_;
295 
296   const uint32_t dex_method_idx_;  // The method we're working on.
297   const DexFile* const dex_file_;  // The dex file containing the method.
298   const CodeItemDataAccessor code_item_accessor_;
299 
300   // Instruction widths and flags, one entry per code unit.
301   // Owned, but not unique_ptr since insn_flags_ are allocated in arenas.
302   ArenaUniquePtr<InstructionFlags[]> insn_flags_;
303 
304   // The types of any error that occurs.
305   std::vector<VerifyError> failures_;
306   // Error messages associated with failures.
307   std::vector<std::ostringstream*> failure_messages_;
308   // Is there a pending hard failure?
309   bool have_pending_hard_failure_;
310   // Is there a pending runtime throw failure? A runtime throw failure is when an instruction
311   // would fail at runtime throwing an exception. Such an instruction causes the following code
312   // to be unreachable. This is set by Fail and used to ensure we don't process unreachable
313   // instructions that would hard fail the verification.
314   // Note: this flag is reset after processing each instruction.
315   bool have_pending_runtime_throw_failure_;
316   // Is there a pending experimental failure?
317   bool have_pending_experimental_failure_;
318 
319   // A version of the above that is not reset and thus captures if there were *any* throw failures.
320   bool have_any_pending_runtime_throw_failure_;
321 
322   // Info message log use primarily for verifier diagnostics.
323   std::ostringstream info_messages_;
324 
325   // Bitset of the encountered failure types. Bits are according to the values in VerifyError.
326   uint32_t encountered_failure_types_;
327 
328   const bool can_load_classes_;
329 
330   // Converts soft failures to hard failures when false. Only false when the compiler isn't
331   // running and the verifier is called from the class linker.
332   const bool allow_soft_failures_;
333 
334   // Indicates the method being verified contains at least one check-cast or aput-object
335   // instruction. Aput-object operations implicitly check for array-store exceptions, similar to
336   // check-cast.
337   bool has_check_casts_;
338 
339   // Link, for the method verifier root linked list.
340   MethodVerifier* link_;
341 
342   friend class art::Thread;
343   friend class ClassVerifier;
344   friend class VerifierDepsTest;
345 
346   DISALLOW_COPY_AND_ASSIGN(MethodVerifier);
347 };
348 
349 }  // namespace verifier
350 }  // namespace art
351 
352 #endif  // ART_RUNTIME_VERIFIER_METHOD_VERIFIER_H_
353