X-Git-Url: http://nsz.repo.hu/git/?a=blobdiff_plain;f=ldso%2Fdynlink.c;h=7b47b1635944432159a22f3fb02d27516910cc1c;hb=25e6fee27f4a293728dd15b659170e7b9c7db9bc;hp=cc677952b4d2e729891d2420600f93d41e0b3384;hpb=d16d7b10997e6f1c224c3de01b43868f0ce2cc3d;p=musl diff --git a/ldso/dynlink.c b/ldso/dynlink.c index cc677952..7b47b163 100644 --- a/ldso/dynlink.c +++ b/ldso/dynlink.c @@ -210,7 +210,8 @@ static void decode_vec(size_t *v, size_t *a, size_t cnt) size_t i; for (i=0; i= sizeof buf) goto nomatch; + buf[l] = name[l]; + } + if (!strcmp(name, "readdir64_r")) + return find_sym(&ldso, "readdir_r", 1); + if (l<2 || name[l-2]!='6' || name[l-1]!='4') + goto nomatch; + buf[l-=2] = 0; + for (p=lfs64_list; *p; p++) { + if (!strcmp(buf, p)) return find_sym(&ldso, buf, 1); + while (*p) p++; + } +nomatch: + return (struct symdef){ 0 }; +} + static void do_relocs(struct dso *dso, size_t *rel, size_t rel_size, size_t stride) { unsigned char *base = dso->base; @@ -389,6 +423,7 @@ static void do_relocs(struct dso *dso, size_t *rel, size_t rel_size, size_t stri def = (sym->st_info>>4) == STB_LOCAL ? (struct symdef){ .dso = dso, .sym = sym } : find_sym(ctx, name, type==REL_PLT); + if (!def.sym) def = get_lfs64(name); if (!def.sym && (sym->st_shndx != SHN_UNDEF || sym->st_info>>4 != STB_WEAK)) { if (dso->lazy && (type==REL_PLT || type==REL_GOT)) { @@ -515,6 +550,23 @@ static void do_relocs(struct dso *dso, size_t *rel, size_t rel_size, size_t stri } } +static void do_relr_relocs(struct dso *dso, size_t *relr, size_t relr_size) +{ + unsigned char *base = dso->base; + size_t *reloc_addr; + for (; relr_size; relr++, relr_size-=sizeof(size_t)) + if ((relr[0]&1) == 0) { + reloc_addr = laddr(dso, relr[0]); + *reloc_addr++ += (size_t)base; + } else { + int i = 0; + for (size_t bitmap=relr[0]; (bitmap>>=1); i++) + if (bitmap&1) + reloc_addr[i] += (size_t)base; + reloc_addr += 8*sizeof(size_t)-1; + } +} + static void redo_lazy_relocs() { struct dso *p = lazy_head, *next; @@ -868,7 +920,7 @@ static int fixup_rpath(struct dso *p, char *buf, size_t buf_size) case ENOENT: case ENOTDIR: case EACCES: - break; + return 0; default: return -1; } @@ -1357,6 +1409,8 @@ static void reloc_all(struct dso *p) 2+(dyn[DT_PLTREL]==DT_RELA)); do_relocs(p, laddr(p, dyn[DT_REL]), dyn[DT_RELSZ], 2); do_relocs(p, laddr(p, dyn[DT_RELA]), dyn[DT_RELASZ], 3); + if (!DL_FDPIC) + do_relr_relocs(p, laddr(p, dyn[DT_RELR]), dyn[DT_RELRSZ]); if (head != &ldso && p->relro_start != p->relro_end) { long ret = __syscall(SYS_mprotect, laddr(p, p->relro_start),