Skip to content

Commit

Permalink
[ELFLOADER] Adjusted fetching of symbol
Browse files Browse the repository at this point in the history
  • Loading branch information
ptitSeb committed Aug 19, 2023
1 parent 58b0338 commit 630f42e
Show file tree
Hide file tree
Showing 3 changed files with 126 additions and 17 deletions.
46 changes: 34 additions & 12 deletions src/elfs/elfloader.c
Original file line number Diff line number Diff line change
Expand Up @@ -521,13 +521,24 @@ int RelocateElfREL(lib_t *maplib, lib_t *local_maplib, int bindnow, elfheader_t*
end = offs + sym->st_size;
}*/
// so weak symbol are the one left
if(old_version==version && old_bind==bind && old_symname==symname) {
offs = old_offs;
end = old_end;
if(bind==STB_WEAK) {
if(old_version==version && old_bind==bind && old_symname==symname) {
offs = old_offs;
end = old_end;
} else {
GetGlobalWeakSymbolStartEnd(maplib, symname, &offs, &end, head, version, vername, globdefver, weakdefver);
if(!offs && !end && local_maplib)
GetGlobalWeakSymbolStartEnd(local_maplib, symname, &offs, &end, head, version, vername, globdefver, weakdefver);
}
} else {
GetGlobalSymbolStartEnd(maplib, symname, &offs, &end, head, version, vername, globdefver, weakdefver);
if(!offs && !end && local_maplib)
GetGlobalSymbolStartEnd(local_maplib, symname, &offs, &end, head, version, vername, globdefver, weakdefver);
if(old_version==version && old_bind==bind && old_symname==symname) {
offs = old_offs;
end = old_end;
} else {
GetGlobalSymbolStartEnd(maplib, symname, &offs, &end, head, version, vername, globdefver, weakdefver);
if(!offs && !end && local_maplib)
GetGlobalSymbolStartEnd(local_maplib, symname, &offs, &end, head, version, vername, globdefver, weakdefver);
}
}
}
old_bind = bind;
Expand Down Expand Up @@ -799,13 +810,24 @@ int RelocateElfRELA(lib_t *maplib, lib_t *local_maplib, int bindnow, elfheader_t
end = offs + sym->st_size;
}*/
// so weak symbol are the one left
if(old_version==version && old_bind==bind && old_symname==symname) {
offs = old_offs;
end = old_end;
if(bind==STB_WEAK) {
if(old_version==version && old_bind==bind && old_symname==symname) {
offs = old_offs;
end = old_end;
} else {
GetGlobalWeakSymbolStartEnd(maplib, symname, &offs, &end, head, version, vername, globdefver, weakdefver);
if(!offs && !end && local_maplib)
GetGlobalWeakSymbolStartEnd(local_maplib, symname, &offs, &end, head, version, vername, globdefver, weakdefver);
}
} else {
GetGlobalSymbolStartEnd(maplib, symname, &offs, &end, head, version, vername, globdefver, weakdefver);
if(!offs && !end && local_maplib)
GetGlobalSymbolStartEnd(local_maplib, symname, &offs, &end, head, version, vername, globdefver, weakdefver);
if(old_version==version && old_bind==bind && old_symname==symname) {
offs = old_offs;
end = old_end;
} else {
GetGlobalSymbolStartEnd(maplib, symname, &offs, &end, head, version, vername, globdefver, weakdefver);
if(!offs && !end && local_maplib)
GetGlobalSymbolStartEnd(local_maplib, symname, &offs, &end, head, version, vername, globdefver, weakdefver);
}
}
}
old_bind = bind;
Expand Down
1 change: 1 addition & 0 deletions src/include/librarian.h
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ int isLibLocal(library_t* lib);
uintptr_t FindGlobalSymbol(lib_t *maplib, const char* name, int version, const char* vername);
int GetNoSelfSymbolStartEnd(lib_t *maplib, const char* name, uintptr_t* start, uintptr_t* end, elfheader_t* self, size_t size, int version, const char* vername, const char* globdefver, const char* weakdefver);
int GetGlobalSymbolStartEnd(lib_t *maplib, const char* name, uintptr_t* start, uintptr_t* end, elfheader_t *self, int version, const char* vername, const char* globdefver, const char* weakdefver);
int GetGlobalWeakSymbolStartEnd(lib_t *maplib, const char* name, uintptr_t* start, uintptr_t* end, elfheader_t *self, int version, const char* vername, const char* globdefver, const char* weakdefver);
int GetGlobalNoWeakSymbolStartEnd(lib_t *maplib, const char* name, uintptr_t* start, uintptr_t* end, int version, const char* vername, const char* defver);
int GetLocalSymbolStartEnd(lib_t *maplib, const char* name, uintptr_t* start, uintptr_t* end, elfheader_t *self, int version, const char* vername, const char* globdefver, const char* weakdefver);
elfheader_t* GetGlobalSymbolElf(lib_t *maplib, const char* name, int version, const char* vername);
Expand Down
96 changes: 91 additions & 5 deletions src/librarian/librarian.c
Original file line number Diff line number Diff line change
Expand Up @@ -443,6 +443,94 @@ int GetNoSelfSymbolStartEnd(lib_t *maplib, const char* name, uintptr_t* start, u
return 0;
}
static int GetGlobalSymbolStartEnd_internal(lib_t *maplib, const char* name, uintptr_t* start, uintptr_t* end, elfheader_t* self, int version, const char* vername, const char* globdefver, const char* weakdefver)
{
int weak = 0;
size_t size = 0;
// search in needed libs from preloaded first, in order
if(my_context->preload)
for(int i=0; i<my_context->preload->size; ++i)
if(GetLibGlobalSymbolStartEnd(my_context->preload->libs[i], name, start, end, size, &weak, version, vername, isLocal(self, my_context->preload->libs[i]), globdefver))
if(*start)
return 1;
// search non-weak symbol, from older to newer (first GLOBAL object wins, starting with self)
if(GetSymbolStartEnd(GetMapSymbols(my_context->elfs[0]), name, start, end, version, vername, (my_context->elfs[0]==self || !self)?1:0, globdefver))
if(*start)
return 1;
// TODO: create a temporary map to search lib only 1 time, and in order of needed...
// search in needed libs from neededlibs first, in order
if(my_context->neededlibs)
for(int i=0; i<my_context->neededlibs->size; ++i)
if(GetLibGlobalSymbolStartEnd(my_context->neededlibs->libs[i], name, start, end, size, &weak, version, vername, isLocal(self, my_context->neededlibs->libs[i]), globdefver))
if(*start) {
return 1;
}
// search in global symbols
if(maplib) {
if(self && self!=my_context->elfs[0] && self!=(void*)1)
if(GetSymbolStartEnd(GetMapSymbols(self), name, start, end, version, vername, 1, globdefver))
if(*start)
return 1;
for(int i=0; i<maplib->libsz; ++i) {
if(GetLibGlobalSymbolStartEnd(maplib->libraries[i], name, start, end, size, &weak, version, vername, isLocal(self, maplib->libraries[i]), globdefver))
if(*start) {
return 1;
}
}
}

// check with default version...
int ok = 0;
// GetSymbolStartEnd should not change start/end if symbol is not found
if(GetSymbolStartEnd(GetWeakSymbols(my_context->elfs[0]), name, start, end, version, vername, (my_context->elfs[0]==self || !self)?1:0, weakdefver))
if(*start)
ok = 1;

for(int i=0; i<maplib->libsz; ++i) {
if(GetLibWeakSymbolStartEnd(maplib->libraries[i], name, start, end, size, &weak, version, vername, isLocal(self, maplib->libraries[i]), weakdefver))
if(*start) {
printf_log(LOG_INFO, "\t\t found weak one in %s\n", maplib->libraries[i]->name);
ok = 1;
}
}
// nope, not found
return (ok && *start)?1:0;
}
void** my_GetGTKDisplay();
void** my_GetGthreadsGotInitialized();
int GetGlobalSymbolStartEnd(lib_t *maplib, const char* name, uintptr_t* start, uintptr_t* end, elfheader_t* self, int version, const char* vername, const char* globdefver, const char* weakdefver)
{
if(GetGlobalSymbolStartEnd_internal(maplib, name, start, end, self, version, vername, globdefver, weakdefver)) {
if(start && end && *end==*start) { // object is of 0 sized, try to see an "_END" object of null size
uintptr_t start2, end2;
char* buff = (char*)malloc(strlen(name) + strlen("_END") + 1);
strcpy(buff, name);
strcat(buff, "_END");
if(GetGlobalSymbolStartEnd_internal(maplib, buff, &start2, &end2, self, version, vername, globdefver, weakdefver)) {
if(end2>*end && start2==end2)
*end = end2;
}
box_free(buff);
}
return 1;
}
// some special case symbol, defined inside box86 itself
if(!strcmp(name, "gdk_display")) {
*start = (uintptr_t)my_GetGTKDisplay();
*end = *start+sizeof(void*);
printf_log(LOG_INFO, "Using global gdk_display for gdk-x11 (%p:%p)\n", start, *(void**)start);
return 1;
}
if(!strcmp(name, "g_threads_got_initialized")) {
*start = (uintptr_t)my_GetGthreadsGotInitialized();
*end = *start+sizeof(int);
printf_log(LOG_INFO, "Using global g_threads_got_initialized for gthread2 (%p:%p)\n", start, *(void**)start);
return 1;
}
// not found...
return 0;
}

static int GetGlobalWeakSymbolStartEnd_internal(lib_t *maplib, const char* name, uintptr_t* start, uintptr_t* end, elfheader_t* self, int version, const char* vername, const char* globdefver, const char* weakdefver)
{
int weak = 0;
size_t size = 0;
Expand Down Expand Up @@ -485,17 +573,15 @@ static int GetGlobalSymbolStartEnd_internal(lib_t *maplib, const char* name, uin
// nope, not found
return (ok && *start)?1:0;
}
void** my_GetGTKDisplay();
void** my_GetGthreadsGotInitialized();
int GetGlobalSymbolStartEnd(lib_t *maplib, const char* name, uintptr_t* start, uintptr_t* end, elfheader_t* self, int version, const char* vername, const char* globdefver, const char* weakdefver)
int GetGlobalWeakSymbolStartEnd(lib_t *maplib, const char* name, uintptr_t* start, uintptr_t* end, elfheader_t* self, int version, const char* vername, const char* globdefver, const char* weakdefver)
{
if(GetGlobalSymbolStartEnd_internal(maplib, name, start, end, self, version, vername, globdefver, weakdefver)) {
if(GetGlobalWeakSymbolStartEnd_internal(maplib, name, start, end, self, version, vername, globdefver, weakdefver)) {
if(start && end && *end==*start) { // object is of 0 sized, try to see an "_END" object of null size
uintptr_t start2, end2;
char* buff = (char*)malloc(strlen(name) + strlen("_END") + 1);
strcpy(buff, name);
strcat(buff, "_END");
if(GetGlobalSymbolStartEnd_internal(maplib, buff, &start2, &end2, self, version, vername, globdefver, weakdefver)) {
if(GetGlobalWeakSymbolStartEnd_internal(maplib, buff, &start2, &end2, self, version, vername, globdefver, weakdefver)) {
if(end2>*end && start2==end2)
*end = end2;
}
Expand Down

0 comments on commit 630f42e

Please sign in to comment.