diff options
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], - ¤t_value, elf_machine_type_class(reloc_type)); + &sym_ref, elf_machine_type_class(reloc_type)); } #if defined (__SUPPORT_LD_DEBUG__) @@ -235,12 +234,12 @@ _dl_do_reloc(struct elf_resolve *tpnt, struct r_scope_elem *scope, if (_dl_debug_move) _dl_dprintf(_dl_debug_file, "\t%s move %d bytes from %x to %x\n", - symname, sym->st_size, + symname, sym_ref.sym->st_size, symbol_addr, reloc_addr); #endif _dl_memcpy ((void *) reloc_addr, (void *) symbol_addr, - sym->st_size); + sym_ref.sym->st_size); } else _dl_dprintf(_dl_debug_file, "no symbol_addr to copy !?\n"); break; diff --git a/ldso/ldso/mips/elfinterp.c b/ldso/ldso/mips/elfinterp.c index 2a433e282..3ca403609 100644 --- a/ldso/ldso/mips/elfinterp.c +++ b/ldso/ldso/mips/elfinterp.c @@ -56,7 +56,7 @@ unsigned long __dl_runtime_resolve(unsigned long sym_index, symname = strtab + sym->st_name; new_addr = (unsigned long) _dl_find_hash(symname, - &_dl_loaded_modules->symbol_scope, tpnt, NULL, ELF_RTYPE_CLASS_PLT, NULL); + &_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); @@ -111,7 +111,7 @@ __dl_runtime_pltresolve(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); @@ -161,8 +161,7 @@ int _dl_parse_relocation_information(struct dyn_elf *xpnt, unsigned long old_val=0; #endif - struct sym_val current_value = { NULL, NULL }; - + struct symbol_ref sym_ref = { NULL, NULL }; /* Now parse the relocation information */ rel_size = rel_size / sizeof(ElfW(Rel)); rpnt = (ELF_RELOC *) rel_addr; @@ -171,6 +170,7 @@ int _dl_parse_relocation_information(struct dyn_elf *xpnt, strtab = (char *) tpnt->dynamic_info[DT_STRTAB]; got = (unsigned long *) tpnt->dynamic_info[DT_PLTGOT]; + for (i = 0; i < rel_size; i++, rpnt++) { reloc_addr = (unsigned long *) (tpnt->loadaddr + (unsigned long) rpnt->r_offset); @@ -189,13 +189,13 @@ int _dl_parse_relocation_information(struct dyn_elf *xpnt, if (reloc_type == R_MIPS_JUMP_SLOT || reloc_type == R_MIPS_COPY) { symbol_addr = (unsigned long)_dl_find_hash(symname, scope, - tpnt, ¤t_value, - elf_machine_type_class(reloc_type), NULL); + tpnt, + elf_machine_type_class(reloc_type), &sym_ref); if (unlikely(!symbol_addr && 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)); } if (!symtab_index) { /* Relocs against STN_UNDEF are usually treated as using a @@ -217,23 +217,26 @@ int _dl_parse_relocation_information(struct dyn_elf *xpnt, case R_MIPS_TLS_TPREL32: # endif { - struct elf_resolve *tpnt_tls = NULL; + struct elf_resolve *tls_tpnt = NULL; + sym_ref.sym = &symtab[symtab_index]; + sym_ref.tpnt = NULL; if (ELF32_ST_BIND(symtab[symtab_index].st_info) != STB_LOCAL) { symbol_addr = (unsigned long) _dl_find_hash(symname, scope, - tpnt, ¤t_value, elf_machine_type_class(reloc_type), &tpnt_tls); + tpnt, elf_machine_type_class(reloc_type), &sym_ref); + tls_tpnt = sym_ref.tpnt; } - /* In case of a TLS reloc, tpnt_tls NULL means we have an 'anonymous' + /* In case of a TLS reloc, tls_tpnt NULL means we have an 'anonymous' symbol. This is the case for a static tls variable, so the lookup module is just that one is referencing the tls variable. */ - if (!tpnt_tls) - tpnt_tls = tpnt; + if (!tls_tpnt) + tls_tpnt = tpnt; switch (reloc_type) { case R_MIPS_TLS_DTPMOD64: case R_MIPS_TLS_DTPMOD32: - if (tpnt_tls) - *(ElfW(Word) *)reloc_addr = tpnt_tls->l_tls_modid; + if (tls_tpnt) + *(ElfW(Word) *)reloc_addr = tls_tpnt->l_tls_modid; #ifdef __SUPPORT_LD_DEBUG__ _dl_dprintf(2, "TLS_DTPMOD : %s, %d, %d\n", symname, old_val, *((unsigned int *)reloc_addr)); @@ -252,9 +255,9 @@ int _dl_parse_relocation_information(struct dyn_elf *xpnt, case R_MIPS_TLS_TPREL32: case R_MIPS_TLS_TPREL64: - CHECK_STATIC_TLS((struct link_map *)tpnt_tls); + CHECK_STATIC_TLS((struct link_map *)tls_tpnt); *(ElfW(Word) *)reloc_addr += - TLS_TPREL_VALUE (tpnt_tls, symbol_addr); + TLS_TPREL_VALUE (tls_tpnt, symbol_addr); #ifdef __SUPPORT_LD_DEBUG__ _dl_dprintf(2, "TLS_TPREL : %s, %x, %x\n", symname, old_val, *((unsigned int *)reloc_addr)); @@ -362,12 +365,12 @@ void _dl_perform_mips_global_got_relocations(struct elf_resolve *tpnt, int lazy) } else { *got_entry = (unsigned long) _dl_find_hash(strtab + - sym->st_name, &_dl_loaded_modules->symbol_scope, tpnt, NULL, ELF_RTYPE_CLASS_PLT, NULL); + sym->st_name, &_dl_loaded_modules->symbol_scope, tpnt, ELF_RTYPE_CLASS_PLT, NULL); } } else if (sym->st_shndx == SHN_COMMON) { *got_entry = (unsigned long) _dl_find_hash(strtab + - sym->st_name, &_dl_loaded_modules->symbol_scope, tpnt, NULL, ELF_RTYPE_CLASS_PLT, NULL); + sym->st_name, &_dl_loaded_modules->symbol_scope, tpnt, ELF_RTYPE_CLASS_PLT, NULL); } else if (ELF_ST_TYPE(sym->st_info) == STT_FUNC && *got_entry != sym->st_value && tmp_lazy) { @@ -379,7 +382,7 @@ void _dl_perform_mips_global_got_relocations(struct elf_resolve *tpnt, int lazy) } else { *got_entry = (unsigned long) _dl_find_hash(strtab + - sym->st_name, &_dl_loaded_modules->symbol_scope, tpnt, NULL, ELF_RTYPE_CLASS_PLT, NULL); + sym->st_name, &_dl_loaded_modules->symbol_scope, tpnt, ELF_RTYPE_CLASS_PLT, NULL); } got_entry++; diff --git a/ldso/ldso/powerpc/elfinterp.c b/ldso/ldso/powerpc/elfinterp.c index 043534ed1..78085ecb0 100644 --- a/ldso/ldso/powerpc/elfinterp.c +++ b/ldso/ldso/powerpc/elfinterp.c @@ -139,7 +139,7 @@ unsigned long _dl_linux_resolver(struct elf_resolve *tpnt, int reloc_entry) /* Get the address of the GOT entry */ finaladdr = (Elf32_Addr) _dl_find_hash(symname, - &_dl_loaded_modules->symbol_scope, tpnt, NULL, ELF_RTYPE_CLASS_PLT, NULL); + &_dl_loaded_modules->symbol_scope, tpnt, ELF_RTYPE_CLASS_PLT, NULL); if (unlikely(!finaladdr)) { _dl_dprintf(2, "%s: can't resolve symbol '%s' in lib '%s'.\n", _dl_progname, symname, tpnt->libname); _dl_exit(1); @@ -187,7 +187,7 @@ _dl_do_reloc (struct elf_resolve *tpnt,struct r_scope_elem *scope, { int reloc_type; int symtab_index; - ElfW(Sym) *sym; + struct symbol_ref sym_ref; Elf32_Addr *reloc_addr; Elf32_Addr finaladdr; struct elf_resolve *tls_tpnt = NULL; @@ -197,33 +197,32 @@ _dl_do_reloc (struct elf_resolve *tpnt,struct r_scope_elem *scope, unsigned long old_val; #endif - struct sym_val current_value = { NULL, NULL }; - symbol_addr = tpnt->loadaddr; /* For R_PPC_RELATIVE */ reloc_addr = (Elf32_Addr *)(intptr_t) (symbol_addr + (unsigned long) rpnt->r_offset); reloc_type = ELF32_R_TYPE(rpnt->r_info); symtab_index = ELF32_R_SYM(rpnt->r_info); - sym = &symtab[symtab_index]; - symname = strtab + sym->st_name; + sym_ref.sym = &symtab[symtab_index]; + sym_ref.tpnt = NULL; + symname = strtab + sym_ref.sym->st_name; 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 might * have been intentional. We should not be linking local symbols * here, so all bases should be covered. */ if (unlikely(!symbol_addr - && (ELF32_ST_TYPE(sym->st_info) != STT_TLS - && ELF32_ST_BIND(sym->st_info) != STB_WEAK))) + && (ELF32_ST_TYPE(sym_ref.sym->st_info) != STT_TLS + && ELF32_ST_BIND(sym_ref.sym->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 { - symbol_addr = sym->st_value; + symbol_addr = sym_ref.sym->st_value; tls_tpnt = tpnt; } - #if defined (__SUPPORT_LD_DEBUG__) old_val = *reloc_addr; #endif @@ -271,10 +270,10 @@ _dl_do_reloc (struct elf_resolve *tpnt,struct r_scope_elem *scope, #if defined (__SUPPORT_LD_DEBUG__) if (_dl_debug_move) _dl_dprintf(_dl_debug_file,"\n%s move %x bytes from %x to %x", - symname, sym->st_size, + symname, sym_ref.sym->st_size, symbol_addr, reloc_addr); #endif - _dl_memcpy((char *) reloc_addr, (char *) finaladdr, sym->st_size); + _dl_memcpy((char *) reloc_addr, (char *) finaladdr, sym_ref.sym->st_size); goto out_nocode; /* No code code modified */ case R_PPC_ADDR16_HA: finaladdr += 0x8000; /* fall through. */ diff --git a/ldso/ldso/sh/elfinterp.c b/ldso/ldso/sh/elfinterp.c index 928a84b40..293bfe31e 100644 --- a/ldso/ldso/sh/elfinterp.c +++ b/ldso/ldso/sh/elfinterp.c @@ -69,7 +69,7 @@ unsigned long _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); @@ -161,42 +161,38 @@ _dl_do_reloc (struct elf_resolve *tpnt, struct r_scope_elem *scope, #endif struct elf_resolve *tls_tpnt = NULL; - 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; if (symtab_index) { symname = strtab + symtab[symtab_index].st_name; - if (ELF32_ST_VISIBILITY(symtab[symtab_index].st_other) - != STV_PROTECTED) { - symbol_addr = (unsigned long) _dl_find_hash(symname, scope, tpnt, ¤t_value, - elf_machine_type_class(reloc_type), &tls_tpnt); - /* - * 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 (!symbol_addr - && (ELF_ST_TYPE(symtab[symtab_index].st_info) != STT_TLS) - && (ELF32_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); - - /* Let the caller to handle the error: it may be non fatal if called from dlopen */ - return 1; - } - } else - /* Resolve protected symbols locally */ - symbol_addr = DL_FIND_HASH_VALUE(tpnt, elf_machine_type_class(reloc_type), - &symtab[symtab_index]); - + symbol_addr = (unsigned long) _dl_find_hash(symname, scope, tpnt, + 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 (!symbol_addr + && (ELF_ST_TYPE(symtab[symtab_index].st_info) != STT_TLS) + && (ELF32_ST_BIND(symtab[symtab_index].st_info) != STB_WEAK)) { + _dl_dprintf(2, "%s: can't resolve symbol '%s'\n", + _dl_progname, symname); + + /* Let the caller to handle the error: it may be non fatal if called from dlopen */ + 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; } #if defined (__SUPPORT_LD_DEBUG__) diff --git a/ldso/ldso/sh64/elfinterp.c b/ldso/ldso/sh64/elfinterp.c index 8f6b32067..caf9f0e14 100644 --- a/ldso/ldso/sh64/elfinterp.c +++ b/ldso/ldso/sh64/elfinterp.c @@ -73,7 +73,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); + 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); @@ -173,13 +173,14 @@ static int _dl_do_reloc(struct elf_resolve *tpnt,struct r_scope_elem *scope, #ifdef __SUPPORT_LD_DEBUG__ unsigned long old_val; #endif - - struct sym_val current_value = { NULL, NULL }; + struct symbol_ref sym_ref; reloc_type = ELF32_R_TYPE(rpnt->r_info); symtab_index = ELF32_R_SYM(rpnt->r_info); symbol_addr = 0; lsb = !!(symtab[symtab_index].st_other & STO_SH5_ISA32); + sym_ref.sym = &symtab[symtab_index]; + sym_ref.tpnt = NULL; symname = strtab + symtab[symtab_index].st_name; reloc_addr = (unsigned long *)(intptr_t) (tpnt->loadaddr + (unsigned long)rpnt->r_offset); @@ -188,7 +189,7 @@ static int _dl_do_reloc(struct elf_resolve *tpnt,struct r_scope_elem *scope, int stb; 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); /* * We want to allow undefined references to weak symbols - this @@ -199,12 +200,12 @@ static int _dl_do_reloc(struct elf_resolve *tpnt,struct r_scope_elem *scope, if (stb != STB_WEAK && !symbol_addr) { _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)); } #ifdef __SUPPORT_LD_DEBUG__ diff --git a/ldso/ldso/sparc/elfinterp.c b/ldso/ldso/sparc/elfinterp.c index b33ad91b1..3c928073b 100644 --- a/ldso/ldso/sparc/elfinterp.c +++ b/ldso/ldso/sparc/elfinterp.c @@ -80,7 +80,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); @@ -171,44 +171,44 @@ _dl_do_reloc(struct elf_resolve *tpnt, struct r_scope_elem *scope, int symtab_index; char *symname; struct elf_resolve *tls_tpnt = 0; - 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), &tls_tpnt); + symbol_addr = (ElfW(Addr))_dl_find_hash(symname, scope, tpnt, + 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_TYPE(sym->st_info) != STT_TLS) - && (ELF_ST_BIND(sym->st_info) != STB_WEAK))) { + if (unlikely(!symbol_addr && (ELF_ST_TYPE(sym_ref.sym->st_info) != STT_TLS) + && (ELF_ST_BIND(sym_ref.sym->st_info) != STB_WEAK))) { /* This may be non-fatal if called from dlopen. */ 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 { /* Relocs against STN_UNDEF are usually treated as using a * symbol value of zero, and using the module containing the * reloc itself. */ - symbol_addr = sym->st_value; + symbol_addr = sym_ref.sym->st_value; tls_tpnt = tpnt; } @@ -267,13 +267,13 @@ _dl_do_reloc(struct elf_resolve *tpnt, struct r_scope_elem *scope, if (_dl_debug_move) _dl_dprintf(_dl_debug_file, "\t%s move %d bytes from %x to %x\n", - symname, sym->st_size, + symname, sym_ref.sym->st_size, symbol_addr, reloc_addr); #endif _dl_memcpy((char *)reloc_addr, (char *)symbol_addr, - sym->st_size); + sym_ref.sym->st_size); } else _dl_dprintf(_dl_debug_file, "no symbol_addr to copy !?\n"); break; @@ -285,7 +285,7 @@ _dl_do_reloc(struct elf_resolve *tpnt, struct r_scope_elem *scope, case R_SPARC_TLS_DTPOFF32: /* During relocation all TLS symbols are defined and used. * Therefore the offset is already correct. */ - *reloc_addr = sym->st_value + rpnt->r_addend; + *reloc_addr = sym_ref.sym->st_value + rpnt->r_addend; break; case R_SPARC_TLS_TPOFF32: @@ -294,7 +294,7 @@ _dl_do_reloc(struct elf_resolve *tpnt, struct r_scope_elem *scope, * It is a negative value which will be added to the * thread pointer. */ CHECK_STATIC_TLS ((struct link_map *) tls_tpnt); - *reloc_addr = sym->st_value - tls_tpnt->l_tls_offset + rpnt->r_addend; + *reloc_addr = sym_ref.sym->st_value - tls_tpnt->l_tls_offset + rpnt->r_addend; break; #endif default: diff --git a/ldso/ldso/x86_64/elfinterp.c b/ldso/ldso/x86_64/elfinterp.c index de5a8c01e..a36b1154c 100644 --- a/ldso/ldso/x86_64/elfinterp.c +++ b/ldso/ldso/x86_64/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); @@ -158,43 +158,43 @@ _dl_do_reloc(struct elf_resolve *tpnt, struct r_scope_elem *scope, int symtab_index; char *symname; struct elf_resolve *tls_tpnt = 0; - 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), &tls_tpnt); + symbol_addr = (ElfW(Addr))_dl_find_hash(symname, scope, tpnt, + 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_TYPE(sym->st_info) != STT_TLS) - && (ELF_ST_BIND(sym->st_info) != STB_WEAK))) { + if (unlikely(!symbol_addr && (ELF_ST_TYPE(sym_ref.sym->st_info) != STT_TLS) + && (ELF_ST_BIND(sym_ref.sym->st_info) != STB_WEAK))) { /* This may be non-fatal if called from dlopen. */ 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 { /* Relocs against STN_UNDEF are usually treated as using a * symbol value of zero, and using the module containing the * reloc itself. */ - symbol_addr = sym->st_value; + symbol_addr = sym_ref.sym->st_value; tls_tpnt = tpnt; } @@ -253,13 +253,13 @@ _dl_do_reloc(struct elf_resolve *tpnt, struct r_scope_elem *scope, if (_dl_debug_move) _dl_dprintf(_dl_debug_file, "\t%s move %d bytes from %x to %x\n", - symname, sym->st_size, + symname, sym_ref.sym->st_size, symbol_addr, reloc_addr); #endif _dl_memcpy((char *)reloc_addr, (char *)symbol_addr, - sym->st_size); + sym_ref.sym->st_size); } else _dl_dprintf(_dl_debug_file, "no symbol_addr to copy !?\n"); break; diff --git a/ldso/ldso/xtensa/elfinterp.c b/ldso/ldso/xtensa/elfinterp.c index 59f641571..93edc1ff2 100644 --- a/ldso/ldso/xtensa/elfinterp.c +++ b/ldso/ldso/xtensa/elfinterp.c @@ -146,26 +146,25 @@ _dl_do_reloc (struct elf_resolve *tpnt, struct r_scope_elem *scope, int reloc_type; int symtab_index; char *symname; - Elf32_Sym *sym; + struct symbol_ref sym_ref; Elf32_Addr *reloc_addr; Elf32_Addr symbol_addr; #if defined (__SUPPORT_LD_DEBUG__) Elf32_Addr old_val; #endif - struct sym_val current_value = { NULL, NULL }; - reloc_addr = (Elf32_Addr *) (tpnt->loadaddr + rpnt->r_offset); reloc_type = ELF32_R_TYPE (rpnt->r_info); symtab_index = ELF32_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 = (Elf32_Addr) - _dl_find_hash (symname, 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); /* * We want to allow undefined references to weak symbols - this might @@ -173,14 +172,14 @@ _dl_do_reloc (struct elf_resolve *tpnt, struct r_scope_elem *scope, * here, so all bases should be covered. */ if (unlikely (!symbol_addr && - ELF32_ST_BIND (sym->st_info) != STB_WEAK)) { + ELF32_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], - ¤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/libdl/libdl.c b/ldso/libdl/libdl.c index 3b49216d4..f95341be7 100644 --- a/ldso/libdl/libdl.c +++ b/ldso/libdl/libdl.c @@ -652,6 +652,7 @@ void *dlsym(void *vhandle, const char *name) struct dyn_elf *rpnt; void *ret; struct elf_resolve *tls_tpnt = NULL; + struct symbol_ref sym_ref = { NULL, NULL }; /* Nastiness to support underscore prefixes. */ #ifdef __UCLIBC_UNDERSCORES__ char tmp_buf[80]; @@ -706,13 +707,13 @@ void *dlsym(void *vhandle, const char *name) tpnt = NULL; if (handle == _dl_symbol_tables) tpnt = handle->dyn; /* Only search RTLD_GLOBAL objs if global object */ - ret = _dl_find_hash(name2, &handle->dyn->symbol_scope, NULL, NULL, 0, &tls_tpnt); + ret = _dl_find_hash(name2, &handle->dyn->symbol_scope, tpnt, 0, &sym_ref); #if defined(USE_TLS) && USE_TLS && defined SHARED - if (tls_tpnt) { + if (sym_ref.tpnt) { /* The found symbol is a thread-local storage variable. Return the address for to the current thread. */ - ret = _dl_tls_symaddr ((struct link_map *)tls_tpnt, (Elf32_Addr)ret); + ret = _dl_tls_symaddr ((struct link_map *)sym_ref.tpnt, (Elf32_Addr)ret); } #endif diff --git a/libc/misc/syslog/syslog.c b/libc/misc/syslog/syslog.c index b10a55615..f1b848f0b 100644 --- a/libc/misc/syslog/syslog.c +++ b/libc/misc/syslog/syslog.c @@ -205,7 +205,7 @@ vsyslog(int pri, const char *fmt, va_list ap) if ((LogMask & LOG_MASK(LOG_PRI(pri))) == 0) goto getout; if (LogFile < 0 || !connected) - openlog_intern(NULL, LogStat | LOG_NDELAY, LOG_USER); + openlog_intern(NULL, LogStat | LOG_NDELAY, (int)LogFacility << 3); /* Set default facility if none specified. */ if ((pri & LOG_FACMASK) == 0) diff --git a/libc/stdio/_scanf.c b/libc/stdio/_scanf.c index 34c1c9abd..28cd21e30 100644 --- a/libc/stdio/_scanf.c +++ b/libc/stdio/_scanf.c @@ -924,7 +924,10 @@ int attribute_hidden __psfs_parse_spec(register psfs_t *psfs) goto ERROR_EINVAL; } - if ((p_m_spec_chars >= CONV_c) + if (p_m_spec_chars == CONV_p) { + /* a pointer has the same size as 'long int' */ + psfs->dataargtype = PA_FLAG_LONG; + } else if ((p_m_spec_chars >= CONV_c) && (psfs->dataargtype & PA_FLAG_LONG)) { p_m_spec_chars -= 3; /* lc -> C, ls -> S, l[ -> ?? */ } diff --git a/libc/sysdeps/linux/cris/sys/user.h b/libc/sysdeps/linux/cris/sys/user.h new file mode 100644 index 000000000..d629c30d7 --- /dev/null +++ b/libc/sysdeps/linux/cris/sys/user.h @@ -0,0 +1,81 @@ +#ifndef __ASM_CRIS_USER_H +#define __ASM_CRIS_USER_H + +/* User-mode register used for core dumps. */ + +struct user_fpregs { +}; + +struct user_regs_struct { + unsigned long r0; /* General registers. */ + unsigned long r1; + unsigned long r2; + unsigned long r3; + unsigned long r4; + unsigned long r5; + unsigned long r6; + unsigned long r7; + unsigned long r8; + unsigned long r9; + unsigned long r10; + unsigned long r11; + unsigned long r12; + unsigned long r13; + unsigned long sp; /* R14, Stack pointer. */ + unsigned long acr; /* R15, Address calculation register. */ + unsigned long bz; /* P0, Constant zero (8-bits). */ + unsigned long vr; /* P1, Version register (8-bits). */ + unsigned long pid; /* P2, Process ID (8-bits). */ + unsigned long srs; /* P3, Support register select (8-bits). */ + unsigned long wz; /* P4, Constant zero (16-bits). */ + unsigned long exs; /* P5, Exception status. */ + unsigned long eda; /* P6, Exception data address. */ + unsigned long mof; /* P7, Multiply overflow regiter. */ + unsigned long dz; /* P8, Constant zero (32-bits). */ + unsigned long ebp; /* P9, Exception base pointer. */ + unsigned long erp; /* P10, Exception return pointer. */ + unsigned long srp; /* P11, Subroutine return pointer. */ + unsigned long nrp; /* P12, NMI return pointer. */ + unsigned long ccs; /* P13, Condition code stack. */ + unsigned long usp; /* P14, User mode stack pointer. */ + unsigned long spc; /* P15, Single step PC. */ +}; + +/* + * Core file format: The core file is written in such a way that gdb + * can understand it and provide useful information to the user (under + * linux we use the `trad-core' bfd). The file contents are as follows: + * + * upage: 1 page consisting of a user struct that tells gdb + * what is present in the file. Directly after this is a + * copy of the task_struct, which is currently not used by gdb, + * but it may come in handy at some point. All of the registers + * are stored as part of the upage. The upage should always be + * only one page long. + * data: The data segment follows next. We use current->end_text to + * current->brk to pick up all of the user variables, plus any memory + * that may have been sbrk'ed. No attempt is made to determine if a + * page is demand-zero or if a page is totally unused, we just cover + * the entire range. All of the addresses are rounded in such a way + * that an integral number of pages is written. + * stack: We need the stack information in order to get a meaningful + * backtrace. We need to write the data from usp to + * current->start_stack, so we round each of these in order to be able + * to write an integer number of pages. + */ + +struct user { + struct user_regs_struct regs; /* entire machine state */ + size_t u_tsize; /* text size (pages) */ + size_t u_dsize; /* data size (pages) */ + size_t u_ssize; /* stack size (pages) */ + unsigned long start_code; /* text starting address */ + unsigned long start_data; /* data starting address */ + unsigned long start_stack; /* stack starting address */ + long int signal; /* signal causing core dump */ + unsigned long u_ar0; /* help gdb find registers */ + unsigned long magic; /* identifies a core file */ + char u_comm[32]; /* user command name */ +}; + +#endif /* __ASM_CRIS_USER_H */ diff --git a/libc/sysdeps/linux/cris/sysdep.h b/libc/sysdeps/linux/cris/sysdep.h index 593e7772e..5960fe235 100644 --- a/libc/sysdeps/linux/cris/sysdep.h +++ b/libc/sysdeps/linux/cris/sysdep.h @@ -20,6 +20,8 @@ #ifndef _SYSDEP_H_ #define _SYSDEP_H_ +#include <sys/syscall.h> + #ifndef C_LABEL /* Define a macro we can use to construct the asm name for a C symbol. */ diff --git a/libpthread/nptl/allocatestack.c b/libpthread/nptl/allocatestack.c index 9ffa7e7e2..1c549cee1 100644 --- a/libpthread/nptl/allocatestack.c +++ b/libpthread/nptl/allocatestack.c @@ -993,7 +993,7 @@ setxid_signal_thread (struct xid_command *cmdp, struct pthread *t) int val; INTERNAL_SYSCALL_DECL (err); -#if __ASSUME_TGKILL +#if defined (__ASSUME_TGKILL) && __ASSUME_TGKILL val = INTERNAL_SYSCALL (tgkill, err, 3, THREAD_GETMEM (THREAD_SELF, pid), t->tid, SIGSETXID); #else diff --git a/libpthread/nptl/pthreadP.h b/libpthread/nptl/pthreadP.h index c45bd1170..fbac7d08f 100644 --- a/libpthread/nptl/pthreadP.h +++ b/libpthread/nptl/pthreadP.h @@ -274,6 +274,8 @@ __do_cancel (void) #define CANCEL_RESET(oldtype) \ __pthread_disable_asynccancel (oldtype) +#define __LABEL_PREFIX__ __stringify(__USER_LABEL_PREFIX__) + #if !defined NOT_IN_libc /* Same as CANCEL_ASYNC, but for use in libc.so. */ # define LIBC_CANCEL_ASYNC() \ @@ -282,22 +284,22 @@ __do_cancel (void) # define LIBC_CANCEL_RESET(oldtype) \ __libc_disable_asynccancel (oldtype) # define LIBC_CANCEL_HANDLED() \ - __asm__ (".globl " __USER_LABEL_PREFIX__ "__libc_enable_asynccancel"); \ - __asm__ (".globl " __USER_LABEL_PREFIX__ "__libc_disable_asynccancel") + __asm__ (".globl " __LABEL_PREFIX__ "__libc_enable_asynccancel"); \ + __asm__ (".globl " __LABEL_PREFIX__ "__libc_disable_asynccancel") #elif defined NOT_IN_libc && defined IS_IN_libpthread # define LIBC_CANCEL_ASYNC() CANCEL_ASYNC () # define LIBC_CANCEL_RESET(val) CANCEL_RESET (val) # define LIBC_CANCEL_HANDLED() \ - __asm__ (".globl " __USER_LABEL_PREFIX__ "__pthread_enable_asynccancel"); \ - __asm__ (".globl " __USER_LABEL_PREFIX__ "__pthread_disable_asynccancel") + __asm__ (".globl " __LABEL_PREFIX__ "__pthread_enable_asynccancel"); \ + __asm__ (".globl " __LABEL_PREFIX__ "__pthread_disable_asynccancel") #elif defined NOT_IN_libc && defined IS_IN_librt # define LIBC_CANCEL_ASYNC() \ __librt_enable_asynccancel () # define LIBC_CANCEL_RESET(val) \ __librt_disable_asynccancel (val) # define LIBC_CANCEL_HANDLED() \ - __asm__ (".globl " __USER_LABEL_PREFIX__ "__librt_enable_asynccancel"); \ - __asm__ (".globl " __USER_LABEL_PREFIX__ "__librt_disable_asynccancel") + __asm__ (".globl " __LABEL_PREFIX__ "__librt_enable_asynccancel"); \ + __asm__ (".globl " __LABEL_PREFIX__ "__librt_disable_asynccancel") #else # define LIBC_CANCEL_ASYNC() 0 /* Just a dummy value. */ # define LIBC_CANCEL_RESET(val) ((void)(val)) /* Nothing, but evaluate it. */ diff --git a/libpthread/nptl/pthread_cancel.c b/libpthread/nptl/pthread_cancel.c index 4a958bcde..163fa0243 100644 --- a/libpthread/nptl/pthread_cancel.c +++ b/libpthread/nptl/pthread_cancel.c @@ -76,7 +76,7 @@ pthread_cancel ( a signal handler. But this is no allowed, pthread_cancel is not guaranteed to be async-safe. */ int val; -#if __ASSUME_TGKILL +#if defined(__ASSUME_TGKILL) && __ASSUME_TGKILL val = INTERNAL_SYSCALL (tgkill, err, 3, THREAD_GETMEM (THREAD_SELF, pid), pd->tid, SIGCANCEL); diff --git a/libpthread/nptl/pthread_create.c b/libpthread/nptl/pthread_create.c index 63e5588d5..86ff1488b 100644 --- a/libpthread/nptl/pthread_create.c +++ b/libpthread/nptl/pthread_create.c @@ -379,11 +379,11 @@ start_thread (void *arg) /* Mark the memory of the stack as usable to the kernel. We free everything except for the space used for the TCB itself. */ size_t pagesize_m1 = __getpagesize () - 1; -#ifdef _STACK_GROWS_DOWN char *sp = CURRENT_STACK_FRAME; +#ifdef _STACK_GROWS_DOWN size_t freesize = (sp - (char *) pd->stackblock) & ~pagesize_m1; #else -# error "to do" + size_t freesize = ((char *) pd->stackblock - sp) & ~pagesize_m1; #endif assert (freesize < pd->stackblock_size); if (freesize > PTHREAD_STACK_MIN) diff --git a/libpthread/nptl/sysdeps/pthread/createthread.c b/libpthread/nptl/sysdeps/pthread/createthread.c index a676e277f..ce86f5f33 100644 --- a/libpthread/nptl/sysdeps/pthread/createthread.c +++ b/libpthread/nptl/sysdeps/pthread/createthread.c @@ -106,7 +106,7 @@ do_clone (struct pthread *pd, const struct pthread_attr *attr, send it the cancellation signal. */ INTERNAL_SYSCALL_DECL (err2); err_out: -#if __ASSUME_TGKILL +#if defined (__ASSUME_TGKILL) && __ASSUME_TGKILL (void) INTERNAL_SYSCALL (tgkill, err2, 3, THREAD_GETMEM (THREAD_SELF, pid), pd->tid, SIGCANCEL); diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/pt-raise.c b/libpthread/nptl/sysdeps/unix/sysv/linux/pt-raise.c index d256ebcb0..622bb66ca 100644 --- a/libpthread/nptl/sysdeps/unix/sysv/linux/pt-raise.c +++ b/libpthread/nptl/sysdeps/unix/sysv/linux/pt-raise.c @@ -28,7 +28,7 @@ int raise ( int sig) { -#if __ASSUME_TGKILL || defined __NR_tgkill +#if (defined(__ASSUME_TGKILL) && __ASSUME_TGKILL) || defined __NR_tgkill /* raise is an async-safe function. It could be called while the fork function temporarily invalidated the PID field. Adjust for that. */ @@ -37,7 +37,7 @@ raise ( pid = -pid; #endif -#if __ASSUME_TGKILL +#if defined(__ASSUME_TGKILL) && __ASSUME_TGKILL return INLINE_SYSCALL (tgkill, 3, pid, THREAD_GETMEM (THREAD_SELF, tid), sig); #else diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/pthread_kill.c b/libpthread/nptl/sysdeps/unix/sysv/linux/pthread_kill.c index 3a70c3764..2d6bb8002 100644 --- a/libpthread/nptl/sysdeps/unix/sysv/linux/pthread_kill.c +++ b/libpthread/nptl/sysdeps/unix/sysv/linux/pthread_kill.c @@ -59,7 +59,7 @@ __pthread_kill ( fork, it would have to happen in a signal handler. But this is no allowed, pthread_kill is not guaranteed to be async-safe. */ int val; -#if __ASSUME_TGKILL +#if defined(__ASSUME_TGKILL) && __ASSUME_TGKILL val = INTERNAL_SYSCALL (tgkill, err, 3, THREAD_GETMEM (THREAD_SELF, pid), tid, signo); #else diff --git a/libpthread/nptl/sysdeps/unix/sysv/linux/raise.c b/libpthread/nptl/sysdeps/unix/sysv/linux/raise.c index da35cfe9f..708ed6d76 100644 --- a/libpthread/nptl/sysdeps/unix/sysv/linux/raise.c +++ b/libpthread/nptl/sysdeps/unix/sysv/linux/raise.c @@ -30,7 +30,7 @@ raise ( int sig) { struct pthread *pd = THREAD_SELF; -#if __ASSUME_TGKILL || defined __NR_tgkill +#if (defined(__ASSUME_TGKILL) && __ASSUME_TGKILL) || defined __NR_tgkill pid_t pid = THREAD_GETMEM (pd, pid); #endif pid_t selftid = THREAD_GETMEM (pd, tid); @@ -45,13 +45,13 @@ raise ( #endif THREAD_SETMEM (pd, tid, selftid); -#if __ASSUME_TGKILL || defined __NR_tgkill +#if (defined(__ASSUME_TGKILL) && __ASSUME_TGKILL) || defined __NR_tgkill /* We do not set the PID field in the TID here since we might be called from a signal handler while the thread executes fork. */ pid = selftid; #endif } -#if __ASSUME_TGKILL || defined __NR_tgkill +#if (defined(__ASSUME_TGKILL) && __ASSUME_TGKILL) || defined __NR_tgkill else /* raise is an async-safe function. It could be called while the fork/vfork function temporarily invalidated the PID field. Adjust for @@ -60,7 +60,7 @@ raise ( pid = (pid & INT_MAX) == 0 ? selftid : -pid; #endif -#if __ASSUME_TGKILL +#if defined(__ASSUME_TGKILL) && __ASSUME_TGKILL return INLINE_SYSCALL (tgkill, 3, pid, selftid, sig); #else # ifdef __NR_tgkill |