| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577 | diff -Nur glibc-2.10.1/ports/sysdeps/mips/dl-lookup.c glibc-2.10.90/ports/sysdeps/mips/dl-lookup.c--- glibc-2.10.1/ports/sysdeps/mips/dl-lookup.c	2009-08-20 08:59:52.000000000 +0200+++ glibc-2.10.90/ports/sysdeps/mips/dl-lookup.c	2009-05-26 22:53:27.000000000 +0200@@ -1,6 +1,9 @@ /* Look up a symbol in the loaded objects.-   MIPS/Linux version - special handling of non-PIC undefined symbol rules.-   Copyright (C) 1995-2005, 2006, 2007, 2009 Free Software Foundation, Inc.+   MIPS/Linux version - this is identical to the common version, but+   because it is in sysdeps/mips, it gets sysdeps/mips/do-lookup.h.+   Using <do-lookup.h> instead of "do-lookup.h" would work too.++   Copyright (C) 1995-2005, 2006, 2007 Free Software Foundation, Inc.    This file is part of the GNU C Library.     The GNU C Library is free software; you can redistribute it and/or@@ -70,387 +73,8 @@ #endif  -/* Inner part of the lookup functions.  We return a value > 0 if we-   found the symbol, the value 0 if nothing is found and < 0 if-   something bad happened.  */-static int-__attribute_noinline__-do_lookup_x (const char *undef_name, uint_fast32_t new_hash,-	     unsigned long int *old_hash, const ElfW(Sym) *ref,-	     struct sym_val *result, struct r_scope_elem *scope, size_t i,-	     const struct r_found_version *const version, int flags,-	     struct link_map *skip, int type_class, struct link_map *undef_map)-{-  size_t n = scope->r_nlist;-  /* Make sure we read the value before proceeding.  Otherwise we-     might use r_list pointing to the initial scope and r_nlist being-     the value after a resize.  That is the only path in dl-open.c not-     protected by GSCOPE.  A read barrier here might be to expensive.  */-  __asm volatile ("" : "+r" (n), "+m" (scope->r_list));-  struct link_map **list = scope->r_list;--  do-    {-      /* These variables are used in the nested function.  */-      Elf_Symndx symidx;-      int num_versions = 0;-      const ElfW(Sym) *versioned_sym = NULL;--      const struct link_map *map = list[i]->l_real;--      /* Here come the extra test needed for `_dl_lookup_symbol_skip'.  */-      if (map == skip)-	continue;--      /* Don't search the executable when resolving a copy reloc.  */-      if ((type_class & ELF_RTYPE_CLASS_COPY) && map->l_type == lt_executable)-	continue;--      /* Do not look into objects which are going to be removed.  */-      if (map->l_removed)-	continue;--      /* Print some debugging info if wanted.  */-      if (__builtin_expect (GLRO(dl_debug_mask) & DL_DEBUG_SYMBOLS, 0))-	_dl_debug_printf ("symbol=%s;  lookup in file=%s [%lu]\n",-			  undef_name,-			  map->l_name[0] ? map->l_name : rtld_progname,-			  map->l_ns);--      /* If the hash table is empty there is nothing to do here.  */-      if (map->l_nbuckets == 0)-	continue;--      /* The tables for this map.  */-      const ElfW(Sym) *symtab = (const void *) D_PTR (map, l_info[DT_SYMTAB]);-      const char *strtab = (const void *) D_PTR (map, l_info[DT_STRTAB]);---      /* Nested routine to check whether the symbol matches.  */-      const ElfW(Sym) *-      __attribute_noinline__-      check_match (const ElfW(Sym) *sym)-      {-	unsigned int stt = ELFW(ST_TYPE) (sym->st_info);-	assert (ELF_RTYPE_CLASS_PLT == 1);-	/* The semantics of zero/non-zero values of undefined symbols-	   differs depending on whether the non-PIC ABI is in use.-	   Under the non-PIC ABI, a non-zero value indicates that-	   there is an address reference to the symbol and thus it-	   must always be resolved (except when resolving a jump slot-	   relocation) to the PLT entry whose address is provided as-	   the symbol's value; a zero value indicates that this-	   canonical-address behaviour is not required.  Yet under the-	   classic MIPS psABI, a zero value indicates that there is an-	   address reference to the function and the dynamic linker-	   must resolve the symbol immediately upon loading.  To avoid-	   conflict, symbols for which the dynamic linker must assume-	   the non-PIC ABI semantics are marked with the STO_MIPS_PLT-	   flag.  */-	if (__builtin_expect ((sym->st_value == 0 /* No value.  */-			       && stt != STT_TLS)-			      || (sym->st_shndx == SHN_UNDEF-				  && !(sym->st_other & STO_MIPS_PLT))-			      || (type_class & (sym->st_shndx == SHN_UNDEF)),-			      0))-	  return NULL;--	/* Ignore all but STT_NOTYPE, STT_OBJECT, STT_FUNC,-	   STT_COMMON, STT_TLS, and STT_GNU_IFUNC since these are no-	   code/data definitions.  */-#define ALLOWED_STT \-	((1 << STT_NOTYPE) | (1 << STT_OBJECT) | (1 << STT_FUNC) \-	 | (1 << STT_COMMON) | (1 << STT_TLS) | (1 << STT_GNU_IFUNC))-	if (__builtin_expect (((1 << stt) & ALLOWED_STT) == 0, 0))-	  return NULL;--	if (sym != ref && strcmp (strtab + sym->st_name, undef_name))-	  /* Not the symbol we are looking for.  */-	  return NULL;--	const ElfW(Half) *verstab = map->l_versyms;-	if (version != NULL)-	  {-	    if (__builtin_expect (verstab == NULL, 0))-	      {-		/* We need a versioned symbol but haven't found any.  If-		   this is the object which is referenced in the verneed-		   entry it is a bug in the library since a symbol must-		   not simply disappear.--		   It would also be a bug in the object since it means that-		   the list of required versions is incomplete and so the-		   tests in dl-version.c haven't found a problem.*/-		assert (version->filename == NULL-			|| ! _dl_name_match_p (version->filename, map));--		/* Otherwise we accept the symbol.  */-	      }-	    else-	      {-		/* We can match the version information or use the-		   default one if it is not hidden.  */-		ElfW(Half) ndx = verstab[symidx] & 0x7fff;-		if ((map->l_versions[ndx].hash != version->hash-		     || strcmp (map->l_versions[ndx].name, version->name))-		    && (version->hidden || map->l_versions[ndx].hash-			|| (verstab[symidx] & 0x8000)))-		  /* It's not the version we want.  */-		  return NULL;-	      }-	  }-	else-	  {-	    /* No specific version is selected.  There are two ways we-	       can got here:--	       - a binary which does not include versioning information-	       is loaded--	       - dlsym() instead of dlvsym() is used to get a symbol which-	       might exist in more than one form--	       If the library does not provide symbol version information-	       there is no problem at at: we simply use the symbol if it-	       is defined.--	       These two lookups need to be handled differently if the-	       library defines versions.  In the case of the old-	       unversioned application the oldest (default) version-	       should be used.  In case of a dlsym() call the latest and-	       public interface should be returned.  */-	    if (verstab != NULL)-	      {-		if ((verstab[symidx] & 0x7fff)-		    >= ((flags & DL_LOOKUP_RETURN_NEWEST) ? 2 : 3))-		  {-		    /* Don't accept hidden symbols.  */-		    if ((verstab[symidx] & 0x8000) == 0-			&& num_versions++ == 0)-		      /* No version so far.  */-		      versioned_sym = sym;--		    return NULL;-		  }-	      }-	  }--	/* There cannot be another entry for this symbol so stop here.  */-	return sym;-      }--      const ElfW(Sym) *sym;-      const ElfW(Addr) *bitmask = map->l_gnu_bitmask;-      if (__builtin_expect (bitmask != NULL, 1))-	{-	  ElfW(Addr) bitmask_word-	    = bitmask[(new_hash / __ELF_NATIVE_CLASS)-		      & map->l_gnu_bitmask_idxbits];--	  unsigned int hashbit1 = new_hash & (__ELF_NATIVE_CLASS - 1);-	  unsigned int hashbit2 = ((new_hash >> map->l_gnu_shift)-				   & (__ELF_NATIVE_CLASS - 1));--	  if (__builtin_expect ((bitmask_word >> hashbit1)-				& (bitmask_word >> hashbit2) & 1, 0))-	    {-	      Elf32_Word bucket = map->l_gnu_buckets[new_hash-						     % map->l_nbuckets];-	      if (bucket != 0)-		{-		  const Elf32_Word *hasharr = &map->l_gnu_chain_zero[bucket];--		  do-		    if (((*hasharr ^ new_hash) >> 1) == 0)-		      {-			symidx = hasharr - map->l_gnu_chain_zero;-			sym = check_match (&symtab[symidx]);-			if (sym != NULL)-			  goto found_it;-		      }-		  while ((*hasharr++ & 1u) == 0);-		}-	    }-	  /* No symbol found.  */-	  symidx = SHN_UNDEF;-	}-      else-	{-	  if (*old_hash == 0xffffffff)-	    *old_hash = _dl_elf_hash (undef_name);--	  /* Use the old SysV-style hash table.  Search the appropriate-	     hash bucket in this object's symbol table for a definition-	     for the same symbol name.  */-	  for (symidx = map->l_buckets[*old_hash % map->l_nbuckets];-	       symidx != STN_UNDEF;-	       symidx = map->l_chain[symidx])-	    {-	      sym = check_match (&symtab[symidx]);-	      if (sym != NULL)-		goto found_it;-	    }-	}--      /* If we have seen exactly one versioned symbol while we are-	 looking for an unversioned symbol and the version is not the-	 default version we still accept this symbol since there are-	 no possible ambiguities.  */-      sym = num_versions == 1 ? versioned_sym : NULL;--      if (sym != NULL)-	{-	found_it:-	  switch (__builtin_expect (ELFW(ST_BIND) (sym->st_info), STB_GLOBAL))-	    {-	    case STB_WEAK:-	      /* Weak definition.  Use this value if we don't find another.  */-	      if (__builtin_expect (GLRO(dl_dynamic_weak), 0))-		{-		  if (! result->s)-		    {-		      result->s = sym;-		      result->m = (struct link_map *) map;-		    }-		  break;-		}-	      /* FALLTHROUGH */-	    case STB_GLOBAL:-	    success:-	      /* Global definition.  Just what we need.  */-	      result->s = sym;-	      result->m = (struct link_map *) map;-	      return 1;--	    case STB_GNU_UNIQUE:;-	      /* We have to determine whether we already found a-		 symbol with this name before.  If not then we have to-		 add it to the search table.  If we already found a-		 definition we have to use it.  */-	      void enter (struct unique_sym *table, size_t size,-			  unsigned int hash, const char *name,-			  const ElfW(Sym) *sym, const struct link_map *map)-	      {-		size_t idx = hash % size;-		size_t hash2 = 1 + hash % (size - 2);-		while (1)-		  {-		    if (table[idx].hashval == 0)-		      {-			table[idx].hashval = hash;-			table[idx].name = strtab + sym->st_name;-			if ((type_class & ELF_RTYPE_CLASS_COPY) != 0)-			  {-			    table[idx].sym = ref;-			    table[idx].map = undef_map;-			  }-			else-			  {-			    table[idx].sym = sym;-			    table[idx].map = map;-			  }-			return;-		      }--		    idx += hash2;-		    if (idx >= size)-		      idx -= size;-		  }-	      }--	      struct unique_sym_table *tab-		= &GL(dl_ns)[map->l_ns]._ns_unique_sym_table;--	      __rtld_lock_lock_recursive (tab->lock);--	      struct unique_sym *entries = tab->entries;-	      size_t size = tab->size;-	      if (entries != NULL)-		{-		  size_t idx = new_hash % size;-		  size_t hash2 = 1 + new_hash % (size - 2);-		  while (1)-		    {-		      if (entries[idx].hashval == new_hash-			  && strcmp (entries[idx].name, undef_name) == 0)-			{-			  result->s = entries[idx].sym;-			  result->m = (struct link_map *) entries[idx].map;-			  __rtld_lock_unlock_recursive (tab->lock);-			  return 1;-			}--		      if (entries[idx].hashval == 0-			  && entries[idx].name == NULL)-			break;--		      idx += hash2;-		      if (idx >= size)-			idx -= size;-		    }--		  if (size * 3 <= tab->n_elements)-		    {-		      /* Expand the table.  */-		      size_t newsize = _dl_higher_prime_number (size);-		      struct unique_sym *newentries-			= calloc (sizeof (struct unique_sym), newsize);-		      if (newentries == NULL)-			{-			nomem:-			  __rtld_lock_unlock_recursive (tab->lock);-			  _dl_fatal_printf ("out of memory\n");-			}--		      for (idx = 0; idx < size; ++idx)-			if (entries[idx].hashval != 0)-			  enter (newentries, newsize, entries[idx].hashval,-				 entries[idx].name, entries[idx].sym,-				 entries[idx].map);--		      tab->free (entries);-		      tab->size = newsize;-		      entries = tab->entries = newentries;-		      tab->free = free;-		    }-		}-	      else-		{-#define INITIAL_NUNIQUE_SYM_TABLE 31-		  size = INITIAL_NUNIQUE_SYM_TABLE;-		  entries = calloc (sizeof (struct unique_sym), size);-		  if (entries == NULL)-		    goto nomem;--		  tab->entries = entries;-		  tab->size = size;-		  tab->free = free;-		}--	      enter (entries, size, new_hash, strtab + sym->st_name, sym, map);-	      ++tab->n_elements;--	      __rtld_lock_unlock_recursive (tab->lock);--	      goto success;--	    default:-	      /* Local symbols are ignored.  */-	      break;-	    }-	}--      /* If this current map is the one mentioned in the verneed entry-	 and we have not found a weak entry, it is a bug.  */-      if (symidx == STN_UNDEF && version != NULL && version->filename != NULL-	  && __builtin_expect (_dl_name_match_p (version->filename, map), 0))-	return -1;-    }-  while (++i < n);--  /* We have not found anything until now.  */-  return 0;-}+/* The actual lookup code.  */+#include "do-lookup.h"   static uint_fast32_t@@ -717,7 +341,7 @@     {       int res = do_lookup_x (undef_name, new_hash, &old_hash, *ref, 			     ¤t_value, *scope, start, version, flags,-			     skip_map, type_class, undef_map);+			     skip_map, type_class);       if (res > 0) 	break; @@ -790,7 +414,7 @@ 	  for (scope = symbol_scope; *scope != NULL; i = 0, ++scope) 	    if (do_lookup_x (undef_name, new_hash, &old_hash, *ref, 			     &protected_value, *scope, i, version, flags,-			     skip_map, ELF_RTYPE_CLASS_PLT, NULL) != 0)+			     skip_map, ELF_RTYPE_CLASS_PLT) != 0) 	      break;  	  if (protected_value.s != NULL && protected_value.m != undef_map)@@ -916,26 +540,21 @@  	  do_lookup_x (undef_name, new_hash, &old_hash, *ref, &val, 		       undef_map->l_local_scope[0], 0, version, 0, NULL,-		       type_class, undef_map);+		       type_class);  	  if (val.s != value->s || val.m != value->m) 	    conflict = 1; 	} -      if (value->s)-	{-	  if (__builtin_expect (ELFW(ST_TYPE) (value->s->st_info)-				== STT_TLS, 0))-	    type_class = 4;-	  else if (__builtin_expect (ELFW(ST_TYPE) (value->s->st_info)-				     == STT_GNU_IFUNC, 0))-	    type_class |= 8;-	}+      if (value->s+	  && (__builtin_expect (ELFW(ST_TYPE) (value->s->st_info)+				== STT_TLS, 0)))+	type_class = 4;        if (conflict 	  || GLRO(dl_trace_prelink_map) == undef_map 	  || GLRO(dl_trace_prelink_map) == NULL-	  || type_class >= 4)+	  || type_class == 4) 	{ 	  _dl_printf ("%s 0x%0*Zx 0x%0*Zx -> 0x%0*Zx 0x%0*Zx ", 		      conflict ? "conflict" : "lookup",diff -Nur glibc-2.10.1/ports/sysdeps/mips/do-lookup.h glibc-2.10.90/ports/sysdeps/mips/do-lookup.h--- glibc-2.10.1/ports/sysdeps/mips/do-lookup.h	1970-01-01 01:00:00.000000000 +0100+++ glibc-2.10.90/ports/sysdeps/mips/do-lookup.h	2009-05-26 22:53:27.000000000 +0200@@ -0,0 +1,37 @@+/* MIPS-specific veneer to GLIBC's do-lookup.h.+   Copyright (C) 2008 Free Software Foundation, Inc.+   This file is part of the GNU C Library.++   The GNU C Library is free software; you can redistribute it and/or+   modify it under the terms of the GNU Lesser General Public+   License as published by the Free Software Foundation; either+   version 2.1 of the License, or (at your option) any later version.++   The GNU C Library is distributed in the hope that it will be useful,+   but WITHOUT ANY WARRANTY; without even the implied warranty of+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU+   Lesser General Public License for more details.++   You should have received a copy of the GNU Lesser General Public+   License along with the GNU C Library; if not, write to the Free+   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA+   02111-1307 USA.  */++/* The semantics of zero/non-zero values of undefined symbols differs+   depending on whether the non-PIC ABI is in use.  Under the non-PIC ABI,+   a non-zero value indicates that there is an address reference to the+   symbol and thus it must always be resolved (except when resolving a jump+   slot relocation) to the PLT entry whose address is provided as the+   symbol's value; a zero value indicates that this canonical-address+   behaviour is not required.  Yet under the classic MIPS psABI, a zero value+   indicates that there is an address reference to the function and the+   dynamic linker must resolve the symbol immediately upon loading.  To+   avoid conflict, symbols for which the dynamic linker must assume the+   non-PIC ABI semantics are marked with the STO_MIPS_PLT flag.  The+   following ugly hack causes the code in the platform-independent+   do-lookup.h file to check this flag correctly.  */+#define st_value st_shndx == SHN_UNDEF && !(sym->st_other & STO_MIPS_PLT)) \+		 || (sym->st_value+#include_next "do-lookup.h"+#undef st_value+diff -Nur glibc-2.10.1/ports/sysdeps/mips/__longjmp.c glibc-2.10.90/ports/sysdeps/mips/__longjmp.c--- glibc-2.10.1/ports/sysdeps/mips/__longjmp.c	2009-08-20 08:59:52.000000000 +0200+++ glibc-2.10.90/ports/sysdeps/mips/__longjmp.c	2009-05-26 22:53:26.000000000 +0200@@ -25,19 +25,19 @@ #endif  void-__longjmp (env_arg, val_arg)-     __jmp_buf env_arg;+__longjmp (env, val_arg)+     __jmp_buf env;      int val_arg; {   /* gcc 1.39.19 miscompiled the longjmp routine (as it did setjmp before      the hack around it); force it to use $a1 for the longjmp value.      Without this it saves $a1 in a register which gets clobbered      along the way.  */-  register struct __jmp_buf_internal_tag *env asm ("a0");   register int val asm ("a1"); #ifdef CHECK_SP   register long sp asm ("$29");-  CHECK_SP (env[0].__sp, sp, long);+  if ((long) (env[0].__sp) < sp)+    __fortify_fail ("longjmp causes uninitialized stack frame"); #endif  #ifdef __mips_hard_floatdiff -Nur glibc-2.10.1/ports/sysdeps/mips/____longjmp_chk.c glibc-2.10.90/ports/sysdeps/mips/____longjmp_chk.c--- glibc-2.10.1/ports/sysdeps/mips/____longjmp_chk.c	1970-01-01 01:00:00.000000000 +0100+++ glibc-2.10.90/ports/sysdeps/mips/____longjmp_chk.c	2009-05-26 22:53:26.000000000 +0200@@ -0,0 +1,22 @@+/* Copyright (C) 2009 Free Software Foundation, Inc.+   This file is part of the GNU C Library.++   The GNU C Library is free software; you can redistribute it and/or+   modify it under the terms of the GNU Lesser General Public+   License as published by the Free Software Foundation; either+   version 2.1 of the License, or (at your option) any later version.++   The GNU C Library is distributed in the hope that it will be useful,+   but WITHOUT ANY WARRANTY; without even the implied warranty of+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU+   Lesser General Public License for more details.++   You should have received a copy of the GNU Lesser General Public+   License along with the GNU C Library; if not, write to the Free+   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA+   02111-1307 USA.  */++#include <stdio.h>+#define __longjmp ____longjmp_chk+#define CHECK_SP+#include <__longjmp.c>diff -Nur glibc-2.10.1/ports/sysdeps/mips/mips64/__longjmp.c glibc-2.10.90/ports/sysdeps/mips/mips64/__longjmp.c--- glibc-2.10.1/ports/sysdeps/mips/mips64/__longjmp.c	2009-08-20 08:59:52.000000000 +0200+++ glibc-2.10.90/ports/sysdeps/mips/mips64/__longjmp.c	2009-05-26 22:53:27.000000000 +0200@@ -27,19 +27,19 @@ #endif  void-__longjmp (env_arg, val_arg)-     __jmp_buf env_arg;+__longjmp (env, val_arg)+     __jmp_buf env;      int val_arg; {   /* gcc 1.39.19 miscompiled the longjmp routine (as it did setjmp before      the hack around it); force it to use $a1 for the longjmp value.      Without this it saves $a1 in a register which gets clobbered      along the way.  */-  register struct __jmp_buf_internal_tag *env asm ("a0");   register int val asm ("a1"); #ifdef CHECK_SP   register long long sp asm ("$29");-  CHECK_SP (env[0].__sp, sp, long long);+  if ((long long) (env[0].__sp) < sp)+    __fortify_fail ("longjmp causes uninitialized stack frame"); #endif  #ifdef __mips_hard_float
 |