mirror of
https://github.com/espressif/binutils-gdb.git
synced 2025-06-28 23:39:35 +08:00
* aoutx.h (hash, compare, struct stringtab_entry, add_to_stringtab):
Use unsigned hash values for better hashing. (hash): Hash in the string length for long strings. * aoutx.h (compare): Replace 3 if's with a subtraction. (translate_to_native_sym_flags, add_to_stringtab): Reorder tests in decreasing order of success, as an optimization. (hash): Take a length arg; ignore chars after #25, for speed. (add_to_stringtab): Pass length to hash.
This commit is contained in:
@ -1,3 +1,45 @@
|
|||||||
|
Fri Jun 25 17:09:55 1993 David J. Mackenzie (djm@thepub.cygnus.com)
|
||||||
|
|
||||||
|
* aoutx.h (hash, compare, struct stringtab_entry, add_to_stringtab):
|
||||||
|
Use unsigned hash values for better hashing.
|
||||||
|
(hash): Hash in the string length for long strings.
|
||||||
|
|
||||||
|
Thu Jun 24 15:47:51 1993 David J. Mackenzie (djm@thepub.cygnus.com)
|
||||||
|
|
||||||
|
* aoutx.h (compare): Replace 3 if's with a subtraction.
|
||||||
|
(translate_to_native_sym_flags, add_to_stringtab): Reorder tests
|
||||||
|
in decreasing order of success, as an optimization.
|
||||||
|
(hash): Take a length arg; ignore chars after #25, for speed.
|
||||||
|
(add_to_stringtab): Pass length to hash.
|
||||||
|
|
||||||
|
Thu Jun 24 17:25:51 1993 Ken Raeburn (raeburn@poseidon.cygnus.com)
|
||||||
|
|
||||||
|
* elf32-sparc.c (sparc_reloc_map): Add SPARC_WDISP22 reloc.
|
||||||
|
|
||||||
|
* elfcode.h (elf_new_section_hook): Do nothing for now.
|
||||||
|
(elf_write_object_contents): Output common symbols the way ELF
|
||||||
|
wants them.
|
||||||
|
|
||||||
|
Wed Jun 23 16:20:07 1993 Ken Raeburn (raeburn@poseidon.cygnus.com)
|
||||||
|
|
||||||
|
* libelf.h (struct elf_obj_tdata and associated macros): Moved
|
||||||
|
here from elfcode.h. A couple of size-specific structure pointers
|
||||||
|
were changed to PTR; uses fixed appropriately.
|
||||||
|
(elf32_symbol_type, elf64_symbol_type): Separated definitions.
|
||||||
|
(bfd_elf_mkobject): Renamed from bfd_elf32_mkobject.
|
||||||
|
(bfd_elf32_mkobject, bfd_elf64_mkobject, elf_mkobject): New
|
||||||
|
temporary macros to ease name change.
|
||||||
|
* elf.c (elf_read, elf_mkobject, elf_get_str_section,
|
||||||
|
elf_string_from_elf_section, bfd_elf_find_section): Moved here
|
||||||
|
from elfcode.h.
|
||||||
|
* doc/Makefile.in (libbfd.h): Process elf.c too.
|
||||||
|
* Makefile.in (elf.o): Note new dependencies.
|
||||||
|
|
||||||
|
* elfcode.h: Lots of stuff moved elsewhere. Deleted some unused
|
||||||
|
code, tweaked some debug hooks.
|
||||||
|
(elf_slurp_reloca_table): Translate ELF section symbols into BFD
|
||||||
|
section symbols.
|
||||||
|
|
||||||
Wed Jun 23 11:34:21 1993 Jim Kingdon (kingdon@cygnus.com)
|
Wed Jun 23 11:34:21 1993 Jim Kingdon (kingdon@cygnus.com)
|
||||||
|
|
||||||
* hosts/riscos.h: New file.
|
* hosts/riscos.h: New file.
|
||||||
|
105
bfd/aoutx.h
105
bfd/aoutx.h
@ -156,6 +156,9 @@ DESCRIPTION
|
|||||||
|
|
||||||
reloc_howto_type howto_table_ext[] =
|
reloc_howto_type howto_table_ext[] =
|
||||||
{
|
{
|
||||||
|
/* type rightshift size bitsize pc_ bit absol compl spec name partial_ src_ dst_ pcrel_
|
||||||
|
rela pos ute ain_on ial_ inplace mask mask offset
|
||||||
|
tive _overf fn */
|
||||||
HOWTO(RELOC_8, 0, 0, 8, false, 0, true, true,0,"8", false, 0,0x000000ff, false),
|
HOWTO(RELOC_8, 0, 0, 8, false, 0, true, true,0,"8", false, 0,0x000000ff, false),
|
||||||
HOWTO(RELOC_16, 0, 1, 16, false, 0, true, true,0,"16", false, 0,0x0000ffff, false),
|
HOWTO(RELOC_16, 0, 1, 16, false, 0, true, true,0,"16", false, 0,0x0000ffff, false),
|
||||||
HOWTO(RELOC_32, 0, 2, 32, false, 0, true, true,0,"32", false, 0,0xffffffff, false),
|
HOWTO(RELOC_32, 0, 2, 32, false, 0, true, true,0,"32", false, 0,0xffffffff, false),
|
||||||
@ -1247,18 +1250,19 @@ DEFUN(translate_to_native_sym_flags,(sym_pointer, cache_ptr, abfd),
|
|||||||
sym_pointer->e_type[0] &= ~N_TYPE;
|
sym_pointer->e_type[0] &= ~N_TYPE;
|
||||||
|
|
||||||
|
|
||||||
if (bfd_get_output_section(cache_ptr) == obj_bsssec (abfd)) {
|
/* We attempt to order these tests by decreasing frequency of success,
|
||||||
sym_pointer->e_type[0] |= N_BSS;
|
according to tcov when linking the linker. */
|
||||||
}
|
if (bfd_get_output_section(cache_ptr) == &bfd_abs_section) {
|
||||||
else if (bfd_get_output_section(cache_ptr) == obj_datasec (abfd)) {
|
sym_pointer->e_type[0] |= N_ABS;
|
||||||
sym_pointer->e_type[0] |= N_DATA;
|
|
||||||
}
|
}
|
||||||
else if (bfd_get_output_section(cache_ptr) == obj_textsec (abfd)) {
|
else if (bfd_get_output_section(cache_ptr) == obj_textsec (abfd)) {
|
||||||
sym_pointer->e_type[0] |= N_TEXT;
|
sym_pointer->e_type[0] |= N_TEXT;
|
||||||
}
|
}
|
||||||
else if (bfd_get_output_section(cache_ptr) == &bfd_abs_section)
|
else if (bfd_get_output_section(cache_ptr) == obj_datasec (abfd)) {
|
||||||
{
|
sym_pointer->e_type[0] |= N_DATA;
|
||||||
sym_pointer->e_type[0] |= N_ABS;
|
}
|
||||||
|
else if (bfd_get_output_section(cache_ptr) == obj_bsssec (abfd)) {
|
||||||
|
sym_pointer->e_type[0] |= N_BSS;
|
||||||
}
|
}
|
||||||
else if (bfd_get_output_section(cache_ptr) == &bfd_und_section)
|
else if (bfd_get_output_section(cache_ptr) == &bfd_und_section)
|
||||||
{
|
{
|
||||||
@ -1295,12 +1299,12 @@ DEFUN(translate_to_native_sym_flags,(sym_pointer, cache_ptr, abfd),
|
|||||||
(sym_pointer+1)->e_type[0] = 1;
|
(sym_pointer+1)->e_type[0] = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (cache_ptr->flags & (BSF_GLOBAL | BSF_EXPORT)) {
|
|
||||||
sym_pointer->e_type[0] |= N_EXT;
|
|
||||||
}
|
|
||||||
if (cache_ptr->flags & BSF_DEBUGGING) {
|
if (cache_ptr->flags & BSF_DEBUGGING) {
|
||||||
sym_pointer->e_type[0] = ((aout_symbol_type *)cache_ptr)->type;
|
sym_pointer->e_type[0] = ((aout_symbol_type *)cache_ptr)->type;
|
||||||
}
|
}
|
||||||
|
else if (cache_ptr->flags & (BSF_GLOBAL | BSF_EXPORT)) {
|
||||||
|
sym_pointer->e_type[0] |= N_EXT;
|
||||||
|
}
|
||||||
if (cache_ptr->flags & BSF_CONSTRUCTOR) {
|
if (cache_ptr->flags & BSF_CONSTRUCTOR) {
|
||||||
int type = ((aout_symbol_type *)cache_ptr)->type;
|
int type = ((aout_symbol_type *)cache_ptr)->type;
|
||||||
switch (type)
|
switch (type)
|
||||||
@ -1451,7 +1455,7 @@ DEFUN(NAME(aout,slurp_symbol_table),(abfd),
|
|||||||
struct stringtab_entry {
|
struct stringtab_entry {
|
||||||
/* Hash value for this string. Only useful so long as we aren't doing
|
/* Hash value for this string. Only useful so long as we aren't doing
|
||||||
substring matches. */
|
substring matches. */
|
||||||
int hash;
|
unsigned int hash;
|
||||||
|
|
||||||
/* Next node to look at, depending on whether the hash value of the string
|
/* Next node to look at, depending on whether the hash value of the string
|
||||||
being searched for is less than or greater than the hash value of the
|
being searched for is less than or greater than the hash value of the
|
||||||
@ -1535,23 +1539,28 @@ struct stringtab_data {
|
|||||||
|
|
||||||
/* Some utility functions for the string table code. */
|
/* Some utility functions for the string table code. */
|
||||||
|
|
||||||
static INLINE int
|
/* For speed, only hash on the first this many bytes of strings.
|
||||||
hash (string)
|
This number was chosen by profiling ld linking itself, with -g. */
|
||||||
char *string;
|
#define HASHMAXLEN 25
|
||||||
|
|
||||||
|
#define HASH_CHAR(c) (sum ^= sum >> 20, sum ^= sum << 7, sum += (c))
|
||||||
|
|
||||||
|
static INLINE unsigned int
|
||||||
|
hash (string, len)
|
||||||
|
unsigned char *string;
|
||||||
|
register unsigned int len;
|
||||||
{
|
{
|
||||||
unsigned int sum = 0;
|
register unsigned int sum = 0;
|
||||||
while (*string)
|
|
||||||
|
if (len > HASHMAXLEN)
|
||||||
{
|
{
|
||||||
#if 0
|
HASH_CHAR (len);
|
||||||
/* This expression borrowed from some code in gnu make. */
|
len = HASHMAXLEN;
|
||||||
sum += *string++, sum = (sum << 7) + (sum >> 20);
|
}
|
||||||
#endif
|
|
||||||
/* This appears to get a better distribution, at least for my one
|
while (len--)
|
||||||
test case. Do some analysis on this later, get a real hash
|
{
|
||||||
algorithm. */
|
HASH_CHAR (*string++);
|
||||||
sum ^= sum >> 20;
|
|
||||||
sum ^= sum << 7;
|
|
||||||
sum += *string++;
|
|
||||||
}
|
}
|
||||||
return sum;
|
return sum;
|
||||||
}
|
}
|
||||||
@ -1581,15 +1590,9 @@ static INLINE int
|
|||||||
compare (entry, str, hash)
|
compare (entry, str, hash)
|
||||||
struct stringtab_entry *entry;
|
struct stringtab_entry *entry;
|
||||||
CONST char *str;
|
CONST char *str;
|
||||||
int hash;
|
unsigned int hash;
|
||||||
{
|
{
|
||||||
if (hash == entry->hash)
|
return hash - entry->hash;
|
||||||
return 0;
|
|
||||||
if (hash > entry->hash)
|
|
||||||
return 1;
|
|
||||||
if (hash < entry->hash)
|
|
||||||
return -1;
|
|
||||||
abort ();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef GATHER_STATISTICS
|
#ifdef GATHER_STATISTICS
|
||||||
@ -1623,8 +1626,8 @@ add_to_stringtab (abfd, str, tab, check)
|
|||||||
int check;
|
int check;
|
||||||
{
|
{
|
||||||
struct stringtab_entry **ep;
|
struct stringtab_entry **ep;
|
||||||
struct stringtab_entry *entry;
|
register struct stringtab_entry *entry;
|
||||||
int hashval, len;
|
unsigned int hashval, len;
|
||||||
|
|
||||||
if (str[0] == 0)
|
if (str[0] == 0)
|
||||||
{
|
{
|
||||||
@ -1662,7 +1665,7 @@ add_to_stringtab (abfd, str, tab, check)
|
|||||||
zero. With a balanced tree, this wouldn't be very useful, but without it,
|
zero. With a balanced tree, this wouldn't be very useful, but without it,
|
||||||
we might get a more even split at the top level, instead of skewing it
|
we might get a more even split at the top level, instead of skewing it
|
||||||
badly should hash("/usr/lib/crt0.o") (or whatever) be far from zero. */
|
badly should hash("/usr/lib/crt0.o") (or whatever) be far from zero. */
|
||||||
hashval = hash (str) ^ tab->hash_zero;
|
hashval = hash (str, len) ^ tab->hash_zero;
|
||||||
ep = &tab->strings;
|
ep = &tab->strings;
|
||||||
if (!*ep)
|
if (!*ep)
|
||||||
{
|
{
|
||||||
@ -1673,13 +1676,19 @@ add_to_stringtab (abfd, str, tab, check)
|
|||||||
|
|
||||||
while (*ep)
|
while (*ep)
|
||||||
{
|
{
|
||||||
int cmp;
|
register int cmp;
|
||||||
|
|
||||||
entry = *ep;
|
entry = *ep;
|
||||||
#ifdef GATHER_STATISTICS
|
#ifdef GATHER_STATISTICS
|
||||||
tab->n_compares++;
|
tab->n_compares++;
|
||||||
#endif
|
#endif
|
||||||
cmp = compare (entry, str, hashval);
|
cmp = compare (entry, str, hashval);
|
||||||
if (cmp == 0)
|
/* The not-equal cases are more frequent, so check them first. */
|
||||||
|
if (cmp > 0)
|
||||||
|
ep = &entry->greater;
|
||||||
|
else if (cmp < 0)
|
||||||
|
ep = &entry->less;
|
||||||
|
else
|
||||||
{
|
{
|
||||||
if (entry->string == str)
|
if (entry->string == str)
|
||||||
{
|
{
|
||||||
@ -1688,7 +1697,9 @@ add_to_stringtab (abfd, str, tab, check)
|
|||||||
#endif
|
#endif
|
||||||
goto match;
|
goto match;
|
||||||
}
|
}
|
||||||
if (!strcmp (entry->string, str))
|
/* Compare the first bytes to save a function call if they
|
||||||
|
don't match. */
|
||||||
|
if (entry->string[0] == str[0] && !strcmp (entry->string, str))
|
||||||
{
|
{
|
||||||
match:
|
match:
|
||||||
#ifdef GATHER_STATISTICS
|
#ifdef GATHER_STATISTICS
|
||||||
@ -1710,19 +1721,14 @@ add_to_stringtab (abfd, str, tab, check)
|
|||||||
#endif
|
#endif
|
||||||
ep = &entry->greater;
|
ep = &entry->greater;
|
||||||
}
|
}
|
||||||
else if (cmp > 0)
|
|
||||||
ep = &entry->greater;
|
|
||||||
else
|
|
||||||
/* cmp < 0 */
|
|
||||||
ep = &entry->less;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* If we get here, nothing that's in the table already matched.
|
/* If we get here, nothing that's in the table already matched.
|
||||||
EP points to the `next' field at the end of the chain; stick a
|
EP points to the `next' field at the end of the chain; stick a
|
||||||
new entry on here. */
|
new entry on here. */
|
||||||
add_it:
|
add_it:
|
||||||
entry = (struct stringtab_entry *) bfd_alloc_by_size_t (abfd,
|
entry = (struct stringtab_entry *)
|
||||||
sizeof (struct stringtab_entry));
|
bfd_alloc_by_size_t (abfd, sizeof (struct stringtab_entry));
|
||||||
|
|
||||||
entry->less = entry->greater = 0;
|
entry->less = entry->greater = 0;
|
||||||
entry->hash = hashval;
|
entry->hash = hashval;
|
||||||
@ -1794,7 +1800,8 @@ emit_strtab (abfd, tab)
|
|||||||
double n_compares = tab->n_compares;
|
double n_compares = tab->n_compares;
|
||||||
double avg_compares = n_compares / n_syms;
|
double avg_compares = n_compares / n_syms;
|
||||||
/* The second value here should usually be near one. */
|
/* The second value here should usually be near one. */
|
||||||
fprintf (stderr, "\t average %f per symbol (%f * log2 nstrings)\n",
|
fprintf (stderr,
|
||||||
|
"\t average %f comparisons per symbol (%f * log2 nstrings)\n",
|
||||||
avg_compares, avg_compares / log2 (count));
|
avg_compares, avg_compares / log2 (count));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user