Skip to content

Commit

Permalink
Smol fixes
Browse files Browse the repository at this point in the history
  • Loading branch information
kynex7510 committed Nov 9, 2024
1 parent 294c8e4 commit c801184
Show file tree
Hide file tree
Showing 4 changed files with 18 additions and 11 deletions.
10 changes: 6 additions & 4 deletions Source/API.c
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,10 @@ void* dlopen(const char* path, int flags) { return ctrdlOpen(path, flags, NULL,
const char* dlerror(void) { return ctrdl_getErrorAsString(ctrdl_getLastError()); }

int dlclose(void* handle) {
// TODO: the pseudo handle should be "freed"?
return !ctrdl_unlockHandle((CTRDLHandle*)handle);
if (handle != CTRDL_MAIN_HANDLE)
return !ctrdl_unlockHandle((CTRDLHandle*)handle);

return 0;
}

void* dlsym(void* handle, const char* name) {
Expand Down Expand Up @@ -145,7 +147,7 @@ void* ctrdlOpen(const char* path, int flags, CTRDLResolverFn resolver, void* res
}

void* ctrdlFOpen(FILE* f, int flags, CTRDLResolverFn resolver, void* resolverUserData) {
if (!f || !ctrdl_checkFlags(flags)) {
if (!f || !ctrdl_checkFlags(flags) || (flags & RTLD_NOLOAD)) {
ctrdl_setLastError(Err_InvalidParam);
return NULL;
}
Expand All @@ -156,7 +158,7 @@ void* ctrdlFOpen(FILE* f, int flags, CTRDLResolverFn resolver, void* resolverUse
}

void* ctrdlMap(const void* buffer, size_t size, int flags, CTRDLResolverFn resolver, void* resolverUserData) {
if (!buffer || !size || !ctrdl_checkFlags(flags)) {
if (!buffer || !size || !ctrdl_checkFlags(flags) || (flags & RTLD_NOLOAD)) {
ctrdl_setLastError(Err_InvalidParam);
return NULL;
}
Expand Down
4 changes: 1 addition & 3 deletions Source/Handle.h
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,6 @@

#define CTRDL_MAIN_HANDLE (CTRDLHandle*)(0x75107510)

typedef void(*InitFiniFn)();

typedef struct {
char* path; // Object path.
u32 base; // Mirror address of mapped region.
Expand All @@ -20,7 +18,7 @@ typedef struct {
size_t refc; // Object refcount.
size_t flags; // Object flags.
void* deps[CTRDL_MAX_DEPS]; // Object dependencies.
InitFiniFn* finiArray; // Fini array address.
Elf32_Addr* finiArray; // Fini array address.
size_t numFiniEntries; // Number of fini functions.
size_t numSymBuckets; // Number of symbol buckets;
Elf32_Word* symBuckets; // Symbol buckets.
Expand Down
12 changes: 8 additions & 4 deletions Source/Loader.c
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,11 @@ static bool ctrdl_loadDeps(LdrData* ldrData, bool local) {
return true;
}

static CTRL_INLINE void ctrdl_callInitFini(Elf32_Addr addr) {
if (addr != 0 && addr != -1)
((void(*)(void))(addr))();
}

static bool ctrdl_mapObject(LdrData* ldrData) {
CTRDLHandle* handle = ldrData->handle;

Expand Down Expand Up @@ -247,7 +252,7 @@ static bool ctrdl_mapObject(LdrData* ldrData) {
const Elf32_Addr* initArray = (const Elf32_Addr*)(handle->base + initEntry.d_un.d_ptr);
const size_t numEntries = initEntrySize.d_un.d_val / sizeof(Elf32_Addr);
for (size_t i = 0; i < numEntries; ++i)
((InitFiniFn)(initArray[i]))();
ctrdl_callInitFini(initArray[i]);
}

// Fill additional data.
Expand All @@ -258,7 +263,7 @@ static bool ctrdl_mapObject(LdrData* ldrData) {
const bool hasFiniSz = ctrdl_getELFDynEntryWithTag(&ldrData->elf, DT_FINI_ARRAYSZ, &finiEntrySize);

if (hasFiniArr && hasFiniSz) {
handle->finiArray = (InitFiniFn*)(handle->base + finiEntry.d_un.d_ptr);
handle->finiArray = (Elf32_Addr*)(handle->base + finiEntry.d_un.d_ptr);
handle->numFiniEntries = finiEntrySize.d_un.d_val / sizeof(Elf32_Addr);
}

Expand Down Expand Up @@ -300,10 +305,9 @@ CTRDLHandle* ctrdl_loadObject(const char* name, int flags, CTRDLStream* stream,

bool ctrdl_unloadObject(CTRDLHandle* handle) {
// Run finalizers.
// TODO: reverse order??
if (handle->finiArray) {
for (size_t i = 0; i < handle->numFiniEntries; ++i)
handle->finiArray[i]();
ctrdl_callInitFini(handle->finiArray[handle->numFiniEntries - i - 1]);
}

// Unmap segments.
Expand Down
3 changes: 3 additions & 0 deletions Tests/Libs/Interop.c
Original file line number Diff line number Diff line change
Expand Up @@ -24,4 +24,7 @@ extern void interop(const char* msg) {
printf("Program says: %s\n", msg);

ctrdlFreeInfo(&info);

if (dlclose(handle))
printf("ERROR: %s.\n", dlerror());
}

0 comments on commit c801184

Please sign in to comment.