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