feat: revamp libraries to use ELF shared objects

This commit is contained in:
2026-04-08 18:35:32 +02:00
parent 28d0614511
commit 8a2a86696a
11 changed files with 638 additions and 233 deletions
+19 -15
View File
@@ -23,11 +23,15 @@ namespace Montauk {
// Library entry tracking
struct LibEntry {
char path[128];
uint64_t baseAddr;
uint64_t loadBias;
uint32_t refcount;
bool inUse;
};
static uint64_t GetLibSlotBase(int libSlot) {
return Sched::LIB_BASE + (uint64_t(libSlot) * Sched::LIB_MAX_SIZE);
}
// Per-process library table
static LibEntry g_libTable[MaxProcesses][MaxLibsPerProcess];
@@ -37,7 +41,7 @@ namespace Montauk {
for (int i = 0; i < MaxLibsPerProcess; i++) {
g_libTable[slot][i].inUse = false;
g_libTable[slot][i].refcount = 0;
g_libTable[slot][i].baseAddr = 0;
g_libTable[slot][i].loadBias = 0;
g_libTable[slot][i].path[0] = '\0';
}
}
@@ -77,8 +81,8 @@ namespace Montauk {
}
// Load the library into the process's address space
uint64_t libBase = Sched::ElfLoadLib(path, proc->pml4Phys, libSlot);
if (libBase == 0) {
uint64_t loadBias = Sched::ElfLoadLib(path, proc->pml4Phys, libSlot);
if (loadBias == 0) {
Kt::KernelLogStream(Kt::ERROR, "Lib") << "Failed to load library: " << path;
return 0;
}
@@ -86,10 +90,10 @@ namespace Montauk {
// Store library info
g_libTable[slot][libSlot].inUse = true;
g_libTable[slot][libSlot].refcount = 1;
g_libTable[slot][libSlot].baseAddr = libBase;
g_libTable[slot][libSlot].loadBias = loadBias;
Lib::strncpy(g_libTable[slot][libSlot].path, path, sizeof(LibEntry::path));
Kt::KernelLogStream(Kt::OK, "Lib") << "Loaded library: " << path << " at base " << kcp::hex << libBase << kcp::dec;
Kt::KernelLogStream(Kt::OK, "Lib") << "Loaded library: " << path << " with load bias " << kcp::hex << loadBias << kcp::dec;
return (uint64_t)(libSlot + 1); // Handle = slot + 1 (0 = invalid)
}
@@ -108,7 +112,7 @@ namespace Montauk {
g_libTable[slot][libSlot].refcount--;
if (g_libTable[slot][libSlot].refcount == 0) {
// Actually unload - free the pages
uint64_t libBase = g_libTable[slot][libSlot].baseAddr;
uint64_t libBase = GetLibSlotBase(libSlot);
uint64_t libEnd = libBase + Sched::LIB_MAX_SIZE;
auto* proc = Sched::GetCurrentProcessPtr();
@@ -124,7 +128,7 @@ namespace Montauk {
}
g_libTable[slot][libSlot].inUse = false;
g_libTable[slot][libSlot].baseAddr = 0;
g_libTable[slot][libSlot].loadBias = 0;
g_libTable[slot][libSlot].path[0] = '\0';
}
@@ -133,7 +137,7 @@ namespace Montauk {
// Resolve a symbol in a loaded library.
// handle = library handle from LoadLib
// symbolOffset = offset of the symbol from the library's base address
// symbolOffset = ELF symbol value from the library's symbol table
// Returns the virtual address of the symbol, or 0 if not found.
static uint64_t Sys_DLSym(uint64_t handle, uint64_t symbolOffset) {
int slot = GetCurrentSlot();
@@ -144,11 +148,11 @@ namespace Montauk {
if (!g_libTable[slot][libSlot].inUse) return 0;
uint64_t libBase = g_libTable[slot][libSlot].baseAddr;
return libBase + symbolOffset;
uint64_t loadBias = g_libTable[slot][libSlot].loadBias;
return loadBias + symbolOffset;
}
// Get library base address (for userspace symbol resolution)
// Get library relocation base / load bias (for userspace symbol resolution)
static uint64_t Sys_GetLibBase(uint64_t handle) {
int slot = GetCurrentSlot();
if (slot < 0) return 0;
@@ -158,7 +162,7 @@ namespace Montauk {
if (!g_libTable[slot][libSlot].inUse) return 0;
return g_libTable[slot][libSlot].baseAddr;
return g_libTable[slot][libSlot].loadBias;
}
// Cleanup library table for a process slot
@@ -171,7 +175,7 @@ namespace Montauk {
// Unmap all libraries for this process
for (int i = 0; i < MaxLibsPerProcess; i++) {
if (g_libTable[slot][i].inUse) {
uint64_t libBase = g_libTable[slot][i].baseAddr;
uint64_t libBase = GetLibSlotBase(i);
uint64_t libEnd = libBase + Sched::LIB_MAX_SIZE;
for (uint64_t va = libBase; va < libEnd; va += 0x1000) {
@@ -184,7 +188,7 @@ namespace Montauk {
g_libTable[slot][i].inUse = false;
g_libTable[slot][i].refcount = 0;
g_libTable[slot][i].baseAddr = 0;
g_libTable[slot][i].loadBias = 0;
}
}
}