mirror of
https://github.com/hyprwm/Hyprland
synced 2024-11-07 17:05:59 +01:00
plugins: Add an API entry for finding functions by name
This commit is contained in:
parent
de3b00b5ee
commit
430778293e
2 changed files with 87 additions and 0 deletions
|
@ -3,6 +3,10 @@
|
||||||
#include "../debug/HyprCtl.hpp"
|
#include "../debug/HyprCtl.hpp"
|
||||||
#include <dlfcn.h>
|
#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) {
|
APICALL bool HyprlandAPI::registerCallbackStatic(HANDLE handle, const std::string& event, HOOK_CALLBACK_FN* fn) {
|
||||||
auto* const PLUGIN = g_pPluginSystem->getPluginByHandle(handle);
|
auto* const PLUGIN = g_pPluginSystem->getPluginByHandle(handle);
|
||||||
|
|
||||||
|
@ -241,3 +245,71 @@ APICALL bool addNotificationV2(HANDLE handle, const std::unordered_map<std::stri
|
||||||
|
|
||||||
return true;
|
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;
|
||||||
|
}
|
|
@ -33,6 +33,12 @@ typedef struct {
|
||||||
std::string version;
|
std::string version;
|
||||||
} PLUGIN_DESCRIPTION_INFO;
|
} PLUGIN_DESCRIPTION_INFO;
|
||||||
|
|
||||||
|
struct SFunctionMatch {
|
||||||
|
void* address = nullptr;
|
||||||
|
std::string signature;
|
||||||
|
std::string demangled;
|
||||||
|
};
|
||||||
|
|
||||||
#define APICALL extern "C"
|
#define APICALL extern "C"
|
||||||
#define EXPORT __attribute__((visibility("default")))
|
#define EXPORT __attribute__((visibility("default")))
|
||||||
#define REQUIRED
|
#define REQUIRED
|
||||||
|
@ -230,4 +236,13 @@ namespace HyprlandAPI {
|
||||||
returns: true on success. False otherwise.
|
returns: true on success. False otherwise.
|
||||||
*/
|
*/
|
||||||
APICALL bool addNotificationV2(HANDLE handle, const std::unordered_map<std::string, std::any>& data);
|
APICALL bool addNotificationV2(HANDLE handle, const std::unordered_map<std::string, std::any>& data);
|
||||||
|
|
||||||
|
/*
|
||||||
|
Returns a vector of found functions matching the provided name.
|
||||||
|
|
||||||
|
These addresses will not change, and should be made static. Lookups are slow.
|
||||||
|
|
||||||
|
Empty means either none found or handle was invalid
|
||||||
|
*/
|
||||||
|
APICALL std::vector<SFunctionMatch> findFunctionsByName(HANDLE handle, const std::string& name);
|
||||||
};
|
};
|
Loading…
Reference in a new issue