/src/binutils-gdb/bfd/hash.c
Line | Count | Source (jump to first uncovered line) |
1 | | /* hash.c -- hash table routines for BFD |
2 | | Copyright (C) 1993-2025 Free Software Foundation, Inc. |
3 | | Written by Steve Chamberlain <sac@cygnus.com> |
4 | | |
5 | | This file is part of BFD, the Binary File Descriptor library. |
6 | | |
7 | | This program is free software; you can redistribute it and/or modify |
8 | | it under the terms of the GNU General Public License as published by |
9 | | the Free Software Foundation; either version 3 of the License, or |
10 | | (at your option) any later version. |
11 | | |
12 | | This program is distributed in the hope that it will be useful, |
13 | | but WITHOUT ANY WARRANTY; without even the implied warranty of |
14 | | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
15 | | GNU General Public License for more details. |
16 | | |
17 | | You should have received a copy of the GNU General Public License |
18 | | along with this program; if not, write to the Free Software |
19 | | Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, |
20 | | MA 02110-1301, USA. */ |
21 | | |
22 | | #include "sysdep.h" |
23 | | #include "bfd.h" |
24 | | #include "libbfd.h" |
25 | | #include "objalloc.h" |
26 | | #include "libiberty.h" |
27 | | |
28 | | /* |
29 | | SECTION |
30 | | Hash Tables |
31 | | |
32 | | @cindex Hash tables |
33 | | BFD provides a simple set of hash table functions. Routines |
34 | | are provided to initialize a hash table, to free a hash table, |
35 | | to look up a string in a hash table and optionally create an |
36 | | entry for it, and to traverse a hash table. There is |
37 | | currently no routine to delete an string from a hash table. |
38 | | |
39 | | The basic hash table does not permit any data to be stored |
40 | | with a string. However, a hash table is designed to present a |
41 | | base class from which other types of hash tables may be |
42 | | derived. These derived types may store additional information |
43 | | with the string. Hash tables were implemented in this way, |
44 | | rather than simply providing a data pointer in a hash table |
45 | | entry, because they were designed for use by the linker back |
46 | | ends. The linker may create thousands of hash table entries, |
47 | | and the overhead of allocating private data and storing and |
48 | | following pointers becomes noticeable. |
49 | | |
50 | | The basic hash table code is in <<hash.c>>. |
51 | | |
52 | | @menu |
53 | | @* Creating and Freeing a Hash Table:: |
54 | | @* Looking Up or Entering a String:: |
55 | | @* Traversing a Hash Table:: |
56 | | @* Deriving a New Hash Table Type:: |
57 | | @end menu |
58 | | |
59 | | INODE |
60 | | Creating and Freeing a Hash Table, Looking Up or Entering a String, Hash Tables, Hash Tables |
61 | | SUBSECTION |
62 | | Creating and freeing a hash table |
63 | | |
64 | | @findex bfd_hash_table_init |
65 | | @findex bfd_hash_table_init_n |
66 | | To create a hash table, create an instance of a <<struct |
67 | | bfd_hash_table>> (defined in <<bfd.h>>) and call |
68 | | <<bfd_hash_table_init>> (if you know approximately how many |
69 | | entries you will need, the function <<bfd_hash_table_init_n>>, |
70 | | which takes a @var{size} argument, may be used). |
71 | | <<bfd_hash_table_init>> returns <<FALSE>> if some sort of |
72 | | error occurs. |
73 | | |
74 | | @findex bfd_hash_newfunc |
75 | | The function <<bfd_hash_table_init>> take as an argument a |
76 | | function to use to create new entries. For a basic hash |
77 | | table, use the function <<bfd_hash_newfunc>>. @xref{Deriving |
78 | | a New Hash Table Type}, for why you would want to use a |
79 | | different value for this argument. |
80 | | |
81 | | @findex bfd_hash_allocate |
82 | | <<bfd_hash_table_init>> will create an objalloc which will be |
83 | | used to allocate new entries. You may allocate memory on this |
84 | | objalloc using <<bfd_hash_allocate>>. |
85 | | |
86 | | @findex bfd_hash_table_free |
87 | | Use <<bfd_hash_table_free>> to free up all the memory that has |
88 | | been allocated for a hash table. This will not free up the |
89 | | <<struct bfd_hash_table>> itself, which you must provide. |
90 | | |
91 | | @findex bfd_hash_set_default_size |
92 | | Use <<bfd_hash_set_default_size>> to set the default size of |
93 | | hash table to use. |
94 | | |
95 | | INODE |
96 | | Looking Up or Entering a String, Traversing a Hash Table, Creating and Freeing a Hash Table, Hash Tables |
97 | | SUBSECTION |
98 | | Looking up or entering a string |
99 | | |
100 | | @findex bfd_hash_lookup |
101 | | The function <<bfd_hash_lookup>> is used both to look up a |
102 | | string in the hash table and to create a new entry. |
103 | | |
104 | | If the @var{create} argument is <<FALSE>>, <<bfd_hash_lookup>> |
105 | | will look up a string. If the string is found, it will |
106 | | returns a pointer to a <<struct bfd_hash_entry>>. If the |
107 | | string is not found in the table <<bfd_hash_lookup>> will |
108 | | return <<NULL>>. You should not modify any of the fields in |
109 | | the returns <<struct bfd_hash_entry>>. |
110 | | |
111 | | If the @var{create} argument is <<TRUE>>, the string will be |
112 | | entered into the hash table if it is not already there. |
113 | | Either way a pointer to a <<struct bfd_hash_entry>> will be |
114 | | returned, either to the existing structure or to a newly |
115 | | created one. In this case, a <<NULL>> return means that an |
116 | | error occurred. |
117 | | |
118 | | If the @var{create} argument is <<TRUE>>, and a new entry is |
119 | | created, the @var{copy} argument is used to decide whether to |
120 | | copy the string onto the hash table objalloc or not. If |
121 | | @var{copy} is passed as <<FALSE>>, you must be careful not to |
122 | | deallocate or modify the string as long as the hash table |
123 | | exists. |
124 | | |
125 | | INODE |
126 | | Traversing a Hash Table, Deriving a New Hash Table Type, Looking Up or Entering a String, Hash Tables |
127 | | SUBSECTION |
128 | | Traversing a hash table |
129 | | |
130 | | @findex bfd_hash_traverse |
131 | | The function <<bfd_hash_traverse>> may be used to traverse a |
132 | | hash table, calling a function on each element. The traversal |
133 | | is done in a random order. |
134 | | |
135 | | <<bfd_hash_traverse>> takes as arguments a function and a |
136 | | generic <<void *>> pointer. The function is called with a |
137 | | hash table entry (a <<struct bfd_hash_entry *>>) and the |
138 | | generic pointer passed to <<bfd_hash_traverse>>. The function |
139 | | must return a <<boolean>> value, which indicates whether to |
140 | | continue traversing the hash table. If the function returns |
141 | | <<FALSE>>, <<bfd_hash_traverse>> will stop the traversal and |
142 | | return immediately. |
143 | | |
144 | | INODE |
145 | | Deriving a New Hash Table Type, , Traversing a Hash Table, Hash Tables |
146 | | SUBSECTION |
147 | | Deriving a new hash table type |
148 | | |
149 | | Many uses of hash tables want to store additional information |
150 | | which each entry in the hash table. Some also find it |
151 | | convenient to store additional information with the hash table |
152 | | itself. This may be done using a derived hash table. |
153 | | |
154 | | Since C is not an object oriented language, creating a derived |
155 | | hash table requires sticking together some boilerplate |
156 | | routines with a few differences specific to the type of hash |
157 | | table you want to create. |
158 | | |
159 | | An example of a derived hash table is the linker hash table. |
160 | | The structures for this are defined in <<bfdlink.h>>. The |
161 | | functions are in <<linker.c>>. |
162 | | |
163 | | You may also derive a hash table from an already derived hash |
164 | | table. For example, the a.out linker backend code uses a hash |
165 | | table derived from the linker hash table. |
166 | | |
167 | | @menu |
168 | | @* Define the Derived Structures:: |
169 | | @* Write the Derived Creation Routine:: |
170 | | @* Write Other Derived Routines:: |
171 | | @end menu |
172 | | |
173 | | INODE |
174 | | Define the Derived Structures, Write the Derived Creation Routine, Deriving a New Hash Table Type, Deriving a New Hash Table Type |
175 | | SUBSUBSECTION |
176 | | Define the derived structures |
177 | | |
178 | | You must define a structure for an entry in the hash table, |
179 | | and a structure for the hash table itself. |
180 | | |
181 | | The first field in the structure for an entry in the hash |
182 | | table must be of the type used for an entry in the hash table |
183 | | you are deriving from. If you are deriving from a basic hash |
184 | | table this is <<struct bfd_hash_entry>>, which is defined in |
185 | | <<bfd.h>>. The first field in the structure for the hash |
186 | | table itself must be of the type of the hash table you are |
187 | | deriving from itself. If you are deriving from a basic hash |
188 | | table, this is <<struct bfd_hash_table>>. |
189 | | |
190 | | For example, the linker hash table defines <<struct |
191 | | bfd_link_hash_entry>> (in <<bfdlink.h>>). The first field, |
192 | | <<root>>, is of type <<struct bfd_hash_entry>>. Similarly, |
193 | | the first field in <<struct bfd_link_hash_table>>, <<table>>, |
194 | | is of type <<struct bfd_hash_table>>. |
195 | | |
196 | | INODE |
197 | | Write the Derived Creation Routine, Write Other Derived Routines, Define the Derived Structures, Deriving a New Hash Table Type |
198 | | SUBSUBSECTION |
199 | | Write the derived creation routine |
200 | | |
201 | | You must write a routine which will create and initialize an |
202 | | entry in the hash table. This routine is passed as the |
203 | | function argument to <<bfd_hash_table_init>>. |
204 | | |
205 | | In order to permit other hash tables to be derived from the |
206 | | hash table you are creating, this routine must be written in a |
207 | | standard way. |
208 | | |
209 | | The first argument to the creation routine is a pointer to a |
210 | | hash table entry. This may be <<NULL>>, in which case the |
211 | | routine should allocate the right amount of space. Otherwise |
212 | | the space has already been allocated by a hash table type |
213 | | derived from this one. |
214 | | |
215 | | After allocating space, the creation routine must call the |
216 | | creation routine of the hash table type it is derived from, |
217 | | passing in a pointer to the space it just allocated. This |
218 | | will initialize any fields used by the base hash table. |
219 | | |
220 | | Finally the creation routine must initialize any local fields |
221 | | for the new hash table type. |
222 | | |
223 | | Here is a boilerplate example of a creation routine. |
224 | | @var{function_name} is the name of the routine. |
225 | | @var{entry_type} is the type of an entry in the hash table you |
226 | | are creating. @var{base_newfunc} is the name of the creation |
227 | | routine of the hash table type your hash table is derived |
228 | | from. |
229 | | |
230 | | EXAMPLE |
231 | | |
232 | | .struct bfd_hash_entry * |
233 | | .@var{function_name} (struct bfd_hash_entry *entry, |
234 | | . struct bfd_hash_table *table, |
235 | | . const char *string) |
236 | | .{ |
237 | | . struct @var{entry_type} *ret = (@var{entry_type} *) entry; |
238 | | . |
239 | | . {* Allocate the structure if it has not already been allocated by a |
240 | | . derived class. *} |
241 | | . if (ret == NULL) |
242 | | . { |
243 | | . ret = bfd_hash_allocate (table, sizeof (* ret)); |
244 | | . if (ret == NULL) |
245 | | . return NULL; |
246 | | . } |
247 | | . |
248 | | . {* Call the allocation method of the base class. *} |
249 | | . ret = ((@var{entry_type} *) |
250 | | . @var{base_newfunc} ((struct bfd_hash_entry *) ret, table, string)); |
251 | | . |
252 | | . {* Initialize the local fields here. *} |
253 | | . |
254 | | . return (struct bfd_hash_entry *) ret; |
255 | | .} |
256 | | |
257 | | DESCRIPTION |
258 | | The creation routine for the linker hash table, which is in |
259 | | <<linker.c>>, looks just like this example. |
260 | | @var{function_name} is <<_bfd_link_hash_newfunc>>. |
261 | | @var{entry_type} is <<struct bfd_link_hash_entry>>. |
262 | | @var{base_newfunc} is <<bfd_hash_newfunc>>, the creation |
263 | | routine for a basic hash table. |
264 | | |
265 | | <<_bfd_link_hash_newfunc>> also initializes the local fields |
266 | | in a linker hash table entry: <<type>>, <<written>> and |
267 | | <<next>>. |
268 | | |
269 | | INODE |
270 | | Write Other Derived Routines, , Write the Derived Creation Routine, Deriving a New Hash Table Type |
271 | | SUBSUBSECTION |
272 | | Write other derived routines |
273 | | |
274 | | You will want to write other routines for your new hash table, |
275 | | as well. |
276 | | |
277 | | You will want an initialization routine which calls the |
278 | | initialization routine of the hash table you are deriving from |
279 | | and initializes any other local fields. For the linker hash |
280 | | table, this is <<_bfd_link_hash_table_init>> in <<linker.c>>. |
281 | | |
282 | | You will want a lookup routine which calls the lookup routine |
283 | | of the hash table you are deriving from and casts the result. |
284 | | The linker hash table uses <<bfd_link_hash_lookup>> in |
285 | | <<linker.c>> (this actually takes an additional argument which |
286 | | it uses to decide how to return the looked up value). |
287 | | |
288 | | You may want a traversal routine. This should just call the |
289 | | traversal routine of the hash table you are deriving from with |
290 | | appropriate casts. The linker hash table uses |
291 | | <<bfd_link_hash_traverse>> in <<linker.c>>. |
292 | | |
293 | | These routines may simply be defined as macros. For example, |
294 | | the a.out backend linker hash table, which is derived from the |
295 | | linker hash table, uses macros for the lookup and traversal |
296 | | routines. These are <<aout_link_hash_lookup>> and |
297 | | <<aout_link_hash_traverse>> in aoutx.h. |
298 | | |
299 | | EXTERNAL |
300 | | .{* An element in the hash table. Most uses will actually use a larger |
301 | | . structure, and an instance of this will be the first field. *} |
302 | | . |
303 | | .struct bfd_hash_entry |
304 | | .{ |
305 | | . {* Next entry for this hash code. *} |
306 | | . struct bfd_hash_entry *next; |
307 | | . {* String being hashed. *} |
308 | | . const char *string; |
309 | | . {* Hash code. This is the full hash code, not the index into the |
310 | | . table. *} |
311 | | . unsigned long hash; |
312 | | .}; |
313 | | . |
314 | | .{* A hash table. *} |
315 | | . |
316 | | .struct bfd_hash_table |
317 | | .{ |
318 | | . {* The hash array. *} |
319 | | . struct bfd_hash_entry **table; |
320 | | . {* A function used to create new elements in the hash table. The |
321 | | . first entry is itself a pointer to an element. When this |
322 | | . function is first invoked, this pointer will be NULL. However, |
323 | | . having the pointer permits a hierarchy of method functions to be |
324 | | . built each of which calls the function in the superclass. Thus |
325 | | . each function should be written to allocate a new block of memory |
326 | | . only if the argument is NULL. *} |
327 | | . struct bfd_hash_entry *(*newfunc) |
328 | | . (struct bfd_hash_entry *, struct bfd_hash_table *, const char *); |
329 | | . {* An objalloc for this hash table. This is a struct objalloc *, |
330 | | . but we use void * to avoid requiring the inclusion of objalloc.h. *} |
331 | | . void *memory; |
332 | | . {* The number of slots in the hash table. *} |
333 | | . unsigned int size; |
334 | | . {* The number of entries in the hash table. *} |
335 | | . unsigned int count; |
336 | | . {* The size of elements. *} |
337 | | . unsigned int entsize; |
338 | | . {* If non-zero, don't grow the hash table. *} |
339 | | . unsigned int frozen:1; |
340 | | .}; |
341 | | . |
342 | | */ |
343 | | |
344 | | /* The default number of entries to use when creating a hash table. */ |
345 | | #define DEFAULT_SIZE 4051 |
346 | | |
347 | | /* The following function returns a nearest prime number which is |
348 | | greater than N, and near a power of two. Copied from libiberty. |
349 | | Returns zero for ridiculously large N to signify an error. */ |
350 | | |
351 | | static uint32_t |
352 | | higher_prime_number (uint32_t n) |
353 | 5.43k | { |
354 | | /* These are primes that are near, but slightly smaller than, a |
355 | | power of two. */ |
356 | 5.43k | static const uint32_t primes[] = |
357 | 5.43k | { |
358 | 5.43k | UINT32_C (31), |
359 | 5.43k | UINT32_C (61), |
360 | 5.43k | UINT32_C (127), |
361 | 5.43k | UINT32_C (251), |
362 | 5.43k | UINT32_C (509), |
363 | 5.43k | UINT32_C (1021), |
364 | 5.43k | UINT32_C (2039), |
365 | 5.43k | UINT32_C (4093), |
366 | 5.43k | UINT32_C (8191), |
367 | 5.43k | UINT32_C (16381), |
368 | 5.43k | UINT32_C (32749), |
369 | 5.43k | UINT32_C (65521), |
370 | 5.43k | UINT32_C (131071), |
371 | 5.43k | UINT32_C (262139), |
372 | 5.43k | UINT32_C (524287), |
373 | 5.43k | UINT32_C (1048573), |
374 | 5.43k | UINT32_C (2097143), |
375 | 5.43k | UINT32_C (4194301), |
376 | 5.43k | UINT32_C (8388593), |
377 | 5.43k | UINT32_C (16777213), |
378 | 5.43k | UINT32_C (33554393), |
379 | 5.43k | UINT32_C (67108859), |
380 | 5.43k | UINT32_C (134217689), |
381 | 5.43k | UINT32_C (268435399), |
382 | 5.43k | UINT32_C (536870909), |
383 | 5.43k | UINT32_C (1073741789), |
384 | 5.43k | UINT32_C (2147483647), |
385 | 5.43k | UINT32_C (4294967291) |
386 | 5.43k | }; |
387 | | |
388 | 5.43k | const uint32_t *low = &primes[0]; |
389 | 5.43k | const uint32_t *high = &primes[sizeof (primes) / sizeof (primes[0])]; |
390 | | |
391 | 32.6k | while (low != high) |
392 | 27.1k | { |
393 | 27.1k | const uint32_t *mid = low + (high - low) / 2; |
394 | 27.1k | if (n >= *mid) |
395 | 11.7k | low = mid + 1; |
396 | 15.4k | else |
397 | 15.4k | high = mid; |
398 | 27.1k | } |
399 | | |
400 | 5.43k | if (n >= *low) |
401 | 0 | return 0; |
402 | | |
403 | 5.43k | return *low; |
404 | 5.43k | } |
405 | | |
406 | | static unsigned int bfd_default_hash_table_size = DEFAULT_SIZE; |
407 | | |
408 | | /* |
409 | | FUNCTION |
410 | | bfd_hash_table_init_n |
411 | | |
412 | | SYNOPSIS |
413 | | bool bfd_hash_table_init_n |
414 | | (struct bfd_hash_table *, |
415 | | struct bfd_hash_entry *(* {*newfunc*}) |
416 | | (struct bfd_hash_entry *, struct bfd_hash_table *, const char *), |
417 | | unsigned int {*entsize*}, unsigned int {*size*}); |
418 | | |
419 | | DESCRIPTION |
420 | | Create a new hash table, given a number of entries. |
421 | | */ |
422 | | |
423 | | bool |
424 | | bfd_hash_table_init_n (struct bfd_hash_table *table, |
425 | | struct bfd_hash_entry *(*newfunc) (struct bfd_hash_entry *, |
426 | | struct bfd_hash_table *, |
427 | | const char *), |
428 | | unsigned int entsize, |
429 | | unsigned int size) |
430 | 9.97M | { |
431 | 9.97M | unsigned long alloc; |
432 | | |
433 | 9.97M | alloc = size; |
434 | 9.97M | alloc *= sizeof (struct bfd_hash_entry *); |
435 | 9.97M | if (alloc / sizeof (struct bfd_hash_entry *) != size) |
436 | 0 | { |
437 | 0 | bfd_set_error (bfd_error_no_memory); |
438 | 0 | return false; |
439 | 0 | } |
440 | | |
441 | 9.97M | table->memory = (void *) objalloc_create (); |
442 | 9.97M | if (table->memory == NULL) |
443 | 0 | { |
444 | 0 | bfd_set_error (bfd_error_no_memory); |
445 | 0 | return false; |
446 | 0 | } |
447 | 9.97M | table->table = (struct bfd_hash_entry **) |
448 | 9.97M | objalloc_alloc ((struct objalloc *) table->memory, alloc); |
449 | 9.97M | if (table->table == NULL) |
450 | 0 | { |
451 | 0 | bfd_hash_table_free (table); |
452 | 0 | bfd_set_error (bfd_error_no_memory); |
453 | 0 | return false; |
454 | 0 | } |
455 | 9.97M | memset ((void *) table->table, 0, alloc); |
456 | 9.97M | table->size = size; |
457 | 9.97M | table->entsize = entsize; |
458 | 9.97M | table->count = 0; |
459 | 9.97M | table->frozen = 0; |
460 | 9.97M | table->newfunc = newfunc; |
461 | 9.97M | return true; |
462 | 9.97M | } |
463 | | |
464 | | /* |
465 | | FUNCTION |
466 | | bfd_hash_table_init |
467 | | |
468 | | SYNOPSIS |
469 | | bool bfd_hash_table_init |
470 | | (struct bfd_hash_table *, |
471 | | struct bfd_hash_entry *(* {*newfunc*}) |
472 | | (struct bfd_hash_entry *, struct bfd_hash_table *, const char *), |
473 | | unsigned int {*entsize*}); |
474 | | |
475 | | DESCRIPTION |
476 | | Create a new hash table with the default number of entries. |
477 | | */ |
478 | | |
479 | | bool |
480 | | bfd_hash_table_init (struct bfd_hash_table *table, |
481 | | struct bfd_hash_entry *(*newfunc) (struct bfd_hash_entry *, |
482 | | struct bfd_hash_table *, |
483 | | const char *), |
484 | | unsigned int entsize) |
485 | 6.46M | { |
486 | 6.46M | return bfd_hash_table_init_n (table, newfunc, entsize, |
487 | 6.46M | bfd_default_hash_table_size); |
488 | 6.46M | } |
489 | | |
490 | | /* |
491 | | FUNCTION |
492 | | bfd_hash_table_free |
493 | | |
494 | | SYNOPSIS |
495 | | void bfd_hash_table_free (struct bfd_hash_table *); |
496 | | |
497 | | DESCRIPTION |
498 | | Free a hash table. |
499 | | */ |
500 | | |
501 | | void |
502 | | bfd_hash_table_free (struct bfd_hash_table *table) |
503 | 9.97M | { |
504 | 9.97M | objalloc_free ((struct objalloc *) table->memory); |
505 | 9.97M | table->memory = NULL; |
506 | 9.97M | } |
507 | | |
508 | | static inline unsigned long |
509 | | bfd_hash_hash (const char *string, unsigned int *lenp) |
510 | 186M | { |
511 | 186M | const unsigned char *s; |
512 | 186M | unsigned long hash; |
513 | 186M | unsigned int len; |
514 | 186M | unsigned int c; |
515 | | |
516 | 186M | BFD_ASSERT (string != NULL); |
517 | 186M | hash = 0; |
518 | 186M | len = 0; |
519 | 186M | s = (const unsigned char *) string; |
520 | 1.58G | while ((c = *s++) != '\0') |
521 | 1.40G | { |
522 | 1.40G | hash += c + (c << 17); |
523 | 1.40G | hash ^= hash >> 2; |
524 | 1.40G | } |
525 | 186M | len = (s - (const unsigned char *) string) - 1; |
526 | 186M | hash += len + (len << 17); |
527 | 186M | hash ^= hash >> 2; |
528 | 186M | if (lenp != NULL) |
529 | 186M | *lenp = len; |
530 | 186M | return hash; |
531 | 186M | } |
532 | | |
533 | | /* |
534 | | FUNCTION |
535 | | bfd_hash_lookup |
536 | | |
537 | | SYNOPSIS |
538 | | struct bfd_hash_entry *bfd_hash_lookup |
539 | | (struct bfd_hash_table *, const char *, |
540 | | bool {*create*}, bool {*copy*}); |
541 | | |
542 | | DESCRIPTION |
543 | | Look up a string in a hash table. |
544 | | */ |
545 | | |
546 | | struct bfd_hash_entry * |
547 | | bfd_hash_lookup (struct bfd_hash_table *table, |
548 | | const char *string, |
549 | | bool create, |
550 | | bool copy) |
551 | 186M | { |
552 | 186M | unsigned long hash; |
553 | 186M | struct bfd_hash_entry *hashp; |
554 | 186M | unsigned int len; |
555 | 186M | unsigned int _index; |
556 | | |
557 | 186M | hash = bfd_hash_hash (string, &len); |
558 | 186M | _index = hash % table->size; |
559 | 186M | for (hashp = table->table[_index]; |
560 | 215M | hashp != NULL; |
561 | 186M | hashp = hashp->next) |
562 | 143M | { |
563 | 143M | if (hashp->hash == hash |
564 | 143M | && strcmp (hashp->string, string) == 0) |
565 | 115M | return hashp; |
566 | 143M | } |
567 | | |
568 | 71.3M | if (! create) |
569 | 1.33M | return NULL; |
570 | | |
571 | 70.0M | if (copy) |
572 | 124 | { |
573 | 124 | char *new_string; |
574 | | |
575 | 124 | new_string = (char *) objalloc_alloc ((struct objalloc *) table->memory, |
576 | 124 | len + 1); |
577 | 124 | if (!new_string) |
578 | 0 | { |
579 | 0 | bfd_set_error (bfd_error_no_memory); |
580 | 0 | return NULL; |
581 | 0 | } |
582 | 124 | memcpy (new_string, string, len + 1); |
583 | 124 | string = new_string; |
584 | 124 | } |
585 | | |
586 | 70.0M | return bfd_hash_insert (table, string, hash); |
587 | 70.0M | } |
588 | | |
589 | | /* |
590 | | FUNCTION |
591 | | bfd_hash_insert |
592 | | |
593 | | SYNOPSIS |
594 | | struct bfd_hash_entry *bfd_hash_insert |
595 | | (struct bfd_hash_table *, |
596 | | const char *, |
597 | | unsigned long {*hash*}); |
598 | | |
599 | | DESCRIPTION |
600 | | Insert an entry in a hash table. |
601 | | */ |
602 | | |
603 | | struct bfd_hash_entry * |
604 | | bfd_hash_insert (struct bfd_hash_table *table, |
605 | | const char *string, |
606 | | unsigned long hash) |
607 | 70.0M | { |
608 | 70.0M | struct bfd_hash_entry *hashp; |
609 | 70.0M | unsigned int _index; |
610 | | |
611 | 70.0M | hashp = (*table->newfunc) (NULL, table, string); |
612 | 70.0M | if (hashp == NULL) |
613 | 0 | return NULL; |
614 | 70.0M | hashp->string = string; |
615 | 70.0M | hashp->hash = hash; |
616 | 70.0M | _index = hash % table->size; |
617 | 70.0M | hashp->next = table->table[_index]; |
618 | 70.0M | table->table[_index] = hashp; |
619 | 70.0M | table->count++; |
620 | | |
621 | 70.0M | if (!table->frozen && table->count > table->size * 3 / 4) |
622 | 5.43k | { |
623 | 5.43k | unsigned long newsize = higher_prime_number (table->size); |
624 | 5.43k | struct bfd_hash_entry **newtable; |
625 | 5.43k | unsigned int hi; |
626 | 5.43k | unsigned long alloc = newsize * sizeof (struct bfd_hash_entry *); |
627 | | |
628 | | /* If we can't find a higher prime, or we can't possibly alloc |
629 | | that much memory, don't try to grow the table. */ |
630 | 5.43k | if (newsize == 0 || alloc / sizeof (struct bfd_hash_entry *) != newsize) |
631 | 0 | { |
632 | 0 | table->frozen = 1; |
633 | 0 | return hashp; |
634 | 0 | } |
635 | | |
636 | 5.43k | newtable = ((struct bfd_hash_entry **) |
637 | 5.43k | objalloc_alloc ((struct objalloc *) table->memory, alloc)); |
638 | 5.43k | if (newtable == NULL) |
639 | 0 | { |
640 | 0 | table->frozen = 1; |
641 | 0 | return hashp; |
642 | 0 | } |
643 | 5.43k | memset (newtable, 0, alloc); |
644 | | |
645 | 22.4M | for (hi = 0; hi < table->size; hi ++) |
646 | 39.2M | while (table->table[hi]) |
647 | 16.8M | { |
648 | 16.8M | struct bfd_hash_entry *chain = table->table[hi]; |
649 | 16.8M | struct bfd_hash_entry *chain_end = chain; |
650 | | |
651 | 24.1M | while (chain_end->next && chain_end->next->hash == chain->hash) |
652 | 7.31M | chain_end = chain_end->next; |
653 | | |
654 | 16.8M | table->table[hi] = chain_end->next; |
655 | 16.8M | _index = chain->hash % newsize; |
656 | 16.8M | chain_end->next = newtable[_index]; |
657 | 16.8M | newtable[_index] = chain; |
658 | 16.8M | } |
659 | 5.43k | table->table = newtable; |
660 | 5.43k | table->size = newsize; |
661 | 5.43k | } |
662 | | |
663 | 70.0M | return hashp; |
664 | 70.0M | } |
665 | | |
666 | | /* |
667 | | FUNCTION |
668 | | bfd_hash_rename |
669 | | |
670 | | SYNOPSIS |
671 | | void bfd_hash_rename (struct bfd_hash_table *, |
672 | | const char *, |
673 | | struct bfd_hash_entry *); |
674 | | |
675 | | DESCRIPTION |
676 | | Rename an entry in a hash table. |
677 | | */ |
678 | | |
679 | | void |
680 | | bfd_hash_rename (struct bfd_hash_table *table, |
681 | | const char *string, |
682 | | struct bfd_hash_entry *ent) |
683 | 0 | { |
684 | 0 | unsigned int _index; |
685 | 0 | struct bfd_hash_entry **pph; |
686 | |
|
687 | 0 | _index = ent->hash % table->size; |
688 | 0 | for (pph = &table->table[_index]; *pph != NULL; pph = &(*pph)->next) |
689 | 0 | if (*pph == ent) |
690 | 0 | break; |
691 | 0 | if (*pph == NULL) |
692 | 0 | abort (); |
693 | | |
694 | 0 | *pph = ent->next; |
695 | 0 | ent->string = string; |
696 | 0 | ent->hash = bfd_hash_hash (string, NULL); |
697 | 0 | _index = ent->hash % table->size; |
698 | 0 | ent->next = table->table[_index]; |
699 | 0 | table->table[_index] = ent; |
700 | 0 | } |
701 | | |
702 | | /* |
703 | | FUNCTION |
704 | | bfd_hash_replace |
705 | | |
706 | | SYNOPSIS |
707 | | void bfd_hash_replace (struct bfd_hash_table *, |
708 | | struct bfd_hash_entry * {*old*}, |
709 | | struct bfd_hash_entry * {*new*}); |
710 | | |
711 | | DESCRIPTION |
712 | | Replace an entry in a hash table. |
713 | | */ |
714 | | |
715 | | void |
716 | | bfd_hash_replace (struct bfd_hash_table *table, |
717 | | struct bfd_hash_entry *old, |
718 | | struct bfd_hash_entry *nw) |
719 | 0 | { |
720 | 0 | unsigned int _index; |
721 | 0 | struct bfd_hash_entry **pph; |
722 | |
|
723 | 0 | _index = old->hash % table->size; |
724 | 0 | for (pph = &table->table[_index]; |
725 | 0 | (*pph) != NULL; |
726 | 0 | pph = &(*pph)->next) |
727 | 0 | { |
728 | 0 | if (*pph == old) |
729 | 0 | { |
730 | 0 | *pph = nw; |
731 | 0 | return; |
732 | 0 | } |
733 | 0 | } |
734 | | |
735 | 0 | abort (); |
736 | 0 | } |
737 | | |
738 | | /* |
739 | | FUNCTION |
740 | | bfd_hash_allocate |
741 | | |
742 | | SYNOPSIS |
743 | | void *bfd_hash_allocate (struct bfd_hash_table *, |
744 | | unsigned int {*size*}); |
745 | | |
746 | | DESCRIPTION |
747 | | Allocate space in a hash table. |
748 | | */ |
749 | | |
750 | | void * |
751 | | bfd_hash_allocate (struct bfd_hash_table *table, |
752 | | unsigned int size) |
753 | 162M | { |
754 | 162M | void * ret; |
755 | | |
756 | 162M | ret = objalloc_alloc ((struct objalloc *) table->memory, size); |
757 | 162M | if (ret == NULL && size != 0) |
758 | 0 | bfd_set_error (bfd_error_no_memory); |
759 | 162M | return ret; |
760 | 162M | } |
761 | | |
762 | | /* |
763 | | FUNCTION |
764 | | bfd_hash_newfunc |
765 | | |
766 | | SYNOPSIS |
767 | | struct bfd_hash_entry *bfd_hash_newfunc |
768 | | (struct bfd_hash_entry *, |
769 | | struct bfd_hash_table *, |
770 | | const char *); |
771 | | |
772 | | DESCRIPTION |
773 | | Base method for creating a new hash table entry. |
774 | | */ |
775 | | |
776 | | struct bfd_hash_entry * |
777 | | bfd_hash_newfunc (struct bfd_hash_entry *entry, |
778 | | struct bfd_hash_table *table, |
779 | | const char *string ATTRIBUTE_UNUSED) |
780 | 162M | { |
781 | 162M | if (entry == NULL) |
782 | 0 | entry = (struct bfd_hash_entry *) bfd_hash_allocate (table, |
783 | 0 | sizeof (* entry)); |
784 | 162M | return entry; |
785 | 162M | } |
786 | | |
787 | | /* |
788 | | FUNCTION |
789 | | bfd_hash_traverse |
790 | | |
791 | | SYNOPSIS |
792 | | void bfd_hash_traverse |
793 | | (struct bfd_hash_table *, |
794 | | bool (*) (struct bfd_hash_entry *, void *), |
795 | | void *); |
796 | | |
797 | | DESCRIPTION |
798 | | Traverse a hash table. |
799 | | */ |
800 | | |
801 | | void |
802 | | bfd_hash_traverse (struct bfd_hash_table *table, |
803 | | bool (*func) (struct bfd_hash_entry *, void *), |
804 | | void *info) |
805 | 0 | { |
806 | 0 | unsigned int i; |
807 | |
|
808 | 0 | table->frozen = 1; |
809 | 0 | for (i = 0; i < table->size; i++) |
810 | 0 | { |
811 | 0 | struct bfd_hash_entry *p; |
812 | |
|
813 | 0 | for (p = table->table[i]; p != NULL; p = p->next) |
814 | 0 | if (! (*func) (p, info)) |
815 | 0 | goto out; |
816 | 0 | } |
817 | 0 | out: |
818 | 0 | table->frozen = 0; |
819 | 0 | } |
820 | | |
821 | | /* |
822 | | FUNCTION |
823 | | bfd_hash_set_default_size |
824 | | |
825 | | SYNOPSIS |
826 | | unsigned int bfd_hash_set_default_size (unsigned int); |
827 | | |
828 | | DESCRIPTION |
829 | | Set hash table default size. |
830 | | */ |
831 | | |
832 | | unsigned int |
833 | | bfd_hash_set_default_size (unsigned int hash_size) |
834 | 0 | { |
835 | | /* These silly_size values result in around 1G and 32M of memory |
836 | | being allocated for the table of pointers. Note that the number |
837 | | of elements allocated will be almost twice the size of any power |
838 | | of two chosen here. */ |
839 | 0 | unsigned int silly_size = sizeof (size_t) > 4 ? 0x4000000 : 0x400000; |
840 | 0 | if (hash_size > silly_size) |
841 | 0 | hash_size = silly_size; |
842 | 0 | else if (hash_size != 0) |
843 | 0 | hash_size--; |
844 | 0 | hash_size = higher_prime_number (hash_size); |
845 | 0 | BFD_ASSERT (hash_size != 0); |
846 | 0 | bfd_default_hash_table_size = hash_size; |
847 | 0 | return bfd_default_hash_table_size; |
848 | 0 | } |
849 | | |
850 | | /* A few different object file formats (a.out, COFF, ELF) use a string |
851 | | table. These functions support adding strings to a string table, |
852 | | returning the byte offset, and writing out the table. |
853 | | |
854 | | Possible improvements: |
855 | | + look for strings matching trailing substrings of other strings |
856 | | + better data structures? balanced trees? |
857 | | + look at reducing memory use elsewhere -- maybe if we didn't have |
858 | | to construct the entire symbol table at once, we could get by |
859 | | with smaller amounts of VM? (What effect does that have on the |
860 | | string table reductions?) */ |
861 | | |
862 | | /* An entry in the strtab hash table. */ |
863 | | |
864 | | struct strtab_hash_entry |
865 | | { |
866 | | struct bfd_hash_entry root; |
867 | | /* Index in string table. */ |
868 | | bfd_size_type index; |
869 | | /* Next string in strtab. */ |
870 | | struct strtab_hash_entry *next; |
871 | | }; |
872 | | |
873 | | /* The strtab hash table. */ |
874 | | |
875 | | struct bfd_strtab_hash |
876 | | { |
877 | | struct bfd_hash_table table; |
878 | | /* Size of strtab--also next available index. */ |
879 | | bfd_size_type size; |
880 | | /* First string in strtab. */ |
881 | | struct strtab_hash_entry *first; |
882 | | /* Last string in strtab. */ |
883 | | struct strtab_hash_entry *last; |
884 | | /* Whether to precede strings with a two or four byte length, |
885 | | as in the XCOFF .debug section. */ |
886 | | char length_field_size; |
887 | | }; |
888 | | |
889 | | |
890 | | /* Routine to create an entry in a strtab. */ |
891 | | |
892 | | static struct bfd_hash_entry * |
893 | | strtab_hash_newfunc (struct bfd_hash_entry *entry, |
894 | | struct bfd_hash_table *table, |
895 | | const char *string) |
896 | 4.05k | { |
897 | 4.05k | struct strtab_hash_entry *ret = (struct strtab_hash_entry *) entry; |
898 | | |
899 | | /* Allocate the structure if it has not already been allocated by a |
900 | | subclass. */ |
901 | 4.05k | if (ret == NULL) |
902 | 4.05k | ret = (struct strtab_hash_entry *) bfd_hash_allocate (table, |
903 | 4.05k | sizeof (* ret)); |
904 | 4.05k | if (ret == NULL) |
905 | 0 | return NULL; |
906 | | |
907 | | /* Call the allocation method of the superclass. */ |
908 | 4.05k | ret = (struct strtab_hash_entry *) |
909 | 4.05k | bfd_hash_newfunc ((struct bfd_hash_entry *) ret, table, string); |
910 | | |
911 | 4.05k | if (ret) |
912 | 4.05k | { |
913 | | /* Initialize the local fields. */ |
914 | 4.05k | ret->index = (bfd_size_type) -1; |
915 | 4.05k | ret->next = NULL; |
916 | 4.05k | } |
917 | | |
918 | 4.05k | return (struct bfd_hash_entry *) ret; |
919 | 4.05k | } |
920 | | |
921 | | /* Look up an entry in an strtab. */ |
922 | | |
923 | | #define strtab_hash_lookup(t, string, create, copy) \ |
924 | 5.02k | ((struct strtab_hash_entry *) \ |
925 | 5.02k | bfd_hash_lookup (&(t)->table, (string), (create), (copy))) |
926 | | |
927 | | /* |
928 | | INTERNAL_FUNCTION |
929 | | _bfd_stringtab_init |
930 | | |
931 | | SYNOPSIS |
932 | | struct bfd_strtab_hash *_bfd_stringtab_init (void); |
933 | | |
934 | | DESCRIPTION |
935 | | Create a new strtab. |
936 | | */ |
937 | | |
938 | | struct bfd_strtab_hash * |
939 | | _bfd_stringtab_init (void) |
940 | 26 | { |
941 | 26 | struct bfd_strtab_hash *table; |
942 | 26 | size_t amt = sizeof (* table); |
943 | | |
944 | 26 | table = (struct bfd_strtab_hash *) bfd_malloc (amt); |
945 | 26 | if (table == NULL) |
946 | 0 | return NULL; |
947 | | |
948 | 26 | if (!bfd_hash_table_init (&table->table, strtab_hash_newfunc, |
949 | 26 | sizeof (struct strtab_hash_entry))) |
950 | 0 | { |
951 | 0 | free (table); |
952 | 0 | return NULL; |
953 | 0 | } |
954 | | |
955 | 26 | table->size = 0; |
956 | 26 | table->first = NULL; |
957 | 26 | table->last = NULL; |
958 | 26 | table->length_field_size = 0; |
959 | | |
960 | 26 | return table; |
961 | 26 | } |
962 | | |
963 | | /* |
964 | | INTERNAL_FUNCTION |
965 | | _bfd_xcoff_stringtab_init |
966 | | |
967 | | SYNOPSIS |
968 | | struct bfd_strtab_hash *_bfd_xcoff_stringtab_init |
969 | | (bool {*isxcoff64*}); |
970 | | |
971 | | DESCRIPTION |
972 | | Create a new strtab in which the strings are output in the format |
973 | | used in the XCOFF .debug section: a two byte length precedes each |
974 | | string. |
975 | | */ |
976 | | |
977 | | struct bfd_strtab_hash * |
978 | | _bfd_xcoff_stringtab_init (bool isxcoff64) |
979 | 0 | { |
980 | 0 | struct bfd_strtab_hash *ret; |
981 | |
|
982 | 0 | ret = _bfd_stringtab_init (); |
983 | 0 | if (ret != NULL) |
984 | 0 | ret->length_field_size = isxcoff64 ? 4 : 2; |
985 | 0 | return ret; |
986 | 0 | } |
987 | | |
988 | | /* |
989 | | INTERNAL_FUNCTION |
990 | | _bfd_stringtab_free |
991 | | |
992 | | SYNOPSIS |
993 | | void _bfd_stringtab_free (struct bfd_strtab_hash *); |
994 | | |
995 | | DESCRIPTION |
996 | | Free a strtab. |
997 | | */ |
998 | | |
999 | | void |
1000 | | _bfd_stringtab_free (struct bfd_strtab_hash *table) |
1001 | 26 | { |
1002 | 26 | bfd_hash_table_free (&table->table); |
1003 | 26 | free (table); |
1004 | 26 | } |
1005 | | |
1006 | | /* |
1007 | | INTERNAL_FUNCTION |
1008 | | _bfd_stringtab_add |
1009 | | |
1010 | | SYNOPSIS |
1011 | | bfd_size_type _bfd_stringtab_add |
1012 | | (struct bfd_strtab_hash *, const char *, |
1013 | | bool {*hash*}, bool {*copy*}); |
1014 | | |
1015 | | DESCRIPTION |
1016 | | Get the index of a string in a strtab, adding it if it is not |
1017 | | already present. If HASH is FALSE, we don't really use the hash |
1018 | | table, and we don't eliminate duplicate strings. If COPY is true |
1019 | | then store a copy of STR if creating a new entry. |
1020 | | */ |
1021 | | |
1022 | | bfd_size_type |
1023 | | _bfd_stringtab_add (struct bfd_strtab_hash *tab, |
1024 | | const char *str, |
1025 | | bool hash, |
1026 | | bool copy) |
1027 | 5.03k | { |
1028 | 5.03k | struct strtab_hash_entry *entry; |
1029 | | |
1030 | 5.03k | if (hash) |
1031 | 5.02k | { |
1032 | 5.02k | entry = strtab_hash_lookup (tab, str, true, copy); |
1033 | 5.02k | if (entry == NULL) |
1034 | 0 | return (bfd_size_type) -1; |
1035 | 5.02k | } |
1036 | 11 | else |
1037 | 11 | { |
1038 | 11 | entry = (struct strtab_hash_entry *) bfd_hash_allocate (&tab->table, |
1039 | 11 | sizeof (* entry)); |
1040 | 11 | if (entry == NULL) |
1041 | 0 | return (bfd_size_type) -1; |
1042 | 11 | if (! copy) |
1043 | 11 | entry->root.string = str; |
1044 | 0 | else |
1045 | 0 | { |
1046 | 0 | size_t len = strlen (str) + 1; |
1047 | 0 | char *n; |
1048 | |
|
1049 | 0 | n = (char *) bfd_hash_allocate (&tab->table, len); |
1050 | 0 | if (n == NULL) |
1051 | 0 | return (bfd_size_type) -1; |
1052 | 0 | memcpy (n, str, len); |
1053 | 0 | entry->root.string = n; |
1054 | 0 | } |
1055 | 11 | entry->index = (bfd_size_type) -1; |
1056 | 11 | entry->next = NULL; |
1057 | 11 | } |
1058 | | |
1059 | 5.03k | if (entry->index == (bfd_size_type) -1) |
1060 | 4.06k | { |
1061 | 4.06k | entry->index = tab->size; |
1062 | 4.06k | tab->size += strlen (str) + 1; |
1063 | 4.06k | entry->index += tab->length_field_size; |
1064 | 4.06k | tab->size += tab->length_field_size; |
1065 | 4.06k | if (tab->first == NULL) |
1066 | 17 | tab->first = entry; |
1067 | 4.04k | else |
1068 | 4.04k | tab->last->next = entry; |
1069 | 4.06k | tab->last = entry; |
1070 | 4.06k | } |
1071 | | |
1072 | 5.03k | return entry->index; |
1073 | 5.03k | } |
1074 | | |
1075 | | /* |
1076 | | INTERNAL_FUNCTION |
1077 | | _bfd_stringtab_size |
1078 | | |
1079 | | SYNOPSIS |
1080 | | bfd_size_type _bfd_stringtab_size (struct bfd_strtab_hash *); |
1081 | | |
1082 | | DESCRIPTION |
1083 | | Get the number of bytes in a strtab. |
1084 | | */ |
1085 | | |
1086 | | bfd_size_type |
1087 | | _bfd_stringtab_size (struct bfd_strtab_hash *tab) |
1088 | 26 | { |
1089 | 26 | return tab->size; |
1090 | 26 | } |
1091 | | |
1092 | | /* |
1093 | | INTERNAL_FUNCTION |
1094 | | _bfd_stringtab_emit |
1095 | | |
1096 | | SYNOPSIS |
1097 | | bool _bfd_stringtab_emit (bfd *, struct bfd_strtab_hash *); |
1098 | | |
1099 | | DESCRIPTION |
1100 | | Write out a strtab. ABFD must already be at the right location in |
1101 | | the file. |
1102 | | */ |
1103 | | |
1104 | | bool |
1105 | | _bfd_stringtab_emit (bfd *abfd, struct bfd_strtab_hash *tab) |
1106 | 26 | { |
1107 | 26 | struct strtab_hash_entry *entry; |
1108 | | |
1109 | 4.08k | for (entry = tab->first; entry != NULL; entry = entry->next) |
1110 | 4.06k | { |
1111 | 4.06k | const char *str; |
1112 | 4.06k | size_t len; |
1113 | | |
1114 | 4.06k | str = entry->root.string; |
1115 | 4.06k | len = strlen (str) + 1; |
1116 | | |
1117 | 4.06k | if (tab->length_field_size == 4) |
1118 | 0 | { |
1119 | 0 | bfd_byte buf[4]; |
1120 | | |
1121 | | /* The output length includes the null byte. */ |
1122 | 0 | bfd_put_32 (abfd, len, buf); |
1123 | 0 | if (bfd_write (buf, 4, abfd) != 4) |
1124 | 0 | return false; |
1125 | 0 | } |
1126 | 4.06k | else if (tab->length_field_size == 2) |
1127 | 0 | { |
1128 | 0 | bfd_byte buf[2]; |
1129 | | |
1130 | | /* The output length includes the null byte. */ |
1131 | 0 | bfd_put_16 (abfd, len, buf); |
1132 | 0 | if (bfd_write (buf, 2, abfd) != 2) |
1133 | 0 | return false; |
1134 | 0 | } |
1135 | | |
1136 | 4.06k | if (bfd_write (str, len, abfd) != len) |
1137 | 0 | return false; |
1138 | 4.06k | } |
1139 | | |
1140 | 26 | return true; |
1141 | 26 | } |