Assumes we already hold si.lock.
fn findModule(si: *SelfInfo, gpa: Allocator, address: usize) error
fn findModule(si: *SelfInfo, gpa: Allocator, address: usize) error{ MissingDebugInfo, OutOfMemory, Unexpected }!*Module {
for (si.modules.items) |*mod| {
const base = @intFromPtr(mod.entry.DllBase);
if (address >= base and address < base + mod.entry.SizeOfImage) return mod;
}
try si.modules.ensureUnusedCapacity(gpa, 1);
var entry: *LDR.DATA_TABLE_ENTRY = undefined;
switch (windows.ntdll.LdrFindEntryForAddress(@ptrFromInt(address), &entry)) {
.SUCCESS => {},
.DLL_NOT_FOUND => return error.MissingDebugInfo,
else => |status| return windows.unexpectedStatus(status),
}
if (si.notification_cookie == null) {
var notification_cookie: LDR.DLL_NOTIFICATION.COOKIE = undefined;
switch ((try si.getNtdllProc(.LdrRegisterDllNotification))(
.{},
&dllNotification,
si,
¬ification_cookie,
)) {
.SUCCESS => si.notification_cookie = notification_cookie,
else => |status| return windows.unexpectedStatus(status),
}
}
const mod = si.modules.addOneAssumeCapacity();
mod.* = .{ .entry = entry, .name = null, .di = null };
return mod;
}