00001 /* 00002 * Copyright 2003, 2004, 2005, 2006 PathScale, Inc. All Rights Reserved. 00003 */ 00004 00005 /* hash.c -- hash table routines for BFD 00006 Copyright 1993, 1994, 1995, 1997, 1999, 2001, 2002, 2003, 2004 00007 Free Software Foundation, Inc. 00008 Written by Steve Chamberlain <sac@cygnus.com> 00009 00010 This file is part of BFD, the Binary File Descriptor library. 00011 00012 This program is free software; you can redistribute it and/or modify 00013 it under the terms of the GNU General Public License as published by 00014 the Free Software Foundation; either version 2 of the License, or 00015 (at your option) any later version. 00016 00017 This program is distributed in the hope that it will be useful, 00018 but WITHOUT ANY WARRANTY; without even the implied warranty of 00019 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00020 GNU General Public License for more details. 00021 00022 You should have received a copy of the GNU General Public License 00023 along with this program; if not, write to the Free Software 00024 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ 00025 00026 #include "bfd.h" 00027 #include "sysdep.h" 00028 #include "libbfd.h" 00029 #include "objalloc.h" 00030 #include "libiberty.h" 00031 00032 /* 00033 SECTION 00034 Hash Tables 00035 00036 @cindex Hash tables 00037 BFD provides a simple set of hash table functions. Routines 00038 are provided to initialize a hash table, to free a hash table, 00039 to look up a string in a hash table and optionally create an 00040 entry for it, and to traverse a hash table. There is 00041 currently no routine to delete an string from a hash table. 00042 00043 The basic hash table does not permit any data to be stored 00044 with a string. However, a hash table is designed to present a 00045 base class from which other types of hash tables may be 00046 derived. These derived types may store additional information 00047 with the string. Hash tables were implemented in this way, 00048 rather than simply providing a data pointer in a hash table 00049 entry, because they were designed for use by the linker back 00050 ends. The linker may create thousands of hash table entries, 00051 and the overhead of allocating private data and storing and 00052 following pointers becomes noticeable. 00053 00054 The basic hash table code is in <<hash.c>>. 00055 00056 @menu 00057 @* Creating and Freeing a Hash Table:: 00058 @* Looking Up or Entering a String:: 00059 @* Traversing a Hash Table:: 00060 @* Deriving a New Hash Table Type:: 00061 @end menu 00062 00063 INODE 00064 Creating and Freeing a Hash Table, Looking Up or Entering a String, Hash Tables, Hash Tables 00065 SUBSECTION 00066 Creating and freeing a hash table 00067 00068 @findex bfd_hash_table_init 00069 @findex bfd_hash_table_init_n 00070 To create a hash table, create an instance of a <<struct 00071 bfd_hash_table>> (defined in <<bfd.h>>) and call 00072 <<bfd_hash_table_init>> (if you know approximately how many 00073 entries you will need, the function <<bfd_hash_table_init_n>>, 00074 which takes a @var{size} argument, may be used). 00075 <<bfd_hash_table_init>> returns <<FALSE>> if some sort of 00076 error occurs. 00077 00078 @findex bfd_hash_newfunc 00079 The function <<bfd_hash_table_init>> take as an argument a 00080 function to use to create new entries. For a basic hash 00081 table, use the function <<bfd_hash_newfunc>>. @xref{Deriving 00082 a New Hash Table Type}, for why you would want to use a 00083 different value for this argument. 00084 00085 @findex bfd_hash_allocate 00086 <<bfd_hash_table_init>> will create an objalloc which will be 00087 used to allocate new entries. You may allocate memory on this 00088 objalloc using <<bfd_hash_allocate>>. 00089 00090 @findex bfd_hash_table_free 00091 Use <<bfd_hash_table_free>> to free up all the memory that has 00092 been allocated for a hash table. This will not free up the 00093 <<struct bfd_hash_table>> itself, which you must provide. 00094 00095 @findex bfd_hash_set_default_size 00096 Use <<bfd_hash_set_default_size>> to set the default size of 00097 hash table to use. 00098 00099 INODE 00100 Looking Up or Entering a String, Traversing a Hash Table, Creating and Freeing a Hash Table, Hash Tables 00101 SUBSECTION 00102 Looking up or entering a string 00103 00104 @findex bfd_hash_lookup 00105 The function <<bfd_hash_lookup>> is used both to look up a 00106 string in the hash table and to create a new entry. 00107 00108 If the @var{create} argument is <<FALSE>>, <<bfd_hash_lookup>> 00109 will look up a string. If the string is found, it will 00110 returns a pointer to a <<struct bfd_hash_entry>>. If the 00111 string is not found in the table <<bfd_hash_lookup>> will 00112 return <<NULL>>. You should not modify any of the fields in 00113 the returns <<struct bfd_hash_entry>>. 00114 00115 If the @var{create} argument is <<TRUE>>, the string will be 00116 entered into the hash table if it is not already there. 00117 Either way a pointer to a <<struct bfd_hash_entry>> will be 00118 returned, either to the existing structure or to a newly 00119 created one. In this case, a <<NULL>> return means that an 00120 error occurred. 00121 00122 If the @var{create} argument is <<TRUE>>, and a new entry is 00123 created, the @var{copy} argument is used to decide whether to 00124 copy the string onto the hash table objalloc or not. If 00125 @var{copy} is passed as <<FALSE>>, you must be careful not to 00126 deallocate or modify the string as long as the hash table 00127 exists. 00128 00129 INODE 00130 Traversing a Hash Table, Deriving a New Hash Table Type, Looking Up or Entering a String, Hash Tables 00131 SUBSECTION 00132 Traversing a hash table 00133 00134 @findex bfd_hash_traverse 00135 The function <<bfd_hash_traverse>> may be used to traverse a 00136 hash table, calling a function on each element. The traversal 00137 is done in a random order. 00138 00139 <<bfd_hash_traverse>> takes as arguments a function and a 00140 generic <<void *>> pointer. The function is called with a 00141 hash table entry (a <<struct bfd_hash_entry *>>) and the 00142 generic pointer passed to <<bfd_hash_traverse>>. The function 00143 must return a <<boolean>> value, which indicates whether to 00144 continue traversing the hash table. If the function returns 00145 <<FALSE>>, <<bfd_hash_traverse>> will stop the traversal and 00146 return immediately. 00147 00148 INODE 00149 Deriving a New Hash Table Type, , Traversing a Hash Table, Hash Tables 00150 SUBSECTION 00151 Deriving a new hash table type 00152 00153 Many uses of hash tables want to store additional information 00154 which each entry in the hash table. Some also find it 00155 convenient to store additional information with the hash table 00156 itself. This may be done using a derived hash table. 00157 00158 Since C is not an object oriented language, creating a derived 00159 hash table requires sticking together some boilerplate 00160 routines with a few differences specific to the type of hash 00161 table you want to create. 00162 00163 An example of a derived hash table is the linker hash table. 00164 The structures for this are defined in <<bfdlink.h>>. The 00165 functions are in <<linker.c>>. 00166 00167 You may also derive a hash table from an already derived hash 00168 table. For example, the a.out linker backend code uses a hash 00169 table derived from the linker hash table. 00170 00171 @menu 00172 @* Define the Derived Structures:: 00173 @* Write the Derived Creation Routine:: 00174 @* Write Other Derived Routines:: 00175 @end menu 00176 00177 INODE 00178 Define the Derived Structures, Write the Derived Creation Routine, Deriving a New Hash Table Type, Deriving a New Hash Table Type 00179 SUBSUBSECTION 00180 Define the derived structures 00181 00182 You must define a structure for an entry in the hash table, 00183 and a structure for the hash table itself. 00184 00185 The first field in the structure for an entry in the hash 00186 table must be of the type used for an entry in the hash table 00187 you are deriving from. If you are deriving from a basic hash 00188 table this is <<struct bfd_hash_entry>>, which is defined in 00189 <<bfd.h>>. The first field in the structure for the hash 00190 table itself must be of the type of the hash table you are 00191 deriving from itself. If you are deriving from a basic hash 00192 table, this is <<struct bfd_hash_table>>. 00193 00194 For example, the linker hash table defines <<struct 00195 bfd_link_hash_entry>> (in <<bfdlink.h>>). The first field, 00196 <<root>>, is of type <<struct bfd_hash_entry>>. Similarly, 00197 the first field in <<struct bfd_link_hash_table>>, <<table>>, 00198 is of type <<struct bfd_hash_table>>. 00199 00200 INODE 00201 Write the Derived Creation Routine, Write Other Derived Routines, Define the Derived Structures, Deriving a New Hash Table Type 00202 SUBSUBSECTION 00203 Write the derived creation routine 00204 00205 You must write a routine which will create and initialize an 00206 entry in the hash table. This routine is passed as the 00207 function argument to <<bfd_hash_table_init>>. 00208 00209 In order to permit other hash tables to be derived from the 00210 hash table you are creating, this routine must be written in a 00211 standard way. 00212 00213 The first argument to the creation routine is a pointer to a 00214 hash table entry. This may be <<NULL>>, in which case the 00215 routine should allocate the right amount of space. Otherwise 00216 the space has already been allocated by a hash table type 00217 derived from this one. 00218 00219 After allocating space, the creation routine must call the 00220 creation routine of the hash table type it is derived from, 00221 passing in a pointer to the space it just allocated. This 00222 will initialize any fields used by the base hash table. 00223 00224 Finally the creation routine must initialize any local fields 00225 for the new hash table type. 00226 00227 Here is a boilerplate example of a creation routine. 00228 @var{function_name} is the name of the routine. 00229 @var{entry_type} is the type of an entry in the hash table you 00230 are creating. @var{base_newfunc} is the name of the creation 00231 routine of the hash table type your hash table is derived 00232 from. 00233 00234 EXAMPLE 00235 00236 .struct bfd_hash_entry * 00237 .@var{function_name} (entry, table, string) 00238 . struct bfd_hash_entry *entry; 00239 . struct bfd_hash_table *table; 00240 . const char *string; 00241 .{ 00242 . struct @var{entry_type} *ret = (@var{entry_type} *) entry; 00243 . 00244 . {* Allocate the structure if it has not already been allocated by a 00245 . derived class. *} 00246 . if (ret == (@var{entry_type} *) NULL) 00247 . { 00248 . ret = ((@var{entry_type} *) 00249 . bfd_hash_allocate (table, sizeof (@var{entry_type}))); 00250 . if (ret == (@var{entry_type} *) NULL) 00251 . return NULL; 00252 . } 00253 . 00254 . {* Call the allocation method of the base class. *} 00255 . ret = ((@var{entry_type} *) 00256 . @var{base_newfunc} ((struct bfd_hash_entry *) ret, table, string)); 00257 . 00258 . {* Initialize the local fields here. *} 00259 . 00260 . return (struct bfd_hash_entry *) ret; 00261 .} 00262 00263 DESCRIPTION 00264 The creation routine for the linker hash table, which is in 00265 <<linker.c>>, looks just like this example. 00266 @var{function_name} is <<_bfd_link_hash_newfunc>>. 00267 @var{entry_type} is <<struct bfd_link_hash_entry>>. 00268 @var{base_newfunc} is <<bfd_hash_newfunc>>, the creation 00269 routine for a basic hash table. 00270 00271 <<_bfd_link_hash_newfunc>> also initializes the local fields 00272 in a linker hash table entry: <<type>>, <<written>> and 00273 <<next>>. 00274 00275 INODE 00276 Write Other Derived Routines, , Write the Derived Creation Routine, Deriving a New Hash Table Type 00277 SUBSUBSECTION 00278 Write other derived routines 00279 00280 You will want to write other routines for your new hash table, 00281 as well. 00282 00283 You will want an initialization routine which calls the 00284 initialization routine of the hash table you are deriving from 00285 and initializes any other local fields. For the linker hash 00286 table, this is <<_bfd_link_hash_table_init>> in <<linker.c>>. 00287 00288 You will want a lookup routine which calls the lookup routine 00289 of the hash table you are deriving from and casts the result. 00290 The linker hash table uses <<bfd_link_hash_lookup>> in 00291 <<linker.c>> (this actually takes an additional argument which 00292 it uses to decide how to return the looked up value). 00293 00294 You may want a traversal routine. This should just call the 00295 traversal routine of the hash table you are deriving from with 00296 appropriate casts. The linker hash table uses 00297 <<bfd_link_hash_traverse>> in <<linker.c>>. 00298 00299 These routines may simply be defined as macros. For example, 00300 the a.out backend linker hash table, which is derived from the 00301 linker hash table, uses macros for the lookup and traversal 00302 routines. These are <<aout_link_hash_lookup>> and 00303 <<aout_link_hash_traverse>> in aoutx.h. 00304 */ 00305 00306 /* The default number of entries to use when creating a hash table. */ 00307 #define DEFAULT_SIZE 4051 00308 static size_t bfd_default_hash_table_size = DEFAULT_SIZE; 00309 00310 /* Create a new hash table, given a number of entries. */ 00311 00312 bfd_boolean 00313 bfd_hash_table_init_n (table, newfunc, size) 00314 struct bfd_hash_table *table; 00315 struct bfd_hash_entry *(*newfunc) PARAMS ((struct bfd_hash_entry *, 00316 struct bfd_hash_table *, 00317 const char *)); 00318 unsigned int size; 00319 { 00320 unsigned int alloc; 00321 00322 alloc = size * sizeof (struct bfd_hash_entry *); 00323 00324 table->memory = (PTR) objalloc_create (); 00325 if (table->memory == NULL) 00326 { 00327 bfd_set_error (bfd_error_no_memory); 00328 return FALSE; 00329 } 00330 table->table = ((struct bfd_hash_entry **) 00331 objalloc_alloc ((struct objalloc *) table->memory, alloc)); 00332 if (table->table == NULL) 00333 { 00334 bfd_set_error (bfd_error_no_memory); 00335 return FALSE; 00336 } 00337 memset ((PTR) table->table, 0, alloc); 00338 table->size = size; 00339 table->newfunc = newfunc; 00340 return TRUE; 00341 } 00342 00343 /* Create a new hash table with the default number of entries. */ 00344 00345 bfd_boolean 00346 bfd_hash_table_init (table, newfunc) 00347 struct bfd_hash_table *table; 00348 struct bfd_hash_entry *(*newfunc) PARAMS ((struct bfd_hash_entry *, 00349 struct bfd_hash_table *, 00350 const char *)); 00351 { 00352 return bfd_hash_table_init_n (table, newfunc, bfd_default_hash_table_size); 00353 } 00354 00355 /* Free a hash table. */ 00356 00357 void 00358 bfd_hash_table_free (table) 00359 struct bfd_hash_table *table; 00360 { 00361 objalloc_free ((struct objalloc *) table->memory); 00362 table->memory = NULL; 00363 } 00364 00365 /* Look up a string in a hash table. */ 00366 00367 struct bfd_hash_entry * 00368 bfd_hash_lookup (table, string, create, copy) 00369 struct bfd_hash_table *table; 00370 const char *string; 00371 bfd_boolean create; 00372 bfd_boolean copy; 00373 { 00374 register const unsigned char *s; 00375 register unsigned long hash; 00376 register unsigned int c; 00377 struct bfd_hash_entry *hashp; 00378 unsigned int len; 00379 unsigned int index; 00380 00381 hash = 0; 00382 len = 0; 00383 s = (const unsigned char *) string; 00384 while ((c = *s++) != '\0') 00385 { 00386 hash += c + (c << 17); 00387 hash ^= hash >> 2; 00388 } 00389 len = (s - (const unsigned char *) string) - 1; 00390 hash += len + (len << 17); 00391 hash ^= hash >> 2; 00392 00393 index = hash % table->size; 00394 for (hashp = table->table[index]; 00395 hashp != (struct bfd_hash_entry *) NULL; 00396 hashp = hashp->next) 00397 { 00398 if (hashp->hash == hash 00399 && strcmp (hashp->string, string) == 0) 00400 return hashp; 00401 } 00402 00403 if (! create) 00404 return (struct bfd_hash_entry *) NULL; 00405 00406 hashp = (*table->newfunc) ((struct bfd_hash_entry *) NULL, table, string); 00407 if (hashp == (struct bfd_hash_entry *) NULL) 00408 return (struct bfd_hash_entry *) NULL; 00409 if (copy) 00410 { 00411 char *new; 00412 00413 new = (char *) objalloc_alloc ((struct objalloc *) table->memory, 00414 len + 1); 00415 if (!new) 00416 { 00417 bfd_set_error (bfd_error_no_memory); 00418 return (struct bfd_hash_entry *) NULL; 00419 } 00420 memcpy (new, string, len + 1); 00421 string = new; 00422 } 00423 hashp->string = string; 00424 hashp->hash = hash; 00425 hashp->next = table->table[index]; 00426 table->table[index] = hashp; 00427 00428 return hashp; 00429 } 00430 00431 /* Replace an entry in a hash table. */ 00432 00433 void 00434 bfd_hash_replace (table, old, nw) 00435 struct bfd_hash_table *table; 00436 struct bfd_hash_entry *old; 00437 struct bfd_hash_entry *nw; 00438 { 00439 unsigned int index; 00440 struct bfd_hash_entry **pph; 00441 00442 index = old->hash % table->size; 00443 for (pph = &table->table[index]; 00444 (*pph) != (struct bfd_hash_entry *) NULL; 00445 pph = &(*pph)->next) 00446 { 00447 if (*pph == old) 00448 { 00449 *pph = nw; 00450 return; 00451 } 00452 } 00453 00454 abort (); 00455 } 00456 00457 /* Base method for creating a new hash table entry. */ 00458 00459 struct bfd_hash_entry * 00460 bfd_hash_newfunc (entry, table, string) 00461 struct bfd_hash_entry *entry; 00462 struct bfd_hash_table *table; 00463 const char *string ATTRIBUTE_UNUSED; 00464 { 00465 if (entry == (struct bfd_hash_entry *) NULL) 00466 entry = ((struct bfd_hash_entry *) 00467 bfd_hash_allocate (table, sizeof (struct bfd_hash_entry))); 00468 return entry; 00469 } 00470 00471 /* Allocate space in a hash table. */ 00472 00473 PTR 00474 bfd_hash_allocate (table, size) 00475 struct bfd_hash_table *table; 00476 unsigned int size; 00477 { 00478 PTR ret; 00479 00480 ret = objalloc_alloc ((struct objalloc *) table->memory, size); 00481 if (ret == NULL && size != 0) 00482 bfd_set_error (bfd_error_no_memory); 00483 #ifdef KEY 00484 memset (ret, 0, size); // For section_is_invalid. 00485 #endif 00486 return ret; 00487 } 00488 00489 /* Traverse a hash table. */ 00490 00491 void 00492 bfd_hash_traverse (table, func, info) 00493 struct bfd_hash_table *table; 00494 bfd_boolean (*func) PARAMS ((struct bfd_hash_entry *, PTR)); 00495 PTR info; 00496 { 00497 unsigned int i; 00498 00499 for (i = 0; i < table->size; i++) 00500 { 00501 struct bfd_hash_entry *p; 00502 00503 for (p = table->table[i]; p != NULL; p = p->next) 00504 { 00505 if (! (*func) (p, info)) 00506 return; 00507 } 00508 } 00509 } 00510 00511 void 00512 bfd_hash_set_default_size (bfd_size_type hash_size) 00513 { 00514 /* Extend this prime list if you want more granularity of hash table size. */ 00515 static const bfd_size_type hash_size_primes[] = 00516 { 00517 1021, 4051, 8599, 16699 00518 }; 00519 size_t index; 00520 00521 /* Work out best prime number near the hash_size. */ 00522 for (index = 0; index < ARRAY_SIZE (hash_size_primes) - 1; ++index) 00523 if (hash_size <= hash_size_primes[index]) 00524 break; 00525 00526 bfd_default_hash_table_size = hash_size_primes[index]; 00527 } 00528 00529 /* A few different object file formats (a.out, COFF, ELF) use a string 00530 table. These functions support adding strings to a string table, 00531 returning the byte offset, and writing out the table. 00532 00533 Possible improvements: 00534 + look for strings matching trailing substrings of other strings 00535 + better data structures? balanced trees? 00536 + look at reducing memory use elsewhere -- maybe if we didn't have 00537 to construct the entire symbol table at once, we could get by 00538 with smaller amounts of VM? (What effect does that have on the 00539 string table reductions?) */ 00540 00541 /* An entry in the strtab hash table. */ 00542 00543 struct strtab_hash_entry 00544 { 00545 struct bfd_hash_entry root; 00546 /* Index in string table. */ 00547 bfd_size_type index; 00548 /* Next string in strtab. */ 00549 struct strtab_hash_entry *next; 00550 }; 00551 00552 /* The strtab hash table. */ 00553 00554 struct bfd_strtab_hash 00555 { 00556 struct bfd_hash_table table; 00557 /* Size of strtab--also next available index. */ 00558 bfd_size_type size; 00559 /* First string in strtab. */ 00560 struct strtab_hash_entry *first; 00561 /* Last string in strtab. */ 00562 struct strtab_hash_entry *last; 00563 /* Whether to precede strings with a two byte length, as in the 00564 XCOFF .debug section. */ 00565 bfd_boolean xcoff; 00566 }; 00567 00568 static struct bfd_hash_entry *strtab_hash_newfunc 00569 PARAMS ((struct bfd_hash_entry *, struct bfd_hash_table *, const char *)); 00570 00571 /* Routine to create an entry in a strtab. */ 00572 00573 static struct bfd_hash_entry * 00574 strtab_hash_newfunc (entry, table, string) 00575 struct bfd_hash_entry *entry; 00576 struct bfd_hash_table *table; 00577 const char *string; 00578 { 00579 struct strtab_hash_entry *ret = (struct strtab_hash_entry *) entry; 00580 00581 /* Allocate the structure if it has not already been allocated by a 00582 subclass. */ 00583 if (ret == (struct strtab_hash_entry *) NULL) 00584 ret = ((struct strtab_hash_entry *) 00585 bfd_hash_allocate (table, sizeof (struct strtab_hash_entry))); 00586 if (ret == (struct strtab_hash_entry *) NULL) 00587 return NULL; 00588 00589 /* Call the allocation method of the superclass. */ 00590 ret = ((struct strtab_hash_entry *) 00591 bfd_hash_newfunc ((struct bfd_hash_entry *) ret, table, string)); 00592 00593 if (ret) 00594 { 00595 /* Initialize the local fields. */ 00596 ret->index = (bfd_size_type) -1; 00597 ret->next = NULL; 00598 } 00599 00600 return (struct bfd_hash_entry *) ret; 00601 } 00602 00603 /* Look up an entry in an strtab. */ 00604 00605 #define strtab_hash_lookup(t, string, create, copy) \ 00606 ((struct strtab_hash_entry *) \ 00607 bfd_hash_lookup (&(t)->table, (string), (create), (copy))) 00608 00609 /* Create a new strtab. */ 00610 00611 struct bfd_strtab_hash * 00612 _bfd_stringtab_init () 00613 { 00614 struct bfd_strtab_hash *table; 00615 bfd_size_type amt = sizeof (struct bfd_strtab_hash); 00616 00617 table = (struct bfd_strtab_hash *) bfd_malloc (amt); 00618 if (table == NULL) 00619 return NULL; 00620 00621 if (! bfd_hash_table_init (&table->table, strtab_hash_newfunc)) 00622 { 00623 free (table); 00624 return NULL; 00625 } 00626 00627 table->size = 0; 00628 table->first = NULL; 00629 table->last = NULL; 00630 table->xcoff = FALSE; 00631 00632 return table; 00633 } 00634 00635 /* Create a new strtab in which the strings are output in the format 00636 used in the XCOFF .debug section: a two byte length precedes each 00637 string. */ 00638 00639 struct bfd_strtab_hash * 00640 _bfd_xcoff_stringtab_init () 00641 { 00642 struct bfd_strtab_hash *ret; 00643 00644 ret = _bfd_stringtab_init (); 00645 if (ret != NULL) 00646 ret->xcoff = TRUE; 00647 return ret; 00648 } 00649 00650 /* Free a strtab. */ 00651 00652 void 00653 _bfd_stringtab_free (table) 00654 struct bfd_strtab_hash *table; 00655 { 00656 bfd_hash_table_free (&table->table); 00657 free (table); 00658 } 00659 00660 /* Get the index of a string in a strtab, adding it if it is not 00661 already present. If HASH is FALSE, we don't really use the hash 00662 table, and we don't eliminate duplicate strings. */ 00663 00664 bfd_size_type 00665 _bfd_stringtab_add (tab, str, hash, copy) 00666 struct bfd_strtab_hash *tab; 00667 const char *str; 00668 bfd_boolean hash; 00669 bfd_boolean copy; 00670 { 00671 register struct strtab_hash_entry *entry; 00672 00673 if (hash) 00674 { 00675 entry = strtab_hash_lookup (tab, str, TRUE, copy); 00676 if (entry == NULL) 00677 return (bfd_size_type) -1; 00678 } 00679 else 00680 { 00681 entry = ((struct strtab_hash_entry *) 00682 bfd_hash_allocate (&tab->table, 00683 sizeof (struct strtab_hash_entry))); 00684 if (entry == NULL) 00685 return (bfd_size_type) -1; 00686 if (! copy) 00687 entry->root.string = str; 00688 else 00689 { 00690 char *n; 00691 00692 n = (char *) bfd_hash_allocate (&tab->table, strlen (str) + 1); 00693 if (n == NULL) 00694 return (bfd_size_type) -1; 00695 entry->root.string = n; 00696 } 00697 entry->index = (bfd_size_type) -1; 00698 entry->next = NULL; 00699 } 00700 00701 if (entry->index == (bfd_size_type) -1) 00702 { 00703 entry->index = tab->size; 00704 tab->size += strlen (str) + 1; 00705 if (tab->xcoff) 00706 { 00707 entry->index += 2; 00708 tab->size += 2; 00709 } 00710 if (tab->first == NULL) 00711 tab->first = entry; 00712 else 00713 tab->last->next = entry; 00714 tab->last = entry; 00715 } 00716 00717 return entry->index; 00718 } 00719 00720 /* Get the number of bytes in a strtab. */ 00721 00722 bfd_size_type 00723 _bfd_stringtab_size (tab) 00724 struct bfd_strtab_hash *tab; 00725 { 00726 return tab->size; 00727 } 00728 00729 /* Write out a strtab. ABFD must already be at the right location in 00730 the file. */ 00731 00732 bfd_boolean 00733 _bfd_stringtab_emit (abfd, tab) 00734 register bfd *abfd; 00735 struct bfd_strtab_hash *tab; 00736 { 00737 register bfd_boolean xcoff; 00738 register struct strtab_hash_entry *entry; 00739 00740 xcoff = tab->xcoff; 00741 00742 for (entry = tab->first; entry != NULL; entry = entry->next) 00743 { 00744 const char *str; 00745 size_t len; 00746 00747 str = entry->root.string; 00748 len = strlen (str) + 1; 00749 00750 if (xcoff) 00751 { 00752 bfd_byte buf[2]; 00753 00754 /* The output length includes the null byte. */ 00755 bfd_put_16 (abfd, (bfd_vma) len, buf); 00756 if (bfd_bwrite ((PTR) buf, (bfd_size_type) 2, abfd) != 2) 00757 return FALSE; 00758 } 00759 00760 if (bfd_bwrite ((PTR) str, (bfd_size_type) len, abfd) != len) 00761 return FALSE; 00762 } 00763 00764 return TRUE; 00765 }
1.5.6