diff -u -r -x texis -x Makeconfig -x version.h -x '*.o' -x '*.1' -x 'Makefile*' -x 'config*' -x libtool -x '*.info' -x '*.tex' binutils-2.16.91.0.4/bfd/elf.c binutils.current/bfd/elf.c --- binutils-2.16.91.0.4/bfd/elf.c 2005-12-22 10:42:52.000000000 +0000 +++ binutils.current/bfd/elf.c 2006-01-20 14:35:28.000000000 +0000 @@ -1212,6 +1212,7 @@ case DT_AUXILIARY: name = "AUXILIARY"; stringp = TRUE; break; case DT_USED: name = "USED"; break; case DT_FILTER: name = "FILTER"; stringp = TRUE; break; + case DT_SUSE_HASHVALS: name = "SUSE_HASHVALS"; break; } fprintf (f, " %-11s ", name); diff -u -r -x texis -x Makeconfig -x version.h -x '*.o' -x '*.1' -x 'Makefile*' -x 'config*' -x libtool -x '*.info' -x '*.tex' binutils-2.16.91.0.4/bfd/elflink.c binutils.current/bfd/elflink.c --- binutils-2.16.91.0.4/bfd/elflink.c 2005-12-22 10:42:52.000000000 +0000 +++ binutils.current/bfd/elflink.c 2006-01-20 15:03:00.000000000 +0000 @@ -174,6 +174,15 @@ flags = bed->dynamic_sec_flags; + if (info->hashvals) + { + s = bfd_make_section (abfd, ".suse.hashvals"); + if (s == NULL + || ! bfd_set_section_flags (abfd, s, flags | SEC_READONLY) + || ! bfd_set_section_alignment (abfd, s, 2)) + return FALSE; + } + /* A dynamically linked executable has a .interp section, but a shared library does not. */ if (info->executable) @@ -5728,6 +5737,24 @@ memset (s->contents, 0, section_sym_count * bed->s->sizeof_sym); } + /* Create the direct bindings section - 1 entry per dynsym */ + s = bfd_get_section_by_name (dynobj, ".suse.hashvals"); + if (s) + { + if (dynsymcount == 0) + s->flags |= SEC_EXCLUDE; + else + { + s->size = dynsymcount * bed->s->sizeof_hash_entry; + s->contents = bfd_zalloc (output_bfd, s->size); + if (s->contents == NULL) + return FALSE; + memset (s->contents, 0xfe, s->size); + if (!_bfd_elf_add_dynamic_entry (info, DT_SUSE_HASHVALS, 0)) + return FALSE; + } + } + /* Compute the size of the hashing table. As a side effect this computes the hash values for all the names we export. */ bucketcount = compute_bucket_count (info); @@ -5799,6 +5828,8 @@ /* Array large enough to hold a section pointer for each local symbol of any input BFD. */ asection **sections; + /* .suse.hashvals section */ + asection *hashvals_sec; /* Buffer to hold swapped out symbols. */ bfd_byte *symbuf; /* And one for symbol section indices. */ @@ -6614,6 +6645,18 @@ ((bfd_byte *) finfo->hash_sec->contents + (bucketcount + 2 + h->dynindx) * hash_entry_size)); + if (finfo->hashvals_sec) + { + bfd_vma offset = hash_entry_size * h->dynindx; + if (offset > finfo->hashvals_sec->size) + fprintf (stderr, "Out of bounds hashvals section index %d size %d\n", + (int) offset, (int) finfo->hashvals_sec->size); + else + bfd_put (8 * hash_entry_size, finfo->output_bfd, + h->u.elf_hash_value, + finfo->hashvals_sec->contents + offset); + } + if (finfo->symver_sec != NULL && finfo->symver_sec->contents != NULL) { Elf_Internal_Versym iversym; @@ -7786,6 +7829,7 @@ finfo.dynsym_sec = NULL; finfo.hash_sec = NULL; finfo.symver_sec = NULL; + finfo.hashvals_sec = NULL; } else { @@ -7794,6 +7838,7 @@ BFD_ASSERT (finfo.dynsym_sec != NULL && finfo.hash_sec != NULL); finfo.symver_sec = bfd_get_section_by_name (dynobj, ".gnu.version"); /* Note that it is OK if symver_sec is NULL. */ + finfo.hashvals_sec = bfd_get_section_by_name (dynobj, ".suse.hashvals"); } finfo.contents = NULL; @@ -8533,6 +8578,9 @@ case DT_HASH: name = ".hash"; goto get_vma; + case DT_SUSE_HASHVALS: + name = ".suse.hashvals"; + goto get_vma; case DT_STRTAB: name = ".dynstr"; goto get_vma; diff -u -r -x texis -x Makeconfig -x version.h -x '*.o' -x '*.1' -x 'Makefile*' -x 'config*' -x libtool -x '*.info' -x '*.tex' binutils-2.16.91.0.4/include/bfdlink.h binutils.current/include/bfdlink.h --- binutils-2.16.91.0.4/include/bfdlink.h 2005-12-22 10:42:52.000000000 +0000 +++ binutils.current/include/bfdlink.h 2006-01-20 14:19:46.000000000 +0000 @@ -261,6 +261,10 @@ need much more time and therefore must be explicitly selected. */ unsigned int optimize: 1; + /* TRUE if we want to produced a section containing pre-computed + hash values. This consumes more space. */ + unsigned int hashvals: 1; + /* TRUE if ok to have multiple definition. */ unsigned int allow_multiple_definition: 1; diff -u -r -x texis -x Makeconfig -x version.h -x '*.o' -x '*.1' -x 'Makefile*' -x 'config*' -x libtool -x '*.info' -x '*.tex' binutils-2.16.91.0.4/include/elf/common.h binutils.current/include/elf/common.h --- binutils-2.16.91.0.4/include/elf/common.h 2005-12-22 10:42:52.000000000 +0000 +++ binutils.current/include/elf/common.h 2006-01-20 14:34:18.000000000 +0000 @@ -604,6 +604,12 @@ #define DT_FILTER 0x7fffffff +/* Selected at random */ +#define DT_SUSE_LO 0x6cbdd030 +#define DT_SUSE_HASHVALS DT_SUSE_LO +#define DT_SUSE_DIRECT DT_SUSE_LO + 1 +#define DT_SUSE_HI 0x6cbdd040 + /* Values used in DT_FEATURE .dynamic entry. */ #define DTF_1_PARINIT 0x00000001 /* From Files binutils-2.16.91.0.4/ld/ld-new and binutils.current/ld/ld-new differ diff -u -r -x texis -x Makeconfig -x version.h -x '*.o' -x '*.1' -x 'Makefile*' -x 'config*' -x libtool -x '*.info' -x '*.tex' binutils-2.16.91.0.4/ld/lexsup.c binutils.current/ld/lexsup.c --- binutils-2.16.91.0.4/ld/lexsup.c 2005-12-22 10:42:52.000000000 +0000 +++ binutils.current/ld/lexsup.c 2006-01-20 14:31:21.000000000 +0000 @@ -78,6 +78,7 @@ OPTION_EL, OPTION_EMBEDDED_RELOCS, OPTION_EXPORT_DYNAMIC, + OPTION_HASHVALS, OPTION_HELP, OPTION_IGNORE, OPTION_MAP, @@ -341,6 +342,8 @@ '\0', NULL, NULL, ONE_DASH }, { {"static", no_argument, NULL, OPTION_NON_SHARED}, '\0', NULL, NULL, ONE_DASH }, + { {"hashvals", no_argument, NULL, OPTION_HASHVALS}, + '\0', NULL, N_("Store pre-computed elf hash codes"), ONE_DASH }, { {"Bsymbolic", no_argument, NULL, OPTION_SYMBOLIC}, '\0', NULL, N_("Bind global references locally"), ONE_DASH }, { {"check-sections", no_argument, NULL, OPTION_CHECK_SECTIONS}, @@ -1111,6 +1114,9 @@ case OPTION_SYMBOLIC: link_info.symbolic = TRUE; break; + case OPTION_HASHVALS: + link_info.hashvals = TRUE; + break; case 't': trace_files = TRUE; break;