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 #include "ti_class_definition.h"
33 
34 #include "base/array_slice.h"
35 #include "class_linker-inl.h"
36 #include "dex/dex_file.h"
37 #include "fixed_up_dex_file.h"
38 #include "handle.h"
39 #include "handle_scope-inl.h"
40 #include "mirror/class-inl.h"
41 #include "mirror/class_ext.h"
42 #include "mirror/object-inl.h"
43 #include "reflection.h"
44 #include "thread.h"
45 
46 namespace openjdkjvmti {
47 
InitializeMemory() const48 void ArtClassDefinition::InitializeMemory() const {
49   DCHECK(art::MemMap::kCanReplaceMapping);
50   VLOG(signals) << "Initializing de-quickened memory for dex file of " << name_;
51   CHECK(dex_data_mmap_ != nullptr);
52   CHECK(temp_mmap_ != nullptr);
53   CHECK_EQ(dex_data_mmap_->GetProtect(), PROT_NONE);
54   CHECK_EQ(temp_mmap_->GetProtect(), PROT_READ | PROT_WRITE);
55 
56   std::string desc = std::string("L") + name_ + ";";
57   std::unique_ptr<FixedUpDexFile>
58       fixed_dex_file(FixedUpDexFile::Create(*initial_dex_file_unquickened_, desc.c_str()));
59   CHECK(fixed_dex_file.get() != nullptr);
60   CHECK_LE(fixed_dex_file->Size(), temp_mmap_->Size());
61   CHECK_EQ(temp_mmap_->Size(), dex_data_mmap_->Size());
62   // Copy the data to the temp mmap.
63   memcpy(temp_mmap_->Begin(), fixed_dex_file->Begin(), fixed_dex_file->Size());
64 
65   // Move the mmap atomically.
66   art::MemMap* source = temp_mmap_.release();
67   std::string error;
68   CHECK(dex_data_mmap_->ReplaceWith(&source, &error)) << "Failed to replace mmap for "
69                                                       << name_ << " because " << error;
70   CHECK(dex_data_mmap_->Protect(PROT_READ));
71 }
72 
IsModified() const73 bool ArtClassDefinition::IsModified() const {
74   // RedefineClasses calls always are 'modified' since they need to change the current_dex_file of
75   // the class.
76   if (redefined_) {
77     return true;
78   }
79 
80   // Check to see if any change has taken place.
81   if (current_dex_file_.data() == dex_data_.data()) {
82     // no change at all.
83     return false;
84   }
85 
86   // The dex_data_ was never touched by the agents.
87   if (dex_data_mmap_ != nullptr && dex_data_mmap_->GetProtect() == PROT_NONE) {
88     if (current_dex_file_.data() == dex_data_mmap_->Begin()) {
89       // the dex_data_ looks like it changed (not equal to current_dex_file_) but we never
90       // initialized the dex_data_mmap_. This means the new_dex_data was filled in without looking
91       // at the initial dex_data_.
92       return true;
93     } else if (dex_data_.data() == dex_data_mmap_->Begin()) {
94       // The dex file used to have modifications but they were not added again.
95       return true;
96     } else {
97       // It's not clear what happened. It's possible that the agent got the current dex file data
98       // from some other source so we need to initialize everything to see if it is the same.
99       VLOG(signals) << "Lazy dex file for " << name_ << " was never touched but the dex_data_ is "
100                     << "changed! Need to initialize the memory to see if anything changed";
101       InitializeMemory();
102     }
103   }
104 
105   // We can definitely read current_dex_file_ and dex_file_ without causing page faults.
106 
107   // Check if the dex file we want to set is the same as the current one.
108   // Unfortunately we need to do this check even if no modifications have been done since it could
109   // be that agents were removed in the mean-time so we still have a different dex file. The dex
110   // checksum means this is likely to be fairly fast.
111   return current_dex_file_.size() != dex_data_.size() ||
112       memcmp(current_dex_file_.data(), dex_data_.data(), current_dex_file_.size()) != 0;
113 }
114 
InitCommon(art::Thread * self,jclass klass)115 jvmtiError ArtClassDefinition::InitCommon(art::Thread* self, jclass klass) {
116   art::ScopedObjectAccess soa(self);
117   art::ObjPtr<art::mirror::Class> m_klass(soa.Decode<art::mirror::Class>(klass));
118   if (m_klass.IsNull()) {
119     return ERR(INVALID_CLASS);
120   }
121   initialized_ = true;
122   klass_ = klass;
123   loader_ = soa.AddLocalReference<jobject>(m_klass->GetClassLoader());
124   std::string descriptor_store;
125   std::string descriptor(m_klass->GetDescriptor(&descriptor_store));
126   name_ = descriptor.substr(1, descriptor.size() - 2);
127   // Android doesn't really have protection domains.
128   protection_domain_ = nullptr;
129   return OK;
130 }
131 
DequickenDexFile(const art::DexFile * dex_file,const char * descriptor,std::vector<unsigned char> * dex_data)132 static void DequickenDexFile(const art::DexFile* dex_file,
133                              const char* descriptor,
134                              /*out*/std::vector<unsigned char>* dex_data)
135     REQUIRES_SHARED(art::Locks::mutator_lock_) {
136   std::unique_ptr<FixedUpDexFile> fixed_dex_file(FixedUpDexFile::Create(*dex_file, descriptor));
137   dex_data->resize(fixed_dex_file->Size());
138   memcpy(dex_data->data(), fixed_dex_file->Begin(), fixed_dex_file->Size());
139 }
140 
141 // Gets the data surrounding the given class.
GetDexDataForRetransformation(art::Handle<art::mirror::Class> klass,std::vector<unsigned char> * dex_data)142 static void GetDexDataForRetransformation(art::Handle<art::mirror::Class> klass,
143                                           /*out*/std::vector<unsigned char>* dex_data)
144     REQUIRES_SHARED(art::Locks::mutator_lock_) {
145   art::StackHandleScope<3> hs(art::Thread::Current());
146   art::Handle<art::mirror::ClassExt> ext(hs.NewHandle(klass->GetExtData()));
147   const art::DexFile* dex_file = nullptr;
148   if (!ext.IsNull()) {
149     art::Handle<art::mirror::Object> orig_dex(hs.NewHandle(ext->GetOriginalDexFile()));
150     if (!orig_dex.IsNull()) {
151       if (orig_dex->IsArrayInstance()) {
152         DCHECK(orig_dex->GetClass()->GetComponentType()->IsPrimitiveByte());
153         art::Handle<art::mirror::ByteArray> orig_dex_bytes(
154             hs.NewHandle(art::down_cast<art::mirror::ByteArray*>(orig_dex->AsArray())));
155         dex_data->resize(orig_dex_bytes->GetLength());
156         memcpy(dex_data->data(), orig_dex_bytes->GetData(), dex_data->size());
157         return;
158       } else if (orig_dex->IsDexCache()) {
159         dex_file = orig_dex->AsDexCache()->GetDexFile();
160       } else {
161         DCHECK(orig_dex->GetClass()->DescriptorEquals("Ljava/lang/Long;"))
162             << "Expected java/lang/Long but found object of type "
163             << orig_dex->GetClass()->PrettyClass();
164         art::ObjPtr<art::mirror::Class> prim_long_class(
165             art::Runtime::Current()->GetClassLinker()->GetClassRoot(
166                 art::ClassLinker::kPrimitiveLong));
167         art::JValue val;
168         if (!art::UnboxPrimitiveForResult(orig_dex.Get(), prim_long_class, &val)) {
169           // This should never happen.
170           LOG(FATAL) << "Unable to unbox a primitive long value!";
171         }
172         dex_file = reinterpret_cast<const art::DexFile*>(static_cast<uintptr_t>(val.GetJ()));
173       }
174     }
175   }
176   if (dex_file == nullptr) {
177     dex_file = &klass->GetDexFile();
178   }
179   std::string storage;
180   DequickenDexFile(dex_file, klass->GetDescriptor(&storage), dex_data);
181 }
182 
DexNeedsDequickening(art::Handle<art::mirror::Class> klass,bool * from_class_ext)183 static bool DexNeedsDequickening(art::Handle<art::mirror::Class> klass,
184                                  /*out*/ bool* from_class_ext)
185     REQUIRES_SHARED(art::Locks::mutator_lock_) {
186   art::ObjPtr<art::mirror::ClassExt> ext(klass->GetExtData());
187   if (ext.IsNull()) {
188     // We don't seem to have ever been redefined so be conservative and say we need de-quickening.
189     *from_class_ext = false;
190     return true;
191   }
192   art::ObjPtr<art::mirror::Object> orig_dex(ext->GetOriginalDexFile());
193   if (orig_dex.IsNull()) {
194     // We don't seem to have ever been redefined so be conservative and say we need de-quickening.
195     *from_class_ext = false;
196     return true;
197   } else if (!orig_dex->IsArrayInstance()) {
198     // We were redefined but the original is held in a dex-cache or dex file. This means that the
199     // original dex file is the one from the disk, which might be quickened.
200     DCHECK(orig_dex->IsDexCache() || orig_dex->GetClass()->DescriptorEquals("Ljava/lang/Long;"));
201     *from_class_ext = true;
202     return true;
203   } else {
204     // An array instance means the original-dex-file is from a redefineClasses which cannot have any
205     // quickening, so it's fine to use directly.
206     DCHECK(orig_dex->GetClass()->GetComponentType()->IsPrimitiveByte());
207     *from_class_ext = true;
208     return false;
209   }
210 }
211 
GetQuickenedDexFile(art::Handle<art::mirror::Class> klass)212 static const art::DexFile* GetQuickenedDexFile(art::Handle<art::mirror::Class> klass)
213     REQUIRES_SHARED(art::Locks::mutator_lock_) {
214   art::ObjPtr<art::mirror::ClassExt> ext(klass->GetExtData());
215   if (ext.IsNull() || ext->GetOriginalDexFile() == nullptr) {
216     return &klass->GetDexFile();
217   }
218 
219   art::ObjPtr<art::mirror::Object> orig_dex(ext->GetOriginalDexFile());
220   DCHECK(!orig_dex->IsArrayInstance());
221   if (orig_dex->IsDexCache()) {
222     return orig_dex->AsDexCache()->GetDexFile();
223   }
224 
225   DCHECK(orig_dex->GetClass()->DescriptorEquals("Ljava/lang/Long;"))
226       << "Expected java/lang/Long but found object of type "
227       << orig_dex->GetClass()->PrettyClass();
228   art::ObjPtr<art::mirror::Class> prim_long_class(
229       art::Runtime::Current()->GetClassLinker()->GetClassRoot(
230           art::ClassLinker::kPrimitiveLong));
231   art::JValue val;
232   if (!art::UnboxPrimitiveForResult(orig_dex.Ptr(), prim_long_class, &val)) {
233     LOG(FATAL) << "Unable to unwrap a long value!";
234   }
235   return reinterpret_cast<const art::DexFile*>(static_cast<uintptr_t>(val.GetJ()));
236 }
237 
238 template<typename GetOriginalDexFile>
InitWithDex(GetOriginalDexFile get_original,const art::DexFile * quick_dex)239 void ArtClassDefinition::InitWithDex(GetOriginalDexFile get_original,
240                                      const art::DexFile* quick_dex) {
241   art::Thread* self = art::Thread::Current();
242   DCHECK(quick_dex != nullptr);
243   if (art::MemMap::kCanReplaceMapping && kEnableOnDemandDexDequicken) {
244     size_t dequick_size = quick_dex->GetDequickenedSize();
245     std::string mmap_name("anon-mmap-for-redefine: ");
246     mmap_name += name_;
247     std::string error;
248     dex_data_mmap_.reset(art::MemMap::MapAnonymous(mmap_name.c_str(),
249                                                    nullptr,
250                                                    dequick_size,
251                                                    PROT_NONE,
252                                                    /*low_4gb*/ false,
253                                                    /*reuse*/ false,
254                                                    &error));
255     mmap_name += "-TEMP";
256     temp_mmap_.reset(art::MemMap::MapAnonymous(mmap_name.c_str(),
257                                                nullptr,
258                                                dequick_size,
259                                                PROT_READ | PROT_WRITE,
260                                                /*low_4gb*/ false,
261                                                /*reuse*/ false,
262                                                &error));
263     if (UNLIKELY(dex_data_mmap_ != nullptr && temp_mmap_ != nullptr)) {
264       // Need to save the initial dexfile so we don't need to search for it in the fault-handler.
265       initial_dex_file_unquickened_ = quick_dex;
266       dex_data_ = art::ArrayRef<const unsigned char>(dex_data_mmap_->Begin(),
267                                                      dex_data_mmap_->Size());
268       if (from_class_ext_) {
269         // We got initial from class_ext so the current one must have undergone redefinition so no
270         // cdex or quickening stuff.
271         // We can only do this if it's not a first load.
272         DCHECK(klass_ != nullptr);
273         const art::DexFile& cur_dex = self->DecodeJObject(klass_)->AsClass()->GetDexFile();
274         current_dex_file_ = art::ArrayRef<const unsigned char>(cur_dex.Begin(), cur_dex.Size());
275       } else {
276         // This class hasn't been redefined before. The dequickened current data is the same as the
277         // dex_data_mmap_ when it's filled it. We don't need to copy anything because the mmap will
278         // not be cleared until after everything is done.
279         current_dex_file_ = art::ArrayRef<const unsigned char>(dex_data_mmap_->Begin(),
280                                                                dequick_size);
281       }
282       return;
283     }
284   }
285   dex_data_mmap_.reset(nullptr);
286   temp_mmap_.reset(nullptr);
287   // Failed to mmap a large enough area (or on-demand dequickening was disabled). This is
288   // unfortunate. Since currently the size is just a guess though we might as well try to do it
289   // manually.
290   get_original(/*out*/&dex_data_memory_);
291   dex_data_ = art::ArrayRef<const unsigned char>(dex_data_memory_);
292   if (from_class_ext_) {
293     // We got initial from class_ext so the current one must have undergone redefinition so no
294     // cdex or quickening stuff.
295     // We can only do this if it's not a first load.
296     DCHECK(klass_ != nullptr);
297     const art::DexFile& cur_dex = self->DecodeJObject(klass_)->AsClass()->GetDexFile();
298     current_dex_file_ = art::ArrayRef<const unsigned char>(cur_dex.Begin(), cur_dex.Size());
299   } else {
300     // No redefinition must have ever happened so the (dequickened) cur_dex is the same as the
301     // initial dex_data. We need to copy it into another buffer to keep it around if we have a
302     // real redefinition.
303     current_dex_memory_.resize(dex_data_.size());
304     memcpy(current_dex_memory_.data(), dex_data_.data(), current_dex_memory_.size());
305     current_dex_file_ = art::ArrayRef<const unsigned char>(current_dex_memory_);
306   }
307 }
308 
Init(art::Thread * self,jclass klass)309 jvmtiError ArtClassDefinition::Init(art::Thread* self, jclass klass) {
310   jvmtiError res = InitCommon(self, klass);
311   if (res != OK) {
312     return res;
313   }
314   art::ScopedObjectAccess soa(self);
315   art::StackHandleScope<1> hs(self);
316   art::Handle<art::mirror::Class> m_klass(hs.NewHandle(self->DecodeJObject(klass)->AsClass()));
317   if (!DexNeedsDequickening(m_klass, &from_class_ext_)) {
318     // We don't need to do any dequickening. We want to copy the data just so we don't need to deal
319     // with the GC moving it around.
320     art::ObjPtr<art::mirror::ByteArray> orig_dex(
321         m_klass->GetExtData()->GetOriginalDexFile()->AsByteArray());
322     dex_data_memory_.resize(orig_dex->GetLength());
323     memcpy(dex_data_memory_.data(), orig_dex->GetData(), dex_data_memory_.size());
324     dex_data_ = art::ArrayRef<const unsigned char>(dex_data_memory_);
325 
326     // Since we are here we must not have any quickened instructions since we were redefined.
327     const art::DexFile& cur_dex = m_klass->GetDexFile();
328     DCHECK(from_class_ext_);
329     current_dex_file_ = art::ArrayRef<const unsigned char>(cur_dex.Begin(), cur_dex.Size());
330     return OK;
331   }
332 
333   // We need to dequicken stuff. This is often super slow (10's of ms). Instead we will do it
334   // dynamically.
335   const art::DexFile* quick_dex = GetQuickenedDexFile(m_klass);
336   auto get_original = [&](/*out*/std::vector<unsigned char>* dex_data)
337       REQUIRES_SHARED(art::Locks::mutator_lock_) {
338     GetDexDataForRetransformation(m_klass, dex_data);
339   };
340   InitWithDex(get_original, quick_dex);
341   return OK;
342 }
343 
Init(art::Thread * self,const jvmtiClassDefinition & def)344 jvmtiError ArtClassDefinition::Init(art::Thread* self, const jvmtiClassDefinition& def) {
345   jvmtiError res = InitCommon(self, def.klass);
346   if (res != OK) {
347     return res;
348   }
349   // We are being directly redefined.
350   redefined_ = true;
351   current_dex_file_ = art::ArrayRef<const unsigned char>(def.class_bytes, def.class_byte_count);
352   dex_data_ = art::ArrayRef<const unsigned char>(def.class_bytes, def.class_byte_count);
353   return OK;
354 }
355 
InitFirstLoad(const char * descriptor,art::Handle<art::mirror::ClassLoader> klass_loader,const art::DexFile & dex_file)356 void ArtClassDefinition::InitFirstLoad(const char* descriptor,
357                                        art::Handle<art::mirror::ClassLoader> klass_loader,
358                                        const art::DexFile& dex_file) {
359   art::Thread* self = art::Thread::Current();
360   art::ScopedObjectAccess soa(self);
361   initialized_ = true;
362   // No Class
363   klass_ = nullptr;
364   loader_ = soa.AddLocalReference<jobject>(klass_loader.Get());
365   std::string descriptor_str(descriptor);
366   name_ = descriptor_str.substr(1, descriptor_str.size() - 2);
367   // Android doesn't really have protection domains.
368   protection_domain_ = nullptr;
369   auto get_original = [&](/*out*/std::vector<unsigned char>* dex_data)
370       REQUIRES_SHARED(art::Locks::mutator_lock_) {
371     DequickenDexFile(&dex_file, descriptor, dex_data);
372   };
373   InitWithDex(get_original, &dex_file);
374 }
375 
376 }  // namespace openjdkjvmti
377