1 |
/* hash.c -- hash table routines for BFD |
/* hash.c -- hash table routines for BFD |
2 |
Copyright 1993, 1994, 1995, 1997, 1999, 2001, 2002 |
Copyright 1993, 1994, 1995, 1997, 1999, 2001, 2002, 2003, 2004 |
3 |
Free Software Foundation, Inc. |
Free Software Foundation, Inc. |
4 |
Written by Steve Chamberlain <sac@cygnus.com> |
Written by Steve Chamberlain <sac@cygnus.com> |
5 |
|
|
6 |
This file is part of BFD, the Binary File Descriptor library. |
This file is part of BFD, the Binary File Descriptor library. |
7 |
|
|
8 |
This program is free software; you can redistribute it and/or modify |
This program is free software; you can redistribute it and/or modify |
9 |
it under the terms of the GNU General Public License as published by |
it under the terms of the GNU General Public License as published by |
10 |
the Free Software Foundation; either version 2 of the License, or |
the Free Software Foundation; either version 2 of the License, or |
11 |
(at your option) any later version. |
(at your option) any later version. |
12 |
|
|
13 |
This program is distributed in the hope that it will be useful, |
This program is distributed in the hope that it will be useful, |
14 |
but WITHOUT ANY WARRANTY; without even the implied warranty of |
but WITHOUT ANY WARRANTY; without even the implied warranty of |
15 |
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
16 |
GNU General Public License for more details. |
GNU General Public License for more details. |
17 |
|
|
18 |
You should have received a copy of the GNU General Public License |
You should have received a copy of the GNU General Public License |
19 |
along with this program; if not, write to the Free Software |
along with this program; if not, write to the Free Software |
20 |
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ |
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ |
21 |
|
|
22 |
#include "bfd.h" |
#include "bfd.h" |
23 |
#include "sysdep.h" |
#include "sysdep.h" |
24 |
#include "libbfd.h" |
#include "libbfd.h" |
25 |
#include "objalloc.h" |
#include "objalloc.h" |
26 |
|
#include "libiberty.h" |
27 |
|
|
28 |
/* |
/* |
29 |
SECTION |
SECTION |
68 |
<<bfd_hash_table_init>> (if you know approximately how many |
<<bfd_hash_table_init>> (if you know approximately how many |
69 |
entries you will need, the function <<bfd_hash_table_init_n>>, |
entries you will need, the function <<bfd_hash_table_init_n>>, |
70 |
which takes a @var{size} argument, may be used). |
which takes a @var{size} argument, may be used). |
71 |
<<bfd_hash_table_init>> returns <<false>> if some sort of |
<<bfd_hash_table_init>> returns <<FALSE>> if some sort of |
72 |
error occurs. |
error occurs. |
73 |
|
|
74 |
@findex bfd_hash_newfunc |
@findex bfd_hash_newfunc |
88 |
been allocated for a hash table. This will not free up the |
been allocated for a hash table. This will not free up the |
89 |
<<struct bfd_hash_table>> itself, which you must provide. |
<<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 |
INODE |
96 |
Looking Up or Entering a String, Traversing a Hash Table, Creating and Freeing a Hash Table, Hash Tables |
Looking Up or Entering a String, Traversing a Hash Table, Creating and Freeing a Hash Table, Hash Tables |
97 |
SUBSECTION |
SUBSECTION |
101 |
The function <<bfd_hash_lookup>> is used both to look up a |
The function <<bfd_hash_lookup>> is used both to look up a |
102 |
string in the hash table and to create a new entry. |
string in the hash table and to create a new entry. |
103 |
|
|
104 |
If the @var{create} argument is <<false>>, <<bfd_hash_lookup>> |
If the @var{create} argument is <<FALSE>>, <<bfd_hash_lookup>> |
105 |
will look up a string. If the string is found, it will |
will look up a string. If the string is found, it will |
106 |
returns a pointer to a <<struct bfd_hash_entry>>. If the |
returns a pointer to a <<struct bfd_hash_entry>>. If the |
107 |
string is not found in the table <<bfd_hash_lookup>> will |
string is not found in the table <<bfd_hash_lookup>> will |
108 |
return <<NULL>>. You should not modify any of the fields in |
return <<NULL>>. You should not modify any of the fields in |
109 |
the returns <<struct bfd_hash_entry>>. |
the returns <<struct bfd_hash_entry>>. |
110 |
|
|
111 |
If the @var{create} argument is <<true>>, the string will be |
If the @var{create} argument is <<TRUE>>, the string will be |
112 |
entered into the hash table if it is not already there. |
entered into the hash table if it is not already there. |
113 |
Either way a pointer to a <<struct bfd_hash_entry>> will be |
Either way a pointer to a <<struct bfd_hash_entry>> will be |
114 |
returned, either to the existing structure or to a newly |
returned, either to the existing structure or to a newly |
115 |
created one. In this case, a <<NULL>> return means that an |
created one. In this case, a <<NULL>> return means that an |
116 |
error occurred. |
error occurred. |
117 |
|
|
118 |
If the @var{create} argument is <<true>>, and a new entry is |
If the @var{create} argument is <<TRUE>>, and a new entry is |
119 |
created, the @var{copy} argument is used to decide whether to |
created, the @var{copy} argument is used to decide whether to |
120 |
copy the string onto the hash table objalloc or not. If |
copy the string onto the hash table objalloc or not. If |
121 |
@var{copy} is passed as <<false>>, you must be careful not to |
@var{copy} is passed as <<FALSE>>, you must be careful not to |
122 |
deallocate or modify the string as long as the hash table |
deallocate or modify the string as long as the hash table |
123 |
exists. |
exists. |
124 |
|
|
138 |
generic pointer passed to <<bfd_hash_traverse>>. The function |
generic pointer passed to <<bfd_hash_traverse>>. The function |
139 |
must return a <<boolean>> value, which indicates whether to |
must return a <<boolean>> value, which indicates whether to |
140 |
continue traversing the hash table. If the function returns |
continue traversing the hash table. If the function returns |
141 |
<<false>>, <<bfd_hash_traverse>> will stop the traversal and |
<<FALSE>>, <<bfd_hash_traverse>> will stop the traversal and |
142 |
return immediately. |
return immediately. |
143 |
|
|
144 |
INODE |
INODE |
300 |
*/ |
*/ |
301 |
|
|
302 |
/* The default number of entries to use when creating a hash table. */ |
/* The default number of entries to use when creating a hash table. */ |
303 |
#define DEFAULT_SIZE (4051) |
#define DEFAULT_SIZE 4051 |
304 |
|
static size_t bfd_default_hash_table_size = DEFAULT_SIZE; |
305 |
|
|
306 |
/* Create a new hash table, given a number of entries. */ |
/* Create a new hash table, given a number of entries. */ |
307 |
|
|
308 |
boolean |
bfd_boolean |
309 |
bfd_hash_table_init_n (table, newfunc, size) |
bfd_hash_table_init_n (table, newfunc, size) |
310 |
struct bfd_hash_table *table; |
struct bfd_hash_table *table; |
311 |
struct bfd_hash_entry *(*newfunc) PARAMS ((struct bfd_hash_entry *, |
struct bfd_hash_entry *(*newfunc) PARAMS ((struct bfd_hash_entry *, |
321 |
if (table->memory == NULL) |
if (table->memory == NULL) |
322 |
{ |
{ |
323 |
bfd_set_error (bfd_error_no_memory); |
bfd_set_error (bfd_error_no_memory); |
324 |
return false; |
return FALSE; |
325 |
} |
} |
326 |
table->table = ((struct bfd_hash_entry **) |
table->table = ((struct bfd_hash_entry **) |
327 |
objalloc_alloc ((struct objalloc *) table->memory, alloc)); |
objalloc_alloc ((struct objalloc *) table->memory, alloc)); |
328 |
if (table->table == NULL) |
if (table->table == NULL) |
329 |
{ |
{ |
330 |
bfd_set_error (bfd_error_no_memory); |
bfd_set_error (bfd_error_no_memory); |
331 |
return false; |
return FALSE; |
332 |
} |
} |
333 |
memset ((PTR) table->table, 0, alloc); |
memset ((PTR) table->table, 0, alloc); |
334 |
table->size = size; |
table->size = size; |
335 |
table->newfunc = newfunc; |
table->newfunc = newfunc; |
336 |
return true; |
return TRUE; |
337 |
} |
} |
338 |
|
|
339 |
/* Create a new hash table with the default number of entries. */ |
/* Create a new hash table with the default number of entries. */ |
340 |
|
|
341 |
boolean |
bfd_boolean |
342 |
bfd_hash_table_init (table, newfunc) |
bfd_hash_table_init (table, newfunc) |
343 |
struct bfd_hash_table *table; |
struct bfd_hash_table *table; |
344 |
struct bfd_hash_entry *(*newfunc) PARAMS ((struct bfd_hash_entry *, |
struct bfd_hash_entry *(*newfunc) PARAMS ((struct bfd_hash_entry *, |
345 |
struct bfd_hash_table *, |
struct bfd_hash_table *, |
346 |
const char *)); |
const char *)); |
347 |
{ |
{ |
348 |
return bfd_hash_table_init_n (table, newfunc, DEFAULT_SIZE); |
return bfd_hash_table_init_n (table, newfunc, bfd_default_hash_table_size); |
349 |
} |
} |
350 |
|
|
351 |
/* Free a hash table. */ |
/* Free a hash table. */ |
364 |
bfd_hash_lookup (table, string, create, copy) |
bfd_hash_lookup (table, string, create, copy) |
365 |
struct bfd_hash_table *table; |
struct bfd_hash_table *table; |
366 |
const char *string; |
const char *string; |
367 |
boolean create; |
bfd_boolean create; |
368 |
boolean copy; |
bfd_boolean copy; |
369 |
{ |
{ |
370 |
register const unsigned char *s; |
register const unsigned char *s; |
371 |
register unsigned long hash; |
register unsigned long hash; |
452 |
|
|
453 |
/* Base method for creating a new hash table entry. */ |
/* Base method for creating a new hash table entry. */ |
454 |
|
|
|
/*ARGSUSED*/ |
|
455 |
struct bfd_hash_entry * |
struct bfd_hash_entry * |
456 |
bfd_hash_newfunc (entry, table, string) |
bfd_hash_newfunc (entry, table, string) |
457 |
struct bfd_hash_entry *entry; |
struct bfd_hash_entry *entry; |
484 |
void |
void |
485 |
bfd_hash_traverse (table, func, info) |
bfd_hash_traverse (table, func, info) |
486 |
struct bfd_hash_table *table; |
struct bfd_hash_table *table; |
487 |
boolean (*func) PARAMS ((struct bfd_hash_entry *, PTR)); |
bfd_boolean (*func) PARAMS ((struct bfd_hash_entry *, PTR)); |
488 |
PTR info; |
PTR info; |
489 |
{ |
{ |
490 |
unsigned int i; |
unsigned int i; |
501 |
} |
} |
502 |
} |
} |
503 |
|
|
504 |
|
void |
505 |
|
bfd_hash_set_default_size (bfd_size_type hash_size) |
506 |
|
{ |
507 |
|
/* Extend this prime list if you want more granularity of hash table size. */ |
508 |
|
static const bfd_size_type hash_size_primes[] = |
509 |
|
{ |
510 |
|
1021, 4051, 8599, 16699 |
511 |
|
}; |
512 |
|
size_t index; |
513 |
|
|
514 |
|
/* Work out best prime number near the hash_size. */ |
515 |
|
for (index = 0; index < ARRAY_SIZE (hash_size_primes) - 1; ++index) |
516 |
|
if (hash_size <= hash_size_primes[index]) |
517 |
|
break; |
518 |
|
|
519 |
|
bfd_default_hash_table_size = hash_size_primes[index]; |
520 |
|
} |
521 |
|
|
522 |
/* A few different object file formats (a.out, COFF, ELF) use a string |
/* A few different object file formats (a.out, COFF, ELF) use a string |
523 |
table. These functions support adding strings to a string table, |
table. These functions support adding strings to a string table, |
524 |
returning the byte offset, and writing out the table. |
returning the byte offset, and writing out the table. |
555 |
struct strtab_hash_entry *last; |
struct strtab_hash_entry *last; |
556 |
/* Whether to precede strings with a two byte length, as in the |
/* Whether to precede strings with a two byte length, as in the |
557 |
XCOFF .debug section. */ |
XCOFF .debug section. */ |
558 |
boolean xcoff; |
bfd_boolean xcoff; |
559 |
}; |
}; |
560 |
|
|
561 |
static struct bfd_hash_entry *strtab_hash_newfunc |
static struct bfd_hash_entry *strtab_hash_newfunc |
620 |
table->size = 0; |
table->size = 0; |
621 |
table->first = NULL; |
table->first = NULL; |
622 |
table->last = NULL; |
table->last = NULL; |
623 |
table->xcoff = false; |
table->xcoff = FALSE; |
624 |
|
|
625 |
return table; |
return table; |
626 |
} |
} |
636 |
|
|
637 |
ret = _bfd_stringtab_init (); |
ret = _bfd_stringtab_init (); |
638 |
if (ret != NULL) |
if (ret != NULL) |
639 |
ret->xcoff = true; |
ret->xcoff = TRUE; |
640 |
return ret; |
return ret; |
641 |
} |
} |
642 |
|
|
651 |
} |
} |
652 |
|
|
653 |
/* Get the index of a string in a strtab, adding it if it is not |
/* Get the index of a string in a strtab, adding it if it is not |
654 |
already present. If HASH is false, we don't really use the hash |
already present. If HASH is FALSE, we don't really use the hash |
655 |
table, and we don't eliminate duplicate strings. */ |
table, and we don't eliminate duplicate strings. */ |
656 |
|
|
657 |
bfd_size_type |
bfd_size_type |
658 |
_bfd_stringtab_add (tab, str, hash, copy) |
_bfd_stringtab_add (tab, str, hash, copy) |
659 |
struct bfd_strtab_hash *tab; |
struct bfd_strtab_hash *tab; |
660 |
const char *str; |
const char *str; |
661 |
boolean hash; |
bfd_boolean hash; |
662 |
boolean copy; |
bfd_boolean copy; |
663 |
{ |
{ |
664 |
register struct strtab_hash_entry *entry; |
register struct strtab_hash_entry *entry; |
665 |
|
|
666 |
if (hash) |
if (hash) |
667 |
{ |
{ |
668 |
entry = strtab_hash_lookup (tab, str, true, copy); |
entry = strtab_hash_lookup (tab, str, TRUE, copy); |
669 |
if (entry == NULL) |
if (entry == NULL) |
670 |
return (bfd_size_type) -1; |
return (bfd_size_type) -1; |
671 |
} |
} |
722 |
/* Write out a strtab. ABFD must already be at the right location in |
/* Write out a strtab. ABFD must already be at the right location in |
723 |
the file. */ |
the file. */ |
724 |
|
|
725 |
boolean |
bfd_boolean |
726 |
_bfd_stringtab_emit (abfd, tab) |
_bfd_stringtab_emit (abfd, tab) |
727 |
register bfd *abfd; |
register bfd *abfd; |
728 |
struct bfd_strtab_hash *tab; |
struct bfd_strtab_hash *tab; |
729 |
{ |
{ |
730 |
register boolean xcoff; |
register bfd_boolean xcoff; |
731 |
register struct strtab_hash_entry *entry; |
register struct strtab_hash_entry *entry; |
732 |
|
|
733 |
xcoff = tab->xcoff; |
xcoff = tab->xcoff; |
747 |
/* The output length includes the null byte. */ |
/* The output length includes the null byte. */ |
748 |
bfd_put_16 (abfd, (bfd_vma) len, buf); |
bfd_put_16 (abfd, (bfd_vma) len, buf); |
749 |
if (bfd_bwrite ((PTR) buf, (bfd_size_type) 2, abfd) != 2) |
if (bfd_bwrite ((PTR) buf, (bfd_size_type) 2, abfd) != 2) |
750 |
return false; |
return FALSE; |
751 |
} |
} |
752 |
|
|
753 |
if (bfd_bwrite ((PTR) str, (bfd_size_type) len, abfd) != len) |
if (bfd_bwrite ((PTR) str, (bfd_size_type) len, abfd) != len) |
754 |
return false; |
return FALSE; |
755 |
} |
} |
756 |
|
|
757 |
return true; |
return TRUE; |
758 |
} |
} |