forked from KolibriOS/kolibrios
be1d6256c6
git-svn-id: svn://kolibrios.org@7851 a494cfbc-eb01-0410-851d-a64ba20cac60
92 lines
2.5 KiB
C
92 lines
2.5 KiB
C
#include <kos32sys1.h>
|
||
|
||
#include <stdlib.h>
|
||
#include <string.h>
|
||
#include <dlfcn.h>
|
||
|
||
typedef struct {
|
||
char *name;
|
||
void *ptr;
|
||
} KosExp;
|
||
|
||
typedef struct {
|
||
void **importNames;
|
||
char * libraryName;
|
||
} KosImp;
|
||
|
||
static const char *__error;
|
||
|
||
static int stdcall dll_Load(KosImp *importTable);
|
||
|
||
static int stdcall dll_Load(KosImp *importTableEntry) {
|
||
for (; importTableEntry->importNames; importTableEntry++) {
|
||
char libPath[256] = "/sys/lib/";
|
||
KosExp *exports = NULL;
|
||
void **libImports = importTableEntry->importNames;
|
||
|
||
strcat(libPath, importTableEntry->libraryName);
|
||
if (!(exports = dlopen(libPath, 0))) { return 1; }
|
||
for (; *libImports; libImports++) {
|
||
if (!(*libImports = dlsym(exports, *libImports))) { return 1; }
|
||
}
|
||
}
|
||
return 0;
|
||
}
|
||
|
||
// https://pubs.opengroup.org/onlinepubs/007908799/xsh/dlopen.html
|
||
// Current implementation fully ignores "mode" parameter
|
||
void *dlopen(const char *name, int mode) {
|
||
KosExp *exports = NULL;
|
||
|
||
// загрузить либу сискаллом
|
||
asm volatile ("int $0x40":"=a"(exports):"a"(68), "b"(19), "c"(name));
|
||
if (!exports) {
|
||
char libPath[256] = "/sys/lib/";
|
||
|
||
strcat(libPath, name);
|
||
asm volatile ("int $0x40":"=a"(exports):"a"(68), "b"(19), "c"(libPath));
|
||
if (!exports) {
|
||
__error = "Library not found in \"/sys/lib/\" nor current folder";
|
||
return NULL;
|
||
}
|
||
}
|
||
// Вызвать что-нибудь что начинается с "lib_"
|
||
for (KosExp *export = exports; export->name; export++) {
|
||
if (!memcmp(export->name, "lib_", 4)) {
|
||
asm volatile (
|
||
"call *%4" ::
|
||
"a"(sysmalloc),
|
||
"b"(sysfree),
|
||
"c"(sysrealloc),
|
||
"d"(dll_Load),
|
||
"r"(export->ptr));
|
||
}
|
||
}
|
||
return exports;
|
||
}
|
||
|
||
// https://pubs.opengroup.org/onlinepubs/007908799/xsh/dlsym.html
|
||
void *dlsym(void *handle, const char *name) {
|
||
KosExp *exp = handle;
|
||
|
||
for (; exp->name; exp++) {
|
||
if (!strcmp(exp->name, name)) {
|
||
return exp->ptr;
|
||
}
|
||
}
|
||
__error = "Symbol not found";
|
||
return NULL;
|
||
}
|
||
|
||
// https://pubs.opengroup.org/onlinepubs/007908799/xsh/dlclose.html
|
||
int dlclose(void *handle) {
|
||
return 0;
|
||
}
|
||
|
||
// https://pubs.opengroup.org/onlinepubs/007908799/xsh/dlerror.html
|
||
char *dlerror(void) {
|
||
char *ret = __error ? strdup(__error) : NULL;
|
||
__error = NULL;
|
||
return ret;
|
||
}
|