From: Jakub Bogusz Date: Wed, 20 Dec 2006 23:10:40 +0000 (+0000) Subject: - obsolete X-Git-Tag: auto/th/gdb-6_6-1~1 X-Git-Url: https://git.pld-linux.org/?a=commitdiff_plain;h=7e5145fef29a5c4da684c891690497161dc01e7b;p=packages%2Fgdb.git - obsolete Changed files: gdb-gnu_hash.patch -> 1.2 --- diff --git a/gdb-gnu_hash.patch b/gdb-gnu_hash.patch deleted file mode 100644 index d782118..0000000 --- a/gdb-gnu_hash.patch +++ /dev/null @@ -1,880 +0,0 @@ -2006-07-10 Jakub Jelinek - -include/ - * bfdlink.h (struct bfd_link_info): Add emit_hash and - emit_gnu_hash bitfields. -include/elf/ - * common.h (SHT_GNU_HASH, DT_GNU_HASH): Define. -bfd/ - * elf.c (_bfd_elf_print_private_bfd_data): Handle DT_GNU_HASH. - (bfd_section_from_shdr, elf_fake_sections, assign_section_numbers): - Handle SHT_GNU_HASH. - (special_sections_g): Include .gnu.hash section. - (bfd_elf_gnu_hash): New function. - * elf-bfd.h (bfd_elf_gnu_hash, _bfd_elf_hash_symbol): New prototypes. - (struct elf_backend_data): Add elf_hash_symbol method. - * elflink.c (_bfd_elf_link_create_dynamic_sections): Create .hash - only if info->emit_hash, create .gnu.hash section if - info->emit_gnu_hash. - (struct collect_gnu_hash_codes): New type. - (elf_collect_gnu_hash_codes, elf_renumber_gnu_hash_syms, - _bfd_elf_hash_symbol): New functions. - (compute_bucket_count): Don't compute HASHCODES array, instead add - that and NSYMS as arguments. Use bed->s->sizeof_hash_entry - instead of bed->s->arch_size / 8. Fix .hash size estimation. - When not optimizing, use the number of hashed symbols rather than - dynsymcount. - (bfd_elf_size_dynamic_sections): Only add DT_HASH if info->emit_hash, - and ADD DT_GNU_HASH if info->emit_gnu_hash. - (bfd_elf_size_dynsym_hash_dynstr): Size .hash only if info->emit_hash, - adjust compute_bucket_count caller. Create and populate .gnu.hash - section if info->emit_gnu_hash. - (elf_link_output_extsym): Only populate .hash section if - finfo->hash_sec != NULL. - (bfd_elf_final_link): Adjust assertion. Handle DT_GNU_HASH. - * elfxx-target.h (elf_backend_hash_symbol): Define if not yet defined. - (elfNN_bed): Add elf_backend_hash_symbol. - * elf64-x86-64.c (elf64_x86_64_hash_symbol): New function. - (elf_backend_hash_symbol): Define. - * elf32-i386.c (elf_i386_hash_symbol): New function. - (elf_backend_hash_symbol): Define. - -Index: gdb-6.5/bfd/elf-bfd.h -=================================================================== ---- gdb-6.5.orig/bfd/elf-bfd.h 2006-07-14 01:30:51.000000000 -0300 -+++ gdb-6.5/bfd/elf-bfd.h 2006-07-14 01:31:25.000000000 -0300 -@@ -1022,6 +1022,9 @@ struct elf_backend_data - bfd_boolean *, bfd_boolean *, - bfd *, asection **); - -+ /* Return TRUE if symbol should be hashed in the `.gnu.hash' section. */ -+ bfd_boolean (*elf_hash_symbol) (struct elf_link_hash_entry *); -+ - /* Used to handle bad SHF_LINK_ORDER input. */ - bfd_error_handler_type link_order_error_handler; - -@@ -1462,6 +1465,8 @@ extern bfd_vma _bfd_elf_section_offset - - extern unsigned long bfd_elf_hash - (const char *); -+extern unsigned long bfd_elf_gnu_hash -+ (const char *); - - extern bfd_reloc_status_type bfd_elf_generic_reloc - (bfd *, arelent *, asymbol *, void *, asection *, bfd *, char **); -@@ -1632,6 +1637,8 @@ extern bfd_boolean _bfd_elf_merge_symbol - struct elf_link_hash_entry **, bfd_boolean *, - bfd_boolean *, bfd_boolean *, bfd_boolean *); - -+extern bfd_boolean _bfd_elf_hash_symbol (struct elf_link_hash_entry *); -+ - extern bfd_boolean _bfd_elf_add_default_symbol - (bfd *, struct bfd_link_info *, struct elf_link_hash_entry *, - const char *, Elf_Internal_Sym *, asection **, bfd_vma *, -Index: gdb-6.5/bfd/elf64-x86-64.c -=================================================================== ---- gdb-6.5.orig/bfd/elf64-x86-64.c 2006-07-14 01:30:51.000000000 -0300 -+++ gdb-6.5/bfd/elf64-x86-64.c 2006-07-14 01:31:26.000000000 -0300 -@@ -3614,6 +3614,19 @@ elf64_x86_64_additional_program_headers - return count; - } - -+/* Return TRUE if symbol should be hashed in the `.gnu.hash' section. */ -+ -+static bfd_boolean -+elf64_x86_64_hash_symbol (struct elf_link_hash_entry *h) -+{ -+ if (h->plt.offset != (bfd_vma) -1 -+ && !h->def_regular -+ && !h->pointer_equality_needed) -+ return FALSE; -+ -+ return _bfd_elf_hash_symbol (h); -+} -+ - static const struct bfd_elf_special_section - elf64_x86_64_special_sections[]= - { -@@ -3685,5 +3698,7 @@ static const struct bfd_elf_special_sect - elf64_x86_64_special_sections - #define elf_backend_additional_program_headers \ - elf64_x86_64_additional_program_headers -+#define elf_backend_hash_symbol \ -+ elf64_x86_64_hash_symbol - - #include "elf64-target.h" -Index: gdb-6.5/bfd/elf.c -=================================================================== ---- gdb-6.5.orig/bfd/elf.c 2006-07-14 01:30:51.000000000 -0300 -+++ gdb-6.5/bfd/elf.c 2006-07-14 01:31:26.000000000 -0300 -@@ -206,6 +206,21 @@ bfd_elf_hash (const char *namearg) - return h & 0xffffffff; - } - -+/* DT_GNU_HASH hash function. Do not change this function; you will -+ cause invalid hash tables to be generated. */ -+ -+unsigned long -+bfd_elf_gnu_hash (const char *namearg) -+{ -+ const unsigned char *name = (const unsigned char *) namearg; -+ unsigned long h = 5381; -+ unsigned char ch; -+ -+ while ((ch = *name++) != '\0') -+ h = (h << 5) + h + ch; -+ return h & 0xffffffff; -+} -+ - bfd_boolean - bfd_elf_mkobject (bfd *abfd) - { -@@ -1239,6 +1254,7 @@ _bfd_elf_print_private_bfd_data (bfd *ab - case DT_AUXILIARY: name = "AUXILIARY"; stringp = TRUE; break; - case DT_USED: name = "USED"; break; - case DT_FILTER: name = "FILTER"; stringp = TRUE; break; -+ case DT_GNU_HASH: name = "GNU_HASH"; break; - } - - fprintf (f, " %-11s ", name); -@@ -1822,6 +1838,7 @@ bfd_section_from_shdr (bfd *abfd, unsign - case SHT_FINI_ARRAY: /* .fini_array section. */ - case SHT_PREINIT_ARRAY: /* .preinit_array section. */ - case SHT_GNU_LIBLIST: /* .gnu.liblist section. */ -+ case SHT_GNU_HASH: /* .gnu.hash section. */ - return _bfd_elf_make_section_from_shdr (abfd, hdr, name, shindex); - - case SHT_DYNAMIC: /* Dynamic linking information. */ -@@ -2294,6 +2311,7 @@ static const struct bfd_elf_special_sect - { ".gnu.version_r", 14, 0, SHT_GNU_verneed, 0 }, - { ".gnu.liblist", 12, 0, SHT_GNU_LIBLIST, SHF_ALLOC }, - { ".gnu.conflict", 13, 0, SHT_RELA, SHF_ALLOC }, -+ { ".gnu.hash", 9, 0, SHT_GNU_HASH, SHF_ALLOC }, - { NULL, 0, 0, 0, 0 } - }; - -@@ -2810,6 +2828,10 @@ elf_fake_sections (bfd *abfd, asection * - case SHT_GROUP: - this_hdr->sh_entsize = 4; - break; -+ -+ case SHT_GNU_HASH: -+ this_hdr->sh_entsize = bed->s->arch_size == 64 ? 0 : 4; -+ break; - } - - if ((asect->flags & SEC_ALLOC) != 0) -@@ -3255,6 +3277,7 @@ assign_section_numbers (bfd *abfd, struc - break; - - case SHT_HASH: -+ case SHT_GNU_HASH: - case SHT_GNU_versym: - /* sh_link is the section header index of the symbol table - this hash table or version table is for. */ -Index: gdb-6.5/bfd/elf32-i386.c -=================================================================== ---- gdb-6.5.orig/bfd/elf32-i386.c 2006-07-14 01:30:51.000000000 -0300 -+++ gdb-6.5/bfd/elf32-i386.c 2006-07-14 01:31:26.000000000 -0300 -@@ -3872,6 +3872,18 @@ elf_i386_plt_sym_val (bfd_vma i, const a - return plt->vma + (i + 1) * PLT_ENTRY_SIZE; - } - -+/* Return TRUE if symbol should be hashed in the `.gnu.hash' section. */ -+ -+static bfd_boolean -+elf_i386_hash_symbol (struct elf_link_hash_entry *h) -+{ -+ if (h->plt.offset != (bfd_vma) -1 -+ && !h->def_regular -+ && !h->pointer_equality_needed) -+ return FALSE; -+ -+ return _bfd_elf_hash_symbol (h); -+} - - #define TARGET_LITTLE_SYM bfd_elf32_i386_vec - #define TARGET_LITTLE_NAME "elf32-i386" -@@ -3912,6 +3924,7 @@ elf_i386_plt_sym_val (bfd_vma i, const a - #define elf_backend_size_dynamic_sections elf_i386_size_dynamic_sections - #define elf_backend_always_size_sections elf_i386_always_size_sections - #define elf_backend_plt_sym_val elf_i386_plt_sym_val -+#define elf_backend_hash_symbol elf_i386_hash_symbol - - #include "elf32-target.h" - -Index: gdb-6.5/bfd/elflink.c -=================================================================== ---- gdb-6.5.orig/bfd/elflink.c 2006-07-14 01:30:51.000000000 -0300 -+++ gdb-6.5/bfd/elflink.c 2006-07-14 01:31:26.000000000 -0300 -@@ -240,12 +240,30 @@ _bfd_elf_link_create_dynamic_sections (b - if (!_bfd_elf_define_linkage_sym (abfd, info, s, "_DYNAMIC")) - return FALSE; - -- s = bfd_make_section_with_flags (abfd, ".hash", -- flags | SEC_READONLY); -- if (s == NULL -- || ! bfd_set_section_alignment (abfd, s, bed->s->log_file_align)) -- return FALSE; -- elf_section_data (s)->this_hdr.sh_entsize = bed->s->sizeof_hash_entry; -+ if (info->emit_hash) -+ { -+ s = bfd_make_section_with_flags (abfd, ".hash", flags | SEC_READONLY); -+ if (s == NULL -+ || ! bfd_set_section_alignment (abfd, s, bed->s->log_file_align)) -+ return FALSE; -+ elf_section_data (s)->this_hdr.sh_entsize = bed->s->sizeof_hash_entry; -+ } -+ -+ if (info->emit_gnu_hash) -+ { -+ s = bfd_make_section_with_flags (abfd, ".gnu.hash", -+ flags | SEC_READONLY); -+ if (s == NULL -+ || ! bfd_set_section_alignment (abfd, s, bed->s->log_file_align)) -+ return FALSE; -+ /* For 64-bit ELF, .gnu.hash is a non-uniform entity size section: -+ 4 32-bit words followed by variable count of 64-bit words, then -+ variable count of 32-bit words. */ -+ if (bed->s->arch_size == 64) -+ elf_section_data (s)->this_hdr.sh_entsize = 0; -+ else -+ elf_section_data (s)->this_hdr.sh_entsize = 4; -+ } - - /* Let the backend create the rest of the sections. This lets the - backend set the right flags. The backend will normally create -@@ -4795,6 +4813,131 @@ elf_collect_hash_codes (struct elf_link_ - return TRUE; - } - -+struct collect_gnu_hash_codes -+{ -+ bfd *output_bfd; -+ const struct elf_backend_data *bed; -+ unsigned long int nsyms; -+ unsigned long int maskbits; -+ unsigned long int *hashcodes; -+ unsigned long int *hashval; -+ unsigned long int *indx; -+ unsigned long int *counts; -+ bfd_vma *bitmask; -+ bfd_byte *contents; -+ long int min_dynindx; -+ unsigned long int bucketcount; -+ unsigned long int symindx; -+ long int local_indx; -+ long int shift1, shift2; -+ unsigned long int mask; -+}; -+ -+/* This function will be called though elf_link_hash_traverse to store -+ all hash value of the exported symbols in an array. */ -+ -+static bfd_boolean -+elf_collect_gnu_hash_codes (struct elf_link_hash_entry *h, void *data) -+{ -+ struct collect_gnu_hash_codes *s = data; -+ const char *name; -+ char *p; -+ unsigned long ha; -+ char *alc = NULL; -+ -+ if (h->root.type == bfd_link_hash_warning) -+ h = (struct elf_link_hash_entry *) h->root.u.i.link; -+ -+ /* Ignore indirect symbols. These are added by the versioning code. */ -+ if (h->dynindx == -1) -+ return TRUE; -+ -+ /* Ignore also local symbols and undefined symbols. */ -+ if (! (*s->bed->elf_hash_symbol) (h)) -+ return TRUE; -+ -+ name = h->root.root.string; -+ p = strchr (name, ELF_VER_CHR); -+ if (p != NULL) -+ { -+ alc = bfd_malloc (p - name + 1); -+ memcpy (alc, name, p - name); -+ alc[p - name] = '\0'; -+ name = alc; -+ } -+ -+ /* Compute the hash value. */ -+ ha = bfd_elf_gnu_hash (name); -+ -+ /* Store the found hash value in the array for compute_bucket_count, -+ and also for .dynsym reordering purposes. */ -+ s->hashcodes[s->nsyms] = ha; -+ s->hashval[h->dynindx] = ha; -+ ++s->nsyms; -+ if (s->min_dynindx < 0 || s->min_dynindx > h->dynindx) -+ s->min_dynindx = h->dynindx; -+ -+ if (alc != NULL) -+ free (alc); -+ -+ return TRUE; -+} -+ -+/* This function will be called though elf_link_hash_traverse to do -+ final dynaminc symbol renumbering. */ -+ -+static bfd_boolean -+elf_renumber_gnu_hash_syms (struct elf_link_hash_entry *h, void *data) -+{ -+ struct collect_gnu_hash_codes *s = data; -+ unsigned long int bucket; -+ unsigned long int val; -+ -+ if (h->root.type == bfd_link_hash_warning) -+ h = (struct elf_link_hash_entry *) h->root.u.i.link; -+ -+ /* Ignore indirect symbols. */ -+ if (h->dynindx == -1) -+ return TRUE; -+ -+ /* Ignore also local symbols and undefined symbols. */ -+ if (! (*s->bed->elf_hash_symbol) (h)) -+ { -+ if (h->dynindx >= s->min_dynindx) -+ h->dynindx = s->local_indx++; -+ return TRUE; -+ } -+ -+ bucket = s->hashval[h->dynindx] % s->bucketcount; -+ val = (s->hashval[h->dynindx] >> s->shift1) -+ & ((s->maskbits >> s->shift1) - 1); -+ s->bitmask[val] |= ((bfd_vma) 1) << (s->hashval[h->dynindx] & s->mask); -+ s->bitmask[val] -+ |= ((bfd_vma) 1) << ((s->hashval[h->dynindx] >> s->shift2) & s->mask); -+ val = s->hashval[h->dynindx] & ~(unsigned long int) 1; -+ if (s->counts[bucket] == 1) -+ /* Last element terminates the chain. */ -+ val |= 1; -+ bfd_put_32 (s->output_bfd, val, -+ s->contents + (s->indx[bucket] - s->symindx) * 4); -+ --s->counts[bucket]; -+ h->dynindx = s->indx[bucket]++; -+ return TRUE; -+} -+ -+/* Return TRUE if symbol should be hashed in the `.gnu.hash' section. */ -+ -+bfd_boolean -+_bfd_elf_hash_symbol (struct elf_link_hash_entry *h) -+{ -+ return !(h->forced_local -+ || h->root.type == bfd_link_hash_undefined -+ || h->root.type == bfd_link_hash_undefweak -+ || ((h->root.type == bfd_link_hash_defined -+ || h->root.type == bfd_link_hash_defweak) -+ && h->root.u.def.section->output_section == NULL)); -+} -+ - /* Array used to determine the number of hash table buckets to use - based on the number of symbols there are. If there are fewer than - 3 symbols we use 1 bucket, fewer than 17 symbols we use 3 buckets, -@@ -4816,42 +4959,26 @@ static const size_t elf_buckets[] = - Therefore the result is always a good payoff between few collisions - (= short chain lengths) and table size. */ - static size_t --compute_bucket_count (struct bfd_link_info *info) -+compute_bucket_count (struct bfd_link_info *info, unsigned long int *hashcodes, -+ unsigned long int nsyms, int gnu_hash) - { - size_t dynsymcount = elf_hash_table (info)->dynsymcount; - size_t best_size = 0; -- unsigned long int *hashcodes; -- unsigned long int *hashcodesp; - unsigned long int i; - bfd_size_type amt; - -- /* Compute the hash values for all exported symbols. At the same -- time store the values in an array so that we could use them for -- optimizations. */ -- amt = dynsymcount; -- amt *= sizeof (unsigned long int); -- hashcodes = bfd_malloc (amt); -- if (hashcodes == NULL) -- return 0; -- hashcodesp = hashcodes; -- -- /* Put all hash values in HASHCODES. */ -- elf_link_hash_traverse (elf_hash_table (info), -- elf_collect_hash_codes, &hashcodesp); -- - /* We have a problem here. The following code to optimize the table - size requires an integer type with more the 32 bits. If - BFD_HOST_U_64_BIT is set we know about such a type. */ - #ifdef BFD_HOST_U_64_BIT - if (info->optimize) - { -- unsigned long int nsyms = hashcodesp - hashcodes; - size_t minsize; - size_t maxsize; - BFD_HOST_U_64_BIT best_chlen = ~((BFD_HOST_U_64_BIT) 0); -- unsigned long int *counts ; - bfd *dynobj = elf_hash_table (info)->dynobj; - const struct elf_backend_data *bed = get_elf_backend_data (dynobj); -+ unsigned long int *counts; - - /* Possible optimization parameters: if we have NSYMS symbols we say - that the hashing table must at least have NSYMS/4 and at most -@@ -4860,6 +4987,13 @@ compute_bucket_count (struct bfd_link_in - if (minsize == 0) - minsize = 1; - best_size = maxsize = nsyms * 2; -+ if (gnu_hash) -+ { -+ if (minsize < 2) -+ minsize = 2; -+ if ((best_size & 31) == 0) -+ ++best_size; -+ } - - /* Create array where we count the collisions in. We must use bfd_malloc - since the size could be large. */ -@@ -4867,10 +5001,7 @@ compute_bucket_count (struct bfd_link_in - amt *= sizeof (unsigned long int); - counts = bfd_malloc (amt); - if (counts == NULL) -- { -- free (hashcodes); -- return 0; -- } -+ return 0; - - /* Compute the "optimal" size for the hash table. The criteria is a - minimal chain length. The minor criteria is (of course) the size -@@ -4882,6 +5013,9 @@ compute_bucket_count (struct bfd_link_in - unsigned long int j; - unsigned long int fact; - -+ if (gnu_hash && (i & 31) == 0) -+ continue; -+ - memset (counts, '\0', i * sizeof (unsigned long int)); - - /* Determine how often each hash bucket is used. */ -@@ -4897,9 +5031,9 @@ compute_bucket_count (struct bfd_link_in - # define BFD_TARGET_PAGESIZE (4096) - # endif - -- /* We in any case need 2 + NSYMS entries for the size values and -- the chains. */ -- max = (2 + nsyms) * (bed->s->arch_size / 8); -+ /* We in any case need 2 + DYNSYMCOUNT entries for the size values -+ and the chains. */ -+ max = (2 + dynsymcount) * bed->s->sizeof_hash_entry; - - # if 1 - /* Variant 1: optimize for short chains. We add the squares -@@ -4909,7 +5043,7 @@ compute_bucket_count (struct bfd_link_in - max += counts[j] * counts[j]; - - /* This adds penalties for the overall size of the table. */ -- fact = i / (BFD_TARGET_PAGESIZE / (bed->s->arch_size / 8)) + 1; -+ fact = i / (BFD_TARGET_PAGESIZE / bed->s->sizeof_hash_entry) + 1; - max *= fact * fact; - # else - /* Variant 2: Optimize a lot more for small table. Here we -@@ -4920,7 +5054,7 @@ compute_bucket_count (struct bfd_link_in - - /* The overall size of the table is considered, but not as - strong as in variant 1, where it is squared. */ -- fact = i / (BFD_TARGET_PAGESIZE / (bed->s->arch_size / 8)) + 1; -+ fact = i / (BFD_TARGET_PAGESIZE / bed->s->sizeof_hash_entry) + 1; - max *= fact; - # endif - -@@ -4943,14 +5077,13 @@ compute_bucket_count (struct bfd_link_in - for (i = 0; elf_buckets[i] != 0; i++) - { - best_size = elf_buckets[i]; -- if (dynsymcount < elf_buckets[i + 1]) -+ if (nsyms < elf_buckets[i + 1]) - break; - } -+ if (gnu_hash && best_size < 2) -+ best_size = 2; - } - -- /* Free the arrays we needed. */ -- free (hashcodes); -- - return best_size; - } - -@@ -5308,7 +5441,10 @@ bfd_elf_size_dynamic_sections (bfd *outp - bfd_size_type strsize; - - strsize = _bfd_elf_strtab_size (elf_hash_table (info)->dynstr); -- if (!_bfd_elf_add_dynamic_entry (info, DT_HASH, 0) -+ if ((info->emit_hash -+ && !_bfd_elf_add_dynamic_entry (info, DT_HASH, 0)) -+ || (info->emit_gnu_hash -+ && !_bfd_elf_add_dynamic_entry (info, DT_GNU_HASH, 0)) - || !_bfd_elf_add_dynamic_entry (info, DT_STRTAB, 0) - || !_bfd_elf_add_dynamic_entry (info, DT_SYMTAB, 0) - || !_bfd_elf_add_dynamic_entry (info, DT_STRSZ, strsize) -@@ -5710,8 +5846,6 @@ bfd_elf_size_dynsym_hash_dynstr (bfd *ou - asection *s; - bfd_size_type dynsymcount; - unsigned long section_sym_count; -- size_t bucketcount = 0; -- size_t hash_entry_size; - unsigned int dtagcount; - - dynobj = elf_hash_table (info)->dynobj; -@@ -5762,23 +5896,215 @@ bfd_elf_size_dynsym_hash_dynstr (bfd *ou - memset (s->contents, 0, section_sym_count * bed->s->sizeof_sym); - } - -+ elf_hash_table (info)->bucketcount = 0; -+ - /* 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); -+ if (info->emit_hash) -+ { -+ unsigned long int *hashcodes; -+ unsigned long int *hashcodesp; -+ bfd_size_type amt; -+ unsigned long int nsyms; -+ size_t bucketcount; -+ size_t hash_entry_size; -+ -+ /* Compute the hash values for all exported symbols. At the same -+ time store the values in an array so that we could use them for -+ optimizations. */ -+ amt = dynsymcount * sizeof (unsigned long int); -+ hashcodes = bfd_malloc (amt); -+ if (hashcodes == NULL) -+ return FALSE; -+ hashcodesp = hashcodes; - -- s = bfd_get_section_by_name (dynobj, ".hash"); -- BFD_ASSERT (s != NULL); -- hash_entry_size = elf_section_data (s)->this_hdr.sh_entsize; -- s->size = ((2 + bucketcount + dynsymcount) * hash_entry_size); -- s->contents = bfd_zalloc (output_bfd, s->size); -- if (s->contents == NULL) -- return FALSE; -+ /* Put all hash values in HASHCODES. */ -+ elf_link_hash_traverse (elf_hash_table (info), -+ elf_collect_hash_codes, &hashcodesp); - -- bfd_put (8 * hash_entry_size, output_bfd, bucketcount, s->contents); -- bfd_put (8 * hash_entry_size, output_bfd, dynsymcount, -- s->contents + hash_entry_size); -+ nsyms = hashcodesp - hashcodes; -+ bucketcount -+ = compute_bucket_count (info, hashcodes, nsyms, 0); -+ free (hashcodes); - -- elf_hash_table (info)->bucketcount = bucketcount; -+ if (bucketcount == 0) -+ return FALSE; -+ -+ elf_hash_table (info)->bucketcount = bucketcount; -+ -+ s = bfd_get_section_by_name (dynobj, ".hash"); -+ BFD_ASSERT (s != NULL); -+ hash_entry_size = elf_section_data (s)->this_hdr.sh_entsize; -+ s->size = ((2 + bucketcount + dynsymcount) * hash_entry_size); -+ s->contents = bfd_zalloc (output_bfd, s->size); -+ if (s->contents == NULL) -+ return FALSE; -+ -+ bfd_put (8 * hash_entry_size, output_bfd, bucketcount, s->contents); -+ bfd_put (8 * hash_entry_size, output_bfd, dynsymcount, -+ s->contents + hash_entry_size); -+ } -+ -+ if (info->emit_gnu_hash) -+ { -+ size_t i, cnt; -+ unsigned char *contents; -+ struct collect_gnu_hash_codes cinfo; -+ bfd_size_type amt; -+ size_t bucketcount; -+ -+ memset (&cinfo, 0, sizeof (cinfo)); -+ -+ /* Compute the hash values for all exported symbols. At the same -+ time store the values in an array so that we could use them for -+ optimizations. */ -+ amt = dynsymcount * 2 * sizeof (unsigned long int); -+ cinfo.hashcodes = bfd_malloc (amt); -+ if (cinfo.hashcodes == NULL) -+ return FALSE; -+ -+ cinfo.hashval = cinfo.hashcodes + dynsymcount; -+ cinfo.min_dynindx = -1; -+ cinfo.output_bfd = output_bfd; -+ cinfo.bed = bed; -+ -+ /* Put all hash values in HASHCODES. */ -+ elf_link_hash_traverse (elf_hash_table (info), -+ elf_collect_gnu_hash_codes, &cinfo); -+ -+ bucketcount -+ = compute_bucket_count (info, cinfo.hashcodes, cinfo.nsyms, 1); -+ -+ if (bucketcount == 0) -+ { -+ free (cinfo.hashcodes); -+ return FALSE; -+ } -+ -+ s = bfd_get_section_by_name (dynobj, ".gnu.hash"); -+ BFD_ASSERT (s != NULL); -+ -+ if (cinfo.nsyms == 0) -+ { -+ /* Empty .gnu.hash section is special. */ -+ BFD_ASSERT (cinfo.min_dynindx == -1); -+ free (cinfo.hashcodes); -+ s->size = 5 * 4 + bed->s->arch_size / 8; -+ contents = bfd_zalloc (output_bfd, s->size); -+ if (contents == NULL) -+ return FALSE; -+ s->contents = contents; -+ /* 1 empty bucket. */ -+ bfd_put_32 (output_bfd, 1, contents); -+ /* SYMIDX above the special symbol 0. */ -+ bfd_put_32 (output_bfd, 1, contents + 4); -+ /* Just one word for bitmask. */ -+ bfd_put_32 (output_bfd, 1, contents + 8); -+ /* Only hash fn bloom filter. */ -+ bfd_put_32 (output_bfd, 0, contents + 12); -+ /* No hashes are valid - empty bitmask. */ -+ bfd_put (bed->s->arch_size, output_bfd, 0, contents + 16); -+ /* No hashes in the only bucket. */ -+ bfd_put_32 (output_bfd, 0, -+ contents + 16 + bed->s->arch_size / 8); -+ } -+ else -+ { -+ BFD_ASSERT (cinfo.min_dynindx != -1); -+ unsigned long int maskwords, maskbitslog2; -+ -+ maskbitslog2 = bfd_log2 (cinfo.nsyms) + 1; -+ if (maskbitslog2 < 3) -+ maskbitslog2 = 5; -+ else if ((1 << (maskbitslog2 - 2)) & cinfo.nsyms) -+ maskbitslog2 = maskbitslog2 + 3; -+ else -+ maskbitslog2 = maskbitslog2 + 2; -+ if (bed->s->arch_size == 64) -+ { -+ if (maskbitslog2 == 5) -+ maskbitslog2 = 6; -+ cinfo.shift1 = 6; -+ } -+ else -+ cinfo.shift1 = 5; -+ cinfo.mask = (1 << cinfo.shift1) - 1; -+ cinfo.shift2 = maskbitslog2 + cinfo.shift1; -+ cinfo.maskbits = 1 << maskbitslog2; -+ maskwords = 1 << (maskbitslog2 - cinfo.shift1); -+ amt = bucketcount * sizeof (unsigned long int) * 2; -+ amt += maskwords * sizeof (bfd_vma); -+ cinfo.bitmask = bfd_malloc (amt); -+ if (cinfo.bitmask == NULL) -+ { -+ free (cinfo.hashcodes); -+ return FALSE; -+ } -+ -+ cinfo.counts = (void *) (cinfo.bitmask + maskwords); -+ cinfo.indx = cinfo.counts + bucketcount; -+ cinfo.symindx = dynsymcount - cinfo.nsyms; -+ memset (cinfo.bitmask, 0, maskwords * sizeof (bfd_vma)); -+ -+ /* Determine how often each hash bucket is used. */ -+ memset (cinfo.counts, 0, bucketcount * sizeof (cinfo.counts[0])); -+ for (i = 0; i < cinfo.nsyms; ++i) -+ ++cinfo.counts[cinfo.hashcodes[i] % bucketcount]; -+ -+ for (i = 0, cnt = cinfo.symindx; i < bucketcount; ++i) -+ if (cinfo.counts[i] != 0) -+ { -+ cinfo.indx[i] = cnt; -+ cnt += cinfo.counts[i]; -+ } -+ BFD_ASSERT (cnt == dynsymcount); -+ cinfo.bucketcount = bucketcount; -+ cinfo.local_indx = cinfo.min_dynindx; -+ -+ s->size = (4 + bucketcount + cinfo.nsyms) * 4; -+ s->size += cinfo.maskbits / 8; -+ contents = bfd_zalloc (output_bfd, s->size); -+ if (contents == NULL) -+ { -+ free (cinfo.bitmask); -+ free (cinfo.hashcodes); -+ return FALSE; -+ } -+ -+ s->contents = contents; -+ bfd_put_32 (output_bfd, bucketcount, contents); -+ bfd_put_32 (output_bfd, cinfo.symindx, contents + 4); -+ bfd_put_32 (output_bfd, maskwords, contents + 8); -+ bfd_put_32 (output_bfd, cinfo.shift2, contents + 12); -+ contents += 16 + cinfo.maskbits / 8; -+ -+ for (i = 0; i < bucketcount; ++i) -+ { -+ if (cinfo.counts[i] == 0) -+ bfd_put_32 (output_bfd, 0, contents); -+ else -+ bfd_put_32 (output_bfd, cinfo.indx[i], contents); -+ contents += 4; -+ } -+ -+ cinfo.contents = contents; -+ -+ /* Renumber dynamic symbols, populate .gnu.hash section. */ -+ elf_link_hash_traverse (elf_hash_table (info), -+ elf_renumber_gnu_hash_syms, &cinfo); -+ -+ contents = s->contents + 16; -+ for (i = 0; i < maskwords; ++i) -+ { -+ bfd_put (bed->s->arch_size, output_bfd, cinfo.bitmask[i], -+ contents); -+ contents += bed->s->arch_size / 8; -+ } -+ -+ free (cinfo.bitmask); -+ free (cinfo.hashcodes); -+ } -+ } - - s = bfd_get_section_by_name (dynobj, ".dynstr"); - BFD_ASSERT (s != NULL); -@@ -6647,9 +6973,6 @@ elf_link_output_extsym (struct elf_link_ - { - size_t bucketcount; - size_t bucket; -- size_t hash_entry_size; -- bfd_byte *bucketpos; -- bfd_vma chain; - bfd_byte *esym; - - sym.st_name = h->dynstr_index; -@@ -6663,15 +6986,23 @@ elf_link_output_extsym (struct elf_link_ - - bucketcount = elf_hash_table (finfo->info)->bucketcount; - bucket = h->u.elf_hash_value % bucketcount; -- hash_entry_size -- = elf_section_data (finfo->hash_sec)->this_hdr.sh_entsize; -- bucketpos = ((bfd_byte *) finfo->hash_sec->contents -- + (bucket + 2) * hash_entry_size); -- chain = bfd_get (8 * hash_entry_size, finfo->output_bfd, bucketpos); -- bfd_put (8 * hash_entry_size, finfo->output_bfd, h->dynindx, bucketpos); -- bfd_put (8 * hash_entry_size, finfo->output_bfd, chain, -- ((bfd_byte *) finfo->hash_sec->contents -- + (bucketcount + 2 + h->dynindx) * hash_entry_size)); -+ -+ if (finfo->hash_sec != NULL) -+ { -+ size_t hash_entry_size; -+ bfd_byte *bucketpos; -+ bfd_vma chain; -+ -+ hash_entry_size -+ = elf_section_data (finfo->hash_sec)->this_hdr.sh_entsize; -+ bucketpos = ((bfd_byte *) finfo->hash_sec->contents -+ + (bucket + 2) * hash_entry_size); -+ chain = bfd_get (8 * hash_entry_size, finfo->output_bfd, bucketpos); -+ bfd_put (8 * hash_entry_size, finfo->output_bfd, h->dynindx, bucketpos); -+ bfd_put (8 * hash_entry_size, finfo->output_bfd, chain, -+ ((bfd_byte *) finfo->hash_sec->contents -+ + (bucketcount + 2 + h->dynindx) * hash_entry_size)); -+ } - - if (finfo->symver_sec != NULL && finfo->symver_sec->contents != NULL) - { -@@ -7845,7 +8176,7 @@ bfd_elf_final_link (bfd *abfd, struct bf - { - finfo.dynsym_sec = bfd_get_section_by_name (dynobj, ".dynsym"); - finfo.hash_sec = bfd_get_section_by_name (dynobj, ".hash"); -- BFD_ASSERT (finfo.dynsym_sec != NULL && finfo.hash_sec != NULL); -+ BFD_ASSERT (finfo.dynsym_sec != NULL); - finfo.symver_sec = bfd_get_section_by_name (dynobj, ".gnu.version"); - /* Note that it is OK if symver_sec is NULL. */ - } -@@ -8591,6 +8922,9 @@ bfd_elf_final_link (bfd *abfd, struct bf - case DT_HASH: - name = ".hash"; - goto get_vma; -+ case DT_GNU_HASH: -+ name = ".gnu.hash"; -+ goto get_vma; - case DT_STRTAB: - name = ".dynstr"; - goto get_vma; -Index: gdb-6.5/bfd/elfxx-target.h -=================================================================== ---- gdb-6.5.orig/bfd/elfxx-target.h 2006-07-14 01:30:51.000000000 -0300 -+++ gdb-6.5/bfd/elfxx-target.h 2006-07-14 01:31:26.000000000 -0300 -@@ -553,6 +553,10 @@ - #define elf_backend_merge_symbol NULL - #endif - -+#ifndef elf_backend_hash_symbol -+#define elf_backend_hash_symbol _bfd_elf_hash_symbol -+#endif -+ - extern const struct elf_size_info _bfd_elfNN_size_info; - - #ifndef INCLUDED_TARGET_FILE -@@ -630,6 +634,7 @@ static const struct elf_backend_data elf - elf_backend_common_section_index, - elf_backend_common_section, - elf_backend_merge_symbol, -+ elf_backend_hash_symbol, - elf_backend_link_order_error_handler, - elf_backend_relplt_name, - ELF_MACHINE_ALT1, -Index: gdb-6.5/include/elf/common.h -=================================================================== ---- gdb-6.5.orig/include/elf/common.h 2006-07-14 01:30:51.000000000 -0300 -+++ gdb-6.5/include/elf/common.h 2006-07-14 01:31:26.000000000 -0300 -@@ -338,6 +338,7 @@ - #define SHT_LOOS 0x60000000 /* First of OS specific semantics */ - #define SHT_HIOS 0x6fffffff /* Last of OS specific semantics */ - -+#define SHT_GNU_HASH 0x6ffffff6 /* GNU style symbol hash table */ - #define SHT_GNU_LIBLIST 0x6ffffff7 /* List of prelink dependencies */ - - /* The next three section types are defined by Solaris, and are named -@@ -577,6 +578,7 @@ - #define DT_VALRNGHI 0x6ffffdff - - #define DT_ADDRRNGLO 0x6ffffe00 -+#define DT_GNU_HASH 0x6ffffef5 - #define DT_TLSDESC_PLT 0x6ffffef6 - #define DT_TLSDESC_GOT 0x6ffffef7 - #define DT_GNU_CONFLICT 0x6ffffef8 -Index: gdb-6.5/include/bfdlink.h -=================================================================== ---- gdb-6.5.orig/include/bfdlink.h 2006-04-06 15:52:45.000000000 -0300 -+++ gdb-6.5/include/bfdlink.h 2006-07-14 01:31:26.000000000 -0300 -@@ -324,6 +324,12 @@ struct bfd_link_info - /* TRUE if unreferenced sections should be removed. */ - unsigned int gc_sections: 1; - -+ /* TRUE if .hash section should be created. */ -+ unsigned int emit_hash: 1; -+ -+ /* TRUE if .gnu.hash section should be created. */ -+ unsigned int emit_gnu_hash: 1; -+ - /* What to do with unresolved symbols in an object file. - When producing executables the default is GENERATE_ERROR. - When producing shared libraries the default is IGNORE. The