mirror of
https://github.com/ptitSeb/box64.git
synced 2026-11-07 09:26:11 -10:00
Expand special names in DT_NEEDED names too (for #4682)
This commit is contained in:
1 parent
70cdfdb2c2
commit
37f5e4b7b0
4 files changed
+116
-71
No files matched your search
+83
-71
@@ -1138,6 +1138,81 @@ $PLATFORM – Expands to the processor type of the current machine (see the
|
||||
uname(1) man page description of the -i option). For more details of this token
|
||||
expansion, see “System Specific Shared Objects”
|
||||
*/
|
||||
char* ExpandNeededLibs(elfheader_t* h, char* rpath)
|
||||
{
|
||||
if(!rpath || !h) return rpath;
|
||||
char* rpathref = rpath;
|
||||
while(strstr(rpath, "$$ORIGIN")) {
|
||||
char* origin = box_strdup(h->path);
|
||||
char* p = strrchr(origin, '/');
|
||||
if(p) *p = '\0'; // remove file name to have only full path, without last '/'
|
||||
char* tmp = (char*)box_calloc(1, strlen(rpath)-strlen("$$ORIGIN")+strlen(origin)+1);
|
||||
p = strstr(rpath, "$$ORIGIN");
|
||||
memcpy(tmp, rpath, p-rpath);
|
||||
strcat(tmp, origin);
|
||||
strcat(tmp, p+strlen("$$ORIGIN"));
|
||||
if(rpath!=rpathref)
|
||||
box_free(rpath);
|
||||
rpath = tmp;
|
||||
box_free(origin);
|
||||
}
|
||||
while(strstr(rpath, "$ORIGIN")) {
|
||||
char* origin = box_strdup(h->path);
|
||||
char* p = strrchr(origin, '/');
|
||||
if(p) *p = '\0'; // remove file name to have only full path, without last '/'
|
||||
char* tmp = (char*)box_calloc(1, strlen(rpath)-strlen("$ORIGIN")+strlen(origin)+1);
|
||||
p = strstr(rpath, "$ORIGIN");
|
||||
memcpy(tmp, rpath, p-rpath);
|
||||
strcat(tmp, origin);
|
||||
strcat(tmp, p+strlen("$ORIGIN"));
|
||||
if(rpath!=rpathref)
|
||||
box_free(rpath);
|
||||
rpath = tmp;
|
||||
box_free(origin);
|
||||
}
|
||||
while(strstr(rpath, "${ORIGIN}")) {
|
||||
char* origin = box_strdup(h->path);
|
||||
char* p = strrchr(origin, '/');
|
||||
if(p) *p = '\0'; // remove file name to have only full path, without last '/'
|
||||
char* tmp = (char*)box_calloc(1, strlen(rpath)-strlen("${ORIGIN}")+strlen(origin)+1);
|
||||
p = strstr(rpath, "${ORIGIN}");
|
||||
memcpy(tmp, rpath, p-rpath);
|
||||
strcat(tmp, origin);
|
||||
strcat(tmp, p+strlen("${ORIGIN}"));
|
||||
if(rpath!=rpathref)
|
||||
box_free(rpath);
|
||||
rpath = tmp;
|
||||
box_free(origin);
|
||||
if(!FileExist(rpath, 0) && strstr(rpath, "/../../")) {
|
||||
tmp = (char*)box_calloc(1, strlen(rpath)+1);
|
||||
strcpy(tmp, rpath);
|
||||
// check if one "/.." could be removed for the folder to exist
|
||||
char* p = strstr(tmp, "/../../");
|
||||
memmove(p, p+3, strlen(p+3)+1);
|
||||
if(FileExist(tmp, 0)) {
|
||||
if(rpath!=rpathref)
|
||||
box_free(rpath);
|
||||
rpath = tmp;
|
||||
} else
|
||||
box_free(tmp);
|
||||
}
|
||||
}
|
||||
while(strstr(rpath, "${PLATFORM}")) {
|
||||
char* platform = box_strdup("x86_64");
|
||||
char* p = strrchr(platform, '/');
|
||||
if(p) *p = '\0'; // remove file name to have only full path, without last '/'
|
||||
char* tmp = (char*)box_calloc(1, strlen(rpath)-strlen("${PLATFORM}")+strlen(platform)+1);
|
||||
p = strstr(rpath, "${PLATFORM}");
|
||||
memcpy(tmp, rpath, p-rpath);
|
||||
strcat(tmp, platform);
|
||||
strcat(tmp, p+strlen("${PLATFORM}"));
|
||||
if(rpath!=rpathref)
|
||||
box_free(rpath);
|
||||
rpath = tmp;
|
||||
box_free(platform);
|
||||
}
|
||||
return rpath;
|
||||
}
|
||||
int LoadNeededLibs(elfheader_t* h, lib_t *maplib, int local, int bindnow, int deepbind, box64context_t *box64, x64emu_t* emu)
|
||||
{
|
||||
if(h->needed) // already done
|
||||
@@ -1150,75 +1225,7 @@ int LoadNeededLibs(elfheader_t* h, lib_t *maplib, int local, int bindnow, int de
|
||||
if(tag==DT_RPATH || tag==DT_RUNPATH) {
|
||||
char *rpathref = h->DynStrTab+h->delta+(box64_is32bits?h->Dynamic._32[i].d_un.d_val:h->Dynamic._64[i].d_un.d_val);
|
||||
char* rpath = rpathref;
|
||||
while(strstr(rpath, "$$ORIGIN")) {
|
||||
char* origin = box_strdup(h->path);
|
||||
char* p = strrchr(origin, '/');
|
||||
if(p) *p = '\0'; // remove file name to have only full path, without last '/'
|
||||
char* tmp = (char*)box_calloc(1, strlen(rpath)-strlen("$$ORIGIN")+strlen(origin)+1);
|
||||
p = strstr(rpath, "$$ORIGIN");
|
||||
memcpy(tmp, rpath, p-rpath);
|
||||
strcat(tmp, origin);
|
||||
strcat(tmp, p+strlen("$$ORIGIN"));
|
||||
if(rpath!=rpathref)
|
||||
box_free(rpath);
|
||||
rpath = tmp;
|
||||
box_free(origin);
|
||||
}
|
||||
while(strstr(rpath, "$ORIGIN")) {
|
||||
char* origin = box_strdup(h->path);
|
||||
char* p = strrchr(origin, '/');
|
||||
if(p) *p = '\0'; // remove file name to have only full path, without last '/'
|
||||
char* tmp = (char*)box_calloc(1, strlen(rpath)-strlen("$ORIGIN")+strlen(origin)+1);
|
||||
p = strstr(rpath, "$ORIGIN");
|
||||
memcpy(tmp, rpath, p-rpath);
|
||||
strcat(tmp, origin);
|
||||
strcat(tmp, p+strlen("$ORIGIN"));
|
||||
if(rpath!=rpathref)
|
||||
box_free(rpath);
|
||||
rpath = tmp;
|
||||
box_free(origin);
|
||||
}
|
||||
while(strstr(rpath, "${ORIGIN}")) {
|
||||
char* origin = box_strdup(h->path);
|
||||
char* p = strrchr(origin, '/');
|
||||
if(p) *p = '\0'; // remove file name to have only full path, without last '/'
|
||||
char* tmp = (char*)box_calloc(1, strlen(rpath)-strlen("${ORIGIN}")+strlen(origin)+1);
|
||||
p = strstr(rpath, "${ORIGIN}");
|
||||
memcpy(tmp, rpath, p-rpath);
|
||||
strcat(tmp, origin);
|
||||
strcat(tmp, p+strlen("${ORIGIN}"));
|
||||
if(rpath!=rpathref)
|
||||
box_free(rpath);
|
||||
rpath = tmp;
|
||||
box_free(origin);
|
||||
if(!FileExist(rpath, 0) && strstr(rpath, "/../../")) {
|
||||
tmp = (char*)box_calloc(1, strlen(rpath)+1);
|
||||
strcpy(tmp, rpath);
|
||||
// check if one "/.." could be removed for the folder to exist
|
||||
char* p = strstr(tmp, "/../../");
|
||||
memmove(p, p+3, strlen(p+3)+1);
|
||||
if(FileExist(tmp, 0)) {
|
||||
if(rpath!=rpathref)
|
||||
box_free(rpath);
|
||||
rpath = tmp;
|
||||
} else
|
||||
box_free(tmp);
|
||||
}
|
||||
}
|
||||
while(strstr(rpath, "${PLATFORM}")) {
|
||||
char* platform = box_strdup("x86_64");
|
||||
char* p = strrchr(platform, '/');
|
||||
if(p) *p = '\0'; // remove file name to have only full path, without last '/'
|
||||
char* tmp = (char*)box_calloc(1, strlen(rpath)-strlen("${PLATFORM}")+strlen(platform)+1);
|
||||
p = strstr(rpath, "${PLATFORM}");
|
||||
memcpy(tmp, rpath, p-rpath);
|
||||
strcat(tmp, platform);
|
||||
strcat(tmp, p+strlen("${PLATFORM}"));
|
||||
if(rpath!=rpathref)
|
||||
box_free(rpath);
|
||||
rpath = tmp;
|
||||
box_free(platform);
|
||||
}
|
||||
rpath = ExpandNeededLibs(h, rpath);
|
||||
if(strchr(rpath, '$')) {
|
||||
printf_log(LOG_INFO, "Warning, RPATH with $ variable not supported yet (%s)\n", rpath);
|
||||
} else {
|
||||
@@ -1255,8 +1262,13 @@ int LoadNeededLibs(elfheader_t* h, lib_t *maplib, int local, int bindnow, int de
|
||||
my_context->neededlibs = h->needed;
|
||||
int j=0;
|
||||
for (size_t i=0; i<h->numDynamic; ++i)
|
||||
if((box64_is32bits?h->Dynamic._32[i].d_tag:h->Dynamic._64[i].d_tag)==DT_NEEDED)
|
||||
h->needed->names[j++] = h->DynStrTab+h->delta+(box64_is32bits?h->Dynamic._32[i].d_un.d_val:h->Dynamic._64[i].d_un.d_val);
|
||||
if((box64_is32bits?h->Dynamic._32[i].d_tag:h->Dynamic._64[i].d_tag)==DT_NEEDED) {
|
||||
char* path = h->DynStrTab+h->delta+(box64_is32bits?h->Dynamic._32[i].d_un.d_val:h->Dynamic._64[i].d_un.d_val);
|
||||
char* newpath = ExpandNeededLibs(h, path);
|
||||
if(path!=newpath)
|
||||
path = add1nsname(h->needed, newpath);
|
||||
h->needed->names[j++] = path;
|
||||
}
|
||||
#ifndef ANDROID
|
||||
if(box64_is32bits && strstr(h->name, "lsteamclient.dll.so"))
|
||||
h->needed->names[j++] = "libgcc_s.so.1";
|
||||
|
||||
@@ -79,6 +79,8 @@ typedef struct needed_libs_s {
|
||||
library_t** libs;
|
||||
path_collection_t* rpath;
|
||||
int nb_done;
|
||||
char** nonstaticnames;
|
||||
int ns_size;
|
||||
} needed_libs_t;
|
||||
|
||||
void free_neededlib(needed_libs_t* needed);
|
||||
@@ -88,6 +90,7 @@ void add1_neededlib(needed_libs_t* needed);
|
||||
void add1lib_neededlib(needed_libs_t* needed, library_t* lib, const char* name);
|
||||
void add1lib_neededlib_name(needed_libs_t* needed, library_t* lib, const char* name);
|
||||
void add1libref_neededlib(needed_libs_t* needed, library_t* lib);
|
||||
char* add1nsname(needed_libs_t* needed, char* nsname);
|
||||
|
||||
typedef struct base_segment_s {
|
||||
uintptr_t base;
|
||||
|
||||
@@ -54,6 +54,7 @@ uintptr_t GetEntryPoint(lib_t* maplib, elfheader_t* h);
|
||||
uintptr_t GetLastByte(elfheader_t* h);
|
||||
void AddSymbols(lib_t *maplib, elfheader_t* h);
|
||||
int NeededLibs(elfheader_t* h);
|
||||
char* ExpandNeededLibs(elfheader_t* h, char* rpath);
|
||||
int LoadNeededLibs(elfheader_t* h, lib_t *maplib, int local, int bindnow, int deepbind, box64context_t *box64, x64emu_t* emu);
|
||||
needed_libs_t* GetELfNeededLibs(elfheader_t* h);
|
||||
uintptr_t GetElfInit(elfheader_t* h);
|
||||
|
||||
@@ -1323,6 +1323,13 @@ void free_neededlib(needed_libs_t* needed)
|
||||
FreeCollection(needed->rpath);
|
||||
box_free(needed->rpath);
|
||||
}
|
||||
if(needed->nonstaticnames) {
|
||||
for(int i=0; i<needed->ns_size; ++i)
|
||||
box_free(needed->nonstaticnames[i]);
|
||||
box_free(needed->nonstaticnames);
|
||||
needed->ns_size = 0;
|
||||
needed->nonstaticnames = NULL;
|
||||
}
|
||||
box_free(needed);
|
||||
}
|
||||
void add1_neededlib(needed_libs_t* needed)
|
||||
@@ -1406,8 +1413,30 @@ needed_libs_t* copy_neededlib(needed_libs_t* needed)
|
||||
ret->names = (char**)box_calloc(ret->cap, sizeof(char*));
|
||||
memcpy(ret->libs, needed->libs, ret->size*sizeof(library_t*));
|
||||
memcpy(ret->names, needed->names, ret->size*sizeof(char*));
|
||||
if(needed->nonstaticnames) {
|
||||
ret->ns_size = needed->ns_size;
|
||||
ret->nonstaticnames = (char**)box_malloc(ret->ns_size*sizeof(char*));
|
||||
for(int i=0; i<ret->ns_size; ++i)
|
||||
ret->nonstaticnames[i] = box_strdup(needed->nonstaticnames[i]);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
char* add1nsname(needed_libs_t* needed, char* nsname)
|
||||
{
|
||||
if(!needed->ns_size) {
|
||||
needed->ns_size = 1;
|
||||
needed->nonstaticnames = (char**)box_malloc(needed->ns_size*sizeof(char*));
|
||||
needed->nonstaticnames[0] = nsname;
|
||||
return needed->nonstaticnames[0];
|
||||
}
|
||||
for(int i=0; i<needed->ns_size; ++i)
|
||||
if(!strcmp(needed->nonstaticnames[i], nsname))
|
||||
return needed->nonstaticnames[i];
|
||||
int i = needed->ns_size++;
|
||||
needed->nonstaticnames = (char**)box_realloc(needed->nonstaticnames, (i+1)*sizeof(char*));
|
||||
needed->nonstaticnames[i] = nsname;
|
||||
return needed->nonstaticnames[i];
|
||||
}
|
||||
|
||||
void setNeededLibs(library_t* lib, int n, ...)
|
||||
{
|
||||
|
||||
Reference in new issue
Block a user