ld: resolve: search all images for symbols, rather than just direct links
This commit is contained in:
@@ -27,6 +27,13 @@ static const char *search_paths[] = {
|
||||
static const size_t nr_search_paths
|
||||
= sizeof search_paths / sizeof search_paths[0];
|
||||
|
||||
static struct image_list images = {0};
|
||||
|
||||
struct image_list *global_image_list(void)
|
||||
{
|
||||
return &images;
|
||||
}
|
||||
|
||||
static void report_error(const char *name, int err, const char *msg, ...)
|
||||
{
|
||||
char buf[1024];
|
||||
@@ -35,7 +42,7 @@ static void report_error(const char *name, int err, const char *msg, ...)
|
||||
vsnprintf(buf, sizeof buf, msg, arg);
|
||||
va_end(arg);
|
||||
|
||||
kern_tracef("%s: %s: %s", name, buf, strerror(err));
|
||||
kern_logf("%s: %s: %s", name, buf, strerror(err));
|
||||
}
|
||||
|
||||
static const char *get_image_name(const char *path)
|
||||
@@ -71,7 +78,7 @@ static int find_image(struct elf_image *img)
|
||||
return ENOENT;
|
||||
}
|
||||
|
||||
static int load_images(struct image_list *list)
|
||||
static int load_images(const char *task_name, struct image_list *list)
|
||||
{
|
||||
int status = SUCCESS;
|
||||
struct image_list_iterator it;
|
||||
@@ -91,18 +98,33 @@ static int load_images(struct image_list *list)
|
||||
/* Find the image using its name */
|
||||
status = find_image(image);
|
||||
if (status != SUCCESS) {
|
||||
report_error(
|
||||
task_name,
|
||||
status,
|
||||
"error while loading %s",
|
||||
image->e_leaf.l_name);
|
||||
return status;
|
||||
}
|
||||
case ELF_IMAGE_OPEN:
|
||||
/* parse the image */
|
||||
status = elf_image_parse(image);
|
||||
if (status != SUCCESS) {
|
||||
report_error(
|
||||
task_name,
|
||||
status,
|
||||
"error while loading %s",
|
||||
image->e_leaf.l_name);
|
||||
return status;
|
||||
}
|
||||
case ELF_IMAGE_PARSED:
|
||||
/* load the image */
|
||||
status = elf_image_load(image);
|
||||
if (status != SUCCESS) {
|
||||
report_error(
|
||||
task_name,
|
||||
status,
|
||||
"error while loading %s",
|
||||
image->e_leaf.l_name);
|
||||
return status;
|
||||
}
|
||||
case ELF_IMAGE_LOADED:
|
||||
@@ -114,6 +136,11 @@ static int load_images(struct image_list *list)
|
||||
}
|
||||
|
||||
if (new_dependencies < 0) {
|
||||
report_error(
|
||||
task_name,
|
||||
-new_dependencies,
|
||||
"error while loading %s",
|
||||
image->e_leaf.l_name);
|
||||
return -new_dependencies;
|
||||
}
|
||||
|
||||
@@ -127,7 +154,7 @@ static int load_images(struct image_list *list)
|
||||
return SUCCESS;
|
||||
}
|
||||
|
||||
static int link_images(struct image_list *list)
|
||||
static int link_images(const char *task_name, struct image_list *list)
|
||||
{
|
||||
int status = SUCCESS;
|
||||
struct image_list_iterator it;
|
||||
@@ -143,6 +170,14 @@ static int link_images(struct image_list *list)
|
||||
elf_image_status_to_string(image->e_status));
|
||||
|
||||
status = elf_image_link(image);
|
||||
if (status != SUCCESS) {
|
||||
report_error(
|
||||
task_name,
|
||||
status,
|
||||
"error while loading %s",
|
||||
image->e_leaf.l_name);
|
||||
return status;
|
||||
}
|
||||
|
||||
image_list_iterator_move_next(&it);
|
||||
}
|
||||
@@ -162,7 +197,6 @@ int main(const struct rosetta_bootstrap *bs)
|
||||
const char *task_name = bs->bs_argv[2];
|
||||
const char *image_name = get_image_name(exec_path);
|
||||
|
||||
struct image_list images;
|
||||
image_list_init(&images);
|
||||
|
||||
struct elf_image *exec = NULL;
|
||||
@@ -183,23 +217,13 @@ int main(const struct rosetta_bootstrap *bs)
|
||||
image_name);
|
||||
|
||||
image_list_put(&images, &exec->e_leaf);
|
||||
err = load_images(&images);
|
||||
err = load_images(task_name, &images);
|
||||
if (err != SUCCESS) {
|
||||
report_error(
|
||||
task_name,
|
||||
err,
|
||||
"error while loading %s",
|
||||
exec_path);
|
||||
return -1;
|
||||
}
|
||||
|
||||
err = link_images(&images);
|
||||
err = link_images(task_name, &images);
|
||||
if (err != SUCCESS) {
|
||||
report_error(
|
||||
task_name,
|
||||
err,
|
||||
"error while loading %s",
|
||||
exec_path);
|
||||
return -1;
|
||||
}
|
||||
|
||||
@@ -218,7 +242,12 @@ int main(const struct rosetta_bootstrap *bs)
|
||||
}
|
||||
|
||||
kern_tracef("ld finished");
|
||||
int (*entry)(int, const char **)
|
||||
= (int (*)(int, const char **))exec->e_entry;
|
||||
return entry(bs->bs_argc - 2, bs->bs_argv + 2);
|
||||
struct rosetta_bootstrap exec_bsinfo;
|
||||
memcpy(&exec_bsinfo, bs, sizeof exec_bsinfo);
|
||||
|
||||
exec_bsinfo.bs_argc -= 2;
|
||||
exec_bsinfo.bs_argv += 2;
|
||||
int (*entry)(const struct rosetta_bootstrap *)
|
||||
= (int (*)(const struct rosetta_bootstrap *))exec->e_entry;
|
||||
return entry(&exec_bsinfo);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user