• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /* Copyright (C) 2016 The Android Open Source Project
2  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
3  *
4  * This file implements interfaces from the file jvmti.h. This implementation
5  * is licensed under the same terms as the file jvmti.h.  The
6  * copyright and license information for the file jvmti.h follows.
7  *
8  * Copyright (c) 2003, 2011, Oracle and/or its affiliates. All rights reserved.
9  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
10  *
11  * This code is free software; you can redistribute it and/or modify it
12  * under the terms of the GNU General Public License version 2 only, as
13  * published by the Free Software Foundation.  Oracle designates this
14  * particular file as subject to the "Classpath" exception as provided
15  * by Oracle in the LICENSE file that accompanied this code.
16  *
17  * This code is distributed in the hope that it will be useful, but WITHOUT
18  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
19  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
20  * version 2 for more details (a copy is included in the LICENSE file that
21  * accompanied this code).
22  *
23  * You should have received a copy of the GNU General Public License version
24  * 2 along with this work; if not, write to the Free Software Foundation,
25  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
26  *
27  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
28  * or visit www.oracle.com if you need additional information or have any
29  * questions.
30  */
31 
32 #ifndef ART_OPENJDKJVMTI_TI_REDEFINE_H_
33 #define ART_OPENJDKJVMTI_TI_REDEFINE_H_
34 
35 #include <functional>
36 #include <string>
37 
38 #include <jni.h>
39 
40 #include "art_field.h"
41 #include "art_jvmti.h"
42 #include "base/array_ref.h"
43 #include "base/globals.h"
44 #include "dex/class_accessor.h"
45 #include "dex/dex_file.h"
46 #include "dex/dex_file_structs.h"
47 #include "jni/jni_env_ext-inl.h"
48 #include "jvmti.h"
49 #include "mirror/array.h"
50 #include "mirror/class.h"
51 #include "mirror/dex_cache.h"
52 #include "obj_ptr.h"
53 
54 namespace art {
55 class ClassAccessor;
56 namespace dex {
57 struct ClassDef;
58 }  // namespace dex
59 }  // namespace art
60 
61 namespace openjdkjvmti {
62 
63 class ArtClassDefinition;
64 class RedefinitionDataHolder;
65 class RedefinitionDataIter;
66 
67 enum class RedefinitionType {
68   kStructural,
69   kNormal,
70 };
71 
72 // Class that can redefine a single class's methods.
73 class Redefiner {
74  public:
75   // Redefine the given classes with the given dex data. Note this function does not take ownership
76   // of the dex_data pointers. It is not used after this call however and may be freed if desired.
77   // The caller is responsible for freeing it. The runtime makes its own copy of the data. This
78   // function does not call the transformation events.
79   static jvmtiError RedefineClassesDirect(ArtJvmTiEnv* env,
80                                           art::Runtime* runtime,
81                                           art::Thread* self,
82                                           const std::vector<ArtClassDefinition>& definitions,
83                                           RedefinitionType type,
84                                           /*out*/std::string* error_msg);
85 
86   // Redefine the given classes with the given dex data. Note this function does not take ownership
87   // of the dex_data pointers. It is not used after this call however and may be freed if desired.
88   // The caller is responsible for freeing it. The runtime makes its own copy of the data.
89   static jvmtiError RedefineClasses(jvmtiEnv* env,
90                                     jint class_count,
91                                     const jvmtiClassDefinition* definitions);
92   static jvmtiError StructurallyRedefineClasses(jvmtiEnv* env,
93                                                 jint class_count,
94                                                 const jvmtiClassDefinition* definitions);
95 
96   static jvmtiError IsModifiableClass(jvmtiEnv* env, jclass klass, jboolean* is_redefinable);
97   static jvmtiError IsStructurallyModifiableClass(jvmtiEnv* env,
98                                                   jclass klass,
99                                                   jboolean* is_redefinable);
100 
101   static art::MemMap MoveDataToMemMap(const std::string& original_location,
102                                       art::ArrayRef<const unsigned char> data,
103                                       std::string* error_msg);
104 
105   // Helper for checking if redefinition/retransformation is allowed.
106   template<RedefinitionType kType = RedefinitionType::kNormal>
107   static jvmtiError GetClassRedefinitionError(jclass klass, /*out*/std::string* error_msg)
108       REQUIRES(!art::Locks::mutator_lock_);
109 
110   static jvmtiError StructurallyRedefineClassDirect(jvmtiEnv* env,
111                                                     jclass klass,
112                                                     const unsigned char* data,
113                                                     jint data_size);
114 
115  private:
116   class ClassRedefinition {
117    public:
118     ClassRedefinition(Redefiner* driver,
119                       jclass klass,
120                       const art::DexFile* redefined_dex_file,
121                       const char* class_sig,
122                       art::ArrayRef<const unsigned char> orig_dex_file)
123       REQUIRES_SHARED(art::Locks::mutator_lock_);
124 
125     // NO_THREAD_SAFETY_ANALYSIS so we can unlock the class in the destructor.
126     ~ClassRedefinition() NO_THREAD_SAFETY_ANALYSIS;
127 
128     // Move assignment so we can sort these in a vector.
129     ClassRedefinition& operator=(ClassRedefinition&& other) noexcept {
130       driver_ = other.driver_;
131       klass_ = other.klass_;
132       dex_file_ = std::move(other.dex_file_);
133       class_sig_ = std::move(other.class_sig_);
134       original_dex_file_ = other.original_dex_file_;
135       lock_acquired_ = other.lock_acquired_;
136       other.driver_ = nullptr;
137       return *this;
138     }
139 
140     // Move constructor so we can put these into a vector.
ClassRedefinition(ClassRedefinition && other)141     ClassRedefinition(ClassRedefinition&& other) noexcept
142         : driver_(other.driver_),
143           klass_(other.klass_),
144           dex_file_(std::move(other.dex_file_)),
145           class_sig_(std::move(other.class_sig_)),
146           original_dex_file_(other.original_dex_file_),
147           lock_acquired_(other.lock_acquired_) {
148       other.driver_ = nullptr;
149     }
150 
151     // No copy!
152     ClassRedefinition(ClassRedefinition&) = delete;
153     ClassRedefinition& operator=(ClassRedefinition&) = delete;
154 
155     art::ObjPtr<art::mirror::Class> GetMirrorClass() REQUIRES_SHARED(art::Locks::mutator_lock_);
156     art::ObjPtr<art::mirror::ClassLoader> GetClassLoader()
157         REQUIRES_SHARED(art::Locks::mutator_lock_);
158 
GetDexFile()159     const art::DexFile& GetDexFile() {
160       return *dex_file_;
161     }
162 
163     art::mirror::DexCache* CreateNewDexCache(art::Handle<art::mirror::ClassLoader> loader)
164         REQUIRES_SHARED(art::Locks::mutator_lock_);
165 
166     // This may return nullptr with a OOME pending if allocation fails.
167     art::mirror::Object* AllocateOrGetOriginalDexFile()
168         REQUIRES_SHARED(art::Locks::mutator_lock_);
169 
RecordFailure(jvmtiError e,const std::string & err)170     void RecordFailure(jvmtiError e, const std::string& err) {
171       driver_->RecordFailure(e, class_sig_, err);
172     }
173 
174     bool FinishRemainingCommonAllocations(/*out*/RedefinitionDataIter* cur_data)
175         REQUIRES_SHARED(art::Locks::mutator_lock_);
176 
177     bool FinishNewClassAllocations(RedefinitionDataHolder& holder,
178                                    /*out*/RedefinitionDataIter* cur_data)
179         REQUIRES_SHARED(art::Locks::mutator_lock_);
180     bool CollectAndCreateNewInstances(/*out*/RedefinitionDataIter* cur_data)
181         REQUIRES_SHARED(art::Locks::mutator_lock_);
182 
183     bool AllocateAndRememberNewDexFileCookie(
184         art::Handle<art::mirror::ClassLoader> source_class_loader,
185         art::Handle<art::mirror::Object> dex_file_obj,
186         /*out*/RedefinitionDataIter* cur_data)
187           REQUIRES_SHARED(art::Locks::mutator_lock_);
188 
189     void FindAndAllocateObsoleteMethods(art::ObjPtr<art::mirror::Class> art_klass)
190         REQUIRES(art::Locks::mutator_lock_);
191 
192     art::ObjPtr<art::mirror::Class> AllocateNewClassObject(
193         art::Handle<art::mirror::Class> old_class,
194         art::Handle<art::mirror::Class> super_class,
195         art::Handle<art::mirror::DexCache> cache,
196         uint16_t dex_class_def_index) REQUIRES_SHARED(art::Locks::mutator_lock_);
197     art::ObjPtr<art::mirror::Class> AllocateNewClassObject(art::Handle<art::mirror::DexCache> cache)
198         REQUIRES_SHARED(art::Locks::mutator_lock_);
199 
200     uint32_t GetNewClassSize(art::ClassAccessor& accessor)
201         REQUIRES_SHARED(art::Locks::mutator_lock_);
202 
203     // Checks that the dex file contains only the single expected class and that the top-level class
204     // data has not been modified in an incompatible manner.
205     bool CheckClass() REQUIRES_SHARED(art::Locks::mutator_lock_);
206 
207     // Checks that the contained class can be successfully verified.
208     bool CheckVerification(const RedefinitionDataIter& holder)
209         REQUIRES_SHARED(art::Locks::mutator_lock_);
210 
211     // Preallocates all needed allocations in klass so that we can pause execution safely.
212     bool EnsureClassAllocationsFinished(/*out*/RedefinitionDataIter* data)
213         REQUIRES_SHARED(art::Locks::mutator_lock_);
214 
215     // This will check that no constraints are violated (more than 1 class in dex file, any changes
216     // in number/declaration of methods & fields, changes in access flags, etc.)
217     bool CheckRedefinitionIsValid() REQUIRES_SHARED(art::Locks::mutator_lock_);
218 
219     // Checks that the class can even be redefined.
220     bool CheckRedefinable() REQUIRES_SHARED(art::Locks::mutator_lock_);
221 
222     // Checks that the dex file does not add/remove methods, or change their modifiers or types in
223     // illegal ways.
224     bool CheckMethods() REQUIRES_SHARED(art::Locks::mutator_lock_);
225 
226     // Checks that the dex file does not modify fields types or modifiers in illegal ways.
227     bool CheckFields() REQUIRES_SHARED(art::Locks::mutator_lock_);
228 
229     // Temporary check that a class undergoing structural redefinition has no instances. This
230     // requirement will be removed in time.
231     void UpdateJavaDexFile(art::ObjPtr<art::mirror::Object> java_dex_file,
232                            art::ObjPtr<art::mirror::LongArray> new_cookie)
233         REQUIRES(art::Locks::mutator_lock_);
234 
235     void UpdateFields(art::ObjPtr<art::mirror::Class> mclass)
236         REQUIRES(art::Locks::mutator_lock_);
237 
238     void UpdateMethods(art::ObjPtr<art::mirror::Class> mclass,
239                        const art::dex::ClassDef& class_def)
240         REQUIRES(art::Locks::mutator_lock_);
241 
242     void UpdateClass(const RedefinitionDataIter& cur_data)
243         REQUIRES(art::Locks::mutator_lock_);
244 
245     void CollectNewFieldAndMethodMappings(const RedefinitionDataIter& data,
246                                           std::map<art::ArtMethod*, art::ArtMethod*>* method_map,
247                                           std::map<art::ArtField*, art::ArtField*>* field_map)
248         REQUIRES(art::Locks::mutator_lock_);
249 
250     void RestoreObsoleteMethodMapsIfUnneeded(const RedefinitionDataIter* cur_data)
251         REQUIRES(art::Locks::mutator_lock_);
252 
253     void ReleaseDexFile() REQUIRES_SHARED(art::Locks::mutator_lock_);
254 
255     // This should be done with all threads suspended.
256     void UnregisterJvmtiBreakpoints() REQUIRES_SHARED(art::Locks::mutator_lock_);
257 
258     void RecordNewMethodAdded();
259     void RecordNewFieldAdded();
RecordHasVirtualMembers()260     void RecordHasVirtualMembers() {
261       has_virtuals_ = true;
262     }
263 
HasVirtualMembers()264     bool HasVirtualMembers() const {
265       return has_virtuals_;
266     }
267 
IsStructuralRedefinition()268     bool IsStructuralRedefinition() const {
269       DCHECK(!(added_fields_ || added_methods_) || driver_->IsStructuralRedefinition())
270           << "added_fields_: " << added_fields_ << " added_methods_: " << added_methods_
271           << " driver_->IsStructuralRedefinition(): " << driver_->IsStructuralRedefinition();
272       return driver_->IsStructuralRedefinition() && (added_fields_ || added_methods_);
273     }
274 
275    private:
276     void UpdateClassStructurally(const RedefinitionDataIter& cur_data)
277         REQUIRES(art::Locks::mutator_lock_);
278 
279     void UpdateClassInPlace(const RedefinitionDataIter& cur_data)
280         REQUIRES(art::Locks::mutator_lock_);
281 
282     Redefiner* driver_;
283     jclass klass_;
284     std::unique_ptr<const art::DexFile> dex_file_;
285     std::string class_sig_;
286     art::ArrayRef<const unsigned char> original_dex_file_;
287 
288     bool added_fields_ = false;
289     bool added_methods_ = false;
290     bool has_virtuals_ = false;
291     bool lock_acquired_ = false;
292   };
293 
294   ArtJvmTiEnv* env_;
295   jvmtiError result_;
296   art::Runtime* runtime_;
297   art::Thread* self_;
298   RedefinitionType type_;
299   std::vector<ClassRedefinition> redefinitions_;
300   // Kept as a jclass since we have weird run-state changes that make keeping it around as a
301   // mirror::Class difficult and confusing.
302   std::string* error_msg_;
303 
Redefiner(ArtJvmTiEnv * env,art::Runtime * runtime,art::Thread * self,RedefinitionType type,std::string * error_msg)304   Redefiner(ArtJvmTiEnv* env,
305             art::Runtime* runtime,
306             art::Thread* self,
307             RedefinitionType type,
308             std::string* error_msg)
309       : env_(env),
310         result_(ERR(INTERNAL)),
311         runtime_(runtime),
312         self_(self),
313         type_(type),
314         redefinitions_(),
315         error_msg_(error_msg) { }
316 
317   jvmtiError AddRedefinition(ArtJvmTiEnv* env, const ArtClassDefinition& def)
318       REQUIRES_SHARED(art::Locks::mutator_lock_);
319 
320   template<RedefinitionType kType = RedefinitionType::kNormal>
321   static jvmtiError RedefineClassesGeneric(jvmtiEnv* env,
322                                            jint class_count,
323                                            const jvmtiClassDefinition* definitions);
324 
325   template<RedefinitionType kType = RedefinitionType::kNormal>
326   static jvmtiError IsModifiableClassGeneric(jvmtiEnv* env, jclass klass, jboolean* is_redefinable);
327 
328   template<RedefinitionType kType = RedefinitionType::kNormal>
329   static jvmtiError GetClassRedefinitionError(art::Handle<art::mirror::Class> klass,
330                                               /*out*/std::string* error_msg)
331       REQUIRES_SHARED(art::Locks::mutator_lock_);
332 
333   jvmtiError Run() REQUIRES_SHARED(art::Locks::mutator_lock_);
334 
335   bool CheckAllRedefinitionAreValid() REQUIRES_SHARED(art::Locks::mutator_lock_);
336   bool CheckAllClassesAreVerified(RedefinitionDataHolder& holder)
337       REQUIRES_SHARED(art::Locks::mutator_lock_);
338   void MarkStructuralChanges(RedefinitionDataHolder& holder)
339       REQUIRES_SHARED(art::Locks::mutator_lock_);
340   bool EnsureAllClassAllocationsFinished(RedefinitionDataHolder& holder)
341       REQUIRES_SHARED(art::Locks::mutator_lock_);
342   bool FinishAllRemainingCommonAllocations(RedefinitionDataHolder& holder)
343       REQUIRES_SHARED(art::Locks::mutator_lock_);
344   bool FinishAllNewClassAllocations(RedefinitionDataHolder& holder)
345       REQUIRES_SHARED(art::Locks::mutator_lock_);
346   bool CollectAndCreateNewInstances(RedefinitionDataHolder& holder)
347       REQUIRES_SHARED(art::Locks::mutator_lock_);
348   void ReleaseAllDexFiles() REQUIRES_SHARED(art::Locks::mutator_lock_);
349   void ReverifyClasses(RedefinitionDataHolder& holder) REQUIRES_SHARED(art::Locks::mutator_lock_);
350   void UnregisterAllBreakpoints() REQUIRES_SHARED(art::Locks::mutator_lock_);
351   // Restores the old obsolete methods maps if it turns out they weren't needed (ie there were no
352   // new obsolete methods).
353   void RestoreObsoleteMethodMapsIfUnneeded(RedefinitionDataHolder& holder)
354       REQUIRES(art::Locks::mutator_lock_);
355 
IsStructuralRedefinition()356   bool IsStructuralRedefinition() const {
357     return type_ == RedefinitionType::kStructural;
358   }
359 
360   void RecordFailure(jvmtiError result, const std::string& class_sig, const std::string& error_msg);
RecordFailure(jvmtiError result,const std::string & error_msg)361   void RecordFailure(jvmtiError result, const std::string& error_msg) {
362     RecordFailure(result, "NO CLASS", error_msg);
363   }
364 
365   friend struct CallbackCtx;
366   friend class RedefinitionDataHolder;
367   friend class RedefinitionDataIter;
368 };
369 
370 }  // namespace openjdkjvmti
371 
372 #endif  // ART_OPENJDKJVMTI_TI_REDEFINE_H_
373