diff options
| -rw-r--r-- | test/980-redefine-object/redef_object.cc | 143 | ||||
| -rw-r--r-- | test/980-redefine-object/src/Main.java | 273 | ||||
| -rw-r--r-- | test/980-redefine-object/src/art/Redefinition.java | 91 | ||||
| -rw-r--r-- | test/Android.bp | 5 |
4 files changed, 156 insertions, 356 deletions
diff --git a/test/980-redefine-object/redef_object.cc b/test/980-redefine-object/redef_object.cc new file mode 100644 index 0000000000..b4d82ad76d --- /dev/null +++ b/test/980-redefine-object/redef_object.cc @@ -0,0 +1,143 @@ +/* + * Copyright (C) 2018 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include <limits> +#include <memory> + +#include "jni.h" +#include "jvmti.h" + +// Test infrastructure +#include "jvmti_helper.h" +#include "test_env.h" + +// Slicer's headers have code that triggers these warnings. b/65298177 +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wsign-compare" +#pragma clang diagnostic ignored "-Wunused-parameter" +#include "slicer/instrumentation.h" +#include "slicer/reader.h" +#include "slicer/writer.h" +#pragma clang diagnostic pop + +namespace art { +namespace Test980RedefineObject { + +static void JNICALL RedefineObjectHook(jvmtiEnv *jvmti_env, + JNIEnv* env, + jclass class_being_redefined ATTRIBUTE_UNUSED, + jobject loader ATTRIBUTE_UNUSED, + const char* name, + jobject protection_domain ATTRIBUTE_UNUSED, + jint class_data_len, + const unsigned char* class_data, + jint* new_class_data_len, + unsigned char** new_class_data) { + if (strcmp(name, "java/lang/Object") != 0) { + return; + } + + dex::Reader reader(class_data, class_data_len); + dex::u4 class_index = reader.FindClassIndex("Ljava/lang/Object;"); + if (class_index == dex::kNoIndex) { + env->ThrowNew(env->FindClass("java/lang/RuntimeException"), + "Failed to find object in dex file!"); + return; + } + + reader.CreateClassIr(class_index); + auto dex_ir = reader.GetIr(); + + slicer::MethodInstrumenter mi(dex_ir); + mi.AddTransformation<slicer::EntryHook>(ir::MethodId("Lart/test/TestWatcher;", + "NotifyConstructed"), + /*this_as_object*/ true); + if (!mi.InstrumentMethod(ir::MethodId("Ljava/lang/Object;", + "<init>", + "()V"))) { + env->ThrowNew(env->FindClass("java/lang/RuntimeException"), + "Failed to find Object;-><init>()V in dex file!"); + return; + } + + + dex::Writer writer(dex_ir); + + class JvmtiAllocator : public dex::Writer::Allocator { + public: + explicit JvmtiAllocator(jvmtiEnv* jvmti) : jvmti_(jvmti) {} + + void* Allocate(size_t size) { + unsigned char* res = nullptr; + jvmti_->Allocate(size, &res); + return res; + } + + void Free(void* ptr) { + jvmti_->Deallocate(reinterpret_cast<unsigned char*>(ptr)); + } + + private: + jvmtiEnv* jvmti_; + }; + JvmtiAllocator allocator(jvmti_env); + size_t new_size; + *new_class_data = writer.CreateImage(&allocator, &new_size); + if (new_size > std::numeric_limits<jint>::max()) { + *new_class_data = nullptr; + env->ThrowNew(env->FindClass("java/lang/RuntimeException"), + "transform result is too large!"); + return; + } + *new_class_data_len = static_cast<jint>(new_size); +} + +extern "C" JNIEXPORT void JNICALL Java_Main_addMemoryTrackingCall(JNIEnv* env, + jclass klass ATTRIBUTE_UNUSED, + jclass obj_class, + jthread thr) { + jvmtiCapabilities caps {.can_retransform_classes = 1}; + if (JvmtiErrorToException(env, jvmti_env, jvmti_env->AddCapabilities(&caps))) { + return; + } + jvmtiEventCallbacks cb {.ClassFileLoadHook = RedefineObjectHook }; + if (JvmtiErrorToException(env, jvmti_env, jvmti_env->SetEventCallbacks(&cb, sizeof(cb)))) { + return; + } + if (JvmtiErrorToException(env, + jvmti_env, + jvmti_env->SetEventNotificationMode(JVMTI_ENABLE, + JVMTI_EVENT_CLASS_FILE_LOAD_HOOK, + thr))) { + return; + } + if (JvmtiErrorToException(env, + jvmti_env, + jvmti_env->RetransformClasses(1, &obj_class))) { + return; + } + if (JvmtiErrorToException(env, + jvmti_env, + jvmti_env->SetEventNotificationMode(JVMTI_DISABLE, + JVMTI_EVENT_CLASS_FILE_LOAD_HOOK, + thr))) { + return; + } +} + +} // namespace Test980RedefineObject +} // namespace art + diff --git a/test/980-redefine-object/src/Main.java b/test/980-redefine-object/src/Main.java index 2428b55a4e..efbc75f6c5 100644 --- a/test/980-redefine-object/src/Main.java +++ b/test/980-redefine-object/src/Main.java @@ -14,278 +14,16 @@ * limitations under the License. */ -import static art.Redefinition.doCommonClassRedefinition; - import java.lang.reflect.Method; import java.util.ArrayList; import java.util.Base64; import java.util.LinkedList; public class Main { - - // TODO We should make this run on the RI. - /** - * This test cannot be run on the RI. - */ - private static final byte[] CLASS_BYTES = new byte[0]; - - // TODO It might be a good idea to replace this hard-coded Object definition with a - // retransformation based test. /** - * Base64 encoding of the following smali file. - * - * .class public Ljava/lang/Object; - * .source "Object.java" - * # instance fields - * .field private transient shadow$_klass_:Ljava/lang/Class; - * .annotation system Ldalvik/annotation/Signature; - * value = { - * "Ljava/lang/Class", - * "<*>;" - * } - * .end annotation - * .end field - * - * .field private transient shadow$_monitor_:I - * # direct methods - * .method public constructor <init>()V - * .registers 1 - * .prologue - * invoke-static {p0}, Lart/test/TestWatcher;->NotifyConstructed(Ljava/lang/Object;)V - * return-void - * .end method - * - * .method static identityHashCode(Ljava/lang/Object;)I - * .registers 7 - * .prologue - * iget v0, p0, Ljava/lang/Object;->shadow$_monitor_:I - * const/high16 v3, -0x40000000 # -2.0f - * const/high16 v2, -0x80000000 - * const v1, 0xfffffff - * const/high16 v4, -0x40000000 # -2.0f - * and-int/2addr v4, v0 - * const/high16 v5, -0x80000000 - * if-ne v4, v5, :cond_15 - * const v4, 0xfffffff - * and-int/2addr v4, v0 - * return v4 - * :cond_15 - * invoke-static {p0}, Ljava/lang/Object;->identityHashCodeNative(Ljava/lang/Object;)I - * move-result v4 - * return v4 - * .end method - * - * .method private static native identityHashCodeNative(Ljava/lang/Object;)I - * .annotation build Ldalvik/annotation/optimization/FastNative; - * .end annotation - * .end method - * - * .method private native internalClone()Ljava/lang/Object; - * .annotation build Ldalvik/annotation/optimization/FastNative; - * .end annotation - * .end method - * - * - * # virtual methods - * .method protected clone()Ljava/lang/Object; - * .registers 4 - * .annotation system Ldalvik/annotation/Throws; - * value = { - * Ljava/lang/CloneNotSupportedException; - * } - * .end annotation - * - * .prologue - * instance-of v0, p0, Ljava/lang/Cloneable; - * if-nez v0, :cond_2d - * new-instance v0, Ljava/lang/CloneNotSupportedException; - * new-instance v1, Ljava/lang/StringBuilder; - * invoke-direct {v1}, Ljava/lang/StringBuilder;-><init>()V - * const-string/jumbo v2, "Class " - * invoke-virtual {v1, v2}, Ljava/lang/StringBuilder;->append(Ljava/lang/String;)Ljava/lang/StringBuilder; - * move-result-object v1 - * invoke-virtual {p0}, Ljava/lang/Object;->getClass()Ljava/lang/Class; - * move-result-object v2 - * invoke-virtual {v2}, Ljava/lang/Class;->getName()Ljava/lang/String; - * move-result-object v2 - * invoke-virtual {v1, v2}, Ljava/lang/StringBuilder;->append(Ljava/lang/String;)Ljava/lang/StringBuilder; - * move-result-object v1 - * const-string/jumbo v2, " doesn\'t implement Cloneable" - * invoke-virtual {v1, v2}, Ljava/lang/StringBuilder;->append(Ljava/lang/String;)Ljava/lang/StringBuilder; - * move-result-object v1 - * invoke-virtual {v1}, Ljava/lang/StringBuilder;->toString()Ljava/lang/String; - * move-result-object v1 - * invoke-direct {v0, v1}, Ljava/lang/CloneNotSupportedException;-><init>(Ljava/lang/String;)V - * throw v0 - * :cond_2d - * invoke-direct {p0}, Ljava/lang/Object;->internalClone()Ljava/lang/Object; - * move-result-object v0 - * return-object v0 - * .end method - * - * .method public equals(Ljava/lang/Object;)Z - * .registers 3 - * .prologue - * if-ne p0, p1, :cond_4 - * const/4 v0, 0x1 - * :goto_3 - * return v0 - * :cond_4 - * const/4 v0, 0x0 - * goto :goto_3 - * .end method - * - * .method protected finalize()V - * .registers 1 - * .annotation system Ldalvik/annotation/Throws; - * value = { - * Ljava/lang/Throwable; - * } - * .end annotation - * .prologue - * return-void - * .end method - * - * .method public final getClass()Ljava/lang/Class; - * .registers 2 - * .annotation system Ldalvik/annotation/Signature; - * value = { - * "()", - * "Ljava/lang/Class", - * "<*>;" - * } - * .end annotation - * .prologue - * iget-object v0, p0, Ljava/lang/Object;->shadow$_klass_:Ljava/lang/Class; - * return-object v0 - * .end method - * - * .method public hashCode()I - * .registers 2 - * .prologue - * invoke-static {p0}, Ljava/lang/Object;->identityHashCode(Ljava/lang/Object;)I - * move-result v0 - * return v0 - * .end method - * - * .method public final native notify()V - * .annotation build Ldalvik/annotation/optimization/FastNative; - * .end annotation - * .end method - * - * .method public final native notifyAll()V - * .annotation build Ldalvik/annotation/optimization/FastNative; - * .end annotation - * .end method - * - * .method public toString()Ljava/lang/String; - * .registers 3 - * .prologue - * new-instance v0, Ljava/lang/StringBuilder; - * invoke-direct {v0}, Ljava/lang/StringBuilder;-><init>()V - * invoke-virtual {p0}, Ljava/lang/Object;->getClass()Ljava/lang/Class; - * move-result-object v1 - * invoke-virtual {v1}, Ljava/lang/Class;->getName()Ljava/lang/String; - * move-result-object v1 - * invoke-virtual {v0, v1}, Ljava/lang/StringBuilder;->append(Ljava/lang/String;)Ljava/lang/StringBuilder; - * move-result-object v0 - * const-string/jumbo v1, "@" - * invoke-virtual {v0, v1}, Ljava/lang/StringBuilder;->append(Ljava/lang/String;)Ljava/lang/StringBuilder; - * move-result-object v0 - * invoke-virtual {p0}, Ljava/lang/Object;->hashCode()I - * move-result v1 - * invoke-static {v1}, Ljava/lang/Integer;->toHexString(I)Ljava/lang/String; - * move-result-object v1 - * invoke-virtual {v0, v1}, Ljava/lang/StringBuilder;->append(Ljava/lang/String;)Ljava/lang/StringBuilder; - * move-result-object v0 - * invoke-virtual {v0}, Ljava/lang/StringBuilder;->toString()Ljava/lang/String; - * move-result-object v0 - * return-object v0 - * .end method - * - * .method public final native wait()V - * .annotation system Ldalvik/annotation/Throws; - * value = { - * Ljava/lang/InterruptedException; - * } - * .end annotation - * - * .annotation build Ldalvik/annotation/optimization/FastNative; - * .end annotation - * .end method - * - * .method public final wait(J)V - * .registers 4 - * .annotation system Ldalvik/annotation/Throws; - * value = { - * Ljava/lang/InterruptedException; - * } - * .end annotation - * .prologue - * const/4 v0, 0x0 - * invoke-virtual {p0, p1, p2, v0}, Ljava/lang/Object;->wait(JI)V - * return-void - * .end method - * - * .method public final native wait(JI)V - * .annotation system Ldalvik/annotation/Throws; - * value = { - * Ljava/lang/InterruptedException; - * } - * .end annotation - * - * .annotation build Ldalvik/annotation/optimization/FastNative; - * .end annotation - * .end method + * NB This test cannot be run on the RI. + * TODO We should make this run on the RI. */ - private static final byte[] DEX_BYTES = Base64.getDecoder().decode( - "ZGV4CjAzNQDUlMR9j03MYuOKekKs2p7zJzu2IfDb7RlMCgAAcAAAAHhWNBIAAAAAAAAAAIgJAAA6" + - "AAAAcAAAABEAAABYAQAADQAAAJwBAAACAAAAOAIAABYAAABIAgAAAQAAAPgCAAA0BwAAGAMAABgD" + - "AAA2AwAAOgMAAEADAABIAwAASwMAAFMDAABWAwAAWgMAAF0DAABgAwAAZAMAAGgDAACAAwAAnwMA" + - "ALsDAADoAwAA+gMAAA0EAAA1BAAATAQAAGEEAACDBAAAlwQAAKsEAADGBAAA3QQAAPAEAAD9BAAA" + - "AAUAAAQFAAAJBQAADQUAABAFAAAUBQAAHAUAACMFAAArBQAANQUAAD8FAABIBQAAUgUAAGQFAAB8" + - "BQAAiwUAAJUFAACnBQAAugUAAM0FAADVBQAA3QUAAOgFAADtBQAA/QUAAA8GAAAcBgAAJgYAAC0G" + - "AAAGAAAACAAAAAwAAAANAAAADgAAAA8AAAARAAAAEgAAABMAAAAUAAAAFQAAABYAAAAXAAAAGAAA" + - "ABkAAAAcAAAAIAAAAAYAAAAAAAAAAAAAAAcAAAAAAAAAPAYAAAkAAAAGAAAAAAAAAAkAAAALAAAA" + - "AAAAAAkAAAAMAAAAAAAAAAoAAAAMAAAARAYAAAsAAAANAAAAVAYAABwAAAAPAAAAAAAAAB0AAAAP" + - "AAAATAYAAB4AAAAPAAAANAYAAB8AAAAPAAAAPAYAAB8AAAAPAAAAVAYAACEAAAAQAAAAPAYAAAsA" + - "BgA0AAAACwAAADUAAAACAAoAGgAAAAYABAAnAAAABwALAAMAAAAJAAUANgAAAAsABwADAAAACwAD" + - "ACMAAAALAAwAJAAAAAsABwAlAAAACwACACYAAAALAAAAKAAAAAsAAQApAAAACwABACoAAAALAAMA" + - "KwAAAAsABwAxAAAACwAHADIAAAALAAQANwAAAAsABwA5AAAACwAIADkAAAALAAkAOQAAAA0ABwAD" + - "AAAADQAGACIAAAANAAQANwAAAAsAAAABAAAA/////wAAAAAbAAAA0AYAAD4JAAAAAAAAHCBkb2Vz" + - "bid0IGltcGxlbWVudCBDbG9uZWFibGUAAigpAAQ8Kj47AAY8aW5pdD4AAUAABkNsYXNzIAABSQAC" + - "SUwAAUoAAUwAAkxJAAJMTAAWTGFydC90ZXN0L1Rlc3RXYXRjaGVyOwAdTGRhbHZpay9hbm5vdGF0" + - "aW9uL1NpZ25hdHVyZTsAGkxkYWx2aWsvYW5ub3RhdGlvbi9UaHJvd3M7ACtMZGFsdmlrL2Fubm90" + - "YXRpb24vb3B0aW1pemF0aW9uL0Zhc3ROYXRpdmU7ABBMamF2YS9sYW5nL0NsYXNzABFMamF2YS9s" + - "YW5nL0NsYXNzOwAmTGphdmEvbGFuZy9DbG9uZU5vdFN1cHBvcnRlZEV4Y2VwdGlvbjsAFUxqYXZh" + - "L2xhbmcvQ2xvbmVhYmxlOwATTGphdmEvbGFuZy9JbnRlZ2VyOwAgTGphdmEvbGFuZy9JbnRlcnJ1" + - "cHRlZEV4Y2VwdGlvbjsAEkxqYXZhL2xhbmcvT2JqZWN0OwASTGphdmEvbGFuZy9TdHJpbmc7ABlM" + - "amF2YS9sYW5nL1N0cmluZ0J1aWxkZXI7ABVMamF2YS9sYW5nL1Rocm93YWJsZTsAEU5vdGlmeUNv" + - "bnN0cnVjdGVkAAtPYmplY3QuamF2YQABVgACVkoAA1ZKSQACVkwAAVoAAlpMAAZhcHBlbmQABWNs" + - "b25lAAZlcXVhbHMACGZpbmFsaXplAAhnZXRDbGFzcwAHZ2V0TmFtZQAIaGFzaENvZGUAEGlkZW50" + - "aXR5SGFzaENvZGUAFmlkZW50aXR5SGFzaENvZGVOYXRpdmUADWludGVybmFsQ2xvbmUACGxvY2tX" + - "b3JkABBsb2NrV29yZEhhc2hNYXNrABFsb2NrV29yZFN0YXRlSGFzaAARbG9ja1dvcmRTdGF0ZU1h" + - "c2sABm1pbGxpcwAGbm90aWZ5AAlub3RpZnlBbGwAA29iagAOc2hhZG93JF9rbGFzc18AEHNoYWRv" + - "dyRfbW9uaXRvcl8AC3RvSGV4U3RyaW5nAAh0b1N0cmluZwAFdmFsdWUABHdhaXQAAAIAAAABAAAA" + - "AQAAAAsAAAABAAAAAAAAAAEAAAABAAAAAQAAAAwAAgQBOBwBGAcCBAE4HAEYCgIDATgcAhcQFwIC" + - "BAE4HAEYDgAFAAIDATgcAxcBFxAXAgAAAAAAAAAAAAEAAABaBgAAAgAAAGIGAAB8BgAAAQAAAGIG" + - "AAABAAAAagYAAAEAAAB0BgAAAQAAAHwGAAABAAAAfwYAAAAAAAABAAAACgAAAAAAAAAAAAAAsAYA" + - "AAUAAACUBgAABwAAALgGAAAIAAAAyAYAAAsAAADABgAADAAAAMAGAAANAAAAwAYAAA4AAADABgAA" + - "EAAAAJwGAAARAAAAqAYAABIAAACcBgAAKAAHDgBwATQHDi0DAC0BLQMDMAEtAwIvATwDAS4BeFsA" + - "7AEABw5LARoPOsYArAEBNAcOAMUEAAcOAEEABw4AaAAHDgCRAgAHDgCmAwExBw5LAAAAAQABAAEA" + - "AAA4BwAABAAAAHEQAAAAAA4ABwABAAEAAAA9BwAAGgAAAFJgAQAVAwDAFQIAgBQB////DxUEAMC1" + - "BBUFAIAzVAcAFAT///8PtQQPBHEQCwAGAAoEDwQEAAEAAgAAAFkHAAAyAAAAIDAIADkAKwAiAAcA" + - "IgENAHAQEwABABsCBQAAAG4gFAAhAAwBbhAIAAMADAJuEAEAAgAMAm4gFAAhAAwBGwIAAAAAbiAU" + - "ACEADAFuEBUAAQAMAXAgAgAQACcAcBAMAAMADAARAAMAAgAAAAAAZQcAAAYAAAAzIQQAEhAPABIA" + - "KP4BAAEAAAAAAGwHAAABAAAADgAAAAIAAQAAAAAAcgcAAAMAAABUEAAAEQAAAAIAAQABAAAAdwcA" + - "AAUAAABxEAoAAQAKAA8AAAADAAEAAgAAAHwHAAApAAAAIgANAHAQEwAAAG4QCAACAAwBbhABAAEA" + - "DAFuIBQAEAAMABsBBAAAAG4gFAAQAAwAbhAJAAIACgFxEAMAAQAMAW4gFAAQAAwAbhAVAAAADAAR" + - "AAAABAADAAQAAACCBwAABQAAABIAbkASACEDDgAAAgQLAIIBAYIBBIGABIwPBgikDwGKAgABggIA" + - "BQToDwEB3BABBPgQARGMEQEBpBEEkQIAAZECAAEBwBEBkQIAARGkEgGRAgAAABAAAAAAAAAAAQAA" + - "AAAAAAABAAAAOgAAAHAAAAACAAAAEQAAAFgBAAADAAAADQAAAJwBAAAEAAAAAgAAADgCAAAFAAAA" + - "FgAAAEgCAAAGAAAAAQAAAPgCAAACIAAAOgAAABgDAAABEAAABQAAADQGAAAEIAAABgAAAFoGAAAD" + - "EAAACQAAAIwGAAAGIAAAAQAAANAGAAADIAAACQAAADgHAAABIAAACQAAAIwHAAAAIAAAAQAAAD4J" + - "AAAAEAAAAQAAAIgJAAA="); private static final String LISTENER_LOCATION = System.getenv("DEX_LOCATION") + "/980-redefine-object-ex.jar"; @@ -361,7 +99,7 @@ public class Main { // Redefine the Object Class. safePrintln("Redefining the Object class to add a hook into the <init> method"); - doCommonClassRedefinition(Object.class, CLASS_BYTES, DEX_BYTES); + addMemoryTrackingCall(Object.class, Thread.currentThread()); safePrintln("Allocating an j.l.Object after redefining Object class"); Object o2 = new Object(); @@ -407,5 +145,10 @@ public class Main { safePrintln("Finishing test!"); } + // This is from 929-search/search.cc private static native void addToBootClassLoader(String s); + // This is from 980-redefine-object/redef_object.cc + // It will add a call to Lart/test/TestWatcher;->NotifyConstructed()V in the Object <init>()V + // function. + private static native void addMemoryTrackingCall(Class c, Thread thr); } diff --git a/test/980-redefine-object/src/art/Redefinition.java b/test/980-redefine-object/src/art/Redefinition.java deleted file mode 100644 index 56d2938a01..0000000000 --- a/test/980-redefine-object/src/art/Redefinition.java +++ /dev/null @@ -1,91 +0,0 @@ -/* - * Copyright (C) 2017 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package art; - -import java.util.ArrayList; -// Common Redefinition functions. Placed here for use by CTS -public class Redefinition { - public static final class CommonClassDefinition { - public final Class<?> target; - public final byte[] class_file_bytes; - public final byte[] dex_file_bytes; - - public CommonClassDefinition(Class<?> target, byte[] class_file_bytes, byte[] dex_file_bytes) { - this.target = target; - this.class_file_bytes = class_file_bytes; - this.dex_file_bytes = dex_file_bytes; - } - } - - // A set of possible test configurations. Test should set this if they need to. - // This must be kept in sync with the defines in ti-agent/common_helper.cc - public static enum Config { - COMMON_REDEFINE(0), - COMMON_RETRANSFORM(1), - COMMON_TRANSFORM(2); - - private final int val; - private Config(int val) { - this.val = val; - } - } - - public static void setTestConfiguration(Config type) { - nativeSetTestConfiguration(type.val); - } - - private static native void nativeSetTestConfiguration(int type); - - // Transforms the class - public static native void doCommonClassRedefinition(Class<?> target, - byte[] classfile, - byte[] dexfile); - - public static void doMultiClassRedefinition(CommonClassDefinition... defs) { - ArrayList<Class<?>> classes = new ArrayList<>(); - ArrayList<byte[]> class_files = new ArrayList<>(); - ArrayList<byte[]> dex_files = new ArrayList<>(); - - for (CommonClassDefinition d : defs) { - classes.add(d.target); - class_files.add(d.class_file_bytes); - dex_files.add(d.dex_file_bytes); - } - doCommonMultiClassRedefinition(classes.toArray(new Class<?>[0]), - class_files.toArray(new byte[0][]), - dex_files.toArray(new byte[0][])); - } - - public static void addMultiTransformationResults(CommonClassDefinition... defs) { - for (CommonClassDefinition d : defs) { - addCommonTransformationResult(d.target.getCanonicalName(), - d.class_file_bytes, - d.dex_file_bytes); - } - } - - public static native void doCommonMultiClassRedefinition(Class<?>[] targets, - byte[][] classfiles, - byte[][] dexfiles); - public static native void doCommonClassRetransformation(Class<?>... target); - public static native void setPopRetransformations(boolean pop); - public static native void popTransformationFor(String name); - public static native void enableCommonRetransformation(boolean enable); - public static native void addCommonTransformationResult(String target_name, - byte[] class_bytes, - byte[] dex_bytes); -} diff --git a/test/Android.bp b/test/Android.bp index 7909bf897a..e0ec286314 100644 --- a/test/Android.bp +++ b/test/Android.bp @@ -314,10 +314,15 @@ art_cc_defaults { "909-attach-agent/attach.cc", "912-classes/classes_art.cc", "936-search-onload/search_onload.cc", + "980-redefine-object/redef_object.cc", "983-source-transform-verify/source_transform_art.cc", "1940-ddms-ext/ddm_ext.cc", "1944-sudden-exit/sudden_exit.cc", ], + static_libs: [ + "libz", + "slicer", + ], } art_cc_test_library { |