Branch data Line data Source code
1 : : /* Compute hash value for given string according to ELF standard.
2 : : Copyright (C) 2006 Red Hat, Inc.
3 : : This file is part of elfutils.
4 : : Written by Ulrich Drepper <drepper@redhat.com>, 1995.
5 : :
6 : : This file is free software; you can redistribute it and/or modify
7 : : it under the terms of either
8 : :
9 : : * the GNU Lesser General Public License as published by the Free
10 : : Software Foundation; either version 3 of the License, or (at
11 : : your option) any later version
12 : :
13 : : or
14 : :
15 : : * the GNU General Public License as published by the Free
16 : : Software Foundation; either version 2 of the License, or (at
17 : : your option) any later version
18 : :
19 : : or both in parallel, as here.
20 : :
21 : : elfutils is distributed in the hope that it will be useful, but
22 : : WITHOUT ANY WARRANTY; without even the implied warranty of
23 : : MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
24 : : General Public License for more details.
25 : :
26 : : You should have received copies of the GNU General Public License and
27 : : the GNU Lesser General Public License along with this program. If
28 : : not, see <http://www.gnu.org/licenses/>. */
29 : :
30 : : #ifndef _DL_HASH_H
31 : : #define _DL_HASH_H 1
32 : :
33 : :
34 : : /* This is the hashing function specified by the ELF ABI. In the
35 : : first five operations no overflow is possible so we optimized it a
36 : : bit. */
37 : : static inline unsigned int
38 : : __attribute__ ((__pure__))
39 : 88818 : _dl_elf_hash (const char *name)
40 : : {
41 : 88818 : const unsigned char *iname = (const unsigned char *) name;
42 : 88818 : unsigned int hash = (unsigned int) *iname++;
43 [ + + ]: 88818 : if (*iname != '\0')
44 : : {
45 : 88796 : hash = (hash << 4) + (unsigned int) *iname++;
46 [ + + ]: 88796 : if (*iname != '\0')
47 : : {
48 : 88615 : hash = (hash << 4) + (unsigned int) *iname++;
49 [ + + ]: 88615 : if (*iname != '\0')
50 : : {
51 : 86802 : hash = (hash << 4) + (unsigned int) *iname++;
52 [ + + ]: 86802 : if (*iname != '\0')
53 : : {
54 : 68792 : hash = (hash << 4) + (unsigned int) *iname++;
55 [ + + ]: 77894 : while (*iname != '\0')
56 : : {
57 : : unsigned int hi;
58 : 9102 : hash = (hash << 4) + (unsigned int) *iname++;
59 : 9102 : hi = hash & 0xf0000000;
60 : :
61 : : /* The algorithm specified in the ELF ABI is as
62 : : follows:
63 : :
64 : : if (hi != 0)
65 : : hash ^= hi >> 24;
66 : :
67 : : hash &= ~hi;
68 : :
69 : : But the following is equivalent and a lot
70 : : faster, especially on modern processors. */
71 : :
72 : 9102 : hash ^= hi;
73 : 9102 : hash ^= hi >> 24;
74 : : }
75 : : }
76 : : }
77 : : }
78 : : }
79 : 88818 : return hash;
80 : : }
81 : :
82 : : #endif /* dl-hash.h */
|