mirror of
https://github.com/LSPosed/LSPlant.git
synced 2025-05-04 20:42:02 +08:00
Fix static method hook lost if it is deoptimized before class initialization
This commit is contained in:
parent
e0e8cc11dc
commit
7ebe6b476a
@ -27,21 +27,21 @@ private:
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
using BackupMethods = std::list<std::tuple<art::ArtMethod *, void *>>;
|
||||
using BackupMethods = phmap::flat_hash_map<art::ArtMethod *, void *>;
|
||||
inline static phmap::flat_hash_map<const art::Thread *,
|
||||
phmap::flat_hash_map<const dex::ClassDef *, BackupMethods>>
|
||||
backup_methods_;
|
||||
inline static std::mutex backup_methods_lock_;
|
||||
|
||||
static void BackupClassMethods(const dex::ClassDef *class_def, art::Thread *self) {
|
||||
std::list<std::tuple<art::ArtMethod *, void *>> out;
|
||||
BackupMethods out;
|
||||
if (!class_def) return;
|
||||
{
|
||||
hooked_classes_.if_contains(class_def, [&out](const auto &it) {
|
||||
for (auto method : it.second) {
|
||||
if (method->IsStatic()) {
|
||||
LOGV("Backup hooked method %p because of initialization", method);
|
||||
out.emplace_back(method, method->GetEntryPoint());
|
||||
out.emplace(method, method->GetEntryPoint());
|
||||
}
|
||||
}
|
||||
});
|
||||
@ -51,7 +51,7 @@ private:
|
||||
for (auto method : it.second) {
|
||||
if (method->IsStatic()) {
|
||||
LOGV("Backup deoptimized method %p because of initialization", method);
|
||||
out.emplace_back(method, method->GetEntryPoint());
|
||||
out.emplace(method, method->GetEntryPoint());
|
||||
}
|
||||
}
|
||||
});
|
||||
|
@ -79,19 +79,20 @@ private:
|
||||
for (const auto &[art_method, old_trampoline] : methods) {
|
||||
auto new_trampoline = art_method->GetEntryPoint();
|
||||
art_method->SetEntryPoint(old_trampoline);
|
||||
if (IsDeoptimized(art_method)) {
|
||||
auto deoptimized = IsDeoptimized(art_method);
|
||||
auto backup_method = IsHooked(art_method);
|
||||
if (backup_method) {
|
||||
// If deoptimized, the backup entrypoint should be already set to interpreter
|
||||
if (!deoptimized && new_trampoline != old_trampoline) [[unlikely]] {
|
||||
LOGV("propagate entrypoint for orig %p backup %p", art_method, backup_method);
|
||||
backup_method->SetEntryPoint(new_trampoline);
|
||||
}
|
||||
} else if (deoptimized) {
|
||||
if (new_trampoline != art_quick_to_interpreter_bridge &&
|
||||
new_trampoline != art_quick_generic_jni_trampoline) {
|
||||
LOGV("re-deoptimize for %p", art_method);
|
||||
SetEntryPointsToInterpreter(art_method);
|
||||
}
|
||||
continue;
|
||||
}
|
||||
if (auto backup_method = IsHooked(art_method); backup_method) [[likely]] {
|
||||
if (new_trampoline != old_trampoline) [[unlikely]] {
|
||||
LOGV("propagate entrypoint for %p", backup_method);
|
||||
backup_method->SetEntryPoint(new_trampoline);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user