mirror of
https://github.com/hyprwm/Hyprland
synced 2024-11-02 09:46:00 +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 <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);
|
||||
|
||||
|
@ -241,3 +245,71 @@ 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;
|
||||
}
|
|
@ -33,6 +33,12 @@ typedef struct {
|
|||
std::string version;
|
||||
} PLUGIN_DESCRIPTION_INFO;
|
||||
|
||||
struct SFunctionMatch {
|
||||
void* address = nullptr;
|
||||
std::string signature;
|
||||
std::string demangled;
|
||||
};
|
||||
|
||||
#define APICALL extern "C"
|
||||
#define EXPORT __attribute__((visibility("default")))
|
||||
#define REQUIRED
|
||||
|
@ -230,4 +236,13 @@ namespace HyprlandAPI {
|
|||
returns: true on success. False otherwise.
|
||||
*/
|
||||
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