blob: a433dc9b7588cbf327a7a55415d11b05971b273f [file] [log] [blame]
Alex Light37aa4c92017-03-27 13:02:41 -07001/*
2 * Copyright (C) 2017 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17#include <inttypes.h>
18#include <stdio.h>
19#include <string.h>
20
21#include <iostream>
22#include <vector>
23
24#include "android-base/stringprintf.h"
25
26#include "base/logging.h"
27#include "base/macros.h"
Alex Light40528472017-03-28 09:07:36 -070028#include "bytecode_utils.h"
Alex Light37aa4c92017-03-27 13:02:41 -070029#include "dex_file.h"
Alex Light40528472017-03-28 09:07:36 -070030#include "dex_instruction.h"
Alex Light37aa4c92017-03-27 13:02:41 -070031#include "jit/jit.h"
32#include "jni.h"
33#include "native_stack_dump.h"
34#include "jvmti.h"
35#include "runtime.h"
36#include "scoped_thread_state_change-inl.h"
Andreas Gampeb486a982017-06-01 13:45:54 -070037#include "thread-current-inl.h"
Alex Light37aa4c92017-03-27 13:02:41 -070038#include "thread_list.h"
39
Andreas Gampe3f46c962017-03-30 10:26:59 -070040// Test infrastructure
41#include "jvmti_helper.h"
42#include "test_env.h"
Alex Light37aa4c92017-03-27 13:02:41 -070043
44namespace art {
45namespace Test983SourceTransformVerify {
46
Alex Light40528472017-03-28 09:07:36 -070047constexpr bool kSkipInitialLoad = true;
48
Alex Light37aa4c92017-03-27 13:02:41 -070049// The hook we are using.
50void JNICALL CheckDexFileHook(jvmtiEnv* jvmti_env ATTRIBUTE_UNUSED,
51 JNIEnv* jni_env ATTRIBUTE_UNUSED,
52 jclass class_being_redefined,
53 jobject loader ATTRIBUTE_UNUSED,
54 const char* name,
55 jobject protection_domain ATTRIBUTE_UNUSED,
56 jint class_data_len,
57 const unsigned char* class_data,
58 jint* new_class_data_len ATTRIBUTE_UNUSED,
59 unsigned char** new_class_data ATTRIBUTE_UNUSED) {
Alex Light40528472017-03-28 09:07:36 -070060 if (kSkipInitialLoad && class_being_redefined == nullptr) {
Alex Light37aa4c92017-03-27 13:02:41 -070061 // Something got loaded concurrently. Just ignore it for now.
62 return;
63 }
64 std::cout << "Dex file hook for " << name << std::endl;
65 if (IsJVM()) {
66 return;
67 }
68 std::string error;
69 std::unique_ptr<const DexFile> dex(DexFile::Open(class_data,
70 class_data_len,
71 "fake_location.dex",
Alex Light40528472017-03-28 09:07:36 -070072 /*location_checksum*/ 0,
73 /*oat_dex_file*/ nullptr,
74 /*verify*/ true,
75 /*verify_checksum*/ true,
Alex Light37aa4c92017-03-27 13:02:41 -070076 &error));
77 if (dex.get() == nullptr) {
78 std::cout << "Failed to verify dex file for " << name << " because " << error << std::endl;
Alex Light40528472017-03-28 09:07:36 -070079 return;
80 }
81 for (uint32_t i = 0; i < dex->NumClassDefs(); i++) {
82 const DexFile::ClassDef& def = dex->GetClassDef(i);
83 const uint8_t* data_item = dex->GetClassData(def);
84 if (data_item == nullptr) {
85 continue;
86 }
87 for (ClassDataItemIterator it(*dex, data_item); it.HasNext(); it.Next()) {
88 if (!it.IsAtMethod() || it.GetMethodCodeItem() == nullptr) {
89 continue;
90 }
91 for (CodeItemIterator code_it(*it.GetMethodCodeItem()); !code_it.Done(); code_it.Advance()) {
92 const Instruction& inst = code_it.CurrentInstruction();
93 int forbiden_flags = (Instruction::kVerifyError | Instruction::kVerifyRuntimeOnly);
94 if (inst.Opcode() == Instruction::RETURN_VOID_NO_BARRIER ||
95 (inst.GetVerifyExtraFlags() & forbiden_flags) != 0) {
96 std::cout << "Unexpected instruction found in " << dex->PrettyMethod(it.GetMemberIndex())
97 << " [Dex PC: 0x" << std::hex << code_it.CurrentDexPc() << std::dec << "] : "
98 << inst.DumpString(dex.get()) << std::endl;
99 continue;
100 }
101 }
102 }
Alex Light37aa4c92017-03-27 13:02:41 -0700103 }
104}
105
106// Get all capabilities except those related to retransformation.
107jint OnLoad(JavaVM* vm,
108 char* options ATTRIBUTE_UNUSED,
109 void* reserved ATTRIBUTE_UNUSED) {
110 if (vm->GetEnv(reinterpret_cast<void**>(&jvmti_env), JVMTI_VERSION_1_0)) {
111 printf("Unable to get jvmti env!\n");
112 return 1;
113 }
114 SetAllCapabilities(jvmti_env);
115 jvmtiEventCallbacks cb;
116 memset(&cb, 0, sizeof(cb));
117 cb.ClassFileLoadHook = CheckDexFileHook;
118 if (jvmti_env->SetEventCallbacks(&cb, sizeof(cb)) != JVMTI_ERROR_NONE) {
119 printf("Unable to set class file load hook cb!\n");
120 return 1;
121 }
122 return 0;
123}
124
Alex Light37aa4c92017-03-27 13:02:41 -0700125} // namespace Test983SourceTransformVerify
126} // namespace art