Skip to content

Commit ee908f0

Browse files
feat: add basic jnitrace feature
1 parent b0ca2fc commit ee908f0

File tree

13 files changed

+3727
-237
lines changed

13 files changed

+3727
-237
lines changed

library/src/main/cpp/CMakeLists.txt

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@ if(NOT DEFINED FAKELINKER_MODULE_VERSION_NAME)
4747
set(FAKELINKER_MODULE_VERSION_NAME "3.1.0")
4848
endif()
4949

50-
configure_file("${CMAKE_CURRENT_SOURCE_DIR}/module_config.h.in" "${CMAKE_CURRENT_SOURCE_DIR}/include/linker_version.h")
50+
configure_file("${CMAKE_CURRENT_LIST_DIR}/module_config.h.in" "${CMAKE_CURRENT_LIST_DIR}/include/linker_version.h")
5151

5252
message(STATUS "cmake version:${CMAKE_VERSION}
5353
api:${ANDROID_PLATFORM}
@@ -75,10 +75,13 @@ set(FAKE_LINKER_SRC
7575
${NEON_SRC}
7676

7777
# JNI Hook
78+
linker/art/art_symbol.cpp
79+
linker/art/default_trace_jni.cpp
7880
linker/art/hook_jni_native_interface_impl.cpp
81+
linker/art/jni_helper.cpp
82+
linker/art/trace_jni.cpp
7983

8084
# JNI Common
81-
common/jni_helper.cpp
8285
common/maps_util.cpp
8386
common/unique_fd.cpp
8487
common/unique_memory.cpp

library/src/main/cpp/common/jni_helper.cpp

Lines changed: 0 additions & 210 deletions
This file was deleted.
Lines changed: 124 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,124 @@
1+
#pragma once
2+
3+
#include <jni.h>
4+
5+
#include <string>
6+
7+
#include <linker_macros.h>
8+
#include <macros.h>
9+
10+
namespace art {
11+
12+
inline namespace compatible {
13+
class JavaVMExt;
14+
15+
class DamagedRuntime {
16+
public:
17+
DamagedRuntime() = delete;
18+
19+
static DamagedRuntime *FromRuntime(void *runtime) {
20+
CHECK(jvm_offset_ != -1);
21+
return reinterpret_cast<DamagedRuntime *>(reinterpret_cast<char *>(runtime) + jvm_offset_ - sizeof(void *));
22+
}
23+
24+
static bool InitJavaVMOffset(void *runtime, JavaVMExt *vm) {
25+
if (!runtime || !vm) {
26+
return false;
27+
}
28+
auto *ptr = reinterpret_cast<size_t *>(runtime);
29+
auto target = reinterpret_cast<size_t>(vm);
30+
for (std::size_t i = 0; i < 2000; i++) {
31+
if (ptr[i] == target) {
32+
jvm_offset_ = i * sizeof(size_t);
33+
LOGD("init art::Runtime::java_vm_ offset: %zu", jvm_offset_);
34+
return true;
35+
}
36+
}
37+
return false;
38+
}
39+
40+
JavaVMExt *GetJavaVM() const { return java_vm_.get(); }
41+
42+
ANDROID_GE_R /* art::Runtime* */ void *GetJniIdManager() const { return jni_id_manager_.get(); }
43+
44+
private:
45+
ANDROID_GE_R std::unique_ptr<void *> jni_id_manager_;
46+
std::unique_ptr<JavaVMExt> java_vm_;
47+
48+
// 在 Runtime 类中的偏移,使用前应设置
49+
static size_t jvm_offset_;
50+
};
51+
52+
class JavaVMExt : public JavaVM {
53+
public:
54+
JavaVMExt() = delete;
55+
/* art::Runtime* */ void *GetRuntime() const { return runtime_; }
56+
57+
private:
58+
/* art::Runtime* */ void *const runtime_;
59+
};
60+
61+
class Thread {
62+
public:
63+
Thread() = delete;
64+
65+
private:
66+
void *placeholder_;
67+
};
68+
69+
class JNIEnvExt : public JNIEnv {
70+
public:
71+
JNIEnvExt() = delete;
72+
JavaVMExt *GetVm() const { return vm_; }
73+
74+
static JNIEnvExt *FromJNIEnv(JNIEnv *env) { return reinterpret_cast<JNIEnvExt *>(env); }
75+
76+
private:
77+
Thread *const self_;
78+
JavaVMExt *const vm_;
79+
};
80+
81+
} // namespace compatible
82+
} // namespace art
83+
84+
namespace fakelinker {
85+
86+
class ArtSymbol {
87+
public:
88+
static ArtSymbol *Get();
89+
/**
90+
* @brief Requests basic soinfo to be initialized
91+
*/
92+
static bool Init(JNIEnv *env);
93+
94+
std::string PrettyMethod(jmethodID method, bool with_signature);
95+
std::string PrettyField(jfieldID field, bool with_signature);
96+
/* ArtMethod* */ void *DecodeMethodId(jmethodID method);
97+
/* ArtField* */ void *DecodeFieldId(jfieldID field);
98+
99+
std::string GetMethodShorty(/* ArtMethod* */ void *art_method);
100+
101+
std::string GetMethodShorty(jmethodID method);
102+
103+
/**
104+
* @brief android 11+ Memory layout in the art::Runtime class
105+
* std::unique_ptr<jni::JniIdManager> jni_id_manager_;
106+
* std::unique_ptr<JavaVMExt> java_vm_;
107+
*/
108+
bool can_pretty_field = false;
109+
bool can_pretty_method = false;
110+
111+
private:
112+
ArtSymbol() = default;
113+
bool init_ = false;
114+
ANDROID_GE_R /* art::jni::JniIdManager */ void *jni_id_manager = nullptr;
115+
std::string (*ArtMethodPrettyMethodPtr)(/* ArtMethod* */ void *art_method, bool with_signature) = nullptr;
116+
std::string (*ArtFieldPrettyFieldPtr)(/* ArtField* */ void *art_field, bool with_signature) = nullptr;
117+
ANDROID_GE_R /* ArtMethod* */ void *(*DecodeMethodIdPtr)(/* JniIdManager */ void *thiz, jmethodID method) = nullptr;
118+
ANDROID_GE_R /* ArtField* */ void *(*DecodeFieldIdPtr)(/* JniIdManager */ void *thiz, jfieldID field) = nullptr;
119+
120+
const char *(*NterpGetShortyPtr)(/* ArtMethod* */ void *art_method) = nullptr;
121+
const char *(*ArtMethodGetShortyPtr)(/* ArtMethod* */ void *art_method, uint32_t *out_length) = nullptr;
122+
};
123+
124+
} // namespace fakelinker

0 commit comments

Comments
 (0)