diff options
-rw-r--r-- | libelf/ChangeLog | 4 | ||||
-rw-r--r-- | libelf/dl-hash.h | 75 |
2 files changed, 38 insertions, 41 deletions
diff --git a/libelf/ChangeLog b/libelf/ChangeLog index bb56e5b2..6fba0640 100644 --- a/libelf/ChangeLog +++ b/libelf/ChangeLog @@ -1,3 +1,7 @@ +2015-06-22 Mark Wielaard <mjw@redhat.com> + + * dl-hash.h: Update from glibc. + 2015-06-18 Mark Wielaard <mjw@redhat.com> * elf32_updatefile.c (updatefile): Always free shdr_data and scns diff --git a/libelf/dl-hash.h b/libelf/dl-hash.h index e286d2e8..6ee5d1a6 100644 --- a/libelf/dl-hash.h +++ b/libelf/dl-hash.h @@ -1,31 +1,20 @@ /* Compute hash value for given string according to ELF standard. - Copyright (C) 2006 Red Hat, Inc. - This file is part of elfutils. - Written by Ulrich Drepper <drepper@redhat.com>, 1995. + Copyright (C) 1995-2015 Free Software Foundation, Inc. + This file is part of the GNU C Library. - This file is free software; you can redistribute it and/or modify - it under the terms of either + 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 Lesser General Public License as published by the Free - Software Foundation; either version 3 of the License, or (at - your option) any later version - - or - - * the GNU General Public License as published by the Free - Software Foundation; either version 2 of the License, or (at - your option) any later version - - or both in parallel, as here. - - elfutils is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of + 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 - General Public License for more details. + Lesser General Public License for more details. - You should have received copies of the GNU General Public License and - the GNU Lesser General Public License along with this program. If - not, see <http://www.gnu.org/licenses/>. */ + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + <http://www.gnu.org/licenses/>. */ #ifndef _DL_HASH_H #define _DL_HASH_H 1 @@ -34,44 +23,48 @@ /* This is the hashing function specified by the ELF ABI. In the first five operations no overflow is possible so we optimized it a bit. */ -static inline unsigned int -__attribute__ ((__pure__)) -_dl_elf_hash (const char *name) +static unsigned int +__attribute__ ((unused)) +_dl_elf_hash (const char *name_arg) { - const unsigned char *iname = (const unsigned char *) name; - unsigned int hash = (unsigned int) *iname++; - if (*iname != '\0') + const unsigned char *name = (const unsigned char *) name_arg; + unsigned long int hash = *name; + if (hash != 0 && name[1] != '\0') { - hash = (hash << 4) + (unsigned int) *iname++; - if (*iname != '\0') + hash = (hash << 4) + name[1]; + if (name[2] != '\0') { - hash = (hash << 4) + (unsigned int) *iname++; - if (*iname != '\0') + hash = (hash << 4) + name[2]; + if (name[3] != '\0') { - hash = (hash << 4) + (unsigned int) *iname++; - if (*iname != '\0') + hash = (hash << 4) + name[3]; + if (name[4] != '\0') { - hash = (hash << 4) + (unsigned int) *iname++; - while (*iname != '\0') + hash = (hash << 4) + name[4]; + name += 5; + while (*name != '\0') { - unsigned int hi; - hash = (hash << 4) + (unsigned int) *iname++; + unsigned long int hi; + hash = (hash << 4) + *name++; hi = hash & 0xf0000000; /* The algorithm specified in the ELF ABI is as follows: if (hi != 0) - hash ^= hi >> 24; + hash ^= hi >> 24; hash &= ~hi; But the following is equivalent and a lot faster, especially on modern processors. */ - hash ^= hi; hash ^= hi >> 24; } + + /* Second part of the modified formula. This + operation can be lifted outside the loop. */ + hash &= 0x0fffffff; } } } |