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 | 
