9783e04a64
check the result for NULL. Most set bfd_error to no_memory and return in that case; a few are harder to fix, and are marked with "FIXME <return type>". * elf32-hppa.c (hppa_elf_build_arg_reloc_stub hppa_elf_build_long_branch_stub): Check bfd_make_empty_symbol return. * linker.c (_bfd_generic_link_output_symbols _bfd_generic_link_write_global_symbol): Ditto * section.c (bfd_make_section_anyway): Ditto. * tekhex.c (find_chunk tekhex_mkobject): Check bfd_alloc. (first_phase): Ditto. FIXME void (tekhex_make_empty_symbol): Check bfd_zalloc. * sunos.c (sunos_read_dynamic_info): Check bfd_zalloc. (MY(read_dynamic_symbols) MY(read_dynamic_relocs)): Check bfd_alloc. * stringhash.c (_bfd_stringtab_hash_newfunc): Check bfd_hash_allocate. * srec.c: Indent. (fillup_symbols): Check bfd_alloc. FIXME void (srec_mkobject srec_get_section_contents srec_set_section_contents): Check bfd_alloc. (srec_make_empty_symbol): Check bfd_zalloc. * som.c (hppa_som_gen_reloc_type): Check bfd_alloc_by_size_t. (make_unique_section): Check bfd_alloc. (som_new_section_hook): Check bfd_zalloc. (bfd_som_attach_aux_hdr): Ditto. FIXME void * rs6000-core.c (rs6000coff_core_p): Check bfd_zalloc. * osf-core.c (osf_core_make_empty_symbol): Check bfd_zalloc. (osf_core_core_file_p): Check bfd_alloc. * oasys.c (oasys_slurp_symbol_table oasys_archive_p oasys_mkobject oasys_object_p oasys_new_section_hook oasys_set_section_contents): Check bfd_alloc. (oasys_slurp_section_data): Check bfd_zalloc and bfd_alloc. (oasys_make_empty_symbol): Check bfd_zalloc. * nlmcode.h (nlm_make_empty_symbol): Check bfd_zalloc. (nlm_slurp_symbol_table): Check bfd_zalloc and bfd_alloc. * nlm32-sparc.c (nlm_sparc_read_import): Check bfd_alloc. * nlm32-i386.c (nlm_i386_read_import): Check bfd_alloc. * nlm32-alpha.c (nlm_alpha_read_import): Check bfd_alloc. * linker.c (_bfd_link_hash_newfunc (generic_link_hash_newfunc (archive_hash_newfunc (_bfd_generic_link_add_one_symbol): Check bfd_hash_allocate. (_bfd_generic_final_link (_bfd_generic_link_output_symbols (default_indirect_link_order): Check bfd_alloc. (bfd_new_link_order): Check bfd_alloc_by_size_t. * irix-core.c (irix_core_make_empty_symbol): Check bfd_zalloc. * ieee.c: Indent. (read_id get_symbol get_section_entry ieee_archive_p ieee_object_p ieee_slurp_section_data ieee_new_section_hook): Check bfd_alloc. (do_one): Check bfd_alloc. Return a boolean. (ieee_slurp_section_data): Check it. (init_for_output): Check bfd_alloc. Return a boolean. (ieee_set_section_contents): Check it. (do_with_relocs): Check bfd_alloc. Return a boolean. (ieee_bfd_debug_info_accumulate): Ditto. FIXME void. (ieee_mkobject): Check bfd_zalloc. (ieee_make_empty_symbol): Check bfd_zmalloc. * hpux-core.c (hpux_core_make_empty_symbol): Check bfd_zalloc. * hppabsd-core.c (hppabsd_core_make_empty_symbol): Check bfd_zalloc. (hppabsd_core_core_file_p): Check bfd_zalloc. * hp300hpux.c (MY(slurp_symbol_table)): Check bfd_alloc. * elfcode.h (elf_new_section_hook): Check bfd_alloc. (bfd_section_from_phdr): Ditto. (write_relocs): Ditto. FIXME void (elf_map_symbols assign_section_numbers map_program_segments): Ditto. Return a boolean. (swap_out_syms): Ditto. Check elf_map_symbols. (elf_slurp_symbol_table): Check bfd_zalloc. (elf_slurp_reloca_table): Check bfd_alloc. (elf_slurp_reloc_table): Ditto. (elf_compute_section_file_positions): Check assign_section_numbers. (assign_file_positions_except_relocs): Return a boolean. Check map_program_segments. (elf_compute_section_file_positions): Check it. * elf32-mips.c (mips_elf_final_link): Check bfd_alloc. * elf32-hppa.c (hppa_elf_stub_branch_reloc): Check bfd_zmalloc and realloc. (hppa_elf_stub_reloc): Ditto. (hppa_elf_build_arg_reloc_stub): Check bfd_zalloc. (hppa_elf_build_long_branch_stub): Ditto. (elf32_hppa_backend_symbol_table_processing): Ditto. * ecoff.c (ecoff_set_symbol_info): Check bfd_alloc. Return a boolean. (ecoff_slurp_symbol_table): Check it. (ecoff_slurp_armap): Check bfd_alloc. (ecoff_write_armap): Check bfd_zalloc. (ecoff_link_hash_newfunc): Check bfd_hash_allocate and _bfd_link_hash_newfunc. (ecoff_link_add_externals): Check bfd_alloc. * ctor.c (bfd_constructor_entry): Check bfd_alloc. * coffgen.c (coff_real_object_p): Check bfd_alloc. (coff_renumber_symbols): Check bfd_alloc_by_size_t. Return a boolean. (coff_write_symbol): Check bfd_alloc. FIXME int (coff_write_linenumbers): Check bfd_alloc. Return a boolean. (coff_section_symbol): Check bfd_alloc_by_size_t. (coff_get_normalized_symtab): Check bfd_alloc. (coff_bfd_make_debug_symbol): Check bfd_zalloc. * libcoff-in.h: Change decls of coff_renumber_symbols, coff_write_linenumbers. * libcoff.h: Rebuilt. * coffcode.h (coff_write_object_contents): Check coff_renumber_symbols, coff_write_linenumbers. * coffcode.h: Indent. (coff_add_missing_symbols): Check bfd_alloc_by_size_t. Return a boolean. (coff_write_object_contents): Check it. * coff-alpha.c (alpha_relocate_section): Check bfd_alloc. * coff-mips.c (mips_relocate_section): Ditto. * archive.c (bfd_slurp_bsd_armap_f2): Check bfd_alloc value. (do_slurp_bsd_armap): Ditto. (compute_and_write_armap): Check bfd_realloc value. * aoutx.h (translate_from_native_sym_flags): Check bfd_alloc return value. Return boolean value. (NAME(aout,make_empty_symbol)): Check bfd_zalloc return value. (NAME(aout,slurp_symbol_table)): Check bf_alloc and bfd_zalloc return value. (add_to_stringtab): Ditto. FIXME void (aout_link_hash_newfunc): Check bfd_hash_allocate return value. (aout_link_add_symbols): Check bfd_alloc value. (translate_symbol_table): Check translate_from_native_sym_flags. * hp300hpux.c (MY(slurp_symbol_table)): Ditto. * aoutx.h (aout_link_hash_newfunc): Check _bfd_link_hash_newfunc. * opncls.c (bfd_zalloc bfd_realloc): Check result of bfd_alloc. * opncls.c (obstack_chunk_alloc): Define as malloc, not bfd_xmalloc_by_size_t. (_bfd_new_bfd): Check obstack_begin for 0 return. * ieee.c (obstack_chunk_alloc): Define as malloc, not bfd_xmalloc_by_size_t. (ieee_archive_p): Check obstack_begin for 0 return and obstack_finish for NULL return. * hash.c (obstack_chunk_alloc): Define as malloc, not bfd_xmalloc_by_size_t. (bfd_hash_table_init_n): Check obstack_begin for 0 return and obstack_finish for NULL return. (bfd_hash_lookup): Check obstack_alloc for NULL return. * ecofflink.c (obstack_chunk_alloc): Define as malloc, not bfd_xmalloc_by_size_t. bfd_ecoff_debug_accumulate bfd_ecoff_debug_accumulate_other): Check obstack_alloc. (add_file_shuffle add_memory_shuffle): Check obstack_alloc for NULL return. Return boolean, not void. (bfd_ecoff_debug_init): Check obstack_begin for 0 return. (bfd_ecoff_debug_accumulate): Check add_file_shuffle and add_memory_shuffle return. (string_hash_newfunc): Check bfd_hash_allocate and bfd_hash_newfunc. (bfd_ecoff_debug_accumulate): Check bfd_alloc. (ecoff_add_string): Check add_memory_shuffle return. * libbfd-in.h (xmalloc, bfd_xmalloc, bfd_xmalloc_by_size_t): Remove decls. * libbfd.h: Rebuilt.
462 lines
15 KiB
C
462 lines
15 KiB
C
/* hash.c -- hash table routines for BFD
|
|
Copyright (C) 1993, 94 Free Software Foundation, Inc.
|
|
Written by Steve Chamberlain <sac@cygnus.com>
|
|
|
|
This file is part of BFD, the Binary File Descriptor library.
|
|
|
|
This program is free software; you can redistribute it and/or modify
|
|
it under the terms of 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.
|
|
|
|
This program 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.
|
|
|
|
You should have received a copy of the GNU General Public License
|
|
along with this program; if not, write to the Free Software
|
|
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
|
|
|
|
#include "bfd.h"
|
|
#include "sysdep.h"
|
|
#include "libbfd.h"
|
|
#include "obstack.h"
|
|
|
|
/*
|
|
SECTION
|
|
Hash Tables
|
|
|
|
@cindex Hash tables
|
|
BFD provides a simple set of hash table functions. Routines
|
|
are provided to initialize a hash table, to free a hash table,
|
|
to look up a string in a hash table and optionally create an
|
|
entry for it, and to traverse a hash table. There is
|
|
currently no routine to delete an string from a hash table.
|
|
|
|
The basic hash table does not permit any data to be stored
|
|
with a string. However, a hash table is designed to present a
|
|
base class from which other types of hash tables may be
|
|
derived. These derived types may store additional information
|
|
with the string. Hash tables were implemented in this way,
|
|
rather than simply providing a data pointer in a hash table
|
|
entry, because they were designed for use by the linker back
|
|
ends. The linker may create thousands of hash table entries,
|
|
and the overhead of allocating private data and storing and
|
|
following pointers becomes noticeable.
|
|
|
|
The basic hash table code is in <<hash.c>>.
|
|
|
|
@menu
|
|
@* Creating and Freeing a Hash Table::
|
|
@* Looking Up or Entering a String::
|
|
@* Traversing a Hash Table::
|
|
@* Deriving a New Hash Table Type::
|
|
@end menu
|
|
|
|
INODE
|
|
Creating and Freeing a Hash Table, Looking Up or Entering a String, Hash Tables, Hash Tables
|
|
SUBSECTION
|
|
Creating and freeing a hash table
|
|
|
|
@findex bfd_hash_table_init
|
|
@findex bfd_hash_table_init_n
|
|
To create a hash table, create an instance of a <<struct
|
|
bfd_hash_table>> (defined in <<bfd.h>>) and call
|
|
<<bfd_hash_table_init>> (if you know approximately how many
|
|
entries you will need, the function <<bfd_hash_table_init_n>>,
|
|
which takes a @var{size} argument, may be used).
|
|
<<bfd_hash_table_init>> returns <<false>> if some sort of
|
|
error occurs.
|
|
|
|
@findex bfd_hash_newfunc
|
|
The function <<bfd_hash_table_init>> take as an argument a
|
|
function to use to create new entries. For a basic hash
|
|
table, use the function <<bfd_hash_newfunc>>. @xref{Deriving
|
|
a New Hash Table Type} for why you would want to use a
|
|
different value for this argument.
|
|
|
|
@findex bfd_hash_allocate
|
|
<<bfd_hash_table_init>> will create an obstack which will be
|
|
used to allocate new entries. You may allocate memory on this
|
|
obstack using <<bfd_hash_allocate>>.
|
|
|
|
@findex bfd_hash_table_free
|
|
Use <<bfd_hash_table_free>> to free up all the memory that has
|
|
been allocated for a hash table. This will not free up the
|
|
<<struct bfd_hash_table>> itself, which you must provide.
|
|
|
|
INODE
|
|
Looking Up or Entering a String, Traversing a Hash Table, Creating and Freeing a Hash Table, Hash Tables
|
|
SUBSECTION
|
|
Looking up or entering a string
|
|
|
|
@findex bfd_hash_lookup
|
|
The function <<bfd_hash_lookup>> is used both to look up a
|
|
string in the hash table and to create a new entry.
|
|
|
|
If the @var{create} argument is <<false>>, <<bfd_hash_lookup>>
|
|
will look up a string. If the string is found, it will
|
|
returns a pointer to a <<struct bfd_hash_entry>>. If the
|
|
string is not found in the table <<bfd_hash_lookup>> will
|
|
return <<NULL>>. You should not modify any of the fields in
|
|
the returns <<struct bfd_hash_entry>>.
|
|
|
|
If the @var{create} argument is <<true>>, the string will be
|
|
entered into the hash table if it is not already there.
|
|
Either way a pointer to a <<struct bfd_hash_entry>> will be
|
|
returned, either to the existing structure or to a newly
|
|
created one. In this case, a <<NULL>> return means that an
|
|
error occurred.
|
|
|
|
If the @var{create} argument is <<true>>, and a new entry is
|
|
created, the @var{copy} argument is used to decide whether to
|
|
copy the string onto the hash table obstack or not. If
|
|
@var{copy} is passed as <<false>>, you must be careful not to
|
|
deallocate or modify the string as long as the hash table
|
|
exists.
|
|
|
|
INODE
|
|
Traversing a Hash Table, Deriving a New Hash Table Type, Looking Up or Entering a String, Hash Tables
|
|
SUBSECTION
|
|
Traversing a hash table
|
|
|
|
@findex bfd_hash_traverse
|
|
The function <<bfd_hash_traverse>> may be used to traverse a
|
|
hash table, calling a function on each element. The traversal
|
|
is done in a random order.
|
|
|
|
<<bfd_hash_traverse>> takes as arguments a function and a
|
|
generic <<void *>> pointer. The function is called with a
|
|
hash table entry (a <<struct bfd_hash_entry *>>) and the
|
|
generic pointer passed to <<bfd_hash_traverse>>. The function
|
|
must return a <<boolean>> value, which indicates whether to
|
|
continue traversing the hash table. If the function returns
|
|
<<false>>, <<bfd_hash_traverse>> will stop the traversal and
|
|
return immediately.
|
|
|
|
INODE
|
|
Deriving a New Hash Table Type, , Traversing a Hash Table, Hash Tables
|
|
SUBSECTION
|
|
Deriving a new hash table type
|
|
|
|
Many uses of hash tables want to store additional information
|
|
which each entry in the hash table. Some also find it
|
|
convenient to store additional information with the hash table
|
|
itself. This may be done using a derived hash table.
|
|
|
|
Since C is not an object oriented language, creating a derived
|
|
hash table requires sticking together some boilerplate
|
|
routines with a few differences specific to the type of hash
|
|
table you want to create.
|
|
|
|
An example of a derived hash table is the linker hash table.
|
|
The structures for this are defined in <<bfdlink.h>>. The
|
|
functions are in <<linker.c>>.
|
|
|
|
You may also derive a hash table from an already derived hash
|
|
table. For example, the a.out linker backend code uses a hash
|
|
table derived from the linker hash table.
|
|
|
|
@menu
|
|
@* Define the Derived Structures::
|
|
@* Write the Derived Creation Routine::
|
|
@* Write Other Derived Routines::
|
|
@end menu
|
|
|
|
INODE
|
|
Define the Derived Structures, Write the Derived Creation Routine, Deriving a New Hash Table Type, Deriving a New Hash Table Type
|
|
SUBSUBSECTION
|
|
Define the derived structures
|
|
|
|
You must define a structure for an entry in the hash table,
|
|
and a structure for the hash table itself.
|
|
|
|
The first field in the structure for an entry in the hash
|
|
table must be of the type used for an entry in the hash table
|
|
you are deriving from. If you are deriving from a basic hash
|
|
table this is <<struct bfd_hash_entry>>, which is defined in
|
|
<<bfd.h>>. The first field in the structure for the hash
|
|
table itself must be of the type of the hash table you are
|
|
deriving from itself. If you are deriving from a basic hash
|
|
table, this is <<struct bfd_hash_table>>.
|
|
|
|
For example, the linker hash table defines <<struct
|
|
bfd_link_hash_entry>> (in <<bfdlink.h>>). The first field,
|
|
<<root>>, is of type <<struct bfd_hash_entry>>. Similarly,
|
|
the first field in <<struct bfd_link_hash_table>>, <<table>>,
|
|
is of type <<struct bfd_hash_table>>.
|
|
|
|
INODE
|
|
Write the Derived Creation Routine, Write Other Derived Routines, Define the Derived Structures, Deriving a New Hash Table Type
|
|
SUBSUBSECTION
|
|
Write the derived creation routine
|
|
|
|
You must write a routine which will create and initialize an
|
|
entry in the hash table. This routine is passed as the
|
|
function argument to <<bfd_hash_table_init>>.
|
|
|
|
In order to permit other hash tables to be derived from the
|
|
hash table you are creating, this routine must be written in a
|
|
standard way.
|
|
|
|
The first argument to the creation routine is a pointer to a
|
|
hash table entry. This may be <<NULL>>, in which case the
|
|
routine should allocate the right amount of space. Otherwise
|
|
the space has already been allocated by a hash table type
|
|
derived from this one.
|
|
|
|
After allocating space, the creation routine must call the
|
|
creation routine of the hash table type it is derived from,
|
|
passing in a pointer to the space it just allocated. This
|
|
will initialize any fields used by the base hash table.
|
|
|
|
Finally the creation routine must initialize any local fields
|
|
for the new hash table type.
|
|
|
|
Here is a boilerplate example of a creation routine.
|
|
@var{function_name} is the name of the routine.
|
|
@var{entry_type} is the type of an entry in the hash table you
|
|
are creating. @var{base_newfunc} is the name of the creation
|
|
routine of the hash table type your hash table is derived
|
|
from.
|
|
|
|
EXAMPLE
|
|
|
|
.struct bfd_hash_entry *
|
|
.@var{function_name} (entry, table, string)
|
|
. struct bfd_hash_entry *entry;
|
|
. struct bfd_hash_table *table;
|
|
. const char *string;
|
|
.{
|
|
. struct @var{entry_type} *ret = (@var{entry_type} *) entry;
|
|
.
|
|
. {* Allocate the structure if it has not already been allocated by a
|
|
. derived class. *}
|
|
. if (ret == (@var{entry_type} *) NULL)
|
|
. ret = ((@var{entry_type} *)
|
|
. bfd_hash_allocate (table, sizeof (@var{entry_type})));
|
|
.
|
|
. {* Call the allocation method of the base class. *}
|
|
. ret = ((@var{entry_type} *)
|
|
. @var{base_newfunc} ((struct bfd_hash_entry *) ret, table, string));
|
|
.
|
|
. {* Initialize the local fields here. *}
|
|
.
|
|
. return (struct bfd_hash_entry *) ret;
|
|
.}
|
|
|
|
DESCRIPTION
|
|
The creation routine for the linker hash table, which is in
|
|
<<linker.c>>, looks just like this example.
|
|
@var{function_name} is <<_bfd_link_hash_newfunc>>.
|
|
@var{entry_type} is <<struct bfd_link_hash_entry>>.
|
|
@var{base_newfunc} is <<bfd_hash_newfunc>>, the creation
|
|
routine for a basic hash table.
|
|
|
|
<<_bfd_link_hash_newfunc>> also initializes the local fields
|
|
in a linker hash table entry: <<type>>, <<written>> and
|
|
<<next>>.
|
|
|
|
INODE
|
|
Write Other Derived Routines, , Write the Derived Creation Routine, Deriving a New Hash Table Type
|
|
SUBSUBSECTION
|
|
Write other derived routines
|
|
|
|
You will want to write other routines for your new hash table,
|
|
as well.
|
|
|
|
You will want an initialization routine which calls the
|
|
initialization routine of the hash table you are deriving from
|
|
and initializes any other local fields. For the linker hash
|
|
table, this is <<_bfd_link_hash_table_init>> in <<linker.c>>.
|
|
|
|
You will want a lookup routine which calls the lookup routine
|
|
of the hash table you are deriving from and casts the result.
|
|
The linker hash table uses <<bfd_link_hash_lookup>> in
|
|
<<linker.c>> (this actually takes an additional argument which
|
|
it uses to decide how to return the looked up value).
|
|
|
|
You may want a traversal routine. This should just call the
|
|
traversal routine of the hash table you are deriving from with
|
|
appropriate casts. The linker hash table uses
|
|
<<bfd_link_hash_traverse>> in <<linker.c>>.
|
|
|
|
These routines may simply be defined as macros. For example,
|
|
the a.out backend linker hash table, which is derived from the
|
|
linker hash table, uses macros for the lookup and traversal
|
|
routines. These are <<aout_link_hash_lookup>> and
|
|
<<aout_link_hash_traverse>> in aoutx.h.
|
|
*/
|
|
|
|
/* Obstack allocation and deallocation routines. */
|
|
#define obstack_chunk_alloc malloc
|
|
#define obstack_chunk_free free
|
|
|
|
/* The default number of entries to use when creating a hash table. */
|
|
#define DEFAULT_SIZE (4051)
|
|
|
|
/* Create a new hash table, given a number of entries. */
|
|
|
|
boolean
|
|
bfd_hash_table_init_n (table, newfunc, size)
|
|
struct bfd_hash_table *table;
|
|
struct bfd_hash_entry *(*newfunc) PARAMS ((struct bfd_hash_entry *,
|
|
struct bfd_hash_table *,
|
|
const char *));
|
|
unsigned int size;
|
|
{
|
|
unsigned int alloc;
|
|
|
|
alloc = size * sizeof (struct bfd_hash_entry *);
|
|
if (!obstack_begin (&table->memory, alloc))
|
|
{
|
|
bfd_error = no_memory;
|
|
return false;
|
|
}
|
|
table->table = ((struct bfd_hash_entry **)
|
|
obstack_alloc (&table->memory, alloc));
|
|
if (!table->table)
|
|
{
|
|
bfd_error = no_memory;
|
|
return false;
|
|
}
|
|
memset ((PTR) table->table, 0, alloc);
|
|
table->size = size;
|
|
table->newfunc = newfunc;
|
|
return true;
|
|
}
|
|
|
|
/* Create a new hash table with the default number of entries. */
|
|
|
|
boolean
|
|
bfd_hash_table_init (table, newfunc)
|
|
struct bfd_hash_table *table;
|
|
struct bfd_hash_entry *(*newfunc) PARAMS ((struct bfd_hash_entry *,
|
|
struct bfd_hash_table *,
|
|
const char *));
|
|
{
|
|
return bfd_hash_table_init_n (table, newfunc, DEFAULT_SIZE);
|
|
}
|
|
|
|
/* Free a hash table. */
|
|
|
|
void
|
|
bfd_hash_table_free (table)
|
|
struct bfd_hash_table *table;
|
|
{
|
|
obstack_free (&table->memory, (PTR) NULL);
|
|
}
|
|
|
|
/* Look up a string in a hash table. */
|
|
|
|
struct bfd_hash_entry *
|
|
bfd_hash_lookup (table, string, create, copy)
|
|
struct bfd_hash_table *table;
|
|
const char *string;
|
|
boolean create;
|
|
boolean copy;
|
|
{
|
|
register const unsigned char *s;
|
|
register unsigned long hash;
|
|
register unsigned int c;
|
|
struct bfd_hash_entry *hashp;
|
|
unsigned int len;
|
|
unsigned int index;
|
|
|
|
hash = 0;
|
|
len = 0;
|
|
s = (const unsigned char *) string;
|
|
while ((c = *s++) != '\0')
|
|
{
|
|
hash += c + (c << 17);
|
|
hash ^= hash >> 2;
|
|
++len;
|
|
}
|
|
hash += len + (len << 17);
|
|
hash ^= hash >> 2;
|
|
|
|
index = hash % table->size;
|
|
for (hashp = table->table[index];
|
|
hashp != (struct bfd_hash_entry *) NULL;
|
|
hashp = hashp->next)
|
|
{
|
|
if (hashp->hash == hash
|
|
&& strcmp (hashp->string, string) == 0)
|
|
return hashp;
|
|
}
|
|
|
|
if (! create)
|
|
return (struct bfd_hash_entry *) NULL;
|
|
|
|
hashp = (*table->newfunc) ((struct bfd_hash_entry *) NULL, table, string);
|
|
if (hashp == (struct bfd_hash_entry *) NULL)
|
|
return (struct bfd_hash_entry *) NULL;
|
|
if (copy)
|
|
{
|
|
char *new;
|
|
|
|
new = (char *) obstack_alloc (&table->memory, len + 1);
|
|
if (!new)
|
|
{
|
|
bfd_error = no_memory;
|
|
return (struct bfd_hash_entry *) NULL;
|
|
}
|
|
strcpy (new, string);
|
|
string = new;
|
|
}
|
|
hashp->string = string;
|
|
hashp->hash = hash;
|
|
hashp->next = table->table[index];
|
|
table->table[index] = hashp;
|
|
|
|
return hashp;
|
|
}
|
|
|
|
/* Base method for creating a new hash table entry. */
|
|
|
|
/*ARGSUSED*/
|
|
struct bfd_hash_entry *
|
|
bfd_hash_newfunc (entry, table, string)
|
|
struct bfd_hash_entry *entry;
|
|
struct bfd_hash_table *table;
|
|
const char *string;
|
|
{
|
|
if (entry == (struct bfd_hash_entry *) NULL)
|
|
entry = ((struct bfd_hash_entry *)
|
|
bfd_hash_allocate (table, sizeof (struct bfd_hash_entry)));
|
|
return entry;
|
|
}
|
|
|
|
/* Allocate space in a hash table. */
|
|
|
|
PTR
|
|
bfd_hash_allocate (table, size)
|
|
struct bfd_hash_table *table;
|
|
unsigned int size;
|
|
{
|
|
return obstack_alloc (&table->memory, size);
|
|
}
|
|
|
|
/* Traverse a hash table. */
|
|
|
|
void
|
|
bfd_hash_traverse (table, func, info)
|
|
struct bfd_hash_table *table;
|
|
boolean (*func) PARAMS ((struct bfd_hash_entry *, PTR));
|
|
PTR info;
|
|
{
|
|
unsigned int i;
|
|
|
|
for (i = 0; i < table->size; i++)
|
|
{
|
|
struct bfd_hash_entry *p;
|
|
|
|
for (p = table->table[i]; p != NULL; p = p->next)
|
|
{
|
|
if (! (*func) (p, info))
|
|
return;
|
|
}
|
|
}
|
|
}
|