1999-05-03 09:29:11 +02:00
|
|
|
|
/* hash.c -- hash table routines for BFD
|
2017-01-02 04:36:43 +01:00
|
|
|
|
Copyright (C) 1993-2017 Free Software Foundation, Inc.
|
1999-05-03 09:29:11 +02:00
|
|
|
|
Written by Steve Chamberlain <sac@cygnus.com>
|
|
|
|
|
|
2004-05-21 17:38:04 +02:00
|
|
|
|
This file is part of BFD, the Binary File Descriptor library.
|
1999-05-03 09:29:11 +02:00
|
|
|
|
|
2004-05-21 17:38:04 +02:00
|
|
|
|
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
|
2007-07-03 16:26:43 +02:00
|
|
|
|
the Free Software Foundation; either version 3 of the License, or
|
2004-05-21 17:38:04 +02:00
|
|
|
|
(at your option) any later version.
|
1999-05-03 09:29:11 +02:00
|
|
|
|
|
2004-05-21 17:38:04 +02:00
|
|
|
|
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.
|
1999-05-03 09:29:11 +02:00
|
|
|
|
|
2004-05-21 17:38:04 +02:00
|
|
|
|
You should have received a copy of the GNU General Public License
|
|
|
|
|
along with this program; if not, write to the Free Software
|
2007-07-03 16:26:43 +02:00
|
|
|
|
Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
|
|
|
|
|
MA 02110-1301, USA. */
|
1999-05-03 09:29:11 +02:00
|
|
|
|
|
|
|
|
|
#include "sysdep.h"
|
2007-04-26 16:47:00 +02:00
|
|
|
|
#include "bfd.h"
|
1999-05-03 09:29:11 +02:00
|
|
|
|
#include "libbfd.h"
|
|
|
|
|
#include "objalloc.h"
|
2004-05-21 17:38:04 +02:00
|
|
|
|
#include "libiberty.h"
|
1999-05-03 09:29:11 +02:00
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
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).
|
2002-11-30 09:39:46 +01:00
|
|
|
|
<<bfd_hash_table_init>> returns <<FALSE>> if some sort of
|
1999-05-03 09:29:11 +02:00
|
|
|
|
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
|
1999-06-04 15:25:23 +02:00
|
|
|
|
a New Hash Table Type}, for why you would want to use a
|
1999-05-03 09:29:11 +02:00
|
|
|
|
different value for this argument.
|
|
|
|
|
|
|
|
|
|
@findex bfd_hash_allocate
|
|
|
|
|
<<bfd_hash_table_init>> will create an objalloc which will be
|
|
|
|
|
used to allocate new entries. You may allocate memory on this
|
|
|
|
|
objalloc 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.
|
|
|
|
|
|
2004-05-21 17:38:04 +02:00
|
|
|
|
@findex bfd_hash_set_default_size
|
|
|
|
|
Use <<bfd_hash_set_default_size>> to set the default size of
|
|
|
|
|
hash table to use.
|
|
|
|
|
|
1999-05-03 09:29:11 +02:00
|
|
|
|
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.
|
|
|
|
|
|
2002-11-30 09:39:46 +01:00
|
|
|
|
If the @var{create} argument is <<FALSE>>, <<bfd_hash_lookup>>
|
1999-05-03 09:29:11 +02:00
|
|
|
|
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>>.
|
|
|
|
|
|
2002-11-30 09:39:46 +01:00
|
|
|
|
If the @var{create} argument is <<TRUE>>, the string will be
|
1999-05-03 09:29:11 +02:00
|
|
|
|
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.
|
|
|
|
|
|
2002-11-30 09:39:46 +01:00
|
|
|
|
If the @var{create} argument is <<TRUE>>, and a new entry is
|
1999-05-03 09:29:11 +02:00
|
|
|
|
created, the @var{copy} argument is used to decide whether to
|
|
|
|
|
copy the string onto the hash table objalloc or not. If
|
2002-11-30 09:39:46 +01:00
|
|
|
|
@var{copy} is passed as <<FALSE>>, you must be careful not to
|
1999-05-03 09:29:11 +02:00
|
|
|
|
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
|
2002-11-30 09:39:46 +01:00
|
|
|
|
<<FALSE>>, <<bfd_hash_traverse>> will stop the traversal and
|
1999-05-03 09:29:11 +02:00
|
|
|
|
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 *
|
2005-03-22 17:14:43 +01:00
|
|
|
|
.@var{function_name} (struct bfd_hash_entry *entry,
|
|
|
|
|
. struct bfd_hash_table *table,
|
|
|
|
|
. const char *string)
|
1999-05-03 09:29:11 +02:00
|
|
|
|
.{
|
|
|
|
|
. struct @var{entry_type} *ret = (@var{entry_type} *) entry;
|
|
|
|
|
.
|
|
|
|
|
. {* Allocate the structure if it has not already been allocated by a
|
|
|
|
|
. derived class. *}
|
2005-03-22 17:14:43 +01:00
|
|
|
|
. if (ret == NULL)
|
1999-05-03 09:29:11 +02:00
|
|
|
|
. {
|
2005-03-22 17:14:43 +01:00
|
|
|
|
. ret = bfd_hash_allocate (table, sizeof (* ret));
|
|
|
|
|
. if (ret == NULL)
|
1999-05-03 09:29:11 +02:00
|
|
|
|
. return NULL;
|
|
|
|
|
. }
|
|
|
|
|
.
|
|
|
|
|
. {* 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,
|
2001-01-23 21:27:54 +01:00
|
|
|
|
as well.
|
1999-05-03 09:29:11 +02:00
|
|
|
|
|
|
|
|
|
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.
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
/* The default number of entries to use when creating a hash table. */
|
2006-05-03 06:20:52 +02:00
|
|
|
|
#define DEFAULT_SIZE 4051
|
2006-05-01 21:36:27 +02:00
|
|
|
|
|
|
|
|
|
/* The following function returns a nearest prime number which is
|
2006-05-03 06:20:52 +02:00
|
|
|
|
greater than N, and near a power of two. Copied from libiberty.
|
|
|
|
|
Returns zero for ridiculously large N to signify an error. */
|
2006-05-01 21:36:27 +02:00
|
|
|
|
|
|
|
|
|
static unsigned long
|
|
|
|
|
higher_prime_number (unsigned long n)
|
|
|
|
|
{
|
|
|
|
|
/* These are primes that are near, but slightly smaller than, a
|
|
|
|
|
power of two. */
|
2011-06-03 18:16:32 +02:00
|
|
|
|
static const unsigned long primes[] =
|
|
|
|
|
{
|
|
|
|
|
(unsigned long) 31,
|
|
|
|
|
(unsigned long) 61,
|
|
|
|
|
(unsigned long) 127,
|
|
|
|
|
(unsigned long) 251,
|
|
|
|
|
(unsigned long) 509,
|
|
|
|
|
(unsigned long) 1021,
|
|
|
|
|
(unsigned long) 2039,
|
|
|
|
|
(unsigned long) 4093,
|
|
|
|
|
(unsigned long) 8191,
|
|
|
|
|
(unsigned long) 16381,
|
|
|
|
|
(unsigned long) 32749,
|
|
|
|
|
(unsigned long) 65521,
|
|
|
|
|
(unsigned long) 131071,
|
|
|
|
|
(unsigned long) 262139,
|
|
|
|
|
(unsigned long) 524287,
|
|
|
|
|
(unsigned long) 1048573,
|
|
|
|
|
(unsigned long) 2097143,
|
|
|
|
|
(unsigned long) 4194301,
|
|
|
|
|
(unsigned long) 8388593,
|
|
|
|
|
(unsigned long) 16777213,
|
|
|
|
|
(unsigned long) 33554393,
|
|
|
|
|
(unsigned long) 67108859,
|
|
|
|
|
(unsigned long) 134217689,
|
|
|
|
|
(unsigned long) 268435399,
|
|
|
|
|
(unsigned long) 536870909,
|
|
|
|
|
(unsigned long) 1073741789,
|
|
|
|
|
(unsigned long) 2147483647,
|
2006-05-01 21:36:27 +02:00
|
|
|
|
/* 4294967291L */
|
2011-06-03 18:16:32 +02:00
|
|
|
|
((unsigned long) 2147483647) + ((unsigned long) 2147483644),
|
2006-05-01 21:36:27 +02:00
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
const unsigned long *low = &primes[0];
|
2006-05-03 06:20:52 +02:00
|
|
|
|
const unsigned long *high = &primes[sizeof (primes) / sizeof (primes[0])];
|
2006-05-01 21:36:27 +02:00
|
|
|
|
|
|
|
|
|
while (low != high)
|
|
|
|
|
{
|
|
|
|
|
const unsigned long *mid = low + (high - low) / 2;
|
|
|
|
|
if (n >= *mid)
|
|
|
|
|
low = mid + 1;
|
|
|
|
|
else
|
|
|
|
|
high = mid;
|
|
|
|
|
}
|
|
|
|
|
|
2006-05-03 06:20:52 +02:00
|
|
|
|
if (n >= *low)
|
|
|
|
|
return 0;
|
2006-05-01 21:36:27 +02:00
|
|
|
|
|
|
|
|
|
return *low;
|
|
|
|
|
}
|
|
|
|
|
|
2011-04-20 14:52:16 +02:00
|
|
|
|
static unsigned long bfd_default_hash_table_size = DEFAULT_SIZE;
|
1999-05-03 09:29:11 +02:00
|
|
|
|
|
|
|
|
|
/* Create a new hash table, given a number of entries. */
|
|
|
|
|
|
2002-11-30 09:39:46 +01:00
|
|
|
|
bfd_boolean
|
2005-03-22 17:14:43 +01:00
|
|
|
|
bfd_hash_table_init_n (struct bfd_hash_table *table,
|
|
|
|
|
struct bfd_hash_entry *(*newfunc) (struct bfd_hash_entry *,
|
|
|
|
|
struct bfd_hash_table *,
|
|
|
|
|
const char *),
|
2006-03-16 13:20:16 +01:00
|
|
|
|
unsigned int entsize,
|
2005-03-22 17:14:43 +01:00
|
|
|
|
unsigned int size)
|
1999-05-03 09:29:11 +02:00
|
|
|
|
{
|
2011-04-20 14:52:16 +02:00
|
|
|
|
unsigned long alloc;
|
1999-05-03 09:29:11 +02:00
|
|
|
|
|
2011-04-20 14:52:16 +02:00
|
|
|
|
alloc = size;
|
|
|
|
|
alloc *= sizeof (struct bfd_hash_entry *);
|
|
|
|
|
if (alloc / sizeof (struct bfd_hash_entry *) != size)
|
|
|
|
|
{
|
|
|
|
|
bfd_set_error (bfd_error_no_memory);
|
|
|
|
|
return FALSE;
|
|
|
|
|
}
|
1999-05-03 09:29:11 +02:00
|
|
|
|
|
2005-03-22 17:14:43 +01:00
|
|
|
|
table->memory = (void *) objalloc_create ();
|
1999-05-03 09:29:11 +02:00
|
|
|
|
if (table->memory == NULL)
|
|
|
|
|
{
|
|
|
|
|
bfd_set_error (bfd_error_no_memory);
|
2002-11-30 09:39:46 +01:00
|
|
|
|
return FALSE;
|
1999-05-03 09:29:11 +02:00
|
|
|
|
}
|
2009-09-09 23:38:59 +02:00
|
|
|
|
table->table = (struct bfd_hash_entry **)
|
|
|
|
|
objalloc_alloc ((struct objalloc *) table->memory, alloc);
|
1999-05-03 09:29:11 +02:00
|
|
|
|
if (table->table == NULL)
|
|
|
|
|
{
|
Free linker hash table from bfd_close.
Also tidies numerous error exit paths in various link_hash_table_create
functions that failed to free memory.
include/
* bfdlink.h (struct bfd_link_hash_table): Add hash_table_free field.
bfd/
* archive.c: Include bfdlink.h.
(_bfd_archive_close_and_cleanup): Call linker hash_table_free.
* bfd.c (struct bfd): Add is_linker_output field.
* elf-bfd.h (_bfd_elf_link_hash_table_free): Update prototype.
* linker.c (_bfd_link_hash_table_init): Set up hash_table_free,
link.hash and is_linker_output.
(_bfd_generic_link_hash_table_free): Replace bfd_link_hash_table*
param with bfd*. Assert is_linker_output and link.hash, and
clear them before exit.
* elf-m10300.c (elf32_mn10300_link_hash_table_free): Replace
bfd_link_hash_table* param with bfd*. Hack is_linker_output
and link.hash so we can free two linker hash tables.
(elf32_mn10300_link_hash_table_create): Create static_hash_table
first. Clean up on errors. Set hash_table_free pointer.
* elf32-arm.c (elf32_arm_link_hash_table_free): Replace
bfd_link_hash_table* param with bfd*.
(elf32_arm_link_hash_table_create): Clean up on errors. Set
hash_table_free pointer.
* elf32-avr.c, * elf32-hppa.c, * elf32-i386.c, * elf32-m68hc1x.c,
* elf32-m68k.c, * elf32-metag.c, * elf32-nios2.c, * elf32-xgate.c,
* elf64-ia64-vms.c, * elf64-ppc.c, * elf64-x86-64.c, * elflink.c,
* elfnn-aarch64.c, * elfnn-ia64.c, * elfxx-sparc.c,
* xcofflink.c: Similarly.
* simple.c (bfd_simple_get_relocated_section_contents): Save and
clear link.next before creating linker hash table. Clean up on
errors, and restore link.next on exit.
* elf32-m68hc1x.h (m68hc11_elf_bfd_link_hash_table_free): Delete.
* elf32-xgate.h (xgate_elf_bfd_link_hash_table_free): Delete.
* elfxx-sparc.h (_bfd_sparc_elf_link_hash_table_free): Delete.
* libcoff-in.h (_bfd_xcoff_bfd_link_hash_table_free): Delete.
* hash.c (bfd_hash_table_init_n): Free table on error.
* libbfd-in.h (_bfd_generic_link_hash_table_free): Update proto.
* bfd-in2.h: Regenerate.
* libbfd.h: Regenerate.
* libcoff.h: Regenerate.
2014-06-13 11:41:39 +02:00
|
|
|
|
bfd_hash_table_free (table);
|
1999-05-03 09:29:11 +02:00
|
|
|
|
bfd_set_error (bfd_error_no_memory);
|
2002-11-30 09:39:46 +01:00
|
|
|
|
return FALSE;
|
1999-05-03 09:29:11 +02:00
|
|
|
|
}
|
2005-03-22 17:14:43 +01:00
|
|
|
|
memset ((void *) table->table, 0, alloc);
|
1999-05-03 09:29:11 +02:00
|
|
|
|
table->size = size;
|
2006-03-16 13:20:16 +01:00
|
|
|
|
table->entsize = entsize;
|
2006-05-01 21:36:27 +02:00
|
|
|
|
table->count = 0;
|
2006-11-20 02:38:38 +01:00
|
|
|
|
table->frozen = 0;
|
1999-05-03 09:29:11 +02:00
|
|
|
|
table->newfunc = newfunc;
|
2002-11-30 09:39:46 +01:00
|
|
|
|
return TRUE;
|
1999-05-03 09:29:11 +02:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Create a new hash table with the default number of entries. */
|
|
|
|
|
|
2002-11-30 09:39:46 +01:00
|
|
|
|
bfd_boolean
|
2005-03-22 17:14:43 +01:00
|
|
|
|
bfd_hash_table_init (struct bfd_hash_table *table,
|
|
|
|
|
struct bfd_hash_entry *(*newfunc) (struct bfd_hash_entry *,
|
|
|
|
|
struct bfd_hash_table *,
|
2006-03-16 13:20:16 +01:00
|
|
|
|
const char *),
|
|
|
|
|
unsigned int entsize)
|
1999-05-03 09:29:11 +02:00
|
|
|
|
{
|
2006-03-16 13:20:16 +01:00
|
|
|
|
return bfd_hash_table_init_n (table, newfunc, entsize,
|
|
|
|
|
bfd_default_hash_table_size);
|
1999-05-03 09:29:11 +02:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Free a hash table. */
|
|
|
|
|
|
|
|
|
|
void
|
2005-03-22 17:14:43 +01:00
|
|
|
|
bfd_hash_table_free (struct bfd_hash_table *table)
|
1999-05-03 09:29:11 +02:00
|
|
|
|
{
|
2009-09-09 23:38:59 +02:00
|
|
|
|
objalloc_free ((struct objalloc *) table->memory);
|
1999-05-03 09:29:11 +02:00
|
|
|
|
table->memory = NULL;
|
|
|
|
|
}
|
|
|
|
|
|
2010-11-08 03:48:57 +01:00
|
|
|
|
static inline unsigned long
|
|
|
|
|
bfd_hash_hash (const char *string, unsigned int *lenp)
|
1999-05-03 09:29:11 +02:00
|
|
|
|
{
|
2005-03-22 17:14:43 +01:00
|
|
|
|
const unsigned char *s;
|
|
|
|
|
unsigned long hash;
|
1999-05-03 09:29:11 +02:00
|
|
|
|
unsigned int len;
|
2010-11-08 03:48:57 +01:00
|
|
|
|
unsigned int c;
|
2001-01-23 21:27:54 +01:00
|
|
|
|
|
1999-05-03 09:29:11 +02:00
|
|
|
|
hash = 0;
|
|
|
|
|
len = 0;
|
|
|
|
|
s = (const unsigned char *) string;
|
|
|
|
|
while ((c = *s++) != '\0')
|
|
|
|
|
{
|
|
|
|
|
hash += c + (c << 17);
|
|
|
|
|
hash ^= hash >> 2;
|
|
|
|
|
}
|
2002-05-17 11:52:04 +02:00
|
|
|
|
len = (s - (const unsigned char *) string) - 1;
|
1999-05-03 09:29:11 +02:00
|
|
|
|
hash += len + (len << 17);
|
|
|
|
|
hash ^= hash >> 2;
|
2010-11-08 03:48:57 +01:00
|
|
|
|
if (lenp != NULL)
|
|
|
|
|
*lenp = len;
|
|
|
|
|
return hash;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Look up a string in a hash table. */
|
|
|
|
|
|
|
|
|
|
struct bfd_hash_entry *
|
|
|
|
|
bfd_hash_lookup (struct bfd_hash_table *table,
|
|
|
|
|
const char *string,
|
|
|
|
|
bfd_boolean create,
|
|
|
|
|
bfd_boolean copy)
|
|
|
|
|
{
|
|
|
|
|
unsigned long hash;
|
|
|
|
|
struct bfd_hash_entry *hashp;
|
|
|
|
|
unsigned int len;
|
|
|
|
|
unsigned int _index;
|
1999-05-03 09:29:11 +02:00
|
|
|
|
|
2010-11-08 03:48:57 +01:00
|
|
|
|
hash = bfd_hash_hash (string, &len);
|
2009-12-11 14:42:17 +01:00
|
|
|
|
_index = hash % table->size;
|
|
|
|
|
for (hashp = table->table[_index];
|
2005-03-22 17:14:43 +01:00
|
|
|
|
hashp != NULL;
|
1999-05-03 09:29:11 +02:00
|
|
|
|
hashp = hashp->next)
|
|
|
|
|
{
|
|
|
|
|
if (hashp->hash == hash
|
|
|
|
|
&& strcmp (hashp->string, string) == 0)
|
|
|
|
|
return hashp;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (! create)
|
2005-03-22 17:14:43 +01:00
|
|
|
|
return NULL;
|
1999-05-03 09:29:11 +02:00
|
|
|
|
|
|
|
|
|
if (copy)
|
|
|
|
|
{
|
Updated sources to avoid using the identifier name "new", which is a
keyword in c++.
* bfd/aoutx.h (NAME (aout, make_empty_symbol)): Rename variable
new to new_symbol.
* bfd/coffgen.c (coff_make_empty_symbol)
(coff_bfd_make_debug_symbol): Rename variable new to new_symbol.
* bfd/cpu-ia64-opc.c (ext_reg, ins_imms_scaled): Rename variable
new to new_insn.
* bfd/doc/chew.c (newentry, add_intrinsic): Rename variable new to
new_d.
* bfd/ecoff.c (_bfd_ecoff_make_empty_symbol): Rename variable new
to new_symbol.
* bfd/elf32-m68k.c (elf_m68k_get_got_entry_type): Rename argument
new to new_reloc.
* bfd/hash.c (bfd_hash_lookup): Rename variable new to new_string.
* bfd/ieee.c (ieee_make_empty_symbol): Rename variable new to
new_symbol.
* bfd/linker.c (bfd_new_link_order): Rename variable new to
new_lo.
* bfd/mach-o.c (bfd_mach_o_sizeof_headers): Rename variable new to
symbol.
* bfd/oasys.c (oasys_make_empty_symbol): Rename variable new to
new_symbol_type.
* bfd/pdp11.c (NAME (aout, make_empty_symbol)): Rename variable
new to new_symbol_type.
* bfd/plugin.c (bfd_plugin_make_empty_symbol): Rename variable new
to new_symbol.
* bfd/rs6000-core.c (CoreHdr, VmInfo): Rename union member new to
new_dump.
(read_hdr, rs6000coff_core_p)
(rs6000coff_core_file_matches_executable_p)
(rs6000coff_core_file_failing_command)
(rs6000coff_core_file_failing_signal): Updated function to use new
union member name.
* bfd/som.c (som_make_empty_symbol): Rename variable new to
new_symbol_type.
* bfd/syms.c (_bfd_generic_make_empty_symbol): Rename variable new
to new_symbol.
* bfd/tekhex.c (first_phase, tekhex_make_empty_symbol): Rename
variable new to new_symbol.
* binutils/nlmconv.c (main): Rename variable new to new_name.
* gas/config/tc-arm.c (insert_reg_alias): Rename variable new to
new_reg.
* gas/config/tc-dlx.c (parse_operand): Rename variable new to
new_pos.
* gas/config/tc-ia64.c (ia64_gen_real_reloc_type): Rename variable
new to newr.
* gas/config/tc-mcore.c (parse_exp, parse_imm): Rename variable
new to new_pointer.
* gas/config/tc-microblaze.c (parse_exp, parse_imm, check_got):
Change name from new to new_pointer.
* gas/config/tc-or32.c (parse_operand): Rename variable new to
new_pointer.
* gas/config/tc-pdp11.c (md_assemble): Rename variable new to
new_pointer.
* gas/config/tc-pj.c (alias): Change argument new to new_name.
* gas/config/tc-score.c (s3_build_score_ops_hsh): Rename variable
new to new_opcode. (s3_build_dependency_insn_hsh) Rename variable
new to new_i2n. (s3_convert): Rename variables old and new to
r_old and r_new.
* gas/config/tc-score7.c (s7_build_score_ops_hsh): Rename variable
new to new_opcode. (s7_build_dependency_insn_hsh): Rename variable
new to new_i2d. (s7_b32_relax_to_b16, s7_convert_frag): Rename
variables old and new to r_old and r_new.
* gas/config/tc-sh.c (parse_exp): Rename variable new to
new_pointer.
* gas/config/tc-sh64.c (shmedia_parse_exp): Rename variable new to
new_pointer.
* gas/config/tc-tic4x.c (tic4x_operand_parse): Rename variable new
to new_pointer.
* gas/config/tc-z8k.c (parse_exp): Rename variable new to
new_pointer.
* gas/listing.c (listing_newline): Rename variable new to new_i.
* ld/ldexp.c (exp_intop, exp_bigintop, exp_relop, exp_binop)
(exp_trinop, exp_unop, exp_nameop, exp_assop): Rename variable new
to new_e.
* ld/ldfile.c (ldfile_add_library_path): Rename variable new to
new_dirs. (ldfile_add_arch): Rename variable new to new_arch.
* ld/ldlang.c (new_statement, lang_final, lang_add_wild)
(lang_target, lang_add_fill, lang_add_data, lang_add_assignment)
(lang_add_insert): Rename variable new to new_stmt. (new_afile):
Added missing cast. (lang_memory_region_lookup): Rename variable
new to new_region. (init_os): Rename variable new to
new_userdata. (lang_add_section): Rename variable new to
new_section. (ldlang_add_undef): Rename variable new to
new_undef. (realsymbol): Rename variable new to new_name.
* opcodes/z8kgen.c (internal, gas): Rename variable new to new_op.
Updated sources to avoid using the identifier name "template",
which is a keyword in c++.
* bfd/elf32-arm.c (struct stub_def): Rename member template to
template_sequence. (arm_build_one_stub,
find_stub_size_and_template, arm_size_one_stub, arm_map_one_stub):
Rename variable template to template_sequence.
* bfd/elfxx-ia64.c (elfNN_ia64_relax_br, elfNN_ia64_relax_brl):
Rename variable template to template_val.
* gas/config/tc-arm.c (struct asm_cond, struct asm_psr, struct
asm_barrier_opt): Change member template to
template_name. (md_begin): Update code to reflect new member
names.
* gas/config/tc-i386.c (struct templates, struct _i386_insn)
(match_template, cpu_flags_match, match_reg_size, match_mem_size)
(operand_size_match, md_begin, i386_print_statistics, pi)
(build_vex_prefix, md_assemble, parse_insn, optimize_imm)
(optimize_disp): Updated code to use new names. (parse_insn):
Added casts.
* gas/config/tc-ia64.c (dot_template, emit_one_bundle): Updated
code to use new names.
* gas/config/tc-score.c (struct s3_asm_opcode): Renamed member
template to template_name. (s3_parse_16_32_inst, s3_parse_48_inst,
s3_do_macro_ldst_label, s3_build_score_ops_hsh): Update code to
use new names.
* gas/config/tc-score7.c (struct s7_asm_opcode): Renamed member
template to template_name. (s7_parse_16_32_inst,
s7_do_macro_ldst_label, s7_build_score_ops_hsh): Update code to
use new names.
* gas/config/tc-tic30.c (md_begin, struct tic30_insn)
(md_assemble): Update code to use new names.
* gas/config/tc-tic54x.c (struct _tic54x_insn, md_begin)
(optimize_insn, tic54x_parse_insn, next_line_shows_parallel):
Update code to use new names.
* include/opcode/tic30.h (template): Rename type template to
insn_template. Updated code to use new name.
* include/opcode/tic54x.h (template): Rename type template to
insn_template.
* opcodes/cris-dis.c (bytes_to_skip): Update code to use new name.
* opcodes/i386-dis.c (putop): Update code to use new name.
* opcodes/i386-gen.c (process_i386_opcodes): Update code to use
new name.
* opcodes/i386-opc.h (struct template): Rename struct template to
insn_template. Update code accordingly.
* opcodes/i386-tbl.h (i386_optab): Update type to use new name.
* opcodes/ia64-dis.c (print_insn_ia64): Rename variable template
to template_val.
* opcodes/tic30-dis.c (struct instruction, get_tic30_instruction):
Update code to use new name.
* opcodes/tic54x-dis.c (has_lkaddr, get_insn_size)
(print_parallel_instruction, print_insn_tic54x, tic54x_get_insn):
Update code to use new name.
* opcodes/tic54x-opc.c (tic54x_unknown_opcode, tic54x_optab):
Update type to new name.
2009-08-30 00:11:02 +02:00
|
|
|
|
char *new_string;
|
1999-05-03 09:29:11 +02:00
|
|
|
|
|
Updated sources to avoid using the identifier name "new", which is a
keyword in c++.
* bfd/aoutx.h (NAME (aout, make_empty_symbol)): Rename variable
new to new_symbol.
* bfd/coffgen.c (coff_make_empty_symbol)
(coff_bfd_make_debug_symbol): Rename variable new to new_symbol.
* bfd/cpu-ia64-opc.c (ext_reg, ins_imms_scaled): Rename variable
new to new_insn.
* bfd/doc/chew.c (newentry, add_intrinsic): Rename variable new to
new_d.
* bfd/ecoff.c (_bfd_ecoff_make_empty_symbol): Rename variable new
to new_symbol.
* bfd/elf32-m68k.c (elf_m68k_get_got_entry_type): Rename argument
new to new_reloc.
* bfd/hash.c (bfd_hash_lookup): Rename variable new to new_string.
* bfd/ieee.c (ieee_make_empty_symbol): Rename variable new to
new_symbol.
* bfd/linker.c (bfd_new_link_order): Rename variable new to
new_lo.
* bfd/mach-o.c (bfd_mach_o_sizeof_headers): Rename variable new to
symbol.
* bfd/oasys.c (oasys_make_empty_symbol): Rename variable new to
new_symbol_type.
* bfd/pdp11.c (NAME (aout, make_empty_symbol)): Rename variable
new to new_symbol_type.
* bfd/plugin.c (bfd_plugin_make_empty_symbol): Rename variable new
to new_symbol.
* bfd/rs6000-core.c (CoreHdr, VmInfo): Rename union member new to
new_dump.
(read_hdr, rs6000coff_core_p)
(rs6000coff_core_file_matches_executable_p)
(rs6000coff_core_file_failing_command)
(rs6000coff_core_file_failing_signal): Updated function to use new
union member name.
* bfd/som.c (som_make_empty_symbol): Rename variable new to
new_symbol_type.
* bfd/syms.c (_bfd_generic_make_empty_symbol): Rename variable new
to new_symbol.
* bfd/tekhex.c (first_phase, tekhex_make_empty_symbol): Rename
variable new to new_symbol.
* binutils/nlmconv.c (main): Rename variable new to new_name.
* gas/config/tc-arm.c (insert_reg_alias): Rename variable new to
new_reg.
* gas/config/tc-dlx.c (parse_operand): Rename variable new to
new_pos.
* gas/config/tc-ia64.c (ia64_gen_real_reloc_type): Rename variable
new to newr.
* gas/config/tc-mcore.c (parse_exp, parse_imm): Rename variable
new to new_pointer.
* gas/config/tc-microblaze.c (parse_exp, parse_imm, check_got):
Change name from new to new_pointer.
* gas/config/tc-or32.c (parse_operand): Rename variable new to
new_pointer.
* gas/config/tc-pdp11.c (md_assemble): Rename variable new to
new_pointer.
* gas/config/tc-pj.c (alias): Change argument new to new_name.
* gas/config/tc-score.c (s3_build_score_ops_hsh): Rename variable
new to new_opcode. (s3_build_dependency_insn_hsh) Rename variable
new to new_i2n. (s3_convert): Rename variables old and new to
r_old and r_new.
* gas/config/tc-score7.c (s7_build_score_ops_hsh): Rename variable
new to new_opcode. (s7_build_dependency_insn_hsh): Rename variable
new to new_i2d. (s7_b32_relax_to_b16, s7_convert_frag): Rename
variables old and new to r_old and r_new.
* gas/config/tc-sh.c (parse_exp): Rename variable new to
new_pointer.
* gas/config/tc-sh64.c (shmedia_parse_exp): Rename variable new to
new_pointer.
* gas/config/tc-tic4x.c (tic4x_operand_parse): Rename variable new
to new_pointer.
* gas/config/tc-z8k.c (parse_exp): Rename variable new to
new_pointer.
* gas/listing.c (listing_newline): Rename variable new to new_i.
* ld/ldexp.c (exp_intop, exp_bigintop, exp_relop, exp_binop)
(exp_trinop, exp_unop, exp_nameop, exp_assop): Rename variable new
to new_e.
* ld/ldfile.c (ldfile_add_library_path): Rename variable new to
new_dirs. (ldfile_add_arch): Rename variable new to new_arch.
* ld/ldlang.c (new_statement, lang_final, lang_add_wild)
(lang_target, lang_add_fill, lang_add_data, lang_add_assignment)
(lang_add_insert): Rename variable new to new_stmt. (new_afile):
Added missing cast. (lang_memory_region_lookup): Rename variable
new to new_region. (init_os): Rename variable new to
new_userdata. (lang_add_section): Rename variable new to
new_section. (ldlang_add_undef): Rename variable new to
new_undef. (realsymbol): Rename variable new to new_name.
* opcodes/z8kgen.c (internal, gas): Rename variable new to new_op.
Updated sources to avoid using the identifier name "template",
which is a keyword in c++.
* bfd/elf32-arm.c (struct stub_def): Rename member template to
template_sequence. (arm_build_one_stub,
find_stub_size_and_template, arm_size_one_stub, arm_map_one_stub):
Rename variable template to template_sequence.
* bfd/elfxx-ia64.c (elfNN_ia64_relax_br, elfNN_ia64_relax_brl):
Rename variable template to template_val.
* gas/config/tc-arm.c (struct asm_cond, struct asm_psr, struct
asm_barrier_opt): Change member template to
template_name. (md_begin): Update code to reflect new member
names.
* gas/config/tc-i386.c (struct templates, struct _i386_insn)
(match_template, cpu_flags_match, match_reg_size, match_mem_size)
(operand_size_match, md_begin, i386_print_statistics, pi)
(build_vex_prefix, md_assemble, parse_insn, optimize_imm)
(optimize_disp): Updated code to use new names. (parse_insn):
Added casts.
* gas/config/tc-ia64.c (dot_template, emit_one_bundle): Updated
code to use new names.
* gas/config/tc-score.c (struct s3_asm_opcode): Renamed member
template to template_name. (s3_parse_16_32_inst, s3_parse_48_inst,
s3_do_macro_ldst_label, s3_build_score_ops_hsh): Update code to
use new names.
* gas/config/tc-score7.c (struct s7_asm_opcode): Renamed member
template to template_name. (s7_parse_16_32_inst,
s7_do_macro_ldst_label, s7_build_score_ops_hsh): Update code to
use new names.
* gas/config/tc-tic30.c (md_begin, struct tic30_insn)
(md_assemble): Update code to use new names.
* gas/config/tc-tic54x.c (struct _tic54x_insn, md_begin)
(optimize_insn, tic54x_parse_insn, next_line_shows_parallel):
Update code to use new names.
* include/opcode/tic30.h (template): Rename type template to
insn_template. Updated code to use new name.
* include/opcode/tic54x.h (template): Rename type template to
insn_template.
* opcodes/cris-dis.c (bytes_to_skip): Update code to use new name.
* opcodes/i386-dis.c (putop): Update code to use new name.
* opcodes/i386-gen.c (process_i386_opcodes): Update code to use
new name.
* opcodes/i386-opc.h (struct template): Rename struct template to
insn_template. Update code accordingly.
* opcodes/i386-tbl.h (i386_optab): Update type to use new name.
* opcodes/ia64-dis.c (print_insn_ia64): Rename variable template
to template_val.
* opcodes/tic30-dis.c (struct instruction, get_tic30_instruction):
Update code to use new name.
* opcodes/tic54x-dis.c (has_lkaddr, get_insn_size)
(print_parallel_instruction, print_insn_tic54x, tic54x_get_insn):
Update code to use new name.
* opcodes/tic54x-opc.c (tic54x_unknown_opcode, tic54x_optab):
Update type to new name.
2009-08-30 00:11:02 +02:00
|
|
|
|
new_string = (char *) objalloc_alloc ((struct objalloc *) table->memory,
|
|
|
|
|
len + 1);
|
|
|
|
|
if (!new_string)
|
1999-05-03 09:29:11 +02:00
|
|
|
|
{
|
|
|
|
|
bfd_set_error (bfd_error_no_memory);
|
2005-03-22 17:14:43 +01:00
|
|
|
|
return NULL;
|
1999-05-03 09:29:11 +02:00
|
|
|
|
}
|
Updated sources to avoid using the identifier name "new", which is a
keyword in c++.
* bfd/aoutx.h (NAME (aout, make_empty_symbol)): Rename variable
new to new_symbol.
* bfd/coffgen.c (coff_make_empty_symbol)
(coff_bfd_make_debug_symbol): Rename variable new to new_symbol.
* bfd/cpu-ia64-opc.c (ext_reg, ins_imms_scaled): Rename variable
new to new_insn.
* bfd/doc/chew.c (newentry, add_intrinsic): Rename variable new to
new_d.
* bfd/ecoff.c (_bfd_ecoff_make_empty_symbol): Rename variable new
to new_symbol.
* bfd/elf32-m68k.c (elf_m68k_get_got_entry_type): Rename argument
new to new_reloc.
* bfd/hash.c (bfd_hash_lookup): Rename variable new to new_string.
* bfd/ieee.c (ieee_make_empty_symbol): Rename variable new to
new_symbol.
* bfd/linker.c (bfd_new_link_order): Rename variable new to
new_lo.
* bfd/mach-o.c (bfd_mach_o_sizeof_headers): Rename variable new to
symbol.
* bfd/oasys.c (oasys_make_empty_symbol): Rename variable new to
new_symbol_type.
* bfd/pdp11.c (NAME (aout, make_empty_symbol)): Rename variable
new to new_symbol_type.
* bfd/plugin.c (bfd_plugin_make_empty_symbol): Rename variable new
to new_symbol.
* bfd/rs6000-core.c (CoreHdr, VmInfo): Rename union member new to
new_dump.
(read_hdr, rs6000coff_core_p)
(rs6000coff_core_file_matches_executable_p)
(rs6000coff_core_file_failing_command)
(rs6000coff_core_file_failing_signal): Updated function to use new
union member name.
* bfd/som.c (som_make_empty_symbol): Rename variable new to
new_symbol_type.
* bfd/syms.c (_bfd_generic_make_empty_symbol): Rename variable new
to new_symbol.
* bfd/tekhex.c (first_phase, tekhex_make_empty_symbol): Rename
variable new to new_symbol.
* binutils/nlmconv.c (main): Rename variable new to new_name.
* gas/config/tc-arm.c (insert_reg_alias): Rename variable new to
new_reg.
* gas/config/tc-dlx.c (parse_operand): Rename variable new to
new_pos.
* gas/config/tc-ia64.c (ia64_gen_real_reloc_type): Rename variable
new to newr.
* gas/config/tc-mcore.c (parse_exp, parse_imm): Rename variable
new to new_pointer.
* gas/config/tc-microblaze.c (parse_exp, parse_imm, check_got):
Change name from new to new_pointer.
* gas/config/tc-or32.c (parse_operand): Rename variable new to
new_pointer.
* gas/config/tc-pdp11.c (md_assemble): Rename variable new to
new_pointer.
* gas/config/tc-pj.c (alias): Change argument new to new_name.
* gas/config/tc-score.c (s3_build_score_ops_hsh): Rename variable
new to new_opcode. (s3_build_dependency_insn_hsh) Rename variable
new to new_i2n. (s3_convert): Rename variables old and new to
r_old and r_new.
* gas/config/tc-score7.c (s7_build_score_ops_hsh): Rename variable
new to new_opcode. (s7_build_dependency_insn_hsh): Rename variable
new to new_i2d. (s7_b32_relax_to_b16, s7_convert_frag): Rename
variables old and new to r_old and r_new.
* gas/config/tc-sh.c (parse_exp): Rename variable new to
new_pointer.
* gas/config/tc-sh64.c (shmedia_parse_exp): Rename variable new to
new_pointer.
* gas/config/tc-tic4x.c (tic4x_operand_parse): Rename variable new
to new_pointer.
* gas/config/tc-z8k.c (parse_exp): Rename variable new to
new_pointer.
* gas/listing.c (listing_newline): Rename variable new to new_i.
* ld/ldexp.c (exp_intop, exp_bigintop, exp_relop, exp_binop)
(exp_trinop, exp_unop, exp_nameop, exp_assop): Rename variable new
to new_e.
* ld/ldfile.c (ldfile_add_library_path): Rename variable new to
new_dirs. (ldfile_add_arch): Rename variable new to new_arch.
* ld/ldlang.c (new_statement, lang_final, lang_add_wild)
(lang_target, lang_add_fill, lang_add_data, lang_add_assignment)
(lang_add_insert): Rename variable new to new_stmt. (new_afile):
Added missing cast. (lang_memory_region_lookup): Rename variable
new to new_region. (init_os): Rename variable new to
new_userdata. (lang_add_section): Rename variable new to
new_section. (ldlang_add_undef): Rename variable new to
new_undef. (realsymbol): Rename variable new to new_name.
* opcodes/z8kgen.c (internal, gas): Rename variable new to new_op.
Updated sources to avoid using the identifier name "template",
which is a keyword in c++.
* bfd/elf32-arm.c (struct stub_def): Rename member template to
template_sequence. (arm_build_one_stub,
find_stub_size_and_template, arm_size_one_stub, arm_map_one_stub):
Rename variable template to template_sequence.
* bfd/elfxx-ia64.c (elfNN_ia64_relax_br, elfNN_ia64_relax_brl):
Rename variable template to template_val.
* gas/config/tc-arm.c (struct asm_cond, struct asm_psr, struct
asm_barrier_opt): Change member template to
template_name. (md_begin): Update code to reflect new member
names.
* gas/config/tc-i386.c (struct templates, struct _i386_insn)
(match_template, cpu_flags_match, match_reg_size, match_mem_size)
(operand_size_match, md_begin, i386_print_statistics, pi)
(build_vex_prefix, md_assemble, parse_insn, optimize_imm)
(optimize_disp): Updated code to use new names. (parse_insn):
Added casts.
* gas/config/tc-ia64.c (dot_template, emit_one_bundle): Updated
code to use new names.
* gas/config/tc-score.c (struct s3_asm_opcode): Renamed member
template to template_name. (s3_parse_16_32_inst, s3_parse_48_inst,
s3_do_macro_ldst_label, s3_build_score_ops_hsh): Update code to
use new names.
* gas/config/tc-score7.c (struct s7_asm_opcode): Renamed member
template to template_name. (s7_parse_16_32_inst,
s7_do_macro_ldst_label, s7_build_score_ops_hsh): Update code to
use new names.
* gas/config/tc-tic30.c (md_begin, struct tic30_insn)
(md_assemble): Update code to use new names.
* gas/config/tc-tic54x.c (struct _tic54x_insn, md_begin)
(optimize_insn, tic54x_parse_insn, next_line_shows_parallel):
Update code to use new names.
* include/opcode/tic30.h (template): Rename type template to
insn_template. Updated code to use new name.
* include/opcode/tic54x.h (template): Rename type template to
insn_template.
* opcodes/cris-dis.c (bytes_to_skip): Update code to use new name.
* opcodes/i386-dis.c (putop): Update code to use new name.
* opcodes/i386-gen.c (process_i386_opcodes): Update code to use
new name.
* opcodes/i386-opc.h (struct template): Rename struct template to
insn_template. Update code accordingly.
* opcodes/i386-tbl.h (i386_optab): Update type to use new name.
* opcodes/ia64-dis.c (print_insn_ia64): Rename variable template
to template_val.
* opcodes/tic30-dis.c (struct instruction, get_tic30_instruction):
Update code to use new name.
* opcodes/tic54x-dis.c (has_lkaddr, get_insn_size)
(print_parallel_instruction, print_insn_tic54x, tic54x_get_insn):
Update code to use new name.
* opcodes/tic54x-opc.c (tic54x_unknown_opcode, tic54x_optab):
Update type to new name.
2009-08-30 00:11:02 +02:00
|
|
|
|
memcpy (new_string, string, len + 1);
|
|
|
|
|
string = new_string;
|
1999-05-03 09:29:11 +02:00
|
|
|
|
}
|
2007-09-19 14:08:34 +02:00
|
|
|
|
|
|
|
|
|
return bfd_hash_insert (table, string, hash);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Insert an entry in a hash table. */
|
|
|
|
|
|
|
|
|
|
struct bfd_hash_entry *
|
|
|
|
|
bfd_hash_insert (struct bfd_hash_table *table,
|
|
|
|
|
const char *string,
|
|
|
|
|
unsigned long hash)
|
|
|
|
|
{
|
|
|
|
|
struct bfd_hash_entry *hashp;
|
2009-12-11 14:42:17 +01:00
|
|
|
|
unsigned int _index;
|
2007-09-19 14:08:34 +02:00
|
|
|
|
|
|
|
|
|
hashp = (*table->newfunc) (NULL, table, string);
|
|
|
|
|
if (hashp == NULL)
|
|
|
|
|
return NULL;
|
1999-05-03 09:29:11 +02:00
|
|
|
|
hashp->string = string;
|
|
|
|
|
hashp->hash = hash;
|
2009-12-11 14:42:17 +01:00
|
|
|
|
_index = hash % table->size;
|
|
|
|
|
hashp->next = table->table[_index];
|
|
|
|
|
table->table[_index] = hashp;
|
2006-06-06 05:04:12 +02:00
|
|
|
|
table->count++;
|
1999-05-03 09:29:11 +02:00
|
|
|
|
|
2006-11-20 02:38:38 +01:00
|
|
|
|
if (!table->frozen && table->count > table->size * 3 / 4)
|
2006-05-01 21:36:27 +02:00
|
|
|
|
{
|
2006-05-03 06:20:52 +02:00
|
|
|
|
unsigned long newsize = higher_prime_number (table->size);
|
2006-05-01 21:36:27 +02:00
|
|
|
|
struct bfd_hash_entry **newtable;
|
|
|
|
|
unsigned int hi;
|
2006-05-03 06:20:52 +02:00
|
|
|
|
unsigned long alloc = newsize * sizeof (struct bfd_hash_entry *);
|
2006-05-01 21:36:27 +02:00
|
|
|
|
|
2006-05-03 06:20:52 +02:00
|
|
|
|
/* If we can't find a higher prime, or we can't possibly alloc
|
|
|
|
|
that much memory, don't try to grow the table. */
|
|
|
|
|
if (newsize == 0 || alloc / sizeof (struct bfd_hash_entry *) != newsize)
|
|
|
|
|
{
|
2006-11-20 02:38:38 +01:00
|
|
|
|
table->frozen = 1;
|
2006-05-03 06:20:52 +02:00
|
|
|
|
return hashp;
|
|
|
|
|
}
|
2006-05-01 21:36:27 +02:00
|
|
|
|
|
|
|
|
|
newtable = ((struct bfd_hash_entry **)
|
|
|
|
|
objalloc_alloc ((struct objalloc *) table->memory, alloc));
|
2007-09-19 14:08:34 +02:00
|
|
|
|
if (newtable == NULL)
|
|
|
|
|
{
|
|
|
|
|
table->frozen = 1;
|
|
|
|
|
return hashp;
|
|
|
|
|
}
|
2012-07-13 16:22:50 +02:00
|
|
|
|
memset (newtable, 0, alloc);
|
2006-05-01 21:36:27 +02:00
|
|
|
|
|
|
|
|
|
for (hi = 0; hi < table->size; hi ++)
|
|
|
|
|
while (table->table[hi])
|
|
|
|
|
{
|
|
|
|
|
struct bfd_hash_entry *chain = table->table[hi];
|
|
|
|
|
struct bfd_hash_entry *chain_end = chain;
|
|
|
|
|
|
|
|
|
|
while (chain_end->next && chain_end->next->hash == chain->hash)
|
2006-05-03 06:20:52 +02:00
|
|
|
|
chain_end = chain_end->next;
|
2006-05-01 21:36:27 +02:00
|
|
|
|
|
|
|
|
|
table->table[hi] = chain_end->next;
|
2009-12-11 14:42:17 +01:00
|
|
|
|
_index = chain->hash % newsize;
|
|
|
|
|
chain_end->next = newtable[_index];
|
|
|
|
|
newtable[_index] = chain;
|
2006-05-01 21:36:27 +02:00
|
|
|
|
}
|
|
|
|
|
table->table = newtable;
|
|
|
|
|
table->size = newsize;
|
|
|
|
|
}
|
|
|
|
|
|
1999-05-03 09:29:11 +02:00
|
|
|
|
return hashp;
|
|
|
|
|
}
|
|
|
|
|
|
2010-11-08 03:48:57 +01:00
|
|
|
|
/* Rename an entry in a hash table. */
|
|
|
|
|
|
|
|
|
|
void
|
|
|
|
|
bfd_hash_rename (struct bfd_hash_table *table,
|
|
|
|
|
const char *string,
|
|
|
|
|
struct bfd_hash_entry *ent)
|
|
|
|
|
{
|
|
|
|
|
unsigned int _index;
|
|
|
|
|
struct bfd_hash_entry **pph;
|
|
|
|
|
|
|
|
|
|
_index = ent->hash % table->size;
|
|
|
|
|
for (pph = &table->table[_index]; *pph != NULL; pph = &(*pph)->next)
|
|
|
|
|
if (*pph == ent)
|
|
|
|
|
break;
|
|
|
|
|
if (*pph == NULL)
|
|
|
|
|
abort ();
|
|
|
|
|
|
|
|
|
|
*pph = ent->next;
|
|
|
|
|
ent->string = string;
|
|
|
|
|
ent->hash = bfd_hash_hash (string, NULL);
|
|
|
|
|
_index = ent->hash % table->size;
|
|
|
|
|
ent->next = table->table[_index];
|
|
|
|
|
table->table[_index] = ent;
|
|
|
|
|
}
|
|
|
|
|
|
1999-05-03 09:29:11 +02:00
|
|
|
|
/* Replace an entry in a hash table. */
|
|
|
|
|
|
|
|
|
|
void
|
2005-03-22 17:14:43 +01:00
|
|
|
|
bfd_hash_replace (struct bfd_hash_table *table,
|
|
|
|
|
struct bfd_hash_entry *old,
|
|
|
|
|
struct bfd_hash_entry *nw)
|
1999-05-03 09:29:11 +02:00
|
|
|
|
{
|
2009-12-11 14:42:17 +01:00
|
|
|
|
unsigned int _index;
|
1999-05-03 09:29:11 +02:00
|
|
|
|
struct bfd_hash_entry **pph;
|
|
|
|
|
|
2009-12-11 14:42:17 +01:00
|
|
|
|
_index = old->hash % table->size;
|
|
|
|
|
for (pph = &table->table[_index];
|
2005-03-22 17:14:43 +01:00
|
|
|
|
(*pph) != NULL;
|
1999-05-03 09:29:11 +02:00
|
|
|
|
pph = &(*pph)->next)
|
|
|
|
|
{
|
|
|
|
|
if (*pph == old)
|
|
|
|
|
{
|
|
|
|
|
*pph = nw;
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
abort ();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Allocate space in a hash table. */
|
|
|
|
|
|
2005-03-22 17:14:43 +01:00
|
|
|
|
void *
|
|
|
|
|
bfd_hash_allocate (struct bfd_hash_table *table,
|
|
|
|
|
unsigned int size)
|
1999-05-03 09:29:11 +02:00
|
|
|
|
{
|
2005-03-22 17:14:43 +01:00
|
|
|
|
void * ret;
|
1999-05-03 09:29:11 +02:00
|
|
|
|
|
|
|
|
|
ret = objalloc_alloc ((struct objalloc *) table->memory, size);
|
|
|
|
|
if (ret == NULL && size != 0)
|
|
|
|
|
bfd_set_error (bfd_error_no_memory);
|
|
|
|
|
return ret;
|
|
|
|
|
}
|
|
|
|
|
|
2005-03-22 17:14:43 +01:00
|
|
|
|
/* Base method for creating a new hash table entry. */
|
|
|
|
|
|
|
|
|
|
struct bfd_hash_entry *
|
|
|
|
|
bfd_hash_newfunc (struct bfd_hash_entry *entry,
|
|
|
|
|
struct bfd_hash_table *table,
|
|
|
|
|
const char *string ATTRIBUTE_UNUSED)
|
|
|
|
|
{
|
|
|
|
|
if (entry == NULL)
|
2009-09-09 23:38:59 +02:00
|
|
|
|
entry = (struct bfd_hash_entry *) bfd_hash_allocate (table,
|
|
|
|
|
sizeof (* entry));
|
2005-03-22 17:14:43 +01:00
|
|
|
|
return entry;
|
|
|
|
|
}
|
|
|
|
|
|
1999-05-03 09:29:11 +02:00
|
|
|
|
/* Traverse a hash table. */
|
|
|
|
|
|
|
|
|
|
void
|
2005-03-22 17:14:43 +01:00
|
|
|
|
bfd_hash_traverse (struct bfd_hash_table *table,
|
|
|
|
|
bfd_boolean (*func) (struct bfd_hash_entry *, void *),
|
|
|
|
|
void * info)
|
1999-05-03 09:29:11 +02:00
|
|
|
|
{
|
|
|
|
|
unsigned int i;
|
|
|
|
|
|
2006-11-20 02:38:38 +01:00
|
|
|
|
table->frozen = 1;
|
1999-05-03 09:29:11 +02:00
|
|
|
|
for (i = 0; i < table->size; i++)
|
|
|
|
|
{
|
|
|
|
|
struct bfd_hash_entry *p;
|
|
|
|
|
|
|
|
|
|
for (p = table->table[i]; p != NULL; p = p->next)
|
2005-03-22 17:14:43 +01:00
|
|
|
|
if (! (*func) (p, info))
|
2006-11-20 02:38:38 +01:00
|
|
|
|
goto out;
|
1999-05-03 09:29:11 +02:00
|
|
|
|
}
|
2006-11-20 02:38:38 +01:00
|
|
|
|
out:
|
|
|
|
|
table->frozen = 0;
|
1999-05-03 09:29:11 +02:00
|
|
|
|
}
|
|
|
|
|
|
2011-04-20 14:52:16 +02:00
|
|
|
|
unsigned long
|
|
|
|
|
bfd_hash_set_default_size (unsigned long hash_size)
|
2004-05-21 17:38:04 +02:00
|
|
|
|
{
|
|
|
|
|
/* Extend this prime list if you want more granularity of hash table size. */
|
2011-04-20 14:52:16 +02:00
|
|
|
|
static const unsigned long hash_size_primes[] =
|
2004-05-21 17:38:04 +02:00
|
|
|
|
{
|
2011-06-03 18:16:32 +02:00
|
|
|
|
31, 61, 127, 251, 509, 1021, 2039, 4091, 8191, 16381, 32749, 65537
|
2004-05-21 17:38:04 +02:00
|
|
|
|
};
|
2011-04-20 14:52:16 +02:00
|
|
|
|
unsigned int _index;
|
2004-05-21 17:38:04 +02:00
|
|
|
|
|
|
|
|
|
/* Work out best prime number near the hash_size. */
|
2009-12-11 14:42:17 +01:00
|
|
|
|
for (_index = 0; _index < ARRAY_SIZE (hash_size_primes) - 1; ++_index)
|
|
|
|
|
if (hash_size <= hash_size_primes[_index])
|
2004-05-21 17:38:04 +02:00
|
|
|
|
break;
|
|
|
|
|
|
2009-12-11 14:42:17 +01:00
|
|
|
|
bfd_default_hash_table_size = hash_size_primes[_index];
|
2011-04-20 14:52:16 +02:00
|
|
|
|
return bfd_default_hash_table_size;
|
2004-05-21 17:38:04 +02:00
|
|
|
|
}
|
|
|
|
|
|
1999-05-03 09:29:11 +02:00
|
|
|
|
/* A few different object file formats (a.out, COFF, ELF) use a string
|
|
|
|
|
table. These functions support adding strings to a string table,
|
|
|
|
|
returning the byte offset, and writing out the table.
|
|
|
|
|
|
|
|
|
|
Possible improvements:
|
|
|
|
|
+ look for strings matching trailing substrings of other strings
|
|
|
|
|
+ better data structures? balanced trees?
|
|
|
|
|
+ look at reducing memory use elsewhere -- maybe if we didn't have
|
|
|
|
|
to construct the entire symbol table at once, we could get by
|
|
|
|
|
with smaller amounts of VM? (What effect does that have on the
|
|
|
|
|
string table reductions?) */
|
|
|
|
|
|
|
|
|
|
/* An entry in the strtab hash table. */
|
|
|
|
|
|
|
|
|
|
struct strtab_hash_entry
|
|
|
|
|
{
|
|
|
|
|
struct bfd_hash_entry root;
|
|
|
|
|
/* Index in string table. */
|
|
|
|
|
bfd_size_type index;
|
|
|
|
|
/* Next string in strtab. */
|
|
|
|
|
struct strtab_hash_entry *next;
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
/* The strtab hash table. */
|
|
|
|
|
|
|
|
|
|
struct bfd_strtab_hash
|
|
|
|
|
{
|
|
|
|
|
struct bfd_hash_table table;
|
|
|
|
|
/* Size of strtab--also next available index. */
|
|
|
|
|
bfd_size_type size;
|
|
|
|
|
/* First string in strtab. */
|
|
|
|
|
struct strtab_hash_entry *first;
|
|
|
|
|
/* Last string in strtab. */
|
|
|
|
|
struct strtab_hash_entry *last;
|
|
|
|
|
/* Whether to precede strings with a two byte length, as in the
|
|
|
|
|
XCOFF .debug section. */
|
2002-11-30 09:39:46 +01:00
|
|
|
|
bfd_boolean xcoff;
|
1999-05-03 09:29:11 +02:00
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
/* Routine to create an entry in a strtab. */
|
|
|
|
|
|
|
|
|
|
static struct bfd_hash_entry *
|
2005-03-22 17:14:43 +01:00
|
|
|
|
strtab_hash_newfunc (struct bfd_hash_entry *entry,
|
|
|
|
|
struct bfd_hash_table *table,
|
|
|
|
|
const char *string)
|
1999-05-03 09:29:11 +02:00
|
|
|
|
{
|
|
|
|
|
struct strtab_hash_entry *ret = (struct strtab_hash_entry *) entry;
|
|
|
|
|
|
|
|
|
|
/* Allocate the structure if it has not already been allocated by a
|
|
|
|
|
subclass. */
|
2005-03-22 17:14:43 +01:00
|
|
|
|
if (ret == NULL)
|
2009-09-09 23:38:59 +02:00
|
|
|
|
ret = (struct strtab_hash_entry *) bfd_hash_allocate (table,
|
|
|
|
|
sizeof (* ret));
|
2005-03-22 17:14:43 +01:00
|
|
|
|
if (ret == NULL)
|
1999-05-03 09:29:11 +02:00
|
|
|
|
return NULL;
|
|
|
|
|
|
|
|
|
|
/* Call the allocation method of the superclass. */
|
2005-03-22 17:14:43 +01:00
|
|
|
|
ret = (struct strtab_hash_entry *)
|
|
|
|
|
bfd_hash_newfunc ((struct bfd_hash_entry *) ret, table, string);
|
1999-05-03 09:29:11 +02:00
|
|
|
|
|
|
|
|
|
if (ret)
|
|
|
|
|
{
|
|
|
|
|
/* Initialize the local fields. */
|
|
|
|
|
ret->index = (bfd_size_type) -1;
|
|
|
|
|
ret->next = NULL;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return (struct bfd_hash_entry *) ret;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Look up an entry in an strtab. */
|
|
|
|
|
|
|
|
|
|
#define strtab_hash_lookup(t, string, create, copy) \
|
|
|
|
|
((struct strtab_hash_entry *) \
|
|
|
|
|
bfd_hash_lookup (&(t)->table, (string), (create), (copy)))
|
|
|
|
|
|
|
|
|
|
/* Create a new strtab. */
|
|
|
|
|
|
|
|
|
|
struct bfd_strtab_hash *
|
2005-03-22 17:14:43 +01:00
|
|
|
|
_bfd_stringtab_init (void)
|
1999-05-03 09:29:11 +02:00
|
|
|
|
{
|
|
|
|
|
struct bfd_strtab_hash *table;
|
2005-03-22 17:14:43 +01:00
|
|
|
|
bfd_size_type amt = sizeof (* table);
|
1999-05-03 09:29:11 +02:00
|
|
|
|
|
2009-09-09 23:38:59 +02:00
|
|
|
|
table = (struct bfd_strtab_hash *) bfd_malloc (amt);
|
1999-05-03 09:29:11 +02:00
|
|
|
|
if (table == NULL)
|
|
|
|
|
return NULL;
|
|
|
|
|
|
2006-03-16 13:20:16 +01:00
|
|
|
|
if (!bfd_hash_table_init (&table->table, strtab_hash_newfunc,
|
|
|
|
|
sizeof (struct strtab_hash_entry)))
|
1999-05-03 09:29:11 +02:00
|
|
|
|
{
|
|
|
|
|
free (table);
|
|
|
|
|
return NULL;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
table->size = 0;
|
|
|
|
|
table->first = NULL;
|
|
|
|
|
table->last = NULL;
|
2002-11-30 09:39:46 +01:00
|
|
|
|
table->xcoff = FALSE;
|
1999-05-03 09:29:11 +02:00
|
|
|
|
|
|
|
|
|
return table;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Create a new strtab in which the strings are output in the format
|
|
|
|
|
used in the XCOFF .debug section: a two byte length precedes each
|
|
|
|
|
string. */
|
|
|
|
|
|
|
|
|
|
struct bfd_strtab_hash *
|
2005-03-22 17:14:43 +01:00
|
|
|
|
_bfd_xcoff_stringtab_init (void)
|
1999-05-03 09:29:11 +02:00
|
|
|
|
{
|
|
|
|
|
struct bfd_strtab_hash *ret;
|
|
|
|
|
|
|
|
|
|
ret = _bfd_stringtab_init ();
|
|
|
|
|
if (ret != NULL)
|
2002-11-30 09:39:46 +01:00
|
|
|
|
ret->xcoff = TRUE;
|
1999-05-03 09:29:11 +02:00
|
|
|
|
return ret;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Free a strtab. */
|
|
|
|
|
|
|
|
|
|
void
|
2005-03-22 17:14:43 +01:00
|
|
|
|
_bfd_stringtab_free (struct bfd_strtab_hash *table)
|
1999-05-03 09:29:11 +02:00
|
|
|
|
{
|
|
|
|
|
bfd_hash_table_free (&table->table);
|
|
|
|
|
free (table);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Get the index of a string in a strtab, adding it if it is not
|
2002-11-30 09:39:46 +01:00
|
|
|
|
already present. If HASH is FALSE, we don't really use the hash
|
2013-06-24 16:28:17 +02:00
|
|
|
|
table, and we don't eliminate duplicate strings. If COPY is true
|
|
|
|
|
then store a copy of STR if creating a new entry. */
|
1999-05-03 09:29:11 +02:00
|
|
|
|
|
|
|
|
|
bfd_size_type
|
2005-03-22 17:14:43 +01:00
|
|
|
|
_bfd_stringtab_add (struct bfd_strtab_hash *tab,
|
|
|
|
|
const char *str,
|
|
|
|
|
bfd_boolean hash,
|
|
|
|
|
bfd_boolean copy)
|
1999-05-03 09:29:11 +02:00
|
|
|
|
{
|
2005-03-22 17:14:43 +01:00
|
|
|
|
struct strtab_hash_entry *entry;
|
1999-05-03 09:29:11 +02:00
|
|
|
|
|
|
|
|
|
if (hash)
|
|
|
|
|
{
|
2002-11-30 09:39:46 +01:00
|
|
|
|
entry = strtab_hash_lookup (tab, str, TRUE, copy);
|
1999-05-03 09:29:11 +02:00
|
|
|
|
if (entry == NULL)
|
|
|
|
|
return (bfd_size_type) -1;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
2009-09-09 23:38:59 +02:00
|
|
|
|
entry = (struct strtab_hash_entry *) bfd_hash_allocate (&tab->table,
|
|
|
|
|
sizeof (* entry));
|
1999-05-03 09:29:11 +02:00
|
|
|
|
if (entry == NULL)
|
|
|
|
|
return (bfd_size_type) -1;
|
|
|
|
|
if (! copy)
|
|
|
|
|
entry->root.string = str;
|
|
|
|
|
else
|
|
|
|
|
{
|
2013-06-24 16:28:17 +02:00
|
|
|
|
size_t len = strlen (str) + 1;
|
1999-05-03 09:29:11 +02:00
|
|
|
|
char *n;
|
|
|
|
|
|
2013-06-24 16:28:17 +02:00
|
|
|
|
n = (char *) bfd_hash_allocate (&tab->table, len);
|
1999-05-03 09:29:11 +02:00
|
|
|
|
if (n == NULL)
|
|
|
|
|
return (bfd_size_type) -1;
|
2013-06-24 16:28:17 +02:00
|
|
|
|
memcpy (n, str, len);
|
1999-05-03 09:29:11 +02:00
|
|
|
|
entry->root.string = n;
|
|
|
|
|
}
|
|
|
|
|
entry->index = (bfd_size_type) -1;
|
|
|
|
|
entry->next = NULL;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (entry->index == (bfd_size_type) -1)
|
|
|
|
|
{
|
|
|
|
|
entry->index = tab->size;
|
|
|
|
|
tab->size += strlen (str) + 1;
|
|
|
|
|
if (tab->xcoff)
|
|
|
|
|
{
|
|
|
|
|
entry->index += 2;
|
|
|
|
|
tab->size += 2;
|
|
|
|
|
}
|
|
|
|
|
if (tab->first == NULL)
|
|
|
|
|
tab->first = entry;
|
|
|
|
|
else
|
|
|
|
|
tab->last->next = entry;
|
|
|
|
|
tab->last = entry;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return entry->index;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Get the number of bytes in a strtab. */
|
|
|
|
|
|
|
|
|
|
bfd_size_type
|
2005-03-22 17:14:43 +01:00
|
|
|
|
_bfd_stringtab_size (struct bfd_strtab_hash *tab)
|
1999-05-03 09:29:11 +02:00
|
|
|
|
{
|
|
|
|
|
return tab->size;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Write out a strtab. ABFD must already be at the right location in
|
|
|
|
|
the file. */
|
|
|
|
|
|
2002-11-30 09:39:46 +01:00
|
|
|
|
bfd_boolean
|
2005-03-22 17:14:43 +01:00
|
|
|
|
_bfd_stringtab_emit (bfd *abfd, struct bfd_strtab_hash *tab)
|
1999-05-03 09:29:11 +02:00
|
|
|
|
{
|
2005-03-22 17:14:43 +01:00
|
|
|
|
bfd_boolean xcoff;
|
|
|
|
|
struct strtab_hash_entry *entry;
|
1999-05-03 09:29:11 +02:00
|
|
|
|
|
|
|
|
|
xcoff = tab->xcoff;
|
|
|
|
|
|
|
|
|
|
for (entry = tab->first; entry != NULL; entry = entry->next)
|
|
|
|
|
{
|
Touches most files in bfd/, so likely will be blamed for everything..
o bfd_read and bfd_write lose an unnecessary param and become
bfd_bread and bfd_bwrite.
o bfd_*alloc now all take a bfd_size_type arg, and will error if
size_t is too small. eg. 32 bit host, 64 bit bfd, verrry big files
or bugs in linker scripts etc.
o file_ptr becomes a bfd_signed_vma. Besides matching sizes with
various other types involved in handling sections, this should make
it easier for bfd to support a 64 bit off_t on 32 bit hosts that
provide it.
o I've made the H_GET_* and H_PUT_* macros (which invoke bfd_h_{get,put}_*)
generally available. They now cast their args to bfd_vma and
bfd_byte * as appropriate, which removes a swag of casts from the
source.
o Bug fixes to bfd_get8, aix386_core_vec, elf32_h8_relax_section, and
aout-encap.c.
o Zillions of formatting and -Wconversion fixes.
2001-09-18 11:57:26 +02:00
|
|
|
|
const char *str;
|
|
|
|
|
size_t len;
|
1999-05-03 09:29:11 +02:00
|
|
|
|
|
|
|
|
|
str = entry->root.string;
|
|
|
|
|
len = strlen (str) + 1;
|
|
|
|
|
|
|
|
|
|
if (xcoff)
|
|
|
|
|
{
|
|
|
|
|
bfd_byte buf[2];
|
|
|
|
|
|
|
|
|
|
/* The output length includes the null byte. */
|
Touches most files in bfd/, so likely will be blamed for everything..
o bfd_read and bfd_write lose an unnecessary param and become
bfd_bread and bfd_bwrite.
o bfd_*alloc now all take a bfd_size_type arg, and will error if
size_t is too small. eg. 32 bit host, 64 bit bfd, verrry big files
or bugs in linker scripts etc.
o file_ptr becomes a bfd_signed_vma. Besides matching sizes with
various other types involved in handling sections, this should make
it easier for bfd to support a 64 bit off_t on 32 bit hosts that
provide it.
o I've made the H_GET_* and H_PUT_* macros (which invoke bfd_h_{get,put}_*)
generally available. They now cast their args to bfd_vma and
bfd_byte * as appropriate, which removes a swag of casts from the
source.
o Bug fixes to bfd_get8, aix386_core_vec, elf32_h8_relax_section, and
aout-encap.c.
o Zillions of formatting and -Wconversion fixes.
2001-09-18 11:57:26 +02:00
|
|
|
|
bfd_put_16 (abfd, (bfd_vma) len, buf);
|
2005-03-22 17:14:43 +01:00
|
|
|
|
if (bfd_bwrite ((void *) buf, (bfd_size_type) 2, abfd) != 2)
|
2002-11-30 09:39:46 +01:00
|
|
|
|
return FALSE;
|
1999-05-03 09:29:11 +02:00
|
|
|
|
}
|
|
|
|
|
|
2005-03-22 17:14:43 +01:00
|
|
|
|
if (bfd_bwrite ((void *) str, (bfd_size_type) len, abfd) != len)
|
2002-11-30 09:39:46 +01:00
|
|
|
|
return FALSE;
|
1999-05-03 09:29:11 +02:00
|
|
|
|
}
|
|
|
|
|
|
2002-11-30 09:39:46 +01:00
|
|
|
|
return TRUE;
|
1999-05-03 09:29:11 +02:00
|
|
|
|
}
|