1da0c48c4Sopenharmony_ci/* Compute hash value for given string according to ELF standard.
2da0c48c4Sopenharmony_ci   Copyright (C) 1995-2015 Free Software Foundation, Inc.
3da0c48c4Sopenharmony_ci   This file is part of the GNU C Library.
4da0c48c4Sopenharmony_ci
5da0c48c4Sopenharmony_ci   The GNU C Library is free software; you can redistribute it and/or
6da0c48c4Sopenharmony_ci   modify it under the terms of the GNU Lesser General Public
7da0c48c4Sopenharmony_ci   License as published by the Free Software Foundation; either
8da0c48c4Sopenharmony_ci   version 2.1 of the License, or (at your option) any later version.
9da0c48c4Sopenharmony_ci
10da0c48c4Sopenharmony_ci   The GNU C Library is distributed in the hope that it will be useful,
11da0c48c4Sopenharmony_ci   but WITHOUT ANY WARRANTY; without even the implied warranty of
12da0c48c4Sopenharmony_ci   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13da0c48c4Sopenharmony_ci   Lesser General Public License for more details.
14da0c48c4Sopenharmony_ci
15da0c48c4Sopenharmony_ci   You should have received a copy of the GNU Lesser General Public
16da0c48c4Sopenharmony_ci   License along with the GNU C Library; if not, see
17da0c48c4Sopenharmony_ci   <http://www.gnu.org/licenses/>.  */
18da0c48c4Sopenharmony_ci
19da0c48c4Sopenharmony_ci#ifndef _DL_HASH_H
20da0c48c4Sopenharmony_ci#define _DL_HASH_H	1
21da0c48c4Sopenharmony_ci
22da0c48c4Sopenharmony_ci
23da0c48c4Sopenharmony_ci/* This is the hashing function specified by the ELF ABI.  In the
24da0c48c4Sopenharmony_ci   first five operations no overflow is possible so we optimized it a
25da0c48c4Sopenharmony_ci   bit.  */
26da0c48c4Sopenharmony_cistatic unsigned int
27da0c48c4Sopenharmony_ci__attribute__ ((unused))
28da0c48c4Sopenharmony_ci_dl_elf_hash (const char *name_arg)
29da0c48c4Sopenharmony_ci{
30da0c48c4Sopenharmony_ci  const unsigned char *name = (const unsigned char *) name_arg;
31da0c48c4Sopenharmony_ci  unsigned long int hash = *name;
32da0c48c4Sopenharmony_ci  if (hash != 0 && name[1] != '\0')
33da0c48c4Sopenharmony_ci    {
34da0c48c4Sopenharmony_ci      hash = (hash << 4) + name[1];
35da0c48c4Sopenharmony_ci      if (name[2] != '\0')
36da0c48c4Sopenharmony_ci	{
37da0c48c4Sopenharmony_ci	  hash = (hash << 4) + name[2];
38da0c48c4Sopenharmony_ci	  if (name[3] != '\0')
39da0c48c4Sopenharmony_ci	    {
40da0c48c4Sopenharmony_ci	      hash = (hash << 4) + name[3];
41da0c48c4Sopenharmony_ci	      if (name[4] != '\0')
42da0c48c4Sopenharmony_ci		{
43da0c48c4Sopenharmony_ci		  hash = (hash << 4) + name[4];
44da0c48c4Sopenharmony_ci		  name += 5;
45da0c48c4Sopenharmony_ci		  while (*name != '\0')
46da0c48c4Sopenharmony_ci		    {
47da0c48c4Sopenharmony_ci		      unsigned long int hi;
48da0c48c4Sopenharmony_ci		      hash = (hash << 4) + *name++;
49da0c48c4Sopenharmony_ci		      hi = hash & 0xf0000000;
50da0c48c4Sopenharmony_ci
51da0c48c4Sopenharmony_ci		      /* The algorithm specified in the ELF ABI is as
52da0c48c4Sopenharmony_ci			 follows:
53da0c48c4Sopenharmony_ci
54da0c48c4Sopenharmony_ci			 if (hi != 0)
55da0c48c4Sopenharmony_ci			   hash ^= hi >> 24;
56da0c48c4Sopenharmony_ci
57da0c48c4Sopenharmony_ci			 hash &= ~hi;
58da0c48c4Sopenharmony_ci
59da0c48c4Sopenharmony_ci			 But the following is equivalent and a lot
60da0c48c4Sopenharmony_ci			 faster, especially on modern processors.  */
61da0c48c4Sopenharmony_ci
62da0c48c4Sopenharmony_ci		      hash ^= hi >> 24;
63da0c48c4Sopenharmony_ci		    }
64da0c48c4Sopenharmony_ci
65da0c48c4Sopenharmony_ci		  /* Second part of the modified formula.  This
66da0c48c4Sopenharmony_ci		     operation can be lifted outside the loop.  */
67da0c48c4Sopenharmony_ci		  hash &= 0x0fffffff;
68da0c48c4Sopenharmony_ci		}
69da0c48c4Sopenharmony_ci	    }
70da0c48c4Sopenharmony_ci	}
71da0c48c4Sopenharmony_ci    }
72da0c48c4Sopenharmony_ci  return hash;
73da0c48c4Sopenharmony_ci}
74da0c48c4Sopenharmony_ci
75da0c48c4Sopenharmony_ci#endif /* dl-hash.h */
76