implement generic I/O async request object to replace file-specific async requests, refactor lwIP network stack to dispatch requests through IRPs with cancellation support, add cancellation polling to lwIP accept and receive operations using LwipSocketWaitRecvNetbuf and LwipSocketWaitAccept, introduce NetSubmitSocketIrp for routing socket operations via device IRPs, track network IRP statistics with SYS_NET_IRP_STATS, add process module lock spinlock and reference counting for process modules, implement dynamic module loading and unloading via user module handles, add POSIX dynamic loader APIs including dlopen, dlsym, dlerror, and dlclose, introduce PosixStart entry point for posix applications, add new native smoke tests for net IRPs.

This commit is contained in:
maksw committed 2026-06-27 10:37:53 +02:00
1 parent ed3d065abd
commit 1f5477cf66
32 files changed
+3713 -551

No files matched your search

+118
View File
@@ -0,0 +1,118 @@
// POSIX compatibility support for dynamic module loading.
#include <stdint.h>
#include <string.h>
#include <ntlite/syscall.h>
#include "posix.h"
#include "posix_path.h"
#include "posix_fd.h"
static char gDlError[160];
static int gDlErrorPending;
// Clears the process-local dynamic-loader error string.
static void DlClearError(void) {
gDlError[0] = '\0';
gDlErrorPending = 0;
}
// Stores one process-local dynamic-loader error string.
static void DlSetError(const char* message) {
if (!message) message = "dynamic loader error";
strncpy(gDlError, message, sizeof(gDlError) - 1);
gDlError[sizeof(gDlError) - 1] = '\0';
gDlErrorPending = 1;
}
// Converts one native loader status to errno and a dlerror message.
static void DlSetStatusError(const char* operation, uint32_t status) {
(void)status;
errno = PosixStatusToErrno(status);
DlSetError(operation);
}
// Loads one DLL-like user module through the native module loader.
__declspec(dllexport) void* dlopen(const char* filename, int flags) {
(void)flags;
DlClearError();
if (!filename || !filename[0]) {
errno = EINVAL;
DlSetError("dlopen requires a module path");
return 0;
}
char native[512];
const char* path = PosixTranslatePath(filename, native, sizeof(native));
if (!path || strcmp(path, SYNTH_DEVNULL) == 0 || strcmp(path, SYNTH_DEVZERO) == 0) {
errno = EINVAL;
DlSetError("dlopen path is not a loadable module");
return 0;
}
uint32_t handle = 0;
SYS_LOAD_MODULE_REQUEST req;
memset(&req, 0, sizeof(req));
req.Size = sizeof(req);
req.Path = SysSvFromCstr(path);
req.ModuleHandleOut = &handle;
uint32_t status = SysLoadModule(&req);
if (status != STATUS_SUCCESS || handle == 0) {
DlSetStatusError("dlopen failed", status);
return 0;
}
return (void*)(uintptr_t)handle;
}
// Resolves one named export from a native module handle.
__declspec(dllexport) void* dlsym(void* handle, const char* symbol) {
DlClearError();
if (!handle || !symbol || !symbol[0]) {
errno = EINVAL;
DlSetError("dlsym requires a module handle and symbol name");
return 0;
}
uintptr_t address = 0;
SYS_GET_MODULE_EXPORT_REQUEST req;
memset(&req, 0, sizeof(req));
req.Size = sizeof(req);
req.ModuleHandle = (uint32_t)(uintptr_t)handle;
req.Name = SysSvFromCstr(symbol);
req.AddressOut = &address;
uint32_t status = SysGetModuleExport(&req);
if (status != STATUS_SUCCESS || address == 0) {
DlSetStatusError("dlsym failed", status);
return 0;
}
return (void*)address;
}
// Releases one module handle returned by dlopen.
__declspec(dllexport) int dlclose(void* handle) {
DlClearError();
if (!handle) {
errno = EINVAL;
DlSetError("dlclose requires a module handle");
return -1;
}
uint32_t status = SysUnloadModule((uint32_t)(uintptr_t)handle);
if (status != STATUS_SUCCESS) {
DlSetStatusError("dlclose failed", status);
return -1;
}
return 0;
}
// Returns and clears the most recent dynamic-loader error string.
__declspec(dllexport) char* dlerror(void) {
if (!gDlErrorPending || !gDlError[0]) return 0;
gDlErrorPending = 0;
return gDlError;
}