blob: e9cb35e944f18e16edb6a9982e1838d7666194c7 [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>
Alex Light37aa4c92017-03-27 13:02:41 -070018
Andreas Gampe8cf9cb32017-07-19 09:28:38 -070019#include <cstdio>
20#include <cstring>
Alex Light37aa4c92017-03-27 13:02:41 -070021#include <iostream>
22#include <vector>
23
24#include "android-base/stringprintf.h"
Andreas Gampe8cf9cb32017-07-19 09:28:38 -070025#include "jni.h"
26#include "jvmti.h"
Alex Light37aa4c92017-03-27 13:02:41 -070027
Alex Light37aa4c92017-03-27 13:02:41 -070028#include "base/macros.h"
Alex Light40528472017-03-28 09:07:36 -070029#include "bytecode_utils.h"
David Sehr9e734c72018-01-04 17:56:19 -080030#include "dex/code_item_accessors-inl.h"
31#include "dex/dex_file.h"
32#include "dex/dex_file_loader.h"
33#include "dex/dex_instruction.h"
Alex Light37aa4c92017-03-27 13:02:41 -070034#include "jit/jit.h"
Alex Light37aa4c92017-03-27 13:02:41 -070035#include "native_stack_dump.h"
Alex Light37aa4c92017-03-27 13:02:41 -070036#include "runtime.h"
37#include "scoped_thread_state_change-inl.h"
Andreas Gampeb486a982017-06-01 13:45:54 -070038#include "thread-current-inl.h"
Alex Light37aa4c92017-03-27 13:02:41 -070039#include "thread_list.h"
40
Andreas Gampe3f46c962017-03-30 10:26:59 -070041// Test infrastructure
42#include "jvmti_helper.h"
43#include "test_env.h"
Alex Light37aa4c92017-03-27 13:02:41 -070044
45namespace art {
46namespace Test983SourceTransformVerify {
47
Alex Light40528472017-03-28 09:07:36 -070048constexpr bool kSkipInitialLoad = true;
49
Alex Light37aa4c92017-03-27 13:02:41 -070050// The hook we are using.
51void JNICALL CheckDexFileHook(jvmtiEnv* jvmti_env ATTRIBUTE_UNUSED,
52 JNIEnv* jni_env ATTRIBUTE_UNUSED,
53 jclass class_being_redefined,
54 jobject loader ATTRIBUTE_UNUSED,
55 const char* name,
56 jobject protection_domain ATTRIBUTE_UNUSED,
57 jint class_data_len,
58 const unsigned char* class_data,
59 jint* new_class_data_len ATTRIBUTE_UNUSED,
60 unsigned char** new_class_data ATTRIBUTE_UNUSED) {
Alex Light40528472017-03-28 09:07:36 -070061 if (kSkipInitialLoad && class_being_redefined == nullptr) {
Alex Light37aa4c92017-03-27 13:02:41 -070062 // Something got loaded concurrently. Just ignore it for now.
63 return;
64 }
65 std::cout << "Dex file hook for " << name << std::endl;
66 if (IsJVM()) {
67 return;
68 }
69 std::string error;
Mathieu Chartier79c87da2017-10-10 11:54:29 -070070 std::unique_ptr<const DexFile> dex(DexFileLoader::Open(class_data,
71 class_data_len,
72 "fake_location.dex",
73 /*location_checksum*/ 0,
74 /*oat_dex_file*/ nullptr,
75 /*verify*/ true,
76 /*verify_checksum*/ true,
77 &error));
Alex Light37aa4c92017-03-27 13:02:41 -070078 if (dex.get() == nullptr) {
79 std::cout << "Failed to verify dex file for " << name << " because " << error << std::endl;
Alex Light40528472017-03-28 09:07:36 -070080 return;
81 }
82 for (uint32_t i = 0; i < dex->NumClassDefs(); i++) {
83 const DexFile::ClassDef& def = dex->GetClassDef(i);
84 const uint8_t* data_item = dex->GetClassData(def);
85 if (data_item == nullptr) {
86 continue;
87 }
88 for (ClassDataItemIterator it(*dex, data_item); it.HasNext(); it.Next()) {
89 if (!it.IsAtMethod() || it.GetMethodCodeItem() == nullptr) {
90 continue;
91 }
Mathieu Chartier73f21d42018-01-02 14:26:50 -080092 for (const DexInstructionPcPair& pair :
Mathieu Chartier698ebbc2018-01-05 11:00:42 -080093 art::CodeItemInstructionAccessor(*dex, it.GetMethodCodeItem())) {
Mathieu Chartier0021feb2017-11-07 00:08:52 -080094 const Instruction& inst = pair.Inst();
Alex Light40528472017-03-28 09:07:36 -070095 int forbiden_flags = (Instruction::kVerifyError | Instruction::kVerifyRuntimeOnly);
96 if (inst.Opcode() == Instruction::RETURN_VOID_NO_BARRIER ||
97 (inst.GetVerifyExtraFlags() & forbiden_flags) != 0) {
98 std::cout << "Unexpected instruction found in " << dex->PrettyMethod(it.GetMemberIndex())
Mathieu Chartier0021feb2017-11-07 00:08:52 -080099 << " [Dex PC: 0x" << std::hex << pair.DexPc() << std::dec << "] : "
Alex Light40528472017-03-28 09:07:36 -0700100 << inst.DumpString(dex.get()) << std::endl;
101 continue;
102 }
103 }
104 }
Alex Light37aa4c92017-03-27 13:02:41 -0700105 }
106}
107
108// Get all capabilities except those related to retransformation.
109jint OnLoad(JavaVM* vm,
110 char* options ATTRIBUTE_UNUSED,
111 void* reserved ATTRIBUTE_UNUSED) {
112 if (vm->GetEnv(reinterpret_cast<void**>(&jvmti_env), JVMTI_VERSION_1_0)) {
113 printf("Unable to get jvmti env!\n");
114 return 1;
115 }
Alex Light3d324fd2017-07-20 15:38:52 -0700116 SetStandardCapabilities(jvmti_env);
Alex Light37aa4c92017-03-27 13:02:41 -0700117 jvmtiEventCallbacks cb;
118 memset(&cb, 0, sizeof(cb));
119 cb.ClassFileLoadHook = CheckDexFileHook;
120 if (jvmti_env->SetEventCallbacks(&cb, sizeof(cb)) != JVMTI_ERROR_NONE) {
121 printf("Unable to set class file load hook cb!\n");
122 return 1;
123 }
124 return 0;
125}
126
Alex Light37aa4c92017-03-27 13:02:41 -0700127} // namespace Test983SourceTransformVerify
128} // namespace art