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_float
- diff -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
|