diff --git a/core/src/main/cpp/main/include/art/runtime/class_linker.h b/core/src/main/cpp/main/include/art/runtime/class_linker.h
index 405ceb77..2dd7b4b1 100644
--- a/core/src/main/cpp/main/include/art/runtime/class_linker.h
+++ b/core/src/main/cpp/main/include/art/runtime/class_linker.h
@@ -28,6 +28,7 @@
#include "jni_env_ext.h"
#include "context.h"
#include "jni/pending_hooks.h"
+#include "jni/yahfa.h"
#include "utils.h"
#include "HookMain.h"
diff --git a/core/src/main/cpp/main/include/art/runtime/jit/profiling_info.h b/core/src/main/cpp/main/include/art/runtime/jit/profiling_info.h
new file mode 100644
index 00000000..5c0c2a25
--- /dev/null
+++ b/core/src/main/cpp/main/include/art/runtime/jit/profiling_info.h
@@ -0,0 +1,65 @@
+/*
+ * This file is part of LSPosed.
+ *
+ * LSPosed is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * LSPosed is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with LSPosed. If not, see .
+ *
+ * Copyright (C) 2021 LSPosed Contributors
+ */
+
+#pragma once
+
+#include
+#include
+#include
+#include "utils.h"
+#include "jni/pending_hooks.h"
+
+namespace art {
+ namespace profiling_info {
+ inline static size_t OFFSET_art_method = -1;
+
+ CREATE_MEM_HOOK_STUB_ENTRIES(
+ "_ZN3art13ProfilingInfo13AddInvokeInfoEjPNS_6mirror5ClassE",
+ void, AddInvokeInfo, (void * thiz, uint32_t dex_pc, void * clazz_ptr), {
+ void *method = *reinterpret_cast(
+ reinterpret_cast(thiz) + OFFSET_art_method);
+ if (lspd::isHooked(method)) [[unlikely]] return;
+ backup(thiz, dex_pc, clazz_ptr);
+ });
+
+ static void Setup(const SandHook::ElfImg &handle) {
+ int api_level = lspd::GetAndroidApiLevel();
+ switch (api_level) {
+ case __ANDROID_API_Q__:
+ OFFSET_art_method = 0;
+ break;
+ case __ANDROID_API_O_MR1__:
+ [[fallthrough]];
+ case __ANDROID_API_P__:
+ [[fallthrough]];
+ case __ANDROID_API_R__:
+ [[fallthrough]];
+ case __ANDROID_API_S__:
+ if constexpr(lspd::is64) {
+ OFFSET_art_method = 8;
+ } else {
+ OFFSET_art_method = 4;
+ }
+ break;
+ }
+ if (OFFSET_art_method != size_t(-1))
+ lspd::HookSyms(handle, AddInvokeInfo);
+ }
+ }
+}
diff --git a/core/src/main/cpp/main/src/jni/pending_hooks.cpp b/core/src/main/cpp/main/src/jni/pending_hooks.cpp
index 8f1a4a47..025a5649 100644
--- a/core/src/main/cpp/main/src/jni/pending_hooks.cpp
+++ b/core/src/main/cpp/main/src/jni/pending_hooks.cpp
@@ -35,9 +35,6 @@ namespace lspd {
std::unordered_set pending_methods_;
std::shared_mutex pending_methods_lock_;
-
- std::unordered_set hooked_methods_;
- std::shared_mutex hooked_methods_lock_;
}
bool IsClassPending(void *clazz) {
@@ -93,15 +90,4 @@ namespace lspd {
void RegisterPendingHooks(JNIEnv *env) {
REGISTER_LSP_NATIVE_METHODS(PendingHooks);
}
-
- bool isHooked(void *art_method) {
- std::shared_lock lk(hooked_methods_lock_);
- return hooked_methods_.contains(art_method);
- }
-
- void recordHooked(void *art_method) {
- std::unique_lock lk(hooked_methods_lock_);
- hooked_methods_.insert(art_method);
- }
-
-}
+} // namespace lspd
diff --git a/core/src/main/cpp/main/src/jni/pending_hooks.h b/core/src/main/cpp/main/src/jni/pending_hooks.h
index 49dc141d..b991c0e0 100644
--- a/core/src/main/cpp/main/src/jni/pending_hooks.h
+++ b/core/src/main/cpp/main/src/jni/pending_hooks.h
@@ -28,10 +28,6 @@ namespace lspd {
void RegisterPendingHooks(JNIEnv *);
- bool isHooked(void* art_method);
-
- void recordHooked(void* art_method);
-
void DonePendingHook(void *clazz);
bool IsMethodPending(void* art_method);
diff --git a/core/src/main/cpp/main/src/jni/yahfa.cpp b/core/src/main/cpp/main/src/jni/yahfa.cpp
index 72fd92fe..49179ee7 100644
--- a/core/src/main/cpp/main/src/jni/yahfa.cpp
+++ b/core/src/main/cpp/main/src/jni/yahfa.cpp
@@ -27,9 +27,26 @@
#include "art/runtime/thread.h"
#include "art/runtime/gc/scoped_gc_critical_section.h"
#include
+#include
+#include
namespace lspd {
+ namespace {
+ std::unordered_set hooked_methods_;
+ std::shared_mutex hooked_methods_lock_;
+ }
+
+ bool isHooked(void *art_method) {
+ std::shared_lock lk(hooked_methods_lock_);
+ return hooked_methods_.contains(art_method);
+ }
+
+ void recordHooked(void *art_method) {
+ std::unique_lock lk(hooked_methods_lock_);
+ hooked_methods_.insert(art_method);
+ }
+
using namespace startop::dex;
LSP_DEF_NATIVE_METHOD(void, Yahfa, init, jint sdkVersion) {
yahfa::init(env, clazz, sdkVersion);
diff --git a/core/src/main/cpp/main/src/jni/yahfa.h b/core/src/main/cpp/main/src/jni/yahfa.h
index 8f1e1c86..b3c04203 100644
--- a/core/src/main/cpp/main/src/jni/yahfa.h
+++ b/core/src/main/cpp/main/src/jni/yahfa.h
@@ -24,6 +24,10 @@
namespace lspd {
+ bool isHooked(void* art_method);
+
+ void recordHooked(void* art_method);
+
void RegisterYahfa(JNIEnv *);
} // namespace lspd
diff --git a/core/src/main/cpp/main/src/native_hook.cpp b/core/src/main/cpp/main/src/native_hook.cpp
index 8b46ec29..f6cf1a13 100644
--- a/core/src/main/cpp/main/src/native_hook.cpp
+++ b/core/src/main/cpp/main/src/native_hook.cpp
@@ -36,6 +36,7 @@
#include "art/runtime/instrumentation.h"
#include "art/runtime/thread_list.h"
#include "art/runtime/gc/scoped_gc_critical_section.h"
+#include "art/runtime/jit/profiling_info.h"
namespace lspd {
static std::atomic_bool installed = false;
@@ -60,8 +61,9 @@ namespace lspd {
art::instrumentation::DisableUpdateHookedMethodsCode(handle_libart);
art::thread_list::ScopedSuspendAll::Setup(handle_libart);
art::gc::ScopedGCCriticalSection::Setup(handle_libart);
+ art::profiling_info::Setup(handle_libart);
art_img.reset();
LOGD("Inline hooks installed");
}
-}
+} // namespace lspd