xref: /aosp_15_r20/art/openjdkjvmti/ti_class_definition.h (revision 795d594fd825385562da6b089ea9b2033f3abf5a)
1*795d594fSAndroid Build Coastguard Worker /* Copyright (C) 2017 The Android Open Source Project
2*795d594fSAndroid Build Coastguard Worker  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
3*795d594fSAndroid Build Coastguard Worker  *
4*795d594fSAndroid Build Coastguard Worker  * This file implements interfaces from the file jvmti.h. This implementation
5*795d594fSAndroid Build Coastguard Worker  * is licensed under the same terms as the file jvmti.h.  The
6*795d594fSAndroid Build Coastguard Worker  * copyright and license information for the file jvmti.h follows.
7*795d594fSAndroid Build Coastguard Worker  *
8*795d594fSAndroid Build Coastguard Worker  * Copyright (c) 2003, 2011, Oracle and/or its affiliates. All rights reserved.
9*795d594fSAndroid Build Coastguard Worker  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
10*795d594fSAndroid Build Coastguard Worker  *
11*795d594fSAndroid Build Coastguard Worker  * This code is free software; you can redistribute it and/or modify it
12*795d594fSAndroid Build Coastguard Worker  * under the terms of the GNU General Public License version 2 only, as
13*795d594fSAndroid Build Coastguard Worker  * published by the Free Software Foundation.  Oracle designates this
14*795d594fSAndroid Build Coastguard Worker  * particular file as subject to the "Classpath" exception as provided
15*795d594fSAndroid Build Coastguard Worker  * by Oracle in the LICENSE file that accompanied this code.
16*795d594fSAndroid Build Coastguard Worker  *
17*795d594fSAndroid Build Coastguard Worker  * This code is distributed in the hope that it will be useful, but WITHOUT
18*795d594fSAndroid Build Coastguard Worker  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
19*795d594fSAndroid Build Coastguard Worker  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
20*795d594fSAndroid Build Coastguard Worker  * version 2 for more details (a copy is included in the LICENSE file that
21*795d594fSAndroid Build Coastguard Worker  * accompanied this code).
22*795d594fSAndroid Build Coastguard Worker  *
23*795d594fSAndroid Build Coastguard Worker  * You should have received a copy of the GNU General Public License version
24*795d594fSAndroid Build Coastguard Worker  * 2 along with this work; if not, write to the Free Software Foundation,
25*795d594fSAndroid Build Coastguard Worker  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
26*795d594fSAndroid Build Coastguard Worker  *
27*795d594fSAndroid Build Coastguard Worker  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
28*795d594fSAndroid Build Coastguard Worker  * or visit www.oracle.com if you need additional information or have any
29*795d594fSAndroid Build Coastguard Worker  * questions.
30*795d594fSAndroid Build Coastguard Worker  */
31*795d594fSAndroid Build Coastguard Worker 
32*795d594fSAndroid Build Coastguard Worker #ifndef ART_OPENJDKJVMTI_TI_CLASS_DEFINITION_H_
33*795d594fSAndroid Build Coastguard Worker #define ART_OPENJDKJVMTI_TI_CLASS_DEFINITION_H_
34*795d594fSAndroid Build Coastguard Worker 
35*795d594fSAndroid Build Coastguard Worker #include <stddef.h>
36*795d594fSAndroid Build Coastguard Worker #include <sys/mman.h>
37*795d594fSAndroid Build Coastguard Worker #include <sys/types.h>
38*795d594fSAndroid Build Coastguard Worker 
39*795d594fSAndroid Build Coastguard Worker #include "art_jvmti.h"
40*795d594fSAndroid Build Coastguard Worker 
41*795d594fSAndroid Build Coastguard Worker #include "base/array_ref.h"
42*795d594fSAndroid Build Coastguard Worker #include "base/mem_map.h"
43*795d594fSAndroid Build Coastguard Worker #include "events.h"
44*795d594fSAndroid Build Coastguard Worker 
45*795d594fSAndroid Build Coastguard Worker namespace openjdkjvmti {
46*795d594fSAndroid Build Coastguard Worker 
47*795d594fSAndroid Build Coastguard Worker // A struct that stores data needed for redefining/transforming classes. This structure should only
48*795d594fSAndroid Build Coastguard Worker // even be accessed from a single thread and must not survive past the completion of the
49*795d594fSAndroid Build Coastguard Worker // redefinition/retransformation function that created it.
50*795d594fSAndroid Build Coastguard Worker class ArtClassDefinition {
51*795d594fSAndroid Build Coastguard Worker  public:
ArtClassDefinition()52*795d594fSAndroid Build Coastguard Worker   ArtClassDefinition()
53*795d594fSAndroid Build Coastguard Worker       : klass_(nullptr),
54*795d594fSAndroid Build Coastguard Worker         loader_(nullptr),
55*795d594fSAndroid Build Coastguard Worker         name_(),
56*795d594fSAndroid Build Coastguard Worker         protection_domain_(nullptr),
57*795d594fSAndroid Build Coastguard Worker         dex_data_memory_(),
58*795d594fSAndroid Build Coastguard Worker         dex_data_(),
59*795d594fSAndroid Build Coastguard Worker         current_dex_memory_(),
60*795d594fSAndroid Build Coastguard Worker         current_dex_file_(),
61*795d594fSAndroid Build Coastguard Worker         redefined_(false),
62*795d594fSAndroid Build Coastguard Worker         initialized_(false),
63*795d594fSAndroid Build Coastguard Worker         structural_transform_update_(false) {}
64*795d594fSAndroid Build Coastguard Worker 
65*795d594fSAndroid Build Coastguard Worker   jvmtiError InitFirstLoad(const char* descriptor,
66*795d594fSAndroid Build Coastguard Worker                            art::Handle<art::mirror::ClassLoader> klass_loader,
67*795d594fSAndroid Build Coastguard Worker                            const art::DexFile& dex_file);
68*795d594fSAndroid Build Coastguard Worker   jvmtiError Init(art::Thread* self, jclass klass);
69*795d594fSAndroid Build Coastguard Worker   jvmtiError Init(art::Thread* self, const jvmtiClassDefinition& def);
70*795d594fSAndroid Build Coastguard Worker 
71*795d594fSAndroid Build Coastguard Worker   ArtClassDefinition(ArtClassDefinition&& o) = default;
72*795d594fSAndroid Build Coastguard Worker   ArtClassDefinition& operator=(ArtClassDefinition&& o) = default;
73*795d594fSAndroid Build Coastguard Worker 
SetNewDexData(jint new_dex_len,unsigned char * new_dex_data,ArtJvmtiEvent event)74*795d594fSAndroid Build Coastguard Worker   void SetNewDexData(jint new_dex_len, unsigned char* new_dex_data, ArtJvmtiEvent event) {
75*795d594fSAndroid Build Coastguard Worker     DCHECK(IsInitialized());
76*795d594fSAndroid Build Coastguard Worker     if (new_dex_data == nullptr) {
77*795d594fSAndroid Build Coastguard Worker       return;
78*795d594fSAndroid Build Coastguard Worker     } else {
79*795d594fSAndroid Build Coastguard Worker       art::ArrayRef<const unsigned char> new_data(new_dex_data, new_dex_len);
80*795d594fSAndroid Build Coastguard Worker       if (new_data != dex_data_) {
81*795d594fSAndroid Build Coastguard Worker         dex_data_memory_.resize(new_dex_len);
82*795d594fSAndroid Build Coastguard Worker         memcpy(dex_data_memory_.data(), new_dex_data, new_dex_len);
83*795d594fSAndroid Build Coastguard Worker         dex_data_ = art::ArrayRef<const unsigned char>(dex_data_memory_);
84*795d594fSAndroid Build Coastguard Worker         if (event == ArtJvmtiEvent::kStructuralDexFileLoadHook) {
85*795d594fSAndroid Build Coastguard Worker           structural_transform_update_ = true;
86*795d594fSAndroid Build Coastguard Worker         }
87*795d594fSAndroid Build Coastguard Worker       }
88*795d594fSAndroid Build Coastguard Worker     }
89*795d594fSAndroid Build Coastguard Worker   }
90*795d594fSAndroid Build Coastguard Worker 
HasStructuralChanges()91*795d594fSAndroid Build Coastguard Worker   bool HasStructuralChanges() const {
92*795d594fSAndroid Build Coastguard Worker     return structural_transform_update_;
93*795d594fSAndroid Build Coastguard Worker   }
94*795d594fSAndroid Build Coastguard Worker 
GetNewOriginalDexFile()95*795d594fSAndroid Build Coastguard Worker   art::ArrayRef<const unsigned char> GetNewOriginalDexFile() const {
96*795d594fSAndroid Build Coastguard Worker     DCHECK(IsInitialized());
97*795d594fSAndroid Build Coastguard Worker     if (redefined_) {
98*795d594fSAndroid Build Coastguard Worker       return current_dex_file_;
99*795d594fSAndroid Build Coastguard Worker     } else {
100*795d594fSAndroid Build Coastguard Worker       return art::ArrayRef<const unsigned char>();
101*795d594fSAndroid Build Coastguard Worker     }
102*795d594fSAndroid Build Coastguard Worker   }
103*795d594fSAndroid Build Coastguard Worker 
104*795d594fSAndroid Build Coastguard Worker   bool IsModified() const REQUIRES_SHARED(art::Locks::mutator_lock_);
105*795d594fSAndroid Build Coastguard Worker 
IsInitialized()106*795d594fSAndroid Build Coastguard Worker   bool IsInitialized() const {
107*795d594fSAndroid Build Coastguard Worker     return initialized_;
108*795d594fSAndroid Build Coastguard Worker   }
109*795d594fSAndroid Build Coastguard Worker 
GetClass()110*795d594fSAndroid Build Coastguard Worker   jclass GetClass() const {
111*795d594fSAndroid Build Coastguard Worker     DCHECK(IsInitialized());
112*795d594fSAndroid Build Coastguard Worker     return klass_;
113*795d594fSAndroid Build Coastguard Worker   }
114*795d594fSAndroid Build Coastguard Worker 
GetLoader()115*795d594fSAndroid Build Coastguard Worker   jobject GetLoader() const {
116*795d594fSAndroid Build Coastguard Worker     DCHECK(IsInitialized());
117*795d594fSAndroid Build Coastguard Worker     return loader_;
118*795d594fSAndroid Build Coastguard Worker   }
119*795d594fSAndroid Build Coastguard Worker 
GetName()120*795d594fSAndroid Build Coastguard Worker   const std::string& GetName() const {
121*795d594fSAndroid Build Coastguard Worker     DCHECK(IsInitialized());
122*795d594fSAndroid Build Coastguard Worker     return name_;
123*795d594fSAndroid Build Coastguard Worker   }
124*795d594fSAndroid Build Coastguard Worker 
GetProtectionDomain()125*795d594fSAndroid Build Coastguard Worker   jobject GetProtectionDomain() const {
126*795d594fSAndroid Build Coastguard Worker     DCHECK(IsInitialized());
127*795d594fSAndroid Build Coastguard Worker     return protection_domain_;
128*795d594fSAndroid Build Coastguard Worker   }
129*795d594fSAndroid Build Coastguard Worker 
GetDexData()130*795d594fSAndroid Build Coastguard Worker   art::ArrayRef<const unsigned char> GetDexData() const {
131*795d594fSAndroid Build Coastguard Worker     DCHECK(IsInitialized());
132*795d594fSAndroid Build Coastguard Worker     return dex_data_;
133*795d594fSAndroid Build Coastguard Worker   }
134*795d594fSAndroid Build Coastguard Worker 
135*795d594fSAndroid Build Coastguard Worker  private:
136*795d594fSAndroid Build Coastguard Worker   jvmtiError InitCommon(art::Thread* self, jclass klass);
137*795d594fSAndroid Build Coastguard Worker   jvmtiError Init(const art::DexFile& dex_file);
138*795d594fSAndroid Build Coastguard Worker 
139*795d594fSAndroid Build Coastguard Worker   jclass klass_;
140*795d594fSAndroid Build Coastguard Worker   jobject loader_;
141*795d594fSAndroid Build Coastguard Worker   std::string name_;
142*795d594fSAndroid Build Coastguard Worker   jobject protection_domain_;
143*795d594fSAndroid Build Coastguard Worker 
144*795d594fSAndroid Build Coastguard Worker   // A unique_ptr to the current dex_data if it needs to be cleaned up.
145*795d594fSAndroid Build Coastguard Worker   std::vector<unsigned char> dex_data_memory_;
146*795d594fSAndroid Build Coastguard Worker 
147*795d594fSAndroid Build Coastguard Worker   // A ref to the current dex data. This is either dex_data_memory_, or current_dex_file_. This is
148*795d594fSAndroid Build Coastguard Worker   // what the dex file will be turned into.
149*795d594fSAndroid Build Coastguard Worker   art::ArrayRef<const unsigned char> dex_data_;
150*795d594fSAndroid Build Coastguard Worker 
151*795d594fSAndroid Build Coastguard Worker   // This is only used if we failed to create a mmap to store the dequickened data
152*795d594fSAndroid Build Coastguard Worker   std::vector<unsigned char> current_dex_memory_;
153*795d594fSAndroid Build Coastguard Worker 
154*795d594fSAndroid Build Coastguard Worker   // This is a dequickened version of what is loaded right now. It is either current_dex_memory_ (if
155*795d594fSAndroid Build Coastguard Worker   // no other redefinition has ever happened to this) or the current dex_file_ directly (if this
156*795d594fSAndroid Build Coastguard Worker   // class has been redefined, thus it cannot have any quickened stuff).
157*795d594fSAndroid Build Coastguard Worker   art::ArrayRef<const unsigned char> current_dex_file_;
158*795d594fSAndroid Build Coastguard Worker 
159*795d594fSAndroid Build Coastguard Worker   bool redefined_;
160*795d594fSAndroid Build Coastguard Worker 
161*795d594fSAndroid Build Coastguard Worker   bool initialized_;
162*795d594fSAndroid Build Coastguard Worker 
163*795d594fSAndroid Build Coastguard Worker   // Set if we had a new dex from the given transform type.
164*795d594fSAndroid Build Coastguard Worker   bool structural_transform_update_;
165*795d594fSAndroid Build Coastguard Worker 
166*795d594fSAndroid Build Coastguard Worker   DISALLOW_COPY_AND_ASSIGN(ArtClassDefinition);
167*795d594fSAndroid Build Coastguard Worker };
168*795d594fSAndroid Build Coastguard Worker 
169*795d594fSAndroid Build Coastguard Worker }  // namespace openjdkjvmti
170*795d594fSAndroid Build Coastguard Worker 
171*795d594fSAndroid Build Coastguard Worker #endif  // ART_OPENJDKJVMTI_TI_CLASS_DEFINITION_H_
172