| 1 | @section Hash Tables
|
|---|
| 2 | @cindex Hash tables
|
|---|
| 3 | BFD provides a simple set of hash table functions. Routines
|
|---|
| 4 | are provided to initialize a hash table, to free a hash table,
|
|---|
| 5 | to look up a string in a hash table and optionally create an
|
|---|
| 6 | entry for it, and to traverse a hash table. There is
|
|---|
| 7 | currently no routine to delete an string from a hash table.
|
|---|
| 8 |
|
|---|
| 9 | The basic hash table does not permit any data to be stored
|
|---|
| 10 | with a string. However, a hash table is designed to present a
|
|---|
| 11 | base class from which other types of hash tables may be
|
|---|
| 12 | derived. These derived types may store additional information
|
|---|
| 13 | with the string. Hash tables were implemented in this way,
|
|---|
| 14 | rather than simply providing a data pointer in a hash table
|
|---|
| 15 | entry, because they were designed for use by the linker back
|
|---|
| 16 | ends. The linker may create thousands of hash table entries,
|
|---|
| 17 | and the overhead of allocating private data and storing and
|
|---|
| 18 | following pointers becomes noticeable.
|
|---|
| 19 |
|
|---|
| 20 | The basic hash table code is in @code{hash.c}.
|
|---|
| 21 |
|
|---|
| 22 | @menu
|
|---|
| 23 | * Creating and Freeing a Hash Table::
|
|---|
| 24 | * Looking Up or Entering a String::
|
|---|
| 25 | * Traversing a Hash Table::
|
|---|
| 26 | * Deriving a New Hash Table Type::
|
|---|
| 27 | @end menu
|
|---|
| 28 |
|
|---|
| 29 | @node Creating and Freeing a Hash Table, Looking Up or Entering a String, Hash Tables, Hash Tables
|
|---|
| 30 | @subsection Creating and freeing a hash table
|
|---|
| 31 | @findex bfd_hash_table_init
|
|---|
| 32 | @findex bfd_hash_table_init_n
|
|---|
| 33 | To create a hash table, create an instance of a @code{struct
|
|---|
| 34 | bfd_hash_table} (defined in @code{bfd.h}) and call
|
|---|
| 35 | @code{bfd_hash_table_init} (if you know approximately how many
|
|---|
| 36 | entries you will need, the function @code{bfd_hash_table_init_n},
|
|---|
| 37 | which takes a @var{size} argument, may be used).
|
|---|
| 38 | @code{bfd_hash_table_init} returns @code{FALSE} if some sort of
|
|---|
| 39 | error occurs.
|
|---|
| 40 |
|
|---|
| 41 | @findex bfd_hash_newfunc
|
|---|
| 42 | The function @code{bfd_hash_table_init} take as an argument a
|
|---|
| 43 | function to use to create new entries. For a basic hash
|
|---|
| 44 | table, use the function @code{bfd_hash_newfunc}. @xref{Deriving
|
|---|
| 45 | a New Hash Table Type}, for why you would want to use a
|
|---|
| 46 | different value for this argument.
|
|---|
| 47 |
|
|---|
| 48 | @findex bfd_hash_allocate
|
|---|
| 49 | @code{bfd_hash_table_init} will create an objalloc which will be
|
|---|
| 50 | used to allocate new entries. You may allocate memory on this
|
|---|
| 51 | objalloc using @code{bfd_hash_allocate}.
|
|---|
| 52 |
|
|---|
| 53 | @findex bfd_hash_table_free
|
|---|
| 54 | Use @code{bfd_hash_table_free} to free up all the memory that has
|
|---|
| 55 | been allocated for a hash table. This will not free up the
|
|---|
| 56 | @code{struct bfd_hash_table} itself, which you must provide.
|
|---|
| 57 |
|
|---|
| 58 | @node Looking Up or Entering a String, Traversing a Hash Table, Creating and Freeing a Hash Table, Hash Tables
|
|---|
| 59 | @subsection Looking up or entering a string
|
|---|
| 60 | @findex bfd_hash_lookup
|
|---|
| 61 | The function @code{bfd_hash_lookup} is used both to look up a
|
|---|
| 62 | string in the hash table and to create a new entry.
|
|---|
| 63 |
|
|---|
| 64 | If the @var{create} argument is @code{FALSE}, @code{bfd_hash_lookup}
|
|---|
| 65 | will look up a string. If the string is found, it will
|
|---|
| 66 | returns a pointer to a @code{struct bfd_hash_entry}. If the
|
|---|
| 67 | string is not found in the table @code{bfd_hash_lookup} will
|
|---|
| 68 | return @code{NULL}. You should not modify any of the fields in
|
|---|
| 69 | the returns @code{struct bfd_hash_entry}.
|
|---|
| 70 |
|
|---|
| 71 | If the @var{create} argument is @code{TRUE}, the string will be
|
|---|
| 72 | entered into the hash table if it is not already there.
|
|---|
| 73 | Either way a pointer to a @code{struct bfd_hash_entry} will be
|
|---|
| 74 | returned, either to the existing structure or to a newly
|
|---|
| 75 | created one. In this case, a @code{NULL} return means that an
|
|---|
| 76 | error occurred.
|
|---|
| 77 |
|
|---|
| 78 | If the @var{create} argument is @code{TRUE}, and a new entry is
|
|---|
| 79 | created, the @var{copy} argument is used to decide whether to
|
|---|
| 80 | copy the string onto the hash table objalloc or not. If
|
|---|
| 81 | @var{copy} is passed as @code{FALSE}, you must be careful not to
|
|---|
| 82 | deallocate or modify the string as long as the hash table
|
|---|
| 83 | exists.
|
|---|
| 84 |
|
|---|
| 85 | @node Traversing a Hash Table, Deriving a New Hash Table Type, Looking Up or Entering a String, Hash Tables
|
|---|
| 86 | @subsection Traversing a hash table
|
|---|
| 87 | @findex bfd_hash_traverse
|
|---|
| 88 | The function @code{bfd_hash_traverse} may be used to traverse a
|
|---|
| 89 | hash table, calling a function on each element. The traversal
|
|---|
| 90 | is done in a random order.
|
|---|
| 91 |
|
|---|
| 92 | @code{bfd_hash_traverse} takes as arguments a function and a
|
|---|
| 93 | generic @code{void *} pointer. The function is called with a
|
|---|
| 94 | hash table entry (a @code{struct bfd_hash_entry *}) and the
|
|---|
| 95 | generic pointer passed to @code{bfd_hash_traverse}. The function
|
|---|
| 96 | must return a @code{boolean} value, which indicates whether to
|
|---|
| 97 | continue traversing the hash table. If the function returns
|
|---|
| 98 | @code{FALSE}, @code{bfd_hash_traverse} will stop the traversal and
|
|---|
| 99 | return immediately.
|
|---|
| 100 |
|
|---|
| 101 | @node Deriving a New Hash Table Type, , Traversing a Hash Table, Hash Tables
|
|---|
| 102 | @subsection Deriving a new hash table type
|
|---|
| 103 | Many uses of hash tables want to store additional information
|
|---|
| 104 | which each entry in the hash table. Some also find it
|
|---|
| 105 | convenient to store additional information with the hash table
|
|---|
| 106 | itself. This may be done using a derived hash table.
|
|---|
| 107 |
|
|---|
| 108 | Since C is not an object oriented language, creating a derived
|
|---|
| 109 | hash table requires sticking together some boilerplate
|
|---|
| 110 | routines with a few differences specific to the type of hash
|
|---|
| 111 | table you want to create.
|
|---|
| 112 |
|
|---|
| 113 | An example of a derived hash table is the linker hash table.
|
|---|
| 114 | The structures for this are defined in @code{bfdlink.h}. The
|
|---|
| 115 | functions are in @code{linker.c}.
|
|---|
| 116 |
|
|---|
| 117 | You may also derive a hash table from an already derived hash
|
|---|
| 118 | table. For example, the a.out linker backend code uses a hash
|
|---|
| 119 | table derived from the linker hash table.
|
|---|
| 120 |
|
|---|
| 121 | @menu
|
|---|
| 122 | * Define the Derived Structures::
|
|---|
| 123 | * Write the Derived Creation Routine::
|
|---|
| 124 | * Write Other Derived Routines::
|
|---|
| 125 | @end menu
|
|---|
| 126 |
|
|---|
| 127 | @node Define the Derived Structures, Write the Derived Creation Routine, Deriving a New Hash Table Type, Deriving a New Hash Table Type
|
|---|
| 128 | @subsubsection Define the derived structures
|
|---|
| 129 | You must define a structure for an entry in the hash table,
|
|---|
| 130 | and a structure for the hash table itself.
|
|---|
| 131 |
|
|---|
| 132 | The first field in the structure for an entry in the hash
|
|---|
| 133 | table must be of the type used for an entry in the hash table
|
|---|
| 134 | you are deriving from. If you are deriving from a basic hash
|
|---|
| 135 | table this is @code{struct bfd_hash_entry}, which is defined in
|
|---|
| 136 | @code{bfd.h}. The first field in the structure for the hash
|
|---|
| 137 | table itself must be of the type of the hash table you are
|
|---|
| 138 | deriving from itself. If you are deriving from a basic hash
|
|---|
| 139 | table, this is @code{struct bfd_hash_table}.
|
|---|
| 140 |
|
|---|
| 141 | For example, the linker hash table defines @code{struct
|
|---|
| 142 | bfd_link_hash_entry} (in @code{bfdlink.h}). The first field,
|
|---|
| 143 | @code{root}, is of type @code{struct bfd_hash_entry}. Similarly,
|
|---|
| 144 | the first field in @code{struct bfd_link_hash_table}, @code{table},
|
|---|
| 145 | is of type @code{struct bfd_hash_table}.
|
|---|
| 146 |
|
|---|
| 147 | @node Write the Derived Creation Routine, Write Other Derived Routines, Define the Derived Structures, Deriving a New Hash Table Type
|
|---|
| 148 | @subsubsection Write the derived creation routine
|
|---|
| 149 | You must write a routine which will create and initialize an
|
|---|
| 150 | entry in the hash table. This routine is passed as the
|
|---|
| 151 | function argument to @code{bfd_hash_table_init}.
|
|---|
| 152 |
|
|---|
| 153 | In order to permit other hash tables to be derived from the
|
|---|
| 154 | hash table you are creating, this routine must be written in a
|
|---|
| 155 | standard way.
|
|---|
| 156 |
|
|---|
| 157 | The first argument to the creation routine is a pointer to a
|
|---|
| 158 | hash table entry. This may be @code{NULL}, in which case the
|
|---|
| 159 | routine should allocate the right amount of space. Otherwise
|
|---|
| 160 | the space has already been allocated by a hash table type
|
|---|
| 161 | derived from this one.
|
|---|
| 162 |
|
|---|
| 163 | After allocating space, the creation routine must call the
|
|---|
| 164 | creation routine of the hash table type it is derived from,
|
|---|
| 165 | passing in a pointer to the space it just allocated. This
|
|---|
| 166 | will initialize any fields used by the base hash table.
|
|---|
| 167 |
|
|---|
| 168 | Finally the creation routine must initialize any local fields
|
|---|
| 169 | for the new hash table type.
|
|---|
| 170 |
|
|---|
| 171 | Here is a boilerplate example of a creation routine.
|
|---|
| 172 | @var{function_name} is the name of the routine.
|
|---|
| 173 | @var{entry_type} is the type of an entry in the hash table you
|
|---|
| 174 | are creating. @var{base_newfunc} is the name of the creation
|
|---|
| 175 | routine of the hash table type your hash table is derived
|
|---|
| 176 | from.
|
|---|
| 177 |
|
|---|
| 178 |
|
|---|
| 179 | @example
|
|---|
| 180 | struct bfd_hash_entry *
|
|---|
| 181 | @var{function_name} (entry, table, string)
|
|---|
| 182 | struct bfd_hash_entry *entry;
|
|---|
| 183 | struct bfd_hash_table *table;
|
|---|
| 184 | const char *string;
|
|---|
| 185 | @{
|
|---|
| 186 | struct @var{entry_type} *ret = (@var{entry_type} *) entry;
|
|---|
| 187 |
|
|---|
| 188 | /* Allocate the structure if it has not already been allocated by a
|
|---|
| 189 | derived class. */
|
|---|
| 190 | if (ret == (@var{entry_type} *) NULL)
|
|---|
| 191 | @{
|
|---|
| 192 | ret = ((@var{entry_type} *)
|
|---|
| 193 | bfd_hash_allocate (table, sizeof (@var{entry_type})));
|
|---|
| 194 | if (ret == (@var{entry_type} *) NULL)
|
|---|
| 195 | return NULL;
|
|---|
| 196 | @}
|
|---|
| 197 |
|
|---|
| 198 | /* Call the allocation method of the base class. */
|
|---|
| 199 | ret = ((@var{entry_type} *)
|
|---|
| 200 | @var{base_newfunc} ((struct bfd_hash_entry *) ret, table, string));
|
|---|
| 201 |
|
|---|
| 202 | /* Initialize the local fields here. */
|
|---|
| 203 |
|
|---|
| 204 | return (struct bfd_hash_entry *) ret;
|
|---|
| 205 | @}
|
|---|
| 206 | @end example
|
|---|
| 207 | @strong{Description}@*
|
|---|
| 208 | The creation routine for the linker hash table, which is in
|
|---|
| 209 | @code{linker.c}, looks just like this example.
|
|---|
| 210 | @var{function_name} is @code{_bfd_link_hash_newfunc}.
|
|---|
| 211 | @var{entry_type} is @code{struct bfd_link_hash_entry}.
|
|---|
| 212 | @var{base_newfunc} is @code{bfd_hash_newfunc}, the creation
|
|---|
| 213 | routine for a basic hash table.
|
|---|
| 214 |
|
|---|
| 215 | @code{_bfd_link_hash_newfunc} also initializes the local fields
|
|---|
| 216 | in a linker hash table entry: @code{type}, @code{written} and
|
|---|
| 217 | @code{next}.
|
|---|
| 218 |
|
|---|
| 219 | @node Write Other Derived Routines, , Write the Derived Creation Routine, Deriving a New Hash Table Type
|
|---|
| 220 | @subsubsection Write other derived routines
|
|---|
| 221 | You will want to write other routines for your new hash table,
|
|---|
| 222 | as well.
|
|---|
| 223 |
|
|---|
| 224 | You will want an initialization routine which calls the
|
|---|
| 225 | initialization routine of the hash table you are deriving from
|
|---|
| 226 | and initializes any other local fields. For the linker hash
|
|---|
| 227 | table, this is @code{_bfd_link_hash_table_init} in @code{linker.c}.
|
|---|
| 228 |
|
|---|
| 229 | You will want a lookup routine which calls the lookup routine
|
|---|
| 230 | of the hash table you are deriving from and casts the result.
|
|---|
| 231 | The linker hash table uses @code{bfd_link_hash_lookup} in
|
|---|
| 232 | @code{linker.c} (this actually takes an additional argument which
|
|---|
| 233 | it uses to decide how to return the looked up value).
|
|---|
| 234 |
|
|---|
| 235 | You may want a traversal routine. This should just call the
|
|---|
| 236 | traversal routine of the hash table you are deriving from with
|
|---|
| 237 | appropriate casts. The linker hash table uses
|
|---|
| 238 | @code{bfd_link_hash_traverse} in @code{linker.c}.
|
|---|
| 239 |
|
|---|
| 240 | These routines may simply be defined as macros. For example,
|
|---|
| 241 | the a.out backend linker hash table, which is derived from the
|
|---|
| 242 | linker hash table, uses macros for the lookup and traversal
|
|---|
| 243 | routines. These are @code{aout_link_hash_lookup} and
|
|---|
| 244 | @code{aout_link_hash_traverse} in aoutx.h.
|
|---|
| 245 |
|
|---|