This is the mail archive of the elfutils-devel@sourceware.org mailing list for the elfutils project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[PATCH] 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. Copy it whenever the glibc version is updated.

Signed-off-by: Mark Wielaard <mjw@redhat.com>
---
 libelf/dl-hash.h | 75 +++++++++++++++++++++++++-------------------------------
 1 file changed, 34 insertions(+), 41 deletions(-)

diff --git a/libelf/dl-hash.h b/libelf/dl-hash.h
index e286d2e..6ee5d1a 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;
 		}
 	    }
 	}
-- 
1.8.3.1


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]