summaryrefslogtreecommitdiffstats
path: root/libelf
diff options
context:
space:
mode:
authorMark Wielaard <mjw@redhat.com>2015-09-22 14:20:45 +0200
committerMark Wielaard <mjw@redhat.com>2015-09-23 15:50:00 +0200
commite260d79d73be07aee2860c5a5baf4f12c230ad6b (patch)
treebbf773933ebda9c599878b147c95790beb76cd32 /libelf
parentdd8bd91f39c95947ad14cd43d30c17eb8c2827fc (diff)
downloadandroid_external_elfutils-e260d79d73be07aee2860c5a5baf4f12c230ad6b.tar.gz
android_external_elfutils-e260d79d73be07aee2860c5a5baf4f12c230ad6b.tar.bz2
android_external_elfutils-e260d79d73be07aee2860c5a5baf4f12c230ad6b.zip
Update dl-hash.h from glibc.
Our dl-hash.h implementation originally came from, or was written at the same time as, the glibc implementation. At some point (around 9 years ago) they diverged and the elfutils version got an updated copyright header. The glibc version saw various updates/optimizations. Just treat the file like we do for elf.h and copy it whenever the glibc version is updated. Signed-off-by: Mark Wielaard <mjw@redhat.com>
Diffstat (limited to 'libelf')
-rw-r--r--libelf/ChangeLog4
-rw-r--r--libelf/dl-hash.h75
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;
}
}
}