summaryrefslogtreecommitdiffstats
path: root/src/modules.cpp
diff options
context:
space:
mode:
authorsalmonik <salmonik@tuta.io>2026-08-30 03:32:59 +0200
committersalmonik <salmonik@tuta.io>2026-08-30 03:32:59 +0200
commitaa096fe6886681d3338573cd3af779b57a5b56ab (patch)
tree14aee66fa1c3c168c140f02006aec246f9bbc23c /src/modules.cpp
downloadhl2h-aa096fe6886681d3338573cd3af779b57a5b56ab.tar.gz
hl2h-aa096fe6886681d3338573cd3af779b57a5b56ab.zip
init
Diffstat (limited to '')
-rw-r--r--src/modules.cpp69
1 files changed, 69 insertions, 0 deletions
diff --git a/src/modules.cpp b/src/modules.cpp
new file mode 100644
index 0000000..d20fe04
--- /dev/null
+++ b/src/modules.cpp
@@ -0,0 +1,69 @@
1// modules.cpp — /proc/self/maps parsing and module discovery
2#include "hl2h.h"
3
4static bool basename_is(const char *path, const char *base) {
5 size_t pl = strlen(path), bl = strlen(base);
6 if (pl < bl || strcmp(path + pl - bl, base) != 0)
7 return false;
8 return pl == bl || path[pl - bl - 1] == '/';
9}
10
11void find_modules() {
12 g_client = Module();
13 g_engine = Module();
14 FILE *f = fopen("/proc/self/maps", "r");
15 if (!f)
16 return;
17 char line[1024];
18 while (fgets(line, sizeof(line), f)) {
19 unsigned long lo, hi;
20 char perms[8];
21 int consumed = 0;
22 if (sscanf(line, "%lx-%lx %7s %*x %*x:%*x %*u%n", &lo, &hi, perms,
23 &consumed) < 3)
24 continue;
25 if (perms[0] == '-' && perms[1] == '-' && perms[2] == '-')
26 continue; // PROT_NONE
27
28 const char *path = line + consumed;
29 while (*path == ' ' || *path == '\t')
30 path++;
31 size_t pl = strlen(path);
32 while (pl && (path[pl - 1] == '\n' || path[pl - 1] == '\r'))
33 pl--;
34
35 Module *m = nullptr;
36 char clean[1024];
37 if (pl && pl < sizeof(clean)) {
38 memcpy(clean, path, pl);
39 clean[pl] = 0;
40 if (basename_is(clean, "client.so"))
41 m = &g_client;
42 else if (basename_is(clean, "engine.so"))
43 m = &g_engine;
44 } else {
45 // anon: absorb only as .bss tail after a file-backed range
46 if (g_client.valid() && g_client.ranges.back().file &&
47 lo == g_client.ranges.back().hi && hi - lo <= 0x1000000)
48 m = &g_client;
49 else if (g_engine.valid() && g_engine.ranges.back().file &&
50 lo == g_engine.ranges.back().hi && hi - lo <= 0x1000000)
51 m = &g_engine;
52 }
53 if (!m)
54 continue;
55 if (m->ranges.empty()) {
56 if (!pl)
57 continue;
58 m->path = clean;
59 }
60 bool file = pl != 0;
61 if (!m->ranges.empty() && lo == m->ranges.back().hi) {
62 m->ranges.back().hi = hi;
63 m->ranges.back().file = m->ranges.back().file && file;
64 } else {
65 m->ranges.push_back({lo, hi, file});
66 }
67 }
68 fclose(f);
69}