From 7b937c33473edf862b1a70f8729b73988d2d3dc4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=8F=8C=E8=8D=89=E9=85=B8=E9=85=AF?= <17663689+kotori2@users.noreply.github.com> Date: Sat, 16 Apr 2022 18:20:11 +0800 Subject: [PATCH] Use fmtlib to print log (#1854) (release zip size + ~50k) --- .gitmodules | 3 +++ core/src/main/jni/CMakeLists.txt | 2 +- .../main/jni/include/art/runtime/runtime.h | 2 +- core/src/main/jni/include/context.h | 4 ++-- core/src/main/jni/include/logging.h | 23 +++++++++++++------ core/src/main/jni/include/native_util.h | 6 ++--- core/src/main/jni/src/context.cpp | 4 ++-- core/src/main/jni/src/elf_util.cpp | 23 ++++++++----------- core/src/main/jni/src/jni/hook_bridge.cpp | 2 +- core/src/main/jni/src/jni/resources_hook.cpp | 2 +- core/src/main/jni/src/native_api.cpp | 12 +++++----- external/CMakeLists.txt | 2 ++ external/fmt | 1 + magisk-loader/src/main/jni/api/riru_main.cpp | 6 ++--- .../src/main/jni/api/zygisk_main.cpp | 8 +++---- .../src/main/jni/src/magisk_loader.cpp | 12 +++++----- magisk-loader/src/main/jni/src/service.cpp | 6 ++--- 17 files changed, 65 insertions(+), 53 deletions(-) create mode 160000 external/fmt diff --git a/.gitmodules b/.gitmodules index 5b8f9583..e30bf7b6 100644 --- a/.gitmodules +++ b/.gitmodules @@ -10,3 +10,6 @@ [submodule "external/dobby"] path = external/dobby url = https://github.com/LSPosed/Dobby.git +[submodule "external/fmt"] + path = external/fmt + url = https://github.com/fmtlib/fmt.git diff --git a/core/src/main/jni/CMakeLists.txt b/core/src/main/jni/CMakeLists.txt index 8dfa79b8..73cca55e 100644 --- a/core/src/main/jni/CMakeLists.txt +++ b/core/src/main/jni/CMakeLists.txt @@ -13,5 +13,5 @@ add_library(${PROJECT_NAME} STATIC ${SRC_LIST} ${CMAKE_CURRENT_BINARY_DIR}/src/c target_include_directories(${PROJECT_NAME} PUBLIC include) target_include_directories(${PROJECT_NAME} PRIVATE src) -target_link_libraries(${PROJECT_NAME} PUBLIC dobby lsplant_static log) +target_link_libraries(${PROJECT_NAME} PUBLIC dobby lsplant_static log fmt-header-only) target_link_libraries(${PROJECT_NAME} PRIVATE dex_builder_static) diff --git a/core/src/main/jni/include/art/runtime/runtime.h b/core/src/main/jni/include/art/runtime/runtime.h index c84647d4..5551c5bb 100644 --- a/core/src/main/jni/include/art/runtime/runtime.h +++ b/core/src/main/jni/include/art/runtime/runtime.h @@ -48,7 +48,7 @@ namespace art { RETRIEVE_FIELD_SYMBOL(instance, "_ZN3art7Runtime9instance_E"); RETRIEVE_MEM_FUNC_SYMBOL(SetJavaDebuggable, "_ZN3art7Runtime17SetJavaDebuggableEb"); void *thiz = *instance; - LOGD("_ZN3art7Runtime9instance_E = %p", thiz); + LOGD("_ZN3art7Runtime9instance_E = {}", thiz); instance_ = reinterpret_cast(thiz); } }; diff --git a/core/src/main/jni/include/context.h b/core/src/main/jni/include/context.h index 030ddf2a..a05bdc4a 100644 --- a/core/src/main/jni/include/context.h +++ b/core/src/main/jni/include/context.h @@ -104,14 +104,14 @@ namespace lspd { inline void FindAndCall(JNIEnv *env, std::string_view method_name, std::string_view method_sig, Args &&... args) const { if (!entry_class_) [[unlikely]] { - LOGE("cannot call method %s, entry class is null", method_name.data()); + LOGE("cannot call method {}, entry class is null", method_name); return; } jmethodID mid = lsplant::JNI_GetStaticMethodID(env, entry_class_, method_name, method_sig); if (mid) [[likely]] { lsplant::JNI_CallStaticVoidMethod(env, entry_class_, mid, std::forward(args)...); } else { - LOGE("method %s id is null", method_name.data()); + LOGE("method {} id is null", method_name); } } diff --git a/core/src/main/jni/include/logging.h b/core/src/main/jni/include/logging.h index 6d4be69e..7d55e4b4 100644 --- a/core/src/main/jni/include/logging.h +++ b/core/src/main/jni/include/logging.h @@ -22,6 +22,8 @@ #define _LOGGING_H #include +#include +#include #ifndef LOG_TAG #define LOG_TAG "LSPosed" @@ -34,18 +36,25 @@ #define LOGW(...) #define LOGE(...) #else +template +constexpr inline void LOG(int prio, const char* tag, fmt::format_string fmt, T&&... args) { + std::array buf{}; + auto s = fmt::format_to_n(buf.data(), buf.size(), fmt, std::forward(args)...).size; + buf[s] = '\0'; + __android_log_write(prio, tag, buf.data()); +} #ifndef NDEBUG -#define LOGD(fmt, ...) __android_log_print(ANDROID_LOG_DEBUG, LOG_TAG, "%s:%d#%s" ": " fmt, __FILE_NAME__, __LINE__, __PRETTY_FUNCTION__ __VA_OPT__(,) __VA_ARGS__) -#define LOGV(fmt, ...) __android_log_print(ANDROID_LOG_VERBOSE, LOG_TAG, "%s:%d#%s" ": " fmt, __FILE_NAME__, __LINE__, __PRETTY_FUNCTION__ __VA_OPT__(,) __VA_ARGS__) +#define LOGD(fmt, ...) LOG(ANDROID_LOG_DEBUG, LOG_TAG, "{}:{}#{}" ": " fmt, __FILE_NAME__, __LINE__, __PRETTY_FUNCTION__ __VA_OPT__(,) __VA_ARGS__) +#define LOGV(fmt, ...) LOG(ANDROID_LOG_VERBOSE, LOG_TAG, "{}:{}#{}" ": " fmt, __FILE_NAME__, __LINE__, __PRETTY_FUNCTION__ __VA_OPT__(,) __VA_ARGS__) #else #define LOGD(...) #define LOGV(...) #endif -#define LOGI(...) __android_log_print(ANDROID_LOG_INFO, LOG_TAG, __VA_ARGS__) -#define LOGW(...) __android_log_print(ANDROID_LOG_WARN, LOG_TAG, __VA_ARGS__) -#define LOGE(...) __android_log_print(ANDROID_LOG_ERROR, LOG_TAG, __VA_ARGS__) -#define LOGF(...) __android_log_print(ANDROID_LOG_FATAL, LOG_TAG, __VA_ARGS__) -#define PLOGE(fmt, args...) LOGE(fmt " failed with %d: %s", ##args, errno, strerror(errno)) +#define LOGI(...) LOG(ANDROID_LOG_INFO, LOG_TAG, __VA_ARGS__) +#define LOGW(...) LOG(ANDROID_LOG_WARN, LOG_TAG, __VA_ARGS__) +#define LOGE(...) LOG(ANDROID_LOG_ERROR, LOG_TAG, __VA_ARGS__) +#define LOGF(...) LOG(ANDROID_LOG_FATAL, LOG_TAG, __VA_ARGS__) +#define PLOGE(fmt, args...) LOGE(fmt " failed with {}: {}", ##args, errno, strerror(errno)) #endif #endif // _LOGGING_H diff --git a/core/src/main/jni/include/native_util.h b/core/src/main/jni/include/native_util.h index c8a80f95..537420fd 100644 --- a/core/src/main/jni/include/native_util.h +++ b/core/src/main/jni/include/native_util.h @@ -53,7 +53,7 @@ inline bool RegisterNativeMethodsInternal(JNIEnv *env, auto clazz = Context::GetInstance()->FindClassFromCurrentLoader(env, class_name); if (clazz.get() == nullptr) { - LOGF("Couldn't find class: %s", class_name); + LOGF("Couldn't find class: {}", class_name); return false; } return JNI_RegisterNatives(env, clazz, methods, method_count); @@ -90,7 +90,7 @@ inline int HookFunction(void *original, void *replace, void **backup) { if constexpr (isDebug) { Dl_info info; if (dladdr(original, &info)) - LOGD("Hooking %s (%p) from %s (%p)", + LOGD("Hooking {} ({}) from {} ({})", info.dli_sname ? info.dli_sname : "(unknown symbol)", info.dli_saddr, info.dli_fname ? info.dli_fname : "(unknown file)", info.dli_fbase); } @@ -101,7 +101,7 @@ inline int UnhookFunction(void *original) { if constexpr (isDebug) { Dl_info info; if (dladdr(original, &info)) - LOGD("Unhooking %s (%p) from %s (%p)", + LOGD("Unhooking {} ({}) from {} ({})", info.dli_sname ? info.dli_sname : "(unknown symbol)", info.dli_saddr, info.dli_fname ? info.dli_fname : "(unknown file)", info.dli_fbase); } diff --git a/core/src/main/jni/src/context.cpp b/core/src/main/jni/src/context.cpp index c19e937c..343191cb 100644 --- a/core/src/main/jni/src/context.cpp +++ b/core/src/main/jni/src/context.cpp @@ -33,7 +33,7 @@ using namespace lsplant; namespace lspd { Context::PreloadedDex::PreloadedDex(int fd, std::size_t size) { - LOGD("Context::PreloadedDex::PreloadedDex: fd=%d, size=%zu", fd, size); + LOGD("Context::PreloadedDex::PreloadedDex: fd={}, size={}", fd, size); auto *addr = mmap(nullptr, size, PROT_READ, MAP_SHARED, fd, 0); if (addr != MAP_FAILED) { @@ -79,7 +79,7 @@ namespace lspd { } else { LOGE("No loadClass/findClass method found"); } - LOGE("Class %s not found", class_name.data()); + LOGE("Class {} not found", class_name); return {env, nullptr}; } } // namespace lspd diff --git a/core/src/main/jni/src/elf_util.cpp b/core/src/main/jni/src/elf_util.cpp index 903fb159..d35b6616 100644 --- a/core/src/main/jni/src/elf_util.cpp +++ b/core/src/main/jni/src/elf_util.cpp @@ -44,13 +44,13 @@ ElfImg::ElfImg(std::string_view base_name) : elf(base_name) { //load elf int fd = open(elf.data(), O_RDONLY); if (fd < 0) { - LOGE("failed to open %s", elf.data()); + LOGE("failed to open {}", elf); return; } size = lseek(fd, 0, SEEK_END); if (size <= 0) { - LOGE("lseek() failed for %s", elf.data()); + LOGE("lseek() failed for {}", elf); } header = reinterpret_cast(mmap(nullptr, size, PROT_READ, MAP_SHARED, fd, 0)); @@ -203,16 +203,13 @@ ElfImg::~ElfImg() { ElfW(Addr) ElfImg::getSymbOffset(std::string_view name, uint32_t gnu_hash, uint32_t elf_hash) const { if (auto offset = GnuLookup(name, gnu_hash); offset > 0) { - LOGD("found %s %p in %s in dynsym by gnuhash", name.data(), - reinterpret_cast(offset), elf.data()); + LOGD("found {} {:#x} in {} in dynsym by gnuhash", name, offset, elf); return offset; } else if (offset = ElfLookup(name, elf_hash); offset > 0) { - LOGD("found %s %p in %s in dynsym by elfhash", name.data(), - reinterpret_cast(offset), elf.data()); + LOGD("found {} {:#x} in {} in dynsym by elfhash", name, offset, elf); return offset; } else if (offset = LinearLookup(name); offset > 0) { - LOGD("found %s %p in %s in symtab by linear lookup", name.data(), - reinterpret_cast(offset), elf.data()); + LOGD("found {} {:#x} in {} in symtab by linear lookup", name, offset, elf); return offset; } else { return 0; @@ -237,33 +234,33 @@ bool ElfImg::findModuleBase() { std::string_view line{buff, static_cast(nread)}; if ((contains(line, "r-xp") || contains(line, "r--p")) && contains(line, elf)) { - LOGD("found: %*s", static_cast(line.size()), line.data()); + LOGD("found: {}", line); if (auto begin = line.find_last_of(' '); begin != std::string_view::npos && line[++begin] == '/') { found = true; elf = line.substr(begin); if (elf.back() == '\n') elf.pop_back(); - LOGD("update path: %s", elf.data()); + LOGD("update path: {}", elf); break; } } } if (!found) { if (buff) free(buff); - LOGE("failed to read load address for %s", elf.data()); + LOGE("failed to read load address for {}", elf); fclose(maps); return false; } if (char *next = buff; load_addr = strtoul(buff, &next, 16), next == buff) { - LOGE("failed to read load address for %s", elf.data()); + LOGE("failed to read load address for {}", elf); } if (buff) free(buff); fclose(maps); - LOGD("get module base %s: %lx", elf.data(), load_addr); + LOGD("get module base {}: {:#x}", elf, load_addr); base = reinterpret_cast(load_addr); return true; diff --git a/core/src/main/jni/src/jni/hook_bridge.cpp b/core/src/main/jni/src/jni/hook_bridge.cpp index 115c8bc8..d0275fd0 100644 --- a/core/src/main/jni/src/jni/hook_bridge.cpp +++ b/core/src/main/jni/src/jni/hook_bridge.cpp @@ -52,7 +52,7 @@ LSP_DEF_NATIVE_METHOD(jboolean, HookBridge, hookMethod, jobject hookMethod, ~finally() { auto finish = std::chrono::steady_clock::now(); if (newHook) { - LOGV("New hook took %lldus", + LOGV("New hook took {}us", std::chrono::duration_cast(finish - start).count()); } } diff --git a/core/src/main/jni/src/jni/resources_hook.cpp b/core/src/main/jni/src/jni/resources_hook.cpp index f6254d8e..69b7b9cf 100644 --- a/core/src/main/jni/src/jni/resources_hook.cpp +++ b/core/src/main/jni/src/jni/resources_hook.cpp @@ -76,7 +76,7 @@ namespace lspd { kXResourcesClassName)) { classXResources = JNI_NewGlobalRef(env, classXResources_); } else { - LOGE("Error while loading XResources class '%s':", kXResourcesClassName); + LOGE("Error while loading XResources class '{}':", kXResourcesClassName); return JNI_FALSE; } methodXResourcesTranslateResId = JNI_GetStaticMethodID( diff --git a/core/src/main/jni/src/native_api.cpp b/core/src/main/jni/src/native_api.cpp index ab4b3bd5..d6a272e2 100644 --- a/core/src/main/jni/src/native_api.cpp +++ b/core/src/main/jni/src/native_api.cpp @@ -78,7 +78,7 @@ namespace lspd { }); }(); if (!initialized) [[unlikely]] return; - LOGD("native_api: Registered %s", library_name.c_str()); + LOGD("native_api: Registered {}", library_name); moduleNativeLibs.push_back(library_name); } @@ -101,18 +101,18 @@ namespace lspd { } else { ns = "NULL"; } - LOGD("native_api: do_dlopen(%s)", name); + LOGD("native_api: do_dlopen({})", name); if (handle == nullptr) { return nullptr; } for (std::string_view module_lib: moduleNativeLibs) { // the so is a module so if (hasEnding(ns, module_lib)) [[unlikely]] { - LOGD("Loading module native library %s", module_lib.data()); + LOGD("Loading module native library {}", module_lib); void *native_init_sym = dlsym(handle, "native_init"); if (native_init_sym == nullptr) [[unlikely]] { - LOGD("Failed to get symbol \"native_init\" from library %s", - module_lib.data()); + LOGD("Failed to get symbol \"native_init\" from library {}", + module_lib); break; } auto native_init = reinterpret_cast(native_init_sym); @@ -133,7 +133,7 @@ namespace lspd { }); bool InstallNativeAPI(const lsplant::HookHandler & handler) { - LOGD("InstallNativeAPI: %p", symbol_cache->do_dlopen); + LOGD("InstallNativeAPI: {}", symbol_cache->do_dlopen); if (symbol_cache->do_dlopen) [[likely]] { HookSymNoHandle(handler, symbol_cache->do_dlopen, do_dlopen); return true; diff --git a/external/CMakeLists.txt b/external/CMakeLists.txt index 70e5b668..093281bc 100644 --- a/external/CMakeLists.txt +++ b/external/CMakeLists.txt @@ -102,3 +102,5 @@ link_libraries(cxx) add_subdirectory(lsplant/lsplant/src/main/jni) add_subdirectory(dobby) +add_subdirectory(fmt) +target_compile_definitions(fmt-header-only INTERFACE FMT_STATIC_THOUSANDS_SEPARATOR=1 FMT_USE_FLOAT=0 FMT_USE_DOUBLE=0 FMT_USE_LONG_DOUBLE=0) diff --git a/external/fmt b/external/fmt new file mode 160000 index 00000000..96930161 --- /dev/null +++ b/external/fmt @@ -0,0 +1 @@ +Subproject commit 96930161f918d08a689076f500f128522a237a75 diff --git a/magisk-loader/src/main/jni/api/riru_main.cpp b/magisk-loader/src/main/jni/api/riru_main.cpp index 80bb0b17..ab26c9b2 100644 --- a/magisk-loader/src/main/jni/api/riru_main.cpp +++ b/magisk-loader/src/main/jni/api/riru_main.cpp @@ -39,7 +39,7 @@ namespace lspd { void onModuleLoaded() { LOGI("onModuleLoaded: welcome to LSPosed!"); - LOGI("onModuleLoaded: version v%s (%d)", versionName, versionCode); + LOGI("onModuleLoaded: version v{} ({})", versionName, versionCode); InitSymbolCache(nullptr); MagiskLoader::Init(); } @@ -120,8 +120,8 @@ namespace lspd { } RIRU_EXPORT RiruVersionedModuleInfo *init(Riru *riru) { - LOGD("using riru %d", riru->riruApiVersion); - LOGD("module path: %s", riru->magiskModulePath); + LOGD("using riru {}", riru->riruApiVersion); + LOGD("module path: {}", riru->magiskModulePath); lspd::magiskPath = riru->magiskModulePath; if (!lspd::isDebug && lspd::magiskPath.find(lspd::moduleName) == std::string::npos) { LOGE("who am i"); diff --git a/magisk-loader/src/main/jni/api/zygisk_main.cpp b/magisk-loader/src/main/jni/api/zygisk_main.cpp index 05b3537e..2ce87d01 100644 --- a/magisk-loader/src/main/jni/api/zygisk_main.cpp +++ b/magisk-loader/src/main/jni/api/zygisk_main.cpp @@ -61,7 +61,7 @@ namespace lspd { read_sz += ret; } while (read_sz != count && ret != 0); if (read_sz != count) { - PLOGE("read (%zu != %zu)", count, read_sz); + PLOGE("read ({} != {})", count, read_sz); } return read_sz; } @@ -81,7 +81,7 @@ namespace lspd { write_sz += ret; } while (write_sz != count && ret != 0); if (write_sz != count) { - PLOGE("write (%zu != %zu)", count, write_sz); + PLOGE("write ({} != {})", count, write_sz); } return write_sz; } @@ -339,7 +339,7 @@ namespace lspd { SharedMem InitCompanion() { LOGI("ZygiskCompanion: welcome to LSPosed!"); - LOGI("ZygiskCompanion: version v%s (%d)", versionName, versionCode); + LOGI("ZygiskCompanion: version v{} ({})", versionName, versionCode); SharedMem symbol{"symbol", sizeof(lspd::SymbolCache)}; @@ -357,7 +357,7 @@ namespace lspd { void CompanionEntry(int client) { using namespace std::string_literals; static auto symbol = InitCompanion(); - LOGD("Got cache with fd=%d size=%d", symbol.get(), (int) symbol.size()); + LOGD("Got cache with fd={} size={}", symbol.get(), symbol.size()); if (symbol.ok()) { write_int(client, symbol.size()); send_fd(client, symbol.get()); diff --git a/magisk-loader/src/main/jni/src/magisk_loader.cpp b/magisk-loader/src/main/jni/src/magisk_loader.cpp index 60fdfe36..5dbf2ba2 100644 --- a/magisk-loader/src/main/jni/src/magisk_loader.cpp +++ b/magisk-loader/src/main/jni/src/magisk_loader.cpp @@ -96,7 +96,7 @@ namespace lspd { auto *instance = Service::instance(); auto system_server_binder = instance->RequestSystemServerBinder(env); if (!system_server_binder) { - LOGF("Failed to get system server binder, system server initialization failed. "); + LOGF("Failed to get system server binder, system server initialization failed."); return; } @@ -157,12 +157,12 @@ namespace lspd { JUTFString process_name(env, nice_name); skip_ = !symbol_cache->initialized.test(std::memory_order_acquire); if (!skip_ && !app_data_dir) { - LOGD("skip injecting into %s because it has no data dir", process_name.get()); + LOGD("skip injecting into {} because it has no data dir", process_name.get()); skip_ = true; } if (!skip_ && is_child_zygote) { skip_ = true; - LOGD("skip injecting into %s because it's a child zygote", process_name.get()); + LOGD("skip injecting into {} because it's a child zygote", process_name.get()); } if (!skip_ && ((app_id >= FIRST_ISOLATED_UID && app_id <= LAST_ISOLATED_UID) || @@ -170,7 +170,7 @@ namespace lspd { app_id <= LAST_APP_ZYGOTE_ISOLATED_UID) || app_id == SHARED_RELRO_UID)) { skip_ = true; - LOGI("skip injecting into %s because it's isolated", process_name.get()); + LOGI("skip injecting into {} because it's isolated", process_name.get()); } setAllowUnload(skip_); } @@ -204,14 +204,14 @@ namespace lspd { FindAndCall(env, "forkCommon", "(ZLjava/lang/String;Landroid/os/IBinder;)V", JNI_FALSE, nice_name, binder); - LOGD("injected xposed into %s", process_name.get()); + LOGD("injected xposed into {}", process_name.get()); setAllowUnload(false); GetArt(true); } else { auto context = Context::ReleaseInstance(); auto service = Service::ReleaseInstance(); GetArt(true); - LOGD("skipped %s", process_name.get()); + LOGD("skipped {}", process_name.get()); setAllowUnload(true); } } diff --git a/magisk-loader/src/main/jni/src/service.cpp b/magisk-loader/src/main/jni/src/service.cpp index d828b2b8..d7bb7960 100644 --- a/magisk-loader/src/main/jni/src/service.cpp +++ b/magisk-loader/src/main/jni/src/service.cpp @@ -221,7 +221,7 @@ namespace lspd { auto bridge_service = JNI_CallStaticObjectMethod(env, service_manager_class_, get_service_method_, bridge_service_name); if (!bridge_service) { - LOGD("can't get %s", BRIDGE_SERVICE_NAME.data()); + LOGD("can't get {}", BRIDGE_SERVICE_NAME); return {env, nullptr}; } @@ -307,7 +307,7 @@ namespace lspd { if (app_binder) { JNI_NewGlobalRef(env, heart_beat_binder); } - LOGD("Service::RequestSystemServerBinder app_binder: %p", app_binder.get()); + LOGD("Service::RequestSystemServerBinder app_binder: {}", static_cast(app_binder.get())); return app_binder; } @@ -328,7 +328,7 @@ namespace lspd { JNI_CallVoidMethod(env, data, recycleMethod_); JNI_CallVoidMethod(env, reply, recycleMethod_); - LOGD("Service::RequestLSPDex fd=%d, size=%zu", fd, size); + LOGD("Service::RequestLSPDex fd={}, size={}", fd, size); return {fd, size}; } } // namespace lspd