summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorRich Felker <dalias@aerifal.cx>2012-01-20 11:14:27 -0500
committerRich Felker <dalias@aerifal.cx>2012-01-20 11:14:27 -0500
commit0b6dc0974426238cfe8fbb01ef64e7911f2da678 (patch)
treed125a6b4af8936db9d2654da3cdee7fcdd626350 /src
parent07065210cae8ae40fceeee4febf338e1f1aecd0c (diff)
downloadmusl-0b6dc0974426238cfe8fbb01ef64e7911f2da678.tar.gz
fix dynamic linker not to depend on DYNAMIC ptr in 0th entry of GOT
this fixes an issue using gold instead of gnu ld for linking. it also should eliminate the need of the startup code to even load/pass the got address to the dynamic linker. based on patch submitted by sh4rm4 with minor cosmetic changes. further cleanup will follow.
Diffstat (limited to 'src')
-rw-r--r--src/ldso/dynlink.c15
1 files changed, 12 insertions, 3 deletions
diff --git a/src/ldso/dynlink.c b/src/ldso/dynlink.c
index 86d4b803..b26992d3 100644
--- a/src/ldso/dynlink.c
+++ b/src/ldso/dynlink.c
@@ -467,6 +467,7 @@ void *__dynlink(int argc, char **argv, size_t *got)
size_t i;
Phdr *phdr;
Ehdr *ehdr;
+ size_t *lib_dynv;
static struct dso builtin_dsos[3];
struct dso *const app = builtin_dsos+0;
struct dso *const lib = builtin_dsos+1;
@@ -498,8 +499,16 @@ void *__dynlink(int argc, char **argv, size_t *got)
}
}
- /* Relocate ldso's DYNAMIC pointer and load vector */
- decode_vec((void *)(got[0] += aux[AT_BASE]), lib_dyn, DYN_CNT);
+ /* Find the dynamic linker's DYNAMIC section and decode it */
+ ehdr = (void *)aux[AT_BASE];
+ phdr = (void *)(aux[AT_BASE] + ehdr->e_phoff);
+ for (i=ehdr->e_phnum; i--; phdr=(void *)((char *)phdr + ehdr->e_phentsize)) {
+ if (phdr->p_type == PT_DYNAMIC) {
+ lib_dynv = (void *)(aux[AT_BASE] + phdr->p_vaddr);
+ decode_vec(lib_dynv, lib_dyn, DYN_CNT);
+ break;
+ }
+ }
/* Find the program image's DYNAMIC section and decode it */
phdr = (void *)aux[AT_PHDR];
@@ -526,7 +535,7 @@ void *__dynlink(int argc, char **argv, size_t *got)
.strings = (void *)(aux[AT_BASE]+lib_dyn[DT_STRTAB]),
.hashtab = (void *)(aux[AT_BASE]+lib_dyn[DT_HASH]),
.syms = (void *)(aux[AT_BASE]+lib_dyn[DT_SYMTAB]),
- .dynv = (void *)(got[0]),
+ .dynv = lib_dynv,
.name = "libc.so",
.global = 1,
.relocated = 1