66 lines
1.9 KiB
C
66 lines
1.9 KiB
C
// User-mode smoke test for POSIX dynamic module loading.
|
|
|
|
#include <stdint.h>
|
|
#include <stddef.h>
|
|
#include <string.h>
|
|
|
|
#define RTLD_NOW 0x0002
|
|
#define RTLD_LOCAL 0x0004
|
|
|
|
typedef int64_t ssize_t;
|
|
|
|
extern ssize_t write(int fd, const void* buf, size_t count);
|
|
extern void exit(int status);
|
|
extern void* dlopen(const char* filename, int flags);
|
|
extern void* dlsym(void* handle, const char* symbol);
|
|
extern int dlclose(void* handle);
|
|
extern char* dlerror(void);
|
|
|
|
// Writes one NUL-terminated string to stdout.
|
|
static void print(const char* s) {
|
|
write(1, s, strlen(s));
|
|
}
|
|
|
|
// Terminates the current process.
|
|
static void exit_now(int code) {
|
|
for (;;) exit(code);
|
|
}
|
|
|
|
// Fails the smoke test with one message.
|
|
static void fail(const char* message) {
|
|
print("posix_module_smoke: ");
|
|
print(message);
|
|
print("\n");
|
|
exit_now(1);
|
|
}
|
|
|
|
// Verifies that dlerror reports and clears one loader error.
|
|
static void check_dlerror_clear(void) {
|
|
void* missing = dlsym(0, "definitely_missing");
|
|
if (missing) fail("dlsym unexpectedly succeeded");
|
|
char* first = dlerror();
|
|
if (!first || !first[0]) fail("dlerror did not report the failure");
|
|
char* second = dlerror();
|
|
if (second) fail("dlerror did not clear the failure");
|
|
}
|
|
|
|
// Runs the POSIX dynamic loader smoke test.
|
|
int main(void) {
|
|
print("posix_module_smoke: start\n");
|
|
check_dlerror_clear();
|
|
|
|
void* module = dlopen("syscall.dll", RTLD_NOW | RTLD_LOCAL);
|
|
if (!module) fail("dlopen syscall.dll failed");
|
|
|
|
typedef uint32_t (__stdcall *GETPID_FN)(void);
|
|
GETPID_FN getpid_native = (GETPID_FN)dlsym(module, "SysGetCurrentPid");
|
|
if (!getpid_native) fail("dlsym SysGetCurrentPid failed");
|
|
if (getpid_native() == 0) fail("resolved SysGetCurrentPid returned zero");
|
|
|
|
if (dlclose(module) != 0) fail("dlclose syscall.dll failed");
|
|
|
|
print("posix_module_smoke: PASS\n");
|
|
exit_now(0);
|
|
return 0;
|
|
}
|