From: Rich Felker Date: Sun, 26 Jun 2011 02:36:21 +0000 (-0400) Subject: fix some symbol resolution issues in dynamic linker X-Git-Url: http://nsz.repo.hu/git/?p=musl;a=commitdiff_plain;h=32de61e81a64c8bb2cd23e3476f00433692f8e59;hp=1a3ff4f9099cf3d6b65a77cf9bfb7f69a7698a30 fix some symbol resolution issues in dynamic linker 1. search was wrongly beginning with lib itself rather than dso head 2. inconsistent resolution of function pointers for functions in plt --- diff --git a/arch/i386/reloc.h b/arch/i386/reloc.h index 3ca9d11d..490113a0 100644 --- a/arch/i386/reloc.h +++ b/arch/i386/reloc.h @@ -4,6 +4,7 @@ #define ETC_LDSO_PATH "/etc/ld-musl-i386.path" #define IS_COPY(x) ((x)==R_386_COPY) +#define IS_PLT(x) ((x)==R_386_JMP_SLOT) static inline void do_single_reloc(size_t *reloc_addr, int type, size_t sym_val, size_t sym_size, unsigned char *base_addr, size_t addend) { diff --git a/arch/x86_64/reloc.h b/arch/x86_64/reloc.h index 6642fdd4..b0bbfb3e 100644 --- a/arch/x86_64/reloc.h +++ b/arch/x86_64/reloc.h @@ -5,6 +5,7 @@ #define ETC_LDSO_PATH "/etc/ld-musl-x86_64.path" #define IS_COPY(x) ((x)==R_X86_64_COPY) +#define IS_PLT(x) ((x)==R_X86_64_JUMP_SLOT) static inline void do_single_reloc(size_t *reloc_addr, int type, size_t sym_val, size_t sym_size, unsigned char *base_addr, size_t addend) { diff --git a/src/ldso/dynlink.c b/src/ldso/dynlink.c index 472e389d..9e9415ca 100644 --- a/src/ldso/dynlink.c +++ b/src/ldso/dynlink.c @@ -114,7 +114,7 @@ static void do_relocs(unsigned char *base, size_t *rel, size_t rel_size, size_t sym = syms + sym_index; name = strings + sym->st_name; ctx = IS_COPY(type) ? dso->next : dso; - sym_val = (size_t)find_sym(ctx, name, 1); + sym_val = (size_t)find_sym(ctx, name, IS_PLT(type)); sym_size = sym->st_size; } do_single_reloc(reloc_addr, type, sym_val, sym_size, base, rel[2]); @@ -335,11 +335,11 @@ static void reloc_all(struct dso *p) if (p->relocated) continue; decode_vec(p->dynv, dyn, DYN_CNT); do_relocs(p->base, (void *)(p->base+dyn[DT_JMPREL]), dyn[DT_PLTRELSZ], - 2+(dyn[DT_PLTREL]==DT_RELA), p->syms, p->strings, p); + 2+(dyn[DT_PLTREL]==DT_RELA), p->syms, p->strings, head); do_relocs(p->base, (void *)(p->base+dyn[DT_REL]), dyn[DT_RELSZ], - 2, p->syms, p->strings, p); + 2, p->syms, p->strings, head); do_relocs(p->base, (void *)(p->base+dyn[DT_RELA]), dyn[DT_RELASZ], - 3, p->syms, p->strings, p); + 3, p->syms, p->strings, head); p->relocated = 1; } }