diff options
author | Carmelo Amoroso <carmelo.amoroso@st.com> | 2011-01-21 15:04:47 +0100 |
---|---|---|
committer | Carmelo Amoroso <carmelo.amoroso@st.com> | 2011-01-21 15:04:47 +0100 |
commit | 2aee0efdec50321ffbe6891c593611461cc7b16e (patch) | |
tree | f6b3c17d1e3fddf14360317f4f18b86b0c83c045 | |
parent | 8100a075b7dd7471562decb1860571a335d68b0d (diff) | |
parent | b5dd2e706c1a098b2e8cd8df10500a3dde350efc (diff) |
Merge remote branch 'origin/master' into prelink
* origin/master:
bump version to 0.9.32-rc2-git
release 0.9.32-rc2
nptl: Fix __USER_LABEL_PREFIX__ concatenatio
nptl: fix start_thread() for _STACK_GROWS_UP
ldso: get rid of _dl_lookup_hash
Add protected symbols support for all architectures
Revert "ldso/arm: Correct protected symbol resolution"
Revert "ldso_sh: add support for protected symbols to SH"
Revert "ldso/i386: support protected symbols"
cris: Fix build issues
syslog: fix 'everyone logs with user facility'
__psfs_parse_spec: always use long int for %p
buildsys: headers target should not depend on sysnum.h
buildsys: fix make release target
nptl: get rid of the last preprocessor warning when __ASSUME_TGKILL is not defined
remove uClibc_ctype.h if !LOCALE
Revert "Makefile.in: Add header to 'all' target"
nptl: get rid of preprocessor warning when __ASSUME_TGKILL is not defined
Conflicts:
ldso/include/dl-hash.h
ldso/ldso/arm/elfinterp.c
ldso/ldso/avr32/elfinterp.c
ldso/ldso/bfin/elfinterp.c
ldso/ldso/cris/elfinterp.c
ldso/ldso/dl-hash.c
ldso/ldso/i386/elfinterp.c
ldso/ldso/m68k/elfinterp.c
ldso/ldso/mips/elfinterp.c
ldso/ldso/powerpc/elfinterp.c
ldso/ldso/sh/elfinterp.c
ldso/ldso/sh64/elfinterp.c
ldso/ldso/sparc/elfinterp.c
ldso/ldso/x86_64/elfinterp.c
ldso/ldso/xtensa/elfinterp.c
ldso/libdl/libdl.c
Signed-off-by: Carmelo Amoroso <carmelo.amoroso@st.com>
32 files changed, 318 insertions, 243 deletions
diff --git a/Makefile.in b/Makefile.in index d7a5fca60..ab5ab7286 100644 --- a/Makefile.in +++ b/Makefile.in @@ -23,7 +23,7 @@ export KCONFIG_CONFIG ifeq ($(HAVE_DOT_CONFIG),y) -all: headers pregen libs +all: pregen libs libs: pregen # In this section, we need .config @@ -158,11 +158,12 @@ headers_clean-y += HEADERCLEAN_common # libc/sysdeps/linux/Makefile.commonarch to headers-y headers-y += $(target-headers-sysdep) -headers: $(top_builddir)include/bits/uClibc_config.h $(top_builddir)include/bits/sysnum.h | subdirs +headers: $(top_builddir)include/bits/uClibc_config.h | subdirs subdirs: $(addprefix $(top_builddir),$(subdirs)) -pregen-headers: $(pregen-headers-y) +pregen-headers: $(top_builddir)include/bits/sysnum.h $(pregen-headers-y) pregen: pregen-headers $(Q)$(if $(UCLIBC_HAS_LOCALE),$(MAKE) -C extra/locale locale_headers) + $(top_builddir)include/bits/sysnum.h: $(top_srcdir)extra/scripts/gen_bits_syscall_h.sh | $(top_builddir)include/bits @$(disp_gen) $(Q)set -e; \ @@ -241,7 +242,7 @@ HEADERS_RM-$(UCLIBC_HAS_GNU_ERROR) += error.h HEADERS_RM-$(UCLIBC_HAS_GNU_GETOPT)$(UCLIBC_HAS_GETOPT_LONG) += getopt.h HEADERS_RM-$(UCLIBC_HAS_IPV6) += netinet/ip6.h netinet/icmp6.h HEADERS_RM-$(UCLIBC_HAS_BACKTRACE) += execinfo.h -HEADERS_RM-$(UCLIBC_HAS_LOCALE) += iconv.h +HEADERS_RM-$(UCLIBC_HAS_LOCALE) += iconv.h bits/uClibc_ctype.h HEADERS_RM-$(UCLIBC_HAS_PTY) += pty.h HEADERS_RM-$(UCLIBC_HAS_REALTIME) += mqueue.h bits/mqueue.h sched.h \ bits/sched.h \ @@ -260,7 +261,6 @@ HEADERS_RM-$(UCLIBC_HAS_WCHAR) += wchar.h wctype.h HEADERS_RM-$(UCLIBC_HAS_WORDEXP) += wordexp.h HEADERS_RM-$(UCLIBC_HAS_XATTR) += sys/xattr.h HEADERS_RM-$(UCLIBC_HAS_XLOCALE) += xlocale.h -HEADERS_RM-$(UCLIBC_HAS_LOCALE) += bits/uClibc_ctype.h HEADERS_RM-$(UCLIBC_LINUX_SPECIFIC) += sys/fsuid.h sys/inotify.h sys/perm.h \ sys/personality.h \ sys/prctl.h \ @@ -476,7 +476,7 @@ distclean: clean dist release: $(RM) ../uClibc-$(VERSION).tar - git archive HEAD --format=tar --prefix=uClibc-$(VERSION)/ \ + git archive --format=tar --prefix=uClibc-$(VERSION)/ HEAD \ > ../uClibc-$(VERSION).tar cat ../uClibc-$(VERSION).tar | bzip2 -c9 > ../uClibc-$(VERSION).tar.bz2 cat ../uClibc-$(VERSION).tar | xz -e -c8 > ../uClibc-$(VERSION).tar.xz @@ -106,7 +106,7 @@ export RUNTIME_PREFIX DEVEL_PREFIX KERNEL_HEADERS MULTILIB_DIR MAJOR_VERSION := 0 MINOR_VERSION := 9 SUBLEVEL := 32 -EXTRAVERSION :=-rc1-git +EXTRAVERSION :=-rc2-git VERSION := $(MAJOR_VERSION).$(MINOR_VERSION).$(SUBLEVEL) ABI_VERSION := $(MAJOR_VERSION) ifneq ($(EXTRAVERSION),) diff --git a/ldso/include/dl-hash.h b/ldso/include/dl-hash.h index b1927e49a..c7effc588 100644 --- a/ldso/include/dl-hash.h +++ b/ldso/include/dl-hash.h @@ -25,9 +25,9 @@ struct dyn_elf { struct dyn_elf * prev; }; -struct sym_val { - const ElfW(Sym) *s; - struct elf_resolve *m; +struct symbol_ref { + const ElfW(Sym) *sym; + struct elf_resolve *tpnt; }; /* Structure to describe a single list of scope elements. The lookup @@ -156,20 +156,9 @@ extern struct elf_resolve * _dl_add_elf_hash_table(const char * libname, DL_LOADADDR_TYPE loadaddr, unsigned long * dynamic_info, unsigned long dynamic_addr, unsigned long dynamic_size); -/* Only need extra arg with some configurations */ -#if !((defined(USE_TLS) && USE_TLS) || defined __FDPIC__) -# define _dl_lookup_hash(n, r, m, s, c, tpnt) _dl_lookup_hash(n, r, m, s, c) -# define _dl_find_hash(n, r, m, s, t, tpntp) _dl_find_hash(n, r, m, s, t) -#endif -extern char *_dl_lookup_hash(const char *name, struct r_scope_elem *scope, - struct elf_resolve *mytpnt, struct sym_val *symbol, int type_class, - struct elf_resolve **tpntp); -static __always_inline char *_dl_find_hash(const char *name, struct r_scope_elem *scope, - struct elf_resolve *mytpnt, struct sym_val *symbol, int type_class, - struct elf_resolve **tpntp) -{ - return _dl_lookup_hash(name, scope, mytpnt, symbol, type_class, tpntp); -} +extern char *_dl_find_hash(const char *name, struct r_scope_elem *scope, + struct elf_resolve *mytpnt, int type_class, + struct symbol_ref *symbol); extern int _dl_linux_dynamic_link(void); diff --git a/ldso/ldso/arm/elfinterp.c b/ldso/ldso/arm/elfinterp.c index ee2d1e559..5ae85dd2e 100644 --- a/ldso/ldso/arm/elfinterp.c +++ b/ldso/ldso/arm/elfinterp.c @@ -70,7 +70,7 @@ unsigned long _dl_linux_resolver(struct elf_resolve *tpnt, int reloc_entry) /* Get the address of the GOT entry */ new_addr = _dl_find_hash(symname, &_dl_loaded_modules->symbol_scope, - tpnt, NULL, ELF_RTYPE_CLASS_PLT, NULL); + tpnt, ELF_RTYPE_CLASS_PLT, NULL); if (unlikely(!new_addr)) { _dl_dprintf(2, "%s: can't resolve symbol '%s'\n", _dl_progname, symname); @@ -189,22 +189,21 @@ _dl_do_reloc (struct elf_resolve *tpnt,struct r_scope_elem *scope, unsigned long *reloc_addr; unsigned long symbol_addr; const Elf32_Sym *def = 0; + struct symbol_ref sym_ref; struct elf_resolve *def_mod = 0; int goof = 0; - struct sym_val current_value = { NULL, NULL }; - reloc_addr = (unsigned long *) (tpnt->loadaddr + (unsigned long) rpnt->r_offset); reloc_type = ELF32_R_TYPE(rpnt->r_info); symtab_index = ELF32_R_SYM(rpnt->r_info); symbol_addr = 0; + sym_ref.sym = &symtab[symtab_index]; + sym_ref.tpnt = NULL; - if (symtab_index && - (ELF32_ST_VISIBILITY(symtab[symtab_index].st_other) - != STV_PROTECTED)) { + if (symtab_index) { symbol_addr = _dl_find_hash(strtab + symtab[symtab_index].st_name, - scope, tpnt, ¤t_value, elf_machine_type_class(reloc_type), &def_mod); + scope, tpnt, elf_machine_type_class(reloc_type), &sym_ref); /* * We want to allow undefined references to weak symbols - this might @@ -219,19 +218,15 @@ _dl_do_reloc (struct elf_resolve *tpnt,struct r_scope_elem *scope, } if (_dl_trace_prelink) _dl_debug_lookup (symname, tpnt, &symtab[symtab_index], - ¤t_value, elf_machine_type_class(reloc_type)); + &sym_ref, elf_machine_type_class(reloc_type)); + def_mod = sym_ref.tpnt; } else { /* * Relocs against STN_UNDEF are usually treated as using a * symbol value of zero, and using the module containing the * reloc itself. */ - if (symtab_index) - symbol_addr = DL_FIND_HASH_VALUE(tpnt, elf_machine_type_class(reloc_type), - &symtab[symtab_index]); - else - symbol_addr = symtab[symtab_index].st_value; - + symbol_addr = symtab[symtab_index].st_value; def_mod = tpnt; } diff --git a/ldso/ldso/avr32/elfinterp.c b/ldso/ldso/avr32/elfinterp.c index e741fd60e..c3c5b4907 100644 --- a/ldso/ldso/avr32/elfinterp.c +++ b/ldso/ldso/avr32/elfinterp.c @@ -50,9 +50,9 @@ unsigned long _dl_linux_resolver(unsigned long got_offset, unsigned long *got) strtab = (char *)(tpnt->dynamic_info[DT_STRTAB] + tpnt->loadaddr); symname = strtab + sym->st_name; - new_addr = (unsigned long) _dl_find_hash(strtab + sym->st_name, + new_addr = (unsigned long) _dl_find_hash(symname, &_dl_loaded_modules->symbol_scope, tpnt, - NULL, 0, resolver); + ELF_RTYPE_CLASS_PLT, NULL); entry = (unsigned long *)(got + local_gotno + sym_index - gotsym); *entry = new_addr; @@ -127,20 +127,20 @@ static int _dl_do_reloc(struct elf_resolve *tpnt, struct r_scope_elem *scope, #if defined(__SUPPORT_LD_DEBUG__) unsigned long old_val; #endif - - struct sym_val current_value = { NULL, NULL }; + struct symbol_ref sym_ref; reloc_addr = (unsigned long *)(tpnt->loadaddr + rpnt->r_offset); reloc_type = ELF32_R_TYPE(rpnt->r_info); symtab_index = ELF32_R_SYM(rpnt->r_info); symbol_addr = 0; + sym_ref.sym = &symtab[symtab_index]; + sym_ref.tpnt = NULL; symname = strtab + symtab[symtab_index].st_name; if (symtab_index) { symbol_addr = (unsigned long) - _dl_find_hash(strtab + symtab[symtab_index].st_name, - scope, tpnt, ¤t_value, - elf_machine_type_class(reloc_type), NULL); + _dl_find_hash(symname, scope, tpnt, + elf_machine_type_class(reloc_type), &sym_ref); /* Allow undefined references to weak symbols */ if (!symbol_addr && @@ -151,7 +151,7 @@ static int _dl_do_reloc(struct elf_resolve *tpnt, struct r_scope_elem *scope, } if (_dl_trace_prelink) _dl_debug_lookup (symname, tpnt, &symtab[symtab_index], - ¤t_value, elf_machine_type_class(reloc_type)); + &sym_ref, elf_machine_type_class(reloc_type)); } #if defined(__SUPPORT_LD_DEBUG__) diff --git a/ldso/ldso/bfin/elfinterp.c b/ldso/ldso/bfin/elfinterp.c index 466a3b4c1..42c113c50 100644 --- a/ldso/ldso/bfin/elfinterp.c +++ b/ldso/ldso/bfin/elfinterp.c @@ -46,11 +46,11 @@ _dl_linux_resolver (struct elf_resolve *tpnt, int reloc_entry) ElfW(Sym) *symtab; int symtab_index; char *rel_addr; - struct elf_resolve *new_tpnt; char *new_addr; struct funcdesc_value funcval; struct funcdesc_value volatile *got_entry; char *symname; + struct symbol_ref sym_ref; rel_addr = (char *)tpnt->dynamic_info[DT_JMPREL]; @@ -59,15 +59,17 @@ _dl_linux_resolver (struct elf_resolve *tpnt, int reloc_entry) symtab = (Elf32_Sym *) tpnt->dynamic_info[DT_SYMTAB]; strtab = (char *) tpnt->dynamic_info[DT_STRTAB]; + sym_ref.sym = &symtab[symtab_index]; + sym_ref.tpnt = NULL; symname= strtab + symtab[symtab_index].st_name; /* Address of GOT entry fix up */ got_entry = (struct funcdesc_value *) DL_RELOC_ADDR(tpnt->loadaddr, this_reloc->r_offset); /* Get the address to be used to fill in the GOT entry. */ - new_addr = _dl_lookup_hash(symname, &_dl_loaded_modules->symbol_scope, NULL, NULL, 0, &new_tpnt); + new_addr = _dl_find_hash(symname, &_dl_loaded_modules->symbol_scope, NULL, 0, &sym_ref); if (!new_addr) { - new_addr = _dl_lookup_hash(symname, NULL, NULL, NULL, 0, &new_tpnt); + new_addr = _dl_find_hash(symname, NULL, NULL, 0, &sym_ref); if (!new_addr) { _dl_dprintf(2, "%s: can't resolve symbol '%s'\n", _dl_progname, symname); @@ -76,7 +78,7 @@ _dl_linux_resolver (struct elf_resolve *tpnt, int reloc_entry) } funcval.entry_point = new_addr; - funcval.got_value = new_tpnt->loadaddr.got_value; + funcval.got_value = sym_ref.tpnt->loadaddr.got_value; #if defined (__SUPPORT_LD_DEBUG__) if (_dl_debug_bindings) { @@ -165,14 +167,15 @@ _dl_do_reloc (struct elf_resolve *tpnt,struct r_scope_elem *scope, #if defined (__SUPPORT_LD_DEBUG__) unsigned long old_val; #endif - - struct sym_val current_value = { NULL, NULL }; + struct symbol_ref sym_ref; reloc_addr = (unsigned long *) DL_RELOC_ADDR(tpnt->loadaddr, rpnt->r_offset); __asm__ ("" : "=r" (reloc_addr_packed) : "0" (reloc_addr)); reloc_type = ELF_R_TYPE(rpnt->r_info); symtab_index = ELF_R_SYM(rpnt->r_info); symbol_addr = 0; + sym_ref.sym = &symtab[symtab_index]; + sym_ref.tpnt = NULL; symname = strtab + symtab[symtab_index].st_name; if (ELF_ST_BIND (symtab[symtab_index].st_info) == STB_LOCAL) { @@ -181,7 +184,7 @@ _dl_do_reloc (struct elf_resolve *tpnt,struct r_scope_elem *scope, } else { symbol_addr = (unsigned long) - _dl_lookup_hash(symname, scope, NULL, ¤t_value, 0, &symbol_tpnt); + _dl_find_hash(symname, scope, NULL, 0, &sym_ref); /* * We want to allow undefined references to weak symbols - this might @@ -191,12 +194,13 @@ _dl_do_reloc (struct elf_resolve *tpnt,struct r_scope_elem *scope, if (!symbol_addr && ELF_ST_BIND(symtab[symtab_index].st_info) != STB_WEAK) { _dl_dprintf (2, "%s: can't resolve symbol '%s'\n", - _dl_progname, strtab + symtab[symtab_index].st_name); + _dl_progname, symname); _dl_exit (1); } if (_dl_trace_prelink) _dl_debug_lookup (symname, tpnt, &symtab[symtab_index], - ¤t_value, elf_machine_type_class(reloc_type)); + &sym_ref, elf_machine_type_class(reloc_type)); + symbol_tpnt = sym_ref.tpnt; } #if defined (__SUPPORT_LD_DEBUG__) diff --git a/ldso/ldso/cris/elfinterp.c b/ldso/ldso/cris/elfinterp.c index 48802aa7c..c3af90b99 100644 --- a/ldso/ldso/cris/elfinterp.c +++ b/ldso/ldso/cris/elfinterp.c @@ -66,7 +66,7 @@ _dl_linux_resolver(struct elf_resolve *tpnt, int reloc_entry) got_addr = (char **)instr_addr; /* Get the address of the GOT entry. */ - new_addr = _dl_find_hash(symname, &_dl_loaded_modules->symbol_scope, tpnt, NULL, ELF_RTYPE_CLASS_PLT, NULL); + new_addr = _dl_find_hash(symname, &_dl_loaded_modules->symbol_scope, tpnt, ELF_RTYPE_CLASS_PLT, NULL); if (unlikely(!new_addr)) { _dl_dprintf(2, "%s: Can't resolve symbol '%s'\n", _dl_progname, symname); _dl_exit(1); @@ -161,13 +161,14 @@ _dl_do_reloc(struct elf_resolve *tpnt, struct r_scope_elem *scope, #if defined (__SUPPORT_LD_DEBUG__) unsigned long old_val; #endif - - struct sym_val current_value = { NULL, NULL }; + struct symbol_ref sym_ref; reloc_addr = (unsigned long *)(intptr_t)(tpnt->loadaddr + (unsigned long)rpnt->r_offset); reloc_type = ELF32_R_TYPE(rpnt->r_info); symtab_index = ELF32_R_SYM(rpnt->r_info); symbol_addr = 0; + sym_ref.sym = &symtab[symtab_index]; + sym_ref.tpnt = NULL; symname = strtab + symtab[symtab_index].st_name; if (symtab_index) { @@ -176,17 +177,18 @@ _dl_do_reloc(struct elf_resolve *tpnt, struct r_scope_elem *scope, symbol_addr = (unsigned long)tpnt->loadaddr; } else { symbol_addr = (unsigned long)_dl_find_hash(symname, scope, tpnt, - ¤t_value, elf_machine_type_class(reloc_type), NULL); + elf_machine_type_class(reloc_type), &sym_ref); } if (unlikely(!symbol_addr && ELF32_ST_BIND(symtab[symtab_index].st_info) != STB_WEAK)) { _dl_dprintf(2, "%s: can't resolve symbol '%s'\n", _dl_progname, symname); _dl_exit(1); } + symbol_addr += rpnt->r_addend; if (_dl_trace_prelink) _dl_debug_lookup (symname, tpnt, &symtab[symtab_index], - ¤t_value, elf_machine_type_class(reloc_type)); + &sym_ref, elf_machine_type_class(reloc_type)); } #if defined (__SUPPORT_LD_DEBUG__) diff --git a/ldso/ldso/dl-debug.c b/ldso/ldso/dl-debug.c index 47b32316e..8a548195f 100644 --- a/ldso/ldso/dl-debug.c +++ b/ldso/ldso/dl-debug.c @@ -109,7 +109,7 @@ static void debug_reloc(ElfW(Sym) *symtab, char *strtab, ELF_RELOC *rpnt) static void internal_function _dl_debug_lookup (const char *undef_name, struct elf_resolve *undef_map, - const ElfW(Sym) *ref, struct sym_val *value, int type_class) + const ElfW(Sym) *ref, struct symbol_ref *value, int type_class) { #ifdef SHARED unsigned long symbol_addr; @@ -117,8 +117,7 @@ _dl_debug_lookup (const char *undef_name, struct elf_resolve *undef_map, if (_dl_trace_prelink) { int conflict = 0; - struct elf_resolve *tls_tpnt = NULL; - struct sym_val val = { NULL, NULL }; + struct symbol_ref val = { NULL, NULL }; if ((_dl_trace_prelink_map == NULL || _dl_trace_prelink_map == _dl_loaded_modules) @@ -126,14 +125,14 @@ _dl_debug_lookup (const char *undef_name, struct elf_resolve *undef_map, { symbol_addr = (unsigned long) _dl_find_hash(undef_name, &undef_map->symbol_scope, - undef_map, &val, type_class, &tls_tpnt); + undef_map, type_class, &val); - if (val.s != value->s || val.m != value->m) + if (val.sym != value->sym || val.tpnt != value->tpnt) conflict = 1; } - if (value->s - && (__builtin_expect (ELF_ST_TYPE(value->s->st_info) + if (value->sym + && (__builtin_expect (ELF_ST_TYPE(value->sym->st_info) == STT_TLS, 0))) type_class = 4; @@ -146,12 +145,12 @@ _dl_debug_lookup (const char *undef_name, struct elf_resolve *undef_map, conflict ? "conflict" : "lookup", (size_t) undef_map->mapaddr, (size_t) (((ElfW(Addr)) ref) - undef_map->mapaddr), - (size_t) (value->m ? value->m->mapaddr : 0), - (size_t) (value->s ? value->s->st_value : 0)); + (size_t) (value->tpnt ? value->tpnt->mapaddr : 0), + (size_t) (value->sym ? value->sym->st_value : 0)); if (conflict) _dl_dprintf (1, "x %x %x ", - (size_t) (val.m ? val.m->mapaddr : 0), - (size_t) (val.s ? val.s->st_value : 0)); + (size_t) (val.tpnt ? val.tpnt->mapaddr : 0), + (size_t) (val.sym ? val.sym->st_value : 0)); _dl_dprintf (1, "/%x %s\n", type_class, undef_name); } } diff --git a/ldso/ldso/dl-hash.c b/ldso/ldso/dl-hash.c index bb4c56b04..2ec883a86 100644 --- a/ldso/ldso/dl-hash.c +++ b/ldso/ldso/dl-hash.c @@ -267,8 +267,8 @@ _dl_lookup_sysv_hash(struct elf_resolve *tpnt, ElfW(Sym) *symtab, unsigned long * This function resolves externals, and this is either called when we process * relocations or when we call an entry in the PLT table for the first time. */ -char *_dl_lookup_hash(const char *name, struct r_scope_elem *scope, struct elf_resolve *mytpnt, - struct sym_val *symbol, int type_class, struct elf_resolve **tpntp) +char *_dl_find_hash(const char *name, struct r_scope_elem *scope, struct elf_resolve *mytpnt, + int type_class, struct symbol_ref *sym_ref) { struct elf_resolve *tpnt = NULL; ElfW(Sym) *symtab; @@ -284,6 +284,11 @@ char *_dl_lookup_hash(const char *name, struct r_scope_elem *scope, struct elf_r unsigned long gnu_hash_number = _dl_gnu_hash((const unsigned char *)name); #endif + if ((sym_ref) && (sym_ref->sym) && (ELF32_ST_VISIBILITY(sym_ref->sym->st_other) == STV_PROTECTED)) { + sym = sym_ref->sym; + if (mytpnt) + tpnt = mytpnt; + } else for (loop_scope = scope; loop_scope && !sym; loop_scope = loop_scope->next) { for (i = 0; i < loop_scope->r_nlist; i++) { tpnt = loop_scope->r_list[i]; @@ -338,16 +343,15 @@ char *_dl_lookup_hash(const char *name, struct r_scope_elem *scope, struct elf_r } if (sym) { - if (symbol) { - symbol->s = sym; - symbol->m = tpnt; + if (sym_ref) { + sym_ref->sym = sym; + sym_ref->tpnt = tpnt; } /* At this point we have found the requested symbol, do binding */ #if defined(USE_TLS) && USE_TLS if (ELF_ST_TYPE(sym->st_info) == STT_TLS) { - _dl_assert(tpntp != NULL); - *tpntp = tpnt; - + _dl_assert(sym_ref != NULL); + sym_ref->tpnt = tpnt; return (char *)sym->st_value; } #endif @@ -363,8 +367,8 @@ char *_dl_lookup_hash(const char *name, struct r_scope_elem *scope, struct elf_r #endif case STB_GLOBAL: #ifdef __FDPIC__ - if (tpntp) - *tpntp = tpnt; + if (sym_ref) + sym_ref->tpnt = tpnt; #endif return (char *)DL_FIND_HASH_VALUE(tpnt, type_class, sym); default: /* Local symbols not handled here */ @@ -372,8 +376,8 @@ char *_dl_lookup_hash(const char *name, struct r_scope_elem *scope, struct elf_r } } #ifdef __FDPIC__ - if (tpntp) - *tpntp = tpnt; + if (sym_ref) + sym_ref->tpnt = tpnt; #endif return weak_result; } diff --git a/ldso/ldso/i386/elfinterp.c b/ldso/ldso/i386/elfinterp.c index 0c821ce8b..33c14402a 100644 --- a/ldso/ldso/i386/elfinterp.c +++ b/ldso/ldso/i386/elfinterp.c @@ -71,7 +71,7 @@ _dl_linux_resolver(struct elf_resolve *tpnt, int reloc_entry) got_addr = (char **)instr_addr; /* Get the address of the GOT entry. */ - new_addr = _dl_find_hash(symname, &_dl_loaded_modules->symbol_scope, tpnt, NULL, ELF_RTYPE_CLASS_PLT, NULL); + new_addr = _dl_find_hash(symname, &_dl_loaded_modules->symbol_scope, tpnt, ELF_RTYPE_CLASS_PLT, NULL); if (unlikely(!new_addr)) { _dl_dprintf(2, "%s: can't resolve symbol '%s' in lib '%s'.\n", _dl_progname, symname, tpnt->libname); _dl_exit(1); @@ -168,20 +168,19 @@ _dl_do_reloc(struct elf_resolve *tpnt, struct r_scope_elem *scope, #if defined (__SUPPORT_LD_DEBUG__) unsigned long old_val; #endif - - struct sym_val current_value = { NULL, NULL }; + struct symbol_ref sym_ref; reloc_addr = (unsigned long *)(intptr_t)(tpnt->loadaddr + (unsigned long)rpnt->r_offset); reloc_type = ELF32_R_TYPE(rpnt->r_info); symtab_index = ELF32_R_SYM(rpnt->r_info); symbol_addr = 0; + sym_ref.sym = &symtab[symtab_index]; + sym_ref.tpnt = NULL; symname = strtab + symtab[symtab_index].st_name; - if (symtab_index && - (ELF32_ST_VISIBILITY(symtab[symtab_index].st_other) - != STV_PROTECTED)) { + if (symtab_index) { symbol_addr = (unsigned long)_dl_find_hash(symname, scope, tpnt, - ¤t_value, elf_machine_type_class(reloc_type), &tls_tpnt); + elf_machine_type_class(reloc_type), &sym_ref); /* * We want to allow undefined references to weak symbols - this @@ -191,16 +190,12 @@ _dl_do_reloc(struct elf_resolve *tpnt, struct r_scope_elem *scope, if (unlikely(!symbol_addr && (ELF_ST_TYPE(symtab[symtab_index].st_info) != STT_TLS) && ELF32_ST_BIND(symtab[symtab_index].st_info) != STB_WEAK)) return 1; - if (_dl_trace_prelink) _dl_debug_lookup (symname, tpnt, &symtab[symtab_index], - ¤t_value, elf_machine_type_class(reloc_type)); + &sym_ref, elf_machine_type_class(reloc_type)); + tls_tpnt = sym_ref.tpnt; } else { - if (symtab_index) - symbol_addr = DL_FIND_HASH_VALUE(tpnt, elf_machine_type_class(reloc_type), - &symtab[symtab_index]); - else - symbol_addr = symtab[symtab_index].st_value; + symbol_addr = symtab[symtab_index].st_value; tls_tpnt = tpnt; } diff --git a/ldso/ldso/ldso.c b/ldso/ldso/ldso.c index e0d323a9f..2ff441194 100644 --- a/ldso/ldso/ldso.c +++ b/ldso/ldso/ldso.c @@ -380,7 +380,7 @@ void *_dl_get_ready_to_run(struct elf_resolve *tpnt, DL_LOADADDR_TYPE load_addr, ElfW(Phdr) *ppnt; ElfW(Dyn) *dpnt; char *lpntstr; - unsigned int i, cnt, k, nscope_elem; + unsigned int i, cnt, nscope_elem; int unlazy = 0, trace_loaded_objects = 0; struct dyn_elf *rpnt; struct elf_resolve *tcurr; @@ -1128,6 +1128,7 @@ of this helper program; chances are you did not intend to run this program.\n\ local_scope = _dl_malloc(nscope_elem * sizeof(struct elf_resolve *)); i = 1; for (tcurr = _dl_loaded_modules->next; tcurr; tcurr = tcurr->next) { + unsigned int k; cnt = _dl_build_local_scope(local_scope, scope_elem_list[i++]); tcurr->symbol_scope.r_list = _dl_malloc(cnt * sizeof(struct elf_resolve *)); tcurr->symbol_scope.r_nlist = cnt; @@ -1312,7 +1313,7 @@ of this helper program; chances are you did not intend to run this program.\n\ * ld.so.1, so we have to look up each symbol individually. */ - _dl_envp = (unsigned long *) (intptr_t) _dl_find_hash(__C_SYMBOL_PREFIX__ "__environ", global_scope, NULL, NULL, 0, NULL); + _dl_envp = (unsigned long *) (intptr_t) _dl_find_hash(__C_SYMBOL_PREFIX__ "__environ", global_scope, NULL, 0, NULL); if (_dl_envp) *_dl_envp = (unsigned long) envp; @@ -1368,21 +1369,21 @@ of this helper program; chances are you did not intend to run this program.\n\ /* Find the real malloc function and make ldso functions use that from now on */ _dl_malloc_function = (void* (*)(size_t)) (intptr_t) _dl_find_hash(__C_SYMBOL_PREFIX__ "malloc", - global_scope, NULL, NULL, ELF_RTYPE_CLASS_PLT, NULL); + global_scope, NULL, ELF_RTYPE_CLASS_PLT, NULL); #if defined(USE_TLS) && USE_TLS /* Find the real functions and make ldso functions use them from now on */ _dl_calloc_function = (void* (*)(size_t, size_t)) (intptr_t) - _dl_find_hash(__C_SYMBOL_PREFIX__ "calloc", global_scope, NULL, NULL, ELF_RTYPE_CLASS_PLT, NULL); + _dl_find_hash(__C_SYMBOL_PREFIX__ "calloc", global_scope, NULL, ELF_RTYPE_CLASS_PLT, NULL); _dl_realloc_function = (void* (*)(void *, size_t)) (intptr_t) - _dl_find_hash(__C_SYMBOL_PREFIX__ "realloc", global_scope, NULL, NULL, ELF_RTYPE_CLASS_PLT, NULL); + _dl_find_hash(__C_SYMBOL_PREFIX__ "realloc", global_scope, NULL, ELF_RTYPE_CLASS_PLT, NULL); _dl_free_function = (void (*)(void *)) (intptr_t) - _dl_find_hash(__C_SYMBOL_PREFIX__ "free", global_scope, NULL, NULL, ELF_RTYPE_CLASS_PLT, NULL); + _dl_find_hash(__C_SYMBOL_PREFIX__ "free", global_scope, NULL, ELF_RTYPE_CLASS_PLT, NULL); _dl_memalign_function = (void* (*)(size_t, size_t)) (intptr_t) - _dl_find_hash(__C_SYMBOL_PREFIX__ "memalign", global_scope, NULL, NULL, ELF_RTYPE_CLASS_PLT, NULL); + _dl_find_hash(__C_SYMBOL_PREFIX__ "memalign", global_scope, NULL, ELF_RTYPE_CLASS_PLT, NULL); #endif diff --git a/ldso/ldso/m68k/elfinterp.c b/ldso/ldso/m68k/elfinterp.c index 195dba5e5..8ad4ae58b 100644 --- a/ldso/ldso/m68k/elfinterp.c +++ b/ldso/ldso/m68k/elfinterp.c @@ -70,7 +70,7 @@ _dl_linux_resolver(struct elf_resolve *tpnt, int reloc_entry) got_addr = (char **)instr_addr; /* Get the address of the GOT entry. */ - new_addr = _dl_find_hash(symname, &_dl_loaded_modules->symbol_scope, tpnt, NULL, ELF_RTYPE_CLASS_PLT, NULL); + new_addr = _dl_find_hash(symname, &_dl_loaded_modules->symbol_scope, tpnt, ELF_RTYPE_CLASS_PLT, NULL); if (unlikely(!new_addr)) { _dl_dprintf(2, "%s: Can't resolve symbol '%s'\n", _dl_progname, symname); _dl_exit(1); @@ -157,37 +157,36 @@ _dl_do_reloc(struct elf_resolve *tpnt, struct r_scope_elem *scope, int reloc_type; int symtab_index; char *symname; - ElfW(Sym) *sym; + struct symbol_ref sym_ref; ElfW(Addr) *reloc_addr; ElfW(Addr) symbol_addr; #if defined (__SUPPORT_LD_DEBUG__) ElfW(Addr) old_val; #endif - struct sym_val current_value = { NULL, NULL }; - reloc_addr = (ElfW(Addr)*)(tpnt->loadaddr + (unsigned long)rpnt->r_offset); reloc_type = ELF_R_TYPE(rpnt->r_info); symtab_index = ELF_R_SYM(rpnt->r_info); - sym = &symtab[symtab_index]; + sym_ref.sym = &symtab[symtab_index]; + sym_ref.tpnt = NULL; symbol_addr = 0; - symname = strtab + sym->st_name; + symname = strtab + sym_ref.sym->st_name; if (symtab_index) { symbol_addr = (ElfW(Addr))_dl_find_hash(symname, scope, tpnt, - ¤t_value, elf_machine_type_class(reloc_type), NULL); + elf_machine_type_class(reloc_type), &sym_ref); /* * We want to allow undefined references to weak symbols - this * might have been intentional. We should not be linking local * symbols here, so all bases should be covered. */ - if (unlikely(!symbol_addr && ELF_ST_BIND(sym->st_info) != STB_WEAK)) { + if (unlikely(!symbol_addr && ELF_ST_BIND(sym_ref.sym->st_info) != STB_WEAK)) { _dl_dprintf(2, "%s: can't resolve symbol '%s'\n", _dl_progname, symname); _dl_exit(1); } if (_dl_trace_prelink) _dl_debug_lookup (symname, tpnt, &symtab[symtab_index], - |