提交 6b3d5e50 编写于 作者: R Rich Felker

error handling in dynamic linking

some of the code is not yet used, and is in preparation for dlopen
which needs to be able to handle failure loading libraries without
terminating the program.
上级 6e53a6ec
...@@ -12,6 +12,7 @@ ...@@ -12,6 +12,7 @@
#include <errno.h> #include <errno.h>
#include <limits.h> #include <limits.h>
#include <elf.h> #include <elf.h>
#include <setjmp.h>
#include "reloc.h" #include "reloc.h"
...@@ -44,11 +45,14 @@ struct dso ...@@ -44,11 +45,14 @@ struct dso
ino_t ino; ino_t ino;
int global; int global;
int relocated; int relocated;
char name[]; char *name;
char buf[];
}; };
static struct dso *head, *tail, *libc; static struct dso *head, *tail, *libc;
static char *env_path, *sys_path; static char *env_path, *sys_path;
static int runtime;
static jmp_buf rtld_fail;
#define AUX_CNT 15 #define AUX_CNT 15
#define DYN_CNT 34 #define DYN_CNT 34
...@@ -115,6 +119,11 @@ static void do_relocs(unsigned char *base, size_t *rel, size_t rel_size, size_t ...@@ -115,6 +119,11 @@ static void do_relocs(unsigned char *base, size_t *rel, size_t rel_size, size_t
name = strings + sym->st_name; name = strings + sym->st_name;
ctx = IS_COPY(type) ? dso->next : dso; ctx = IS_COPY(type) ? dso->next : dso;
sym_val = (size_t)find_sym(ctx, name, IS_PLT(type)); sym_val = (size_t)find_sym(ctx, name, IS_PLT(type));
if (!sym_val && sym->st_info>>4 != STB_WEAK) {
if (runtime) longjmp(rtld_fail, 1);
dprintf(2, "%s: symbol not found\n", name);
_exit(127);
}
sym_size = sym->st_size; sym_size = sym->st_size;
} }
do_single_reloc(reloc_addr, type, sym_val, sym_size, base, rel[2]); do_single_reloc(reloc_addr, type, sym_val, sym_size, base, rel[2]);
...@@ -308,6 +317,7 @@ static struct dso *load_library(const char *name) ...@@ -308,6 +317,7 @@ static struct dso *load_library(const char *name)
p->ino = st.st_ino; p->ino = st.st_ino;
p->global = 1; p->global = 1;
p->refcnt = 1; p->refcnt = 1;
p->name = p->buf;
strcpy(p->name, name); strcpy(p->name, name);
tail->next = p; tail->next = p;
...@@ -323,7 +333,12 @@ static void load_deps(struct dso *p) ...@@ -323,7 +333,12 @@ static void load_deps(struct dso *p)
for (; p; p=p->next) { for (; p; p=p->next) {
for (i=0; p->dynv[i]; i+=2) { for (i=0; p->dynv[i]; i+=2) {
if (p->dynv[i] != DT_NEEDED) continue; if (p->dynv[i] != DT_NEEDED) continue;
load_library(p->strings + p->dynv[i+1]); if (!load_library(p->strings + p->dynv[i+1])) {
if (runtime) longjmp(rtld_fail, 1);
dprintf(2, "%s: %m (needed by %s)\n",
p->strings + p->dynv[i+1], p->name);
_exit(127);
}
} }
} }
} }
...@@ -395,6 +410,7 @@ void *__dynlink(int argc, char **argv, size_t *got) ...@@ -395,6 +410,7 @@ void *__dynlink(int argc, char **argv, size_t *got)
.hashtab = (void *)(app_dyn[DT_HASH]), .hashtab = (void *)(app_dyn[DT_HASH]),
.syms = (void *)(app_dyn[DT_SYMTAB]), .syms = (void *)(app_dyn[DT_SYMTAB]),
.dynv = (void *)(phdr->p_vaddr), .dynv = (void *)(phdr->p_vaddr),
.name = argv[0],
.next = &lib .next = &lib
}; };
...@@ -404,6 +420,7 @@ void *__dynlink(int argc, char **argv, size_t *got) ...@@ -404,6 +420,7 @@ void *__dynlink(int argc, char **argv, size_t *got)
.hashtab = (void *)(aux[AT_BASE]+lib_dyn[DT_HASH]), .hashtab = (void *)(aux[AT_BASE]+lib_dyn[DT_HASH]),
.syms = (void *)(aux[AT_BASE]+lib_dyn[DT_SYMTAB]), .syms = (void *)(aux[AT_BASE]+lib_dyn[DT_SYMTAB]),
.dynv = (void *)(got[0]), .dynv = (void *)(got[0]),
.name = "libc.so",
.relocated = 1 .relocated = 1
}; };
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册