diff options
author | vaxerski <[email protected]> | 2023-03-31 18:31:11 +0100 |
---|---|---|
committer | vaxerski <[email protected]> | 2023-03-31 18:31:11 +0100 |
commit | 430778293e4ce7c2ae418ff11601d61833b99a67 (patch) | |
tree | ffecb08293844375252de54f63ecd99e3dd8ec3d /src/plugins/PluginAPI.cpp | |
parent | de3b00b5eea6fae5fd55164af06342c82a31d108 (diff) | |
download | Hyprland-430778293e4ce7c2ae418ff11601d61833b99a67.tar.gz Hyprland-430778293e4ce7c2ae418ff11601d61833b99a67.zip |
plugins: Add an API entry for finding functions by name
Diffstat (limited to 'src/plugins/PluginAPI.cpp')
-rw-r--r-- | src/plugins/PluginAPI.cpp | 72 |
1 files changed, 72 insertions, 0 deletions
diff --git a/src/plugins/PluginAPI.cpp b/src/plugins/PluginAPI.cpp index c878516b..8a7e2565 100644 --- a/src/plugins/PluginAPI.cpp +++ b/src/plugins/PluginAPI.cpp @@ -3,6 +3,10 @@ #include "../debug/HyprCtl.hpp" #include <dlfcn.h> +#if defined(__DragonFly__) || defined(__FreeBSD__) || defined(__NetBSD__) +#include <sys/sysctl.h> +#endif + APICALL bool HyprlandAPI::registerCallbackStatic(HANDLE handle, const std::string& event, HOOK_CALLBACK_FN* fn) { auto* const PLUGIN = g_pPluginSystem->getPluginByHandle(handle); @@ -240,4 +244,72 @@ APICALL bool addNotificationV2(HANDLE handle, const std::unordered_map<std::stri } return true; +} + +APICALL std::vector<SFunctionMatch> HyprlandAPI::findFunctionsByName(HANDLE handle, const std::string& name) { + auto* const PLUGIN = g_pPluginSystem->getPluginByHandle(handle); + + if (!PLUGIN) + return std::vector<SFunctionMatch>{}; + +#if defined(KERN_PROC_PATHNAME) + int mib[] = { + CTL_KERN, +#if defined(__NetBSD__) + KERN_PROC_ARGS, + -1, + KERN_PROC_PATHNAME, +#else + KERN_PROC, + KERN_PROC_PATHNAME, + -1, +#endif + }; + u_int miblen = sizeof(mib) / sizeof(mib[0]); + char exe[PATH_MAX] = ""; + size_t sz = sizeof(exe); + sysctl(mib, miblen, &exe, &sz, NULL, 0); + const auto FPATH = std::filesystem::canonical(exe); +#elif defined(__OpenBSD__) + // Neither KERN_PROC_PATHNAME nor /proc are supported + const auto FPATH = std::filesystem::canonical("/usr/local/bin/Hyprland"); +#else + const auto FPATH = std::filesystem::canonical("/proc/self/exe"); +#endif + + const auto SYMBOLS = execAndGet(("nm -D -j " + FPATH.string()).c_str()); + const auto SYMBOLSDEMANGLED = execAndGet(("nm -D -j --demangle=auto " + FPATH.string()).c_str()); + + auto demangledFromID = [&](size_t id) -> std::string { + size_t pos = 0; + size_t count = 0; + while (count < id) { + pos++; + pos = SYMBOLSDEMANGLED.find('\n', pos); + if (pos == std::string::npos) + return ""; + count++; + } + + return SYMBOLSDEMANGLED.substr(pos, SYMBOLSDEMANGLED.find('\n', pos + 1) - pos); + }; + + std::vector<SFunctionMatch> matches; + + std::istringstream inStream(SYMBOLS); + std::string line; + int lineNo = 0; + while (std::getline(inStream, line)) { + if (line.contains(name)) { + void* address = dlsym(nullptr, line.c_str()); + + if (!address) + continue; + + matches.push_back({address, line, demangledFromID(lineNo)}); + } + lineNo++; + } + + return matches; }
\ No newline at end of file |