projects
/
musl
/ blobdiff
commit
grep
author
committer
pickaxe
?
search:
re
summary
|
shortlog
|
log
|
commit
|
commitdiff
|
tree
raw
|
inline
| side by side
PIE support for x86_64 (untested)
[musl]
/
src
/
ldso
/
dynlink.c
diff --git
a/src/ldso/dynlink.c
b/src/ldso/dynlink.c
index
e0013ec
..
3f3316a
100644
(file)
--- a/
src/ldso/dynlink.c
+++ b/
src/ldso/dynlink.c
@@
-18,6
+18,7
@@
#include <dlfcn.h>
static int errflag;
#include <dlfcn.h>
static int errflag;
+static char errbuf[128];
#ifdef __PIC__
#ifdef __PIC__
@@
-37,15
+38,24
@@
typedef Elf64_Sym Sym;
#define R_SYM(x) ((x)>>32)
#endif
#define R_SYM(x) ((x)>>32)
#endif
-struct dso
-{
+struct debug {
+ int ver;
+ void *head;
+ void (*bp)(void);
+ int state;
+ void *base;
+};
+
+struct dso {
+ unsigned char *base;
+ char *name;
+ size_t *dynv;
struct dso *next, *prev;
struct dso *next, *prev;
+
int refcnt;
int refcnt;
- size_t *dynv;
Sym *syms;
uint32_t *hashtab;
char *strings;
Sym *syms;
uint32_t *hashtab;
char *strings;
- unsigned char *base;
unsigned char *map;
size_t map_len;
dev_t dev;
unsigned char *map;
size_t map_len;
dev_t dev;
@@
-54,16
+64,22
@@
struct dso
char relocated;
char constructed;
struct dso **deps;
char relocated;
char constructed;
struct dso **deps;
- char *name;
char buf[];
};
char buf[];
};
+struct __pthread;
+struct __pthread *__pthread_self_init(void);
+
static struct dso *head, *tail, *libc;
static char *env_path, *sys_path, *r_path;
static int rtld_used;
static struct dso *head, *tail, *libc;
static char *env_path, *sys_path, *r_path;
static int rtld_used;
+static int ssp_used;
static int runtime;
static jmp_buf rtld_fail;
static pthread_rwlock_t lock;
static int runtime;
static jmp_buf rtld_fail;
static pthread_rwlock_t lock;
+static struct debug debug;
+
+struct debug *_dl_debug_addr = &debug;
#define AUX_CNT 24
#define DYN_CNT 34
#define AUX_CNT 24
#define DYN_CNT 34
@@
-107,6
+123,7
@@
static void *find_sym(struct dso *dso, const char *s, int need_def)
void *def = 0;
if (h==0x6b366be && !strcmp(s, "dlopen")) rtld_used = 1;
if (h==0x6b3afd && !strcmp(s, "dlsym")) rtld_used = 1;
void *def = 0;
if (h==0x6b366be && !strcmp(s, "dlopen")) rtld_used = 1;
if (h==0x6b3afd && !strcmp(s, "dlsym")) rtld_used = 1;
+ if (h==0x595a4cc && !strcmp(s, "__stack_chk_fail")) ssp_used = 1;
for (; dso; dso=dso->next) {
Sym *sym;
if (!dso->global) continue;
for (; dso; dso=dso->next) {
Sym *sym;
if (!dso->global) continue;
@@
-142,8
+159,11
@@
static void do_relocs(unsigned char *base, size_t *rel, size_t rel_size, size_t
ctx = IS_COPY(type) ? dso->next : dso;
sym_val = (size_t)find_sym(ctx, name, IS_PLT(type));
if (!sym_val && sym->st_info>>4 != STB_WEAK) {
ctx = IS_COPY(type) ? dso->next : dso;
sym_val = (size_t)find_sym(ctx, name, IS_PLT(type));
if (!sym_val && sym->st_info>>4 != STB_WEAK) {
+ snprintf(errbuf, sizeof errbuf,
+ "Error relocating %s: %s: symbol not found",
+ dso->name, name);
if (runtime) longjmp(rtld_fail, 1);
if (runtime) longjmp(rtld_fail, 1);
- dprintf(2, "%s
: symbol not found\n", name
);
+ dprintf(2, "%s
\n", errbuf
);
_exit(127);
}
sym_size = sym->st_size;
_exit(127);
}
sym_size = sym->st_size;
@@
-405,9
+425,11
@@
static void load_deps(struct dso *p)
if (p->dynv[i] != DT_NEEDED) continue;
dep = load_library(p->strings + p->dynv[i+1]);
if (!dep) {
if (p->dynv[i] != DT_NEEDED) continue;
dep = load_library(p->strings + p->dynv[i+1]);
if (!dep) {
- if (runtime) longjmp(rtld_fail, 1);
-
dprintf(2, "%s: %m (needed by %s)\n
",
+ snprintf(errbuf, sizeof errbuf,
+
"Error loading shared library %s: %m (needed by %s)
",
p->strings + p->dynv[i+1], p->name);
p->strings + p->dynv[i+1], p->name);
+ if (runtime) longjmp(rtld_fail, 1);
+ dprintf(2, "%s\n", errbuf);
_exit(127);
}
if (runtime) {
_exit(127);
}
if (runtime) {
@@
-489,6
+511,10
@@
static void do_init_fini(struct dso *p)
}
}
}
}
+void _dl_debug_state(void)
+{
+}
+
void *__dynlink(int argc, char **argv)
{
size_t *auxv, aux[AUX_CNT] = {0};
void *__dynlink(int argc, char **argv)
{
size_t *auxv, aux[AUX_CNT] = {0};
@@
-597,6
+623,16
@@
void *__dynlink(int argc, char **argv)
* all memory used by the dynamic linker. */
runtime = 1;
* all memory used by the dynamic linker. */
runtime = 1;
+ for (i=0; app->dynv[i]; i+=2)
+ if (app->dynv[i]==DT_DEBUG)
+ app->dynv[i+1] = (size_t)&debug;
+ debug.ver = 1;
+ debug.bp = _dl_debug_state;
+ debug.head = head;
+ debug.base = lib->base;
+ debug.state = 0;
+ _dl_debug_state();
+
do_init_fini(tail);
if (!rtld_used) {
do_init_fini(tail);
if (!rtld_used) {
@@
-605,6
+641,8
@@
void *__dynlink(int argc, char **argv)
reclaim((void *)builtin_dsos, 0, sizeof builtin_dsos);
}
reclaim((void *)builtin_dsos, 0, sizeof builtin_dsos);
}
+ if (ssp_used) __pthread_self_init();
+
errno = 0;
return (void *)aux[AT_ENTRY];
}
errno = 0;
return (void *)aux[AT_ENTRY];
}
@@
-634,9
+672,13
@@
void *dlopen(const char *file, int mode)
tail = orig_tail;
tail->next = 0;
p = 0;
tail = orig_tail;
tail->next = 0;
p = 0;
+ errflag = 1;
+ goto end;
} else p = load_library(file);
if (!p) {
} else p = load_library(file);
if (!p) {
+ snprintf(errbuf, sizeof errbuf,
+ "Error loading shared library %s: %m", file);
errflag = 1;
goto end;
}
errflag = 1;
goto end;
}
@@
-661,6
+703,8
@@
void *dlopen(const char *file, int mode)
p->global = 1;
}
p->global = 1;
}
+ _dl_debug_state();
+
do_init_fini(tail);
end:
pthread_rwlock_unlock(&lock);
do_init_fini(tail);
end:
pthread_rwlock_unlock(&lock);
@@
-694,6
+738,7
@@
static void *do_dlsym(struct dso *p, const char *s, void *ra)
return p->deps[i]->base + sym->st_value;
}
errflag = 1;
return p->deps[i]->base + sym->st_value;
}
errflag = 1;
+ snprintf(errbuf, sizeof errbuf, "Symbol not found: %s", s);
return 0;
}
return 0;
}
@@
-720,7
+765,7
@@
char *dlerror()
{
if (!errflag) return 0;
errflag = 0;
{
if (!errflag) return 0;
errflag = 0;
- return
"unknown error"
;
+ return
errbuf
;
}
int dlclose(void *p)
}
int dlclose(void *p)