Handle NEEDED dep failures better in linker
This commit is contained in:
parent
7062734f9d
commit
db1ada51c8
|
@ -163,14 +163,12 @@ static elf_t * open_object(const char * path) {
|
||||||
|
|
||||||
/* If no path (eg. dlopen(NULL)), return the main object (the executable). */
|
/* If no path (eg. dlopen(NULL)), return the main object (the executable). */
|
||||||
if (!path) {
|
if (!path) {
|
||||||
_main_obj->loaded = 1;
|
|
||||||
return _main_obj;
|
return _main_obj;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* If we've already opened a file with this name, return it - don't load things twice. */
|
/* If we've already opened a file with this name, return it - don't load things twice. */
|
||||||
if (hashmap_has(objects_map, (void*)path)) {
|
if (hashmap_has(objects_map, (void*)path)) {
|
||||||
elf_t * object = hashmap_get(objects_map, (void*)path);
|
elf_t * object = hashmap_get(objects_map, (void*)path);
|
||||||
object->loaded = 1;
|
|
||||||
return object;
|
return object;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -592,18 +590,19 @@ static void * do_actual_load(const char * filename, elf_t * lib, int flags) {
|
||||||
node_t * item;
|
node_t * item;
|
||||||
while ((item = list_pop(lib->dependencies))) {
|
while ((item = list_pop(lib->dependencies))) {
|
||||||
|
|
||||||
elf_t * lib = open_object(item->value);
|
elf_t * _lib = open_object(item->value);
|
||||||
|
|
||||||
if (!lib) {
|
if (!_lib) {
|
||||||
/* Missing dependencies are fatal to this process, but
|
/* Missing dependencies are fatal to this process, but
|
||||||
* not to the entire application. */
|
* not to the entire application. */
|
||||||
free((void *)load_addr);
|
free((void *)load_addr);
|
||||||
last_error = "Failed to load a dependency.";
|
last_error = "Failed to load a dependency.";
|
||||||
|
lib->loaded = 0;
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!lib->loaded) {
|
if (!_lib->loaded) {
|
||||||
do_actual_load(item->value, lib, 0);
|
do_actual_load(item->value, _lib, 0);
|
||||||
TRACE_LD("Loaded %s at 0x%x", item->value, lib->base);
|
TRACE_LD("Loaded %s at 0x%x", item->value, lib->base);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -637,6 +636,8 @@ static void * do_actual_load(const char * filename, elf_t * lib, int flags) {
|
||||||
lib->init();
|
lib->init();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
lib->loaded = 1;
|
||||||
|
|
||||||
/* And return an object for the loaded library */
|
/* And return an object for the loaded library */
|
||||||
return (void *)lib;
|
return (void *)lib;
|
||||||
}
|
}
|
||||||
|
@ -656,6 +657,11 @@ static void * dlopen_ld(const char * filename, int flags) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void * ret = do_actual_load(filename, lib, flags);
|
void * ret = do_actual_load(filename, lib, flags);
|
||||||
|
if (!ret) {
|
||||||
|
/* Dependency load failure, remove us from hash */
|
||||||
|
hashmap_remove(objects_map, (void*)filename);
|
||||||
|
}
|
||||||
|
|
||||||
TRACE_LD("Loaded %s at 0x%x", filename, lib->base);
|
TRACE_LD("Loaded %s at 0x%x", filename, lib->base);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
@ -782,6 +788,8 @@ int main(int argc, char * argv[]) {
|
||||||
list_insert(init_libs, lib);
|
list_insert(init_libs, lib);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
lib->loaded = 1;
|
||||||
|
|
||||||
nope:
|
nope:
|
||||||
free(item);
|
free(item);
|
||||||
}
|
}
|
||||||
|
@ -835,6 +843,8 @@ nope:
|
||||||
main_obj->init();
|
main_obj->init();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
main_obj->loaded = 1;
|
||||||
|
|
||||||
/* Move heap start (kind of like a weird sbrk) */
|
/* Move heap start (kind of like a weird sbrk) */
|
||||||
{
|
{
|
||||||
char * args[] = {(char*)end_addr};
|
char * args[] = {(char*)end_addr};
|
||||||
|
|
Loading…
Reference in New Issue