]> git.pld-linux.org Git - packages/gdb.git/blob - gdb-gnu_hash.patch
- pl for -lib
[packages/gdb.git] / gdb-gnu_hash.patch
1 2006-07-10  Jakub Jelinek  <jakub@redhat.com>
2
3 include/
4         * bfdlink.h (struct bfd_link_info): Add emit_hash and
5         emit_gnu_hash bitfields.
6 include/elf/
7         * common.h (SHT_GNU_HASH, DT_GNU_HASH): Define.
8 bfd/
9         * elf.c (_bfd_elf_print_private_bfd_data): Handle DT_GNU_HASH.
10         (bfd_section_from_shdr, elf_fake_sections, assign_section_numbers):
11         Handle SHT_GNU_HASH.
12         (special_sections_g): Include .gnu.hash section.
13         (bfd_elf_gnu_hash): New function.
14         * elf-bfd.h (bfd_elf_gnu_hash, _bfd_elf_hash_symbol): New prototypes.
15         (struct elf_backend_data): Add elf_hash_symbol method.
16         * elflink.c (_bfd_elf_link_create_dynamic_sections): Create .hash
17         only if info->emit_hash, create .gnu.hash section if
18         info->emit_gnu_hash.
19         (struct collect_gnu_hash_codes): New type.
20         (elf_collect_gnu_hash_codes, elf_renumber_gnu_hash_syms,
21         _bfd_elf_hash_symbol): New functions.
22         (compute_bucket_count): Don't compute HASHCODES array, instead add
23         that and NSYMS as arguments.  Use bed->s->sizeof_hash_entry
24         instead of bed->s->arch_size / 8.  Fix .hash size estimation.
25         When not optimizing, use the number of hashed symbols rather than
26         dynsymcount.
27         (bfd_elf_size_dynamic_sections): Only add DT_HASH if info->emit_hash,
28         and ADD DT_GNU_HASH if info->emit_gnu_hash.
29         (bfd_elf_size_dynsym_hash_dynstr): Size .hash only if info->emit_hash,
30         adjust compute_bucket_count caller.  Create and populate .gnu.hash
31         section if info->emit_gnu_hash.
32         (elf_link_output_extsym): Only populate .hash section if
33         finfo->hash_sec != NULL.
34         (bfd_elf_final_link): Adjust assertion.  Handle DT_GNU_HASH.
35         * elfxx-target.h (elf_backend_hash_symbol): Define if not yet defined.
36         (elfNN_bed): Add elf_backend_hash_symbol.
37         * elf64-x86-64.c (elf64_x86_64_hash_symbol): New function.
38         (elf_backend_hash_symbol): Define.
39         * elf32-i386.c (elf_i386_hash_symbol): New function.
40         (elf_backend_hash_symbol): Define.
41
42 Index: gdb-6.5/bfd/elf-bfd.h
43 ===================================================================
44 --- gdb-6.5.orig/bfd/elf-bfd.h  2006-07-14 01:30:51.000000000 -0300
45 +++ gdb-6.5/bfd/elf-bfd.h       2006-07-14 01:31:25.000000000 -0300
46 @@ -1022,6 +1022,9 @@ struct elf_backend_data
47                                bfd_boolean *, bfd_boolean *,
48                                bfd *, asection **);
49  
50 +  /* Return TRUE if symbol should be hashed in the `.gnu.hash' section.  */
51 +  bfd_boolean (*elf_hash_symbol) (struct elf_link_hash_entry *);
52 +
53    /* Used to handle bad SHF_LINK_ORDER input.  */
54    bfd_error_handler_type link_order_error_handler;
55  
56 @@ -1462,6 +1465,8 @@ extern bfd_vma _bfd_elf_section_offset
57  
58  extern unsigned long bfd_elf_hash
59    (const char *);
60 +extern unsigned long bfd_elf_gnu_hash
61 +  (const char *);
62  
63  extern bfd_reloc_status_type bfd_elf_generic_reloc
64    (bfd *, arelent *, asymbol *, void *, asection *, bfd *, char **);
65 @@ -1632,6 +1637,8 @@ extern bfd_boolean _bfd_elf_merge_symbol
66     struct elf_link_hash_entry **, bfd_boolean *,
67     bfd_boolean *, bfd_boolean *, bfd_boolean *);
68  
69 +extern bfd_boolean _bfd_elf_hash_symbol (struct elf_link_hash_entry *);
70 +
71  extern bfd_boolean _bfd_elf_add_default_symbol
72    (bfd *, struct bfd_link_info *, struct elf_link_hash_entry *,
73     const char *, Elf_Internal_Sym *, asection **, bfd_vma *,
74 Index: gdb-6.5/bfd/elf64-x86-64.c
75 ===================================================================
76 --- gdb-6.5.orig/bfd/elf64-x86-64.c     2006-07-14 01:30:51.000000000 -0300
77 +++ gdb-6.5/bfd/elf64-x86-64.c  2006-07-14 01:31:26.000000000 -0300
78 @@ -3614,6 +3614,19 @@ elf64_x86_64_additional_program_headers 
79    return count;
80  }
81  
82 +/* Return TRUE if symbol should be hashed in the `.gnu.hash' section.  */
83 +
84 +static bfd_boolean
85 +elf64_x86_64_hash_symbol (struct elf_link_hash_entry *h)
86 +{
87 +  if (h->plt.offset != (bfd_vma) -1
88 +      && !h->def_regular
89 +      && !h->pointer_equality_needed)
90 +    return FALSE;
91 +
92 +  return _bfd_elf_hash_symbol (h);
93 +}
94 +
95  static const struct bfd_elf_special_section 
96    elf64_x86_64_special_sections[]=
97  {
98 @@ -3685,5 +3698,7 @@ static const struct bfd_elf_special_sect
99    elf64_x86_64_special_sections
100  #define elf_backend_additional_program_headers \
101    elf64_x86_64_additional_program_headers
102 +#define elf_backend_hash_symbol \
103 +  elf64_x86_64_hash_symbol
104  
105  #include "elf64-target.h"
106 Index: gdb-6.5/bfd/elf.c
107 ===================================================================
108 --- gdb-6.5.orig/bfd/elf.c      2006-07-14 01:30:51.000000000 -0300
109 +++ gdb-6.5/bfd/elf.c   2006-07-14 01:31:26.000000000 -0300
110 @@ -206,6 +206,21 @@ bfd_elf_hash (const char *namearg)
111    return h & 0xffffffff;
112  }
113  
114 +/* DT_GNU_HASH hash function.  Do not change this function; you will
115 +   cause invalid hash tables to be generated.  */
116 +
117 +unsigned long
118 +bfd_elf_gnu_hash (const char *namearg)
119 +{
120 +  const unsigned char *name = (const unsigned char *) namearg;
121 +  unsigned long h = 5381;
122 +  unsigned char ch;
123 +
124 +  while ((ch = *name++) != '\0')
125 +    h = (h << 5) + h + ch;
126 +  return h & 0xffffffff;
127 +}
128 +
129  bfd_boolean
130  bfd_elf_mkobject (bfd *abfd)
131  {
132 @@ -1239,6 +1254,7 @@ _bfd_elf_print_private_bfd_data (bfd *ab
133             case DT_AUXILIARY: name = "AUXILIARY"; stringp = TRUE; break;
134             case DT_USED: name = "USED"; break;
135             case DT_FILTER: name = "FILTER"; stringp = TRUE; break;
136 +           case DT_GNU_HASH: name = "GNU_HASH"; break;
137             }
138  
139           fprintf (f, "  %-11s ", name);
140 @@ -1822,6 +1838,7 @@ bfd_section_from_shdr (bfd *abfd, unsign
141      case SHT_FINI_ARRAY:       /* .fini_array section.  */
142      case SHT_PREINIT_ARRAY:    /* .preinit_array section.  */
143      case SHT_GNU_LIBLIST:      /* .gnu.liblist section.  */
144 +    case SHT_GNU_HASH:         /* .gnu.hash section.  */
145        return _bfd_elf_make_section_from_shdr (abfd, hdr, name, shindex);
146  
147      case SHT_DYNAMIC:  /* Dynamic linking information.  */
148 @@ -2294,6 +2311,7 @@ static const struct bfd_elf_special_sect
149    { ".gnu.version_r", 14,  0, SHT_GNU_verneed, 0 },
150    { ".gnu.liblist",   12,  0, SHT_GNU_LIBLIST, SHF_ALLOC },
151    { ".gnu.conflict",  13,  0, SHT_RELA,     SHF_ALLOC },
152 +  { ".gnu.hash",       9,  0, SHT_GNU_HASH, SHF_ALLOC },
153    { NULL,              0,  0, 0,            0 }
154  };
155  
156 @@ -2810,6 +2828,10 @@ elf_fake_sections (bfd *abfd, asection *
157      case SHT_GROUP:
158        this_hdr->sh_entsize = 4;
159        break;
160 +
161 +    case SHT_GNU_HASH:
162 +      this_hdr->sh_entsize = bed->s->arch_size == 64 ? 0 : 4;
163 +      break;
164      }
165  
166    if ((asect->flags & SEC_ALLOC) != 0)
167 @@ -3255,6 +3277,7 @@ assign_section_numbers (bfd *abfd, struc
168           break;
169  
170         case SHT_HASH:
171 +       case SHT_GNU_HASH:
172         case SHT_GNU_versym:
173           /* sh_link is the section header index of the symbol table
174              this hash table or version table is for.  */
175 Index: gdb-6.5/bfd/elf32-i386.c
176 ===================================================================
177 --- gdb-6.5.orig/bfd/elf32-i386.c       2006-07-14 01:30:51.000000000 -0300
178 +++ gdb-6.5/bfd/elf32-i386.c    2006-07-14 01:31:26.000000000 -0300
179 @@ -3872,6 +3872,18 @@ elf_i386_plt_sym_val (bfd_vma i, const a
180    return plt->vma + (i + 1) * PLT_ENTRY_SIZE;
181  }
182  
183 +/* Return TRUE if symbol should be hashed in the `.gnu.hash' section.  */
184 +
185 +static bfd_boolean
186 +elf_i386_hash_symbol (struct elf_link_hash_entry *h)
187 +{
188 +  if (h->plt.offset != (bfd_vma) -1
189 +      && !h->def_regular
190 +      && !h->pointer_equality_needed)
191 +    return FALSE;
192 +
193 +  return _bfd_elf_hash_symbol (h);
194 +}
195  
196  #define TARGET_LITTLE_SYM              bfd_elf32_i386_vec
197  #define TARGET_LITTLE_NAME             "elf32-i386"
198 @@ -3912,6 +3924,7 @@ elf_i386_plt_sym_val (bfd_vma i, const a
199  #define elf_backend_size_dynamic_sections     elf_i386_size_dynamic_sections
200  #define elf_backend_always_size_sections      elf_i386_always_size_sections
201  #define elf_backend_plt_sym_val                      elf_i386_plt_sym_val
202 +#define elf_backend_hash_symbol                      elf_i386_hash_symbol
203  
204  #include "elf32-target.h"
205  
206 Index: gdb-6.5/bfd/elflink.c
207 ===================================================================
208 --- gdb-6.5.orig/bfd/elflink.c  2006-07-14 01:30:51.000000000 -0300
209 +++ gdb-6.5/bfd/elflink.c       2006-07-14 01:31:26.000000000 -0300
210 @@ -240,12 +240,30 @@ _bfd_elf_link_create_dynamic_sections (b
211    if (!_bfd_elf_define_linkage_sym (abfd, info, s, "_DYNAMIC"))
212      return FALSE;
213  
214 -  s = bfd_make_section_with_flags (abfd, ".hash",
215 -                                  flags | SEC_READONLY);
216 -  if (s == NULL
217 -      || ! bfd_set_section_alignment (abfd, s, bed->s->log_file_align))
218 -    return FALSE;
219 -  elf_section_data (s)->this_hdr.sh_entsize = bed->s->sizeof_hash_entry;
220 +  if (info->emit_hash)
221 +    {
222 +      s = bfd_make_section_with_flags (abfd, ".hash", flags | SEC_READONLY);
223 +      if (s == NULL
224 +         || ! bfd_set_section_alignment (abfd, s, bed->s->log_file_align))
225 +       return FALSE;
226 +      elf_section_data (s)->this_hdr.sh_entsize = bed->s->sizeof_hash_entry;
227 +    }
228 +
229 +  if (info->emit_gnu_hash)
230 +    {
231 +      s = bfd_make_section_with_flags (abfd, ".gnu.hash",
232 +                                      flags | SEC_READONLY);
233 +      if (s == NULL
234 +         || ! bfd_set_section_alignment (abfd, s, bed->s->log_file_align))
235 +       return FALSE;
236 +      /* For 64-bit ELF, .gnu.hash is a non-uniform entity size section:
237 +        4 32-bit words followed by variable count of 64-bit words, then
238 +        variable count of 32-bit words.  */
239 +      if (bed->s->arch_size == 64)
240 +       elf_section_data (s)->this_hdr.sh_entsize = 0;
241 +      else
242 +       elf_section_data (s)->this_hdr.sh_entsize = 4;
243 +    }
244  
245    /* Let the backend create the rest of the sections.  This lets the
246       backend set the right flags.  The backend will normally create
247 @@ -4795,6 +4813,131 @@ elf_collect_hash_codes (struct elf_link_
248    return TRUE;
249  }
250  
251 +struct collect_gnu_hash_codes
252 +{
253 +  bfd *output_bfd;
254 +  const struct elf_backend_data *bed;
255 +  unsigned long int nsyms;
256 +  unsigned long int maskbits;
257 +  unsigned long int *hashcodes;
258 +  unsigned long int *hashval;
259 +  unsigned long int *indx;
260 +  unsigned long int *counts;
261 +  bfd_vma *bitmask;
262 +  bfd_byte *contents;
263 +  long int min_dynindx;
264 +  unsigned long int bucketcount;
265 +  unsigned long int symindx;
266 +  long int local_indx;
267 +  long int shift1, shift2;
268 +  unsigned long int mask;
269 +};
270 +
271 +/* This function will be called though elf_link_hash_traverse to store
272 +   all hash value of the exported symbols in an array.  */
273 +
274 +static bfd_boolean
275 +elf_collect_gnu_hash_codes (struct elf_link_hash_entry *h, void *data)
276 +{
277 +  struct collect_gnu_hash_codes *s = data;
278 +  const char *name;
279 +  char *p;
280 +  unsigned long ha;
281 +  char *alc = NULL;
282 +
283 +  if (h->root.type == bfd_link_hash_warning)
284 +    h = (struct elf_link_hash_entry *) h->root.u.i.link;
285 +
286 +  /* Ignore indirect symbols.  These are added by the versioning code.  */
287 +  if (h->dynindx == -1)
288 +    return TRUE;
289 +
290 +  /* Ignore also local symbols and undefined symbols.  */
291 +  if (! (*s->bed->elf_hash_symbol) (h))
292 +    return TRUE;
293 +
294 +  name = h->root.root.string;
295 +  p = strchr (name, ELF_VER_CHR);
296 +  if (p != NULL)
297 +    {
298 +      alc = bfd_malloc (p - name + 1);
299 +      memcpy (alc, name, p - name);
300 +      alc[p - name] = '\0';
301 +      name = alc;
302 +    }
303 +
304 +  /* Compute the hash value.  */
305 +  ha = bfd_elf_gnu_hash (name);
306 +
307 +  /* Store the found hash value in the array for compute_bucket_count,
308 +     and also for .dynsym reordering purposes.  */
309 +  s->hashcodes[s->nsyms] = ha;
310 +  s->hashval[h->dynindx] = ha;
311 +  ++s->nsyms;
312 +  if (s->min_dynindx < 0 || s->min_dynindx > h->dynindx)
313 +    s->min_dynindx = h->dynindx;
314 +
315 +  if (alc != NULL)
316 +    free (alc);
317 +
318 +  return TRUE;
319 +}
320 +
321 +/* This function will be called though elf_link_hash_traverse to do
322 +   final dynaminc symbol renumbering.  */
323 +
324 +static bfd_boolean
325 +elf_renumber_gnu_hash_syms (struct elf_link_hash_entry *h, void *data)
326 +{
327 +  struct collect_gnu_hash_codes *s = data;
328 +  unsigned long int bucket;
329 +  unsigned long int val;
330 +
331 +  if (h->root.type == bfd_link_hash_warning)
332 +    h = (struct elf_link_hash_entry *) h->root.u.i.link;
333 +
334 +  /* Ignore indirect symbols.  */
335 +  if (h->dynindx == -1)
336 +    return TRUE;
337 +
338 +  /* Ignore also local symbols and undefined symbols.  */
339 +  if (! (*s->bed->elf_hash_symbol) (h))
340 +    {
341 +      if (h->dynindx >= s->min_dynindx)
342 +       h->dynindx = s->local_indx++;
343 +      return TRUE;
344 +    }
345 +
346 +  bucket = s->hashval[h->dynindx] % s->bucketcount;
347 +  val = (s->hashval[h->dynindx] >> s->shift1)
348 +       & ((s->maskbits >> s->shift1) - 1);
349 +  s->bitmask[val] |= ((bfd_vma) 1) << (s->hashval[h->dynindx] & s->mask);
350 +  s->bitmask[val]
351 +    |= ((bfd_vma) 1) << ((s->hashval[h->dynindx] >> s->shift2) & s->mask);
352 +  val = s->hashval[h->dynindx] & ~(unsigned long int) 1;
353 +  if (s->counts[bucket] == 1)
354 +    /* Last element terminates the chain.  */
355 +    val |= 1;
356 +  bfd_put_32 (s->output_bfd, val,
357 +             s->contents + (s->indx[bucket] - s->symindx) * 4);
358 +  --s->counts[bucket];
359 +  h->dynindx = s->indx[bucket]++;
360 +  return TRUE;
361 +}
362 +
363 +/* Return TRUE if symbol should be hashed in the `.gnu.hash' section.  */
364 +
365 +bfd_boolean
366 +_bfd_elf_hash_symbol (struct elf_link_hash_entry *h)
367 +{
368 +  return !(h->forced_local
369 +          || h->root.type == bfd_link_hash_undefined
370 +          || h->root.type == bfd_link_hash_undefweak
371 +          || ((h->root.type == bfd_link_hash_defined
372 +               || h->root.type == bfd_link_hash_defweak)
373 +              && h->root.u.def.section->output_section == NULL));
374 +}
375 +
376  /* Array used to determine the number of hash table buckets to use
377     based on the number of symbols there are.  If there are fewer than
378     3 symbols we use 1 bucket, fewer than 17 symbols we use 3 buckets,
379 @@ -4816,42 +4959,26 @@ static const size_t elf_buckets[] =
380     Therefore the result is always a good payoff between few collisions
381     (= short chain lengths) and table size.  */
382  static size_t
383 -compute_bucket_count (struct bfd_link_info *info)
384 +compute_bucket_count (struct bfd_link_info *info, unsigned long int *hashcodes,
385 +                     unsigned long int nsyms, int gnu_hash)
386  {
387    size_t dynsymcount = elf_hash_table (info)->dynsymcount;
388    size_t best_size = 0;
389 -  unsigned long int *hashcodes;
390 -  unsigned long int *hashcodesp;
391    unsigned long int i;
392    bfd_size_type amt;
393  
394 -  /* Compute the hash values for all exported symbols.  At the same
395 -     time store the values in an array so that we could use them for
396 -     optimizations.  */
397 -  amt = dynsymcount;
398 -  amt *= sizeof (unsigned long int);
399 -  hashcodes = bfd_malloc (amt);
400 -  if (hashcodes == NULL)
401 -    return 0;
402 -  hashcodesp = hashcodes;
403 -
404 -  /* Put all hash values in HASHCODES.  */
405 -  elf_link_hash_traverse (elf_hash_table (info),
406 -                         elf_collect_hash_codes, &hashcodesp);
407 -
408    /* We have a problem here.  The following code to optimize the table
409       size requires an integer type with more the 32 bits.  If
410       BFD_HOST_U_64_BIT is set we know about such a type.  */
411  #ifdef BFD_HOST_U_64_BIT
412    if (info->optimize)
413      {
414 -      unsigned long int nsyms = hashcodesp - hashcodes;
415        size_t minsize;
416        size_t maxsize;
417        BFD_HOST_U_64_BIT best_chlen = ~((BFD_HOST_U_64_BIT) 0);
418 -      unsigned long int *counts ;
419        bfd *dynobj = elf_hash_table (info)->dynobj;
420        const struct elf_backend_data *bed = get_elf_backend_data (dynobj);
421 +      unsigned long int *counts;
422  
423        /* Possible optimization parameters: if we have NSYMS symbols we say
424          that the hashing table must at least have NSYMS/4 and at most
425 @@ -4860,6 +4987,13 @@ compute_bucket_count (struct bfd_link_in
426        if (minsize == 0)
427         minsize = 1;
428        best_size = maxsize = nsyms * 2;
429 +      if (gnu_hash)
430 +       {
431 +         if (minsize < 2)
432 +           minsize = 2;
433 +         if ((best_size & 31) == 0)
434 +           ++best_size;
435 +       }
436  
437        /* Create array where we count the collisions in.  We must use bfd_malloc
438          since the size could be large.  */
439 @@ -4867,10 +5001,7 @@ compute_bucket_count (struct bfd_link_in
440        amt *= sizeof (unsigned long int);
441        counts = bfd_malloc (amt);
442        if (counts == NULL)
443 -       {
444 -         free (hashcodes);
445 -         return 0;
446 -       }
447 +       return 0;
448  
449        /* Compute the "optimal" size for the hash table.  The criteria is a
450          minimal chain length.  The minor criteria is (of course) the size
451 @@ -4882,6 +5013,9 @@ compute_bucket_count (struct bfd_link_in
452           unsigned long int j;
453           unsigned long int fact;
454  
455 +         if (gnu_hash && (i & 31) == 0)
456 +           continue;
457 +
458           memset (counts, '\0', i * sizeof (unsigned long int));
459  
460           /* Determine how often each hash bucket is used.  */
461 @@ -4897,9 +5031,9 @@ compute_bucket_count (struct bfd_link_in
462  #  define BFD_TARGET_PAGESIZE  (4096)
463  # endif
464  
465 -         /* We in any case need 2 + NSYMS entries for the size values and
466 -            the chains.  */
467 -         max = (2 + nsyms) * (bed->s->arch_size / 8);
468 +         /* We in any case need 2 + DYNSYMCOUNT entries for the size values
469 +            and the chains.  */
470 +         max = (2 + dynsymcount) * bed->s->sizeof_hash_entry;
471  
472  # if 1
473           /* Variant 1: optimize for short chains.  We add the squares
474 @@ -4909,7 +5043,7 @@ compute_bucket_count (struct bfd_link_in
475             max += counts[j] * counts[j];
476  
477           /* This adds penalties for the overall size of the table.  */
478 -         fact = i / (BFD_TARGET_PAGESIZE / (bed->s->arch_size / 8)) + 1;
479 +         fact = i / (BFD_TARGET_PAGESIZE / bed->s->sizeof_hash_entry) + 1;
480           max *= fact * fact;
481  # else
482           /* Variant 2: Optimize a lot more for small table.  Here we
483 @@ -4920,7 +5054,7 @@ compute_bucket_count (struct bfd_link_in
484  
485           /* The overall size of the table is considered, but not as
486              strong as in variant 1, where it is squared.  */
487 -         fact = i / (BFD_TARGET_PAGESIZE / (bed->s->arch_size / 8)) + 1;
488 +         fact = i / (BFD_TARGET_PAGESIZE / bed->s->sizeof_hash_entry) + 1;
489           max *= fact;
490  # endif
491  
492 @@ -4943,14 +5077,13 @@ compute_bucket_count (struct bfd_link_in
493        for (i = 0; elf_buckets[i] != 0; i++)
494         {
495           best_size = elf_buckets[i];
496 -         if (dynsymcount < elf_buckets[i + 1])
497 +         if (nsyms < elf_buckets[i + 1])
498             break;
499         }
500 +      if (gnu_hash && best_size < 2)
501 +       best_size = 2;
502      }
503  
504 -  /* Free the arrays we needed.  */
505 -  free (hashcodes);
506 -
507    return best_size;
508  }
509  
510 @@ -5308,7 +5441,10 @@ bfd_elf_size_dynamic_sections (bfd *outp
511           bfd_size_type strsize;
512  
513           strsize = _bfd_elf_strtab_size (elf_hash_table (info)->dynstr);
514 -         if (!_bfd_elf_add_dynamic_entry (info, DT_HASH, 0)
515 +         if ((info->emit_hash
516 +              && !_bfd_elf_add_dynamic_entry (info, DT_HASH, 0))
517 +             || (info->emit_gnu_hash
518 +                 && !_bfd_elf_add_dynamic_entry (info, DT_GNU_HASH, 0))
519               || !_bfd_elf_add_dynamic_entry (info, DT_STRTAB, 0)
520               || !_bfd_elf_add_dynamic_entry (info, DT_SYMTAB, 0)
521               || !_bfd_elf_add_dynamic_entry (info, DT_STRSZ, strsize)
522 @@ -5710,8 +5846,6 @@ bfd_elf_size_dynsym_hash_dynstr (bfd *ou
523        asection *s;
524        bfd_size_type dynsymcount;
525        unsigned long section_sym_count;
526 -      size_t bucketcount = 0;
527 -      size_t hash_entry_size;
528        unsigned int dtagcount;
529  
530        dynobj = elf_hash_table (info)->dynobj;
531 @@ -5762,23 +5896,215 @@ bfd_elf_size_dynsym_hash_dynstr (bfd *ou
532           memset (s->contents, 0, section_sym_count * bed->s->sizeof_sym);
533         }
534  
535 +      elf_hash_table (info)->bucketcount = 0;
536 +
537        /* Compute the size of the hashing table.  As a side effect this
538          computes the hash values for all the names we export.  */
539 -      bucketcount = compute_bucket_count (info);
540 +      if (info->emit_hash)
541 +       {
542 +         unsigned long int *hashcodes;
543 +         unsigned long int *hashcodesp;
544 +         bfd_size_type amt;
545 +         unsigned long int nsyms;
546 +         size_t bucketcount;
547 +         size_t hash_entry_size;
548 +
549 +         /* Compute the hash values for all exported symbols.  At the same
550 +            time store the values in an array so that we could use them for
551 +            optimizations.  */
552 +         amt = dynsymcount * sizeof (unsigned long int);
553 +         hashcodes = bfd_malloc (amt);
554 +         if (hashcodes == NULL)
555 +           return FALSE;
556 +         hashcodesp = hashcodes;
557  
558 -      s = bfd_get_section_by_name (dynobj, ".hash");
559 -      BFD_ASSERT (s != NULL);
560 -      hash_entry_size = elf_section_data (s)->this_hdr.sh_entsize;
561 -      s->size = ((2 + bucketcount + dynsymcount) * hash_entry_size);
562 -      s->contents = bfd_zalloc (output_bfd, s->size);
563 -      if (s->contents == NULL)
564 -       return FALSE;
565 +         /* Put all hash values in HASHCODES.  */
566 +         elf_link_hash_traverse (elf_hash_table (info),
567 +                                 elf_collect_hash_codes, &hashcodesp);
568  
569 -      bfd_put (8 * hash_entry_size, output_bfd, bucketcount, s->contents);
570 -      bfd_put (8 * hash_entry_size, output_bfd, dynsymcount,
571 -              s->contents + hash_entry_size);
572 +         nsyms = hashcodesp - hashcodes;
573 +         bucketcount
574 +           = compute_bucket_count (info, hashcodes, nsyms, 0);
575 +         free (hashcodes);
576  
577 -      elf_hash_table (info)->bucketcount = bucketcount;
578 +         if (bucketcount == 0)
579 +           return FALSE;
580 +
581 +         elf_hash_table (info)->bucketcount = bucketcount;
582 +
583 +         s = bfd_get_section_by_name (dynobj, ".hash");
584 +         BFD_ASSERT (s != NULL);
585 +         hash_entry_size = elf_section_data (s)->this_hdr.sh_entsize;
586 +         s->size = ((2 + bucketcount + dynsymcount) * hash_entry_size);
587 +         s->contents = bfd_zalloc (output_bfd, s->size);
588 +         if (s->contents == NULL)
589 +           return FALSE;
590 +
591 +         bfd_put (8 * hash_entry_size, output_bfd, bucketcount, s->contents);
592 +         bfd_put (8 * hash_entry_size, output_bfd, dynsymcount,
593 +                  s->contents + hash_entry_size);
594 +       }
595 +
596 +      if (info->emit_gnu_hash)
597 +       {
598 +         size_t i, cnt;
599 +         unsigned char *contents;
600 +         struct collect_gnu_hash_codes cinfo;
601 +         bfd_size_type amt;
602 +         size_t bucketcount;
603 +
604 +         memset (&cinfo, 0, sizeof (cinfo));
605 +
606 +         /* Compute the hash values for all exported symbols.  At the same
607 +            time store the values in an array so that we could use them for
608 +            optimizations.  */
609 +         amt = dynsymcount * 2 * sizeof (unsigned long int);
610 +         cinfo.hashcodes = bfd_malloc (amt);
611 +         if (cinfo.hashcodes == NULL)
612 +           return FALSE;
613 +
614 +         cinfo.hashval = cinfo.hashcodes + dynsymcount;
615 +         cinfo.min_dynindx = -1;
616 +         cinfo.output_bfd = output_bfd;
617 +         cinfo.bed = bed;
618 +
619 +         /* Put all hash values in HASHCODES.  */
620 +         elf_link_hash_traverse (elf_hash_table (info),
621 +                                 elf_collect_gnu_hash_codes, &cinfo);
622 +
623 +         bucketcount
624 +           = compute_bucket_count (info, cinfo.hashcodes, cinfo.nsyms, 1);
625 +
626 +         if (bucketcount == 0)
627 +           {
628 +             free (cinfo.hashcodes);
629 +             return FALSE;
630 +           }
631 +
632 +         s = bfd_get_section_by_name (dynobj, ".gnu.hash");
633 +         BFD_ASSERT (s != NULL);
634 +
635 +         if (cinfo.nsyms == 0)
636 +           {
637 +             /* Empty .gnu.hash section is special.  */
638 +             BFD_ASSERT (cinfo.min_dynindx == -1);
639 +             free (cinfo.hashcodes);
640 +             s->size = 5 * 4 + bed->s->arch_size / 8;
641 +             contents = bfd_zalloc (output_bfd, s->size);
642 +             if (contents == NULL)
643 +               return FALSE;
644 +             s->contents = contents;
645 +             /* 1 empty bucket.  */
646 +             bfd_put_32 (output_bfd, 1, contents);
647 +             /* SYMIDX above the special symbol 0.  */
648 +             bfd_put_32 (output_bfd, 1, contents + 4);
649 +             /* Just one word for bitmask.  */
650 +             bfd_put_32 (output_bfd, 1, contents + 8);
651 +             /* Only hash fn bloom filter.  */
652 +             bfd_put_32 (output_bfd, 0, contents + 12);
653 +             /* No hashes are valid - empty bitmask.  */
654 +             bfd_put (bed->s->arch_size, output_bfd, 0, contents + 16);
655 +             /* No hashes in the only bucket.  */
656 +             bfd_put_32 (output_bfd, 0,
657 +                         contents + 16 + bed->s->arch_size / 8);
658 +           }
659 +         else
660 +           {
661 +             BFD_ASSERT (cinfo.min_dynindx != -1);
662 +             unsigned long int maskwords, maskbitslog2;
663 +
664 +             maskbitslog2 = bfd_log2 (cinfo.nsyms) + 1;
665 +             if (maskbitslog2 < 3)
666 +               maskbitslog2 = 5;
667 +             else if ((1 << (maskbitslog2 - 2)) & cinfo.nsyms)
668 +               maskbitslog2 = maskbitslog2 + 3;
669 +             else
670 +               maskbitslog2 = maskbitslog2 + 2;
671 +             if (bed->s->arch_size == 64)
672 +               {
673 +                 if (maskbitslog2 == 5)
674 +                   maskbitslog2 = 6;
675 +                 cinfo.shift1 = 6;
676 +               }
677 +             else
678 +               cinfo.shift1 = 5;
679 +             cinfo.mask = (1 << cinfo.shift1) - 1;
680 +             cinfo.shift2 = maskbitslog2 + cinfo.shift1;
681 +             cinfo.maskbits = 1 << maskbitslog2;
682 +             maskwords = 1 << (maskbitslog2 - cinfo.shift1);
683 +             amt = bucketcount * sizeof (unsigned long int) * 2;
684 +             amt += maskwords * sizeof (bfd_vma);
685 +             cinfo.bitmask = bfd_malloc (amt);
686 +             if (cinfo.bitmask == NULL)
687 +               {
688 +                 free (cinfo.hashcodes);
689 +                 return FALSE;
690 +               }
691 +
692 +             cinfo.counts = (void *) (cinfo.bitmask + maskwords);
693 +             cinfo.indx = cinfo.counts + bucketcount;
694 +             cinfo.symindx = dynsymcount - cinfo.nsyms;
695 +             memset (cinfo.bitmask, 0, maskwords * sizeof (bfd_vma));
696 +
697 +             /* Determine how often each hash bucket is used.  */
698 +             memset (cinfo.counts, 0, bucketcount * sizeof (cinfo.counts[0]));
699 +             for (i = 0; i < cinfo.nsyms; ++i)
700 +               ++cinfo.counts[cinfo.hashcodes[i] % bucketcount];
701 +
702 +             for (i = 0, cnt = cinfo.symindx; i < bucketcount; ++i)
703 +               if (cinfo.counts[i] != 0)
704 +                 {
705 +                   cinfo.indx[i] = cnt;
706 +                   cnt += cinfo.counts[i];
707 +                 }
708 +             BFD_ASSERT (cnt == dynsymcount);
709 +             cinfo.bucketcount = bucketcount;
710 +             cinfo.local_indx = cinfo.min_dynindx;
711 +
712 +             s->size = (4 + bucketcount + cinfo.nsyms) * 4;
713 +             s->size += cinfo.maskbits / 8;
714 +             contents = bfd_zalloc (output_bfd, s->size);
715 +             if (contents == NULL)
716 +               {
717 +                 free (cinfo.bitmask);
718 +                 free (cinfo.hashcodes);
719 +                 return FALSE;
720 +               }
721 +
722 +             s->contents = contents;
723 +             bfd_put_32 (output_bfd, bucketcount, contents);
724 +             bfd_put_32 (output_bfd, cinfo.symindx, contents + 4);
725 +             bfd_put_32 (output_bfd, maskwords, contents + 8);
726 +             bfd_put_32 (output_bfd, cinfo.shift2, contents + 12);
727 +             contents += 16 + cinfo.maskbits / 8;
728 +
729 +             for (i = 0; i < bucketcount; ++i)
730 +               {
731 +                 if (cinfo.counts[i] == 0)
732 +                   bfd_put_32 (output_bfd, 0, contents);
733 +                 else
734 +                   bfd_put_32 (output_bfd, cinfo.indx[i], contents);
735 +                 contents += 4;
736 +               }
737 +
738 +             cinfo.contents = contents;
739 +
740 +             /* Renumber dynamic symbols, populate .gnu.hash section.  */
741 +             elf_link_hash_traverse (elf_hash_table (info),
742 +                                     elf_renumber_gnu_hash_syms, &cinfo);
743 +
744 +             contents = s->contents + 16;
745 +             for (i = 0; i < maskwords; ++i)
746 +               {
747 +                 bfd_put (bed->s->arch_size, output_bfd, cinfo.bitmask[i],
748 +                          contents);
749 +                 contents += bed->s->arch_size / 8;
750 +               }
751 +
752 +             free (cinfo.bitmask);
753 +             free (cinfo.hashcodes);
754 +           }
755 +       }
756  
757        s = bfd_get_section_by_name (dynobj, ".dynstr");
758        BFD_ASSERT (s != NULL);
759 @@ -6647,9 +6973,6 @@ elf_link_output_extsym (struct elf_link_
760      {
761        size_t bucketcount;
762        size_t bucket;
763 -      size_t hash_entry_size;
764 -      bfd_byte *bucketpos;
765 -      bfd_vma chain;
766        bfd_byte *esym;
767  
768        sym.st_name = h->dynstr_index;
769 @@ -6663,15 +6986,23 @@ elf_link_output_extsym (struct elf_link_
770  
771        bucketcount = elf_hash_table (finfo->info)->bucketcount;
772        bucket = h->u.elf_hash_value % bucketcount;
773 -      hash_entry_size
774 -       = elf_section_data (finfo->hash_sec)->this_hdr.sh_entsize;
775 -      bucketpos = ((bfd_byte *) finfo->hash_sec->contents
776 -                  + (bucket + 2) * hash_entry_size);
777 -      chain = bfd_get (8 * hash_entry_size, finfo->output_bfd, bucketpos);
778 -      bfd_put (8 * hash_entry_size, finfo->output_bfd, h->dynindx, bucketpos);
779 -      bfd_put (8 * hash_entry_size, finfo->output_bfd, chain,
780 -              ((bfd_byte *) finfo->hash_sec->contents
781 -               + (bucketcount + 2 + h->dynindx) * hash_entry_size));
782 +
783 +      if (finfo->hash_sec != NULL)
784 +       {
785 +         size_t hash_entry_size;
786 +         bfd_byte *bucketpos;
787 +         bfd_vma chain;
788 +
789 +         hash_entry_size
790 +           = elf_section_data (finfo->hash_sec)->this_hdr.sh_entsize;
791 +         bucketpos = ((bfd_byte *) finfo->hash_sec->contents
792 +                      + (bucket + 2) * hash_entry_size);
793 +         chain = bfd_get (8 * hash_entry_size, finfo->output_bfd, bucketpos);
794 +         bfd_put (8 * hash_entry_size, finfo->output_bfd, h->dynindx, bucketpos);
795 +         bfd_put (8 * hash_entry_size, finfo->output_bfd, chain,
796 +                  ((bfd_byte *) finfo->hash_sec->contents
797 +                   + (bucketcount + 2 + h->dynindx) * hash_entry_size));
798 +       }
799  
800        if (finfo->symver_sec != NULL && finfo->symver_sec->contents != NULL)
801         {
802 @@ -7845,7 +8176,7 @@ bfd_elf_final_link (bfd *abfd, struct bf
803      {
804        finfo.dynsym_sec = bfd_get_section_by_name (dynobj, ".dynsym");
805        finfo.hash_sec = bfd_get_section_by_name (dynobj, ".hash");
806 -      BFD_ASSERT (finfo.dynsym_sec != NULL && finfo.hash_sec != NULL);
807 +      BFD_ASSERT (finfo.dynsym_sec != NULL);
808        finfo.symver_sec = bfd_get_section_by_name (dynobj, ".gnu.version");
809        /* Note that it is OK if symver_sec is NULL.  */
810      }
811 @@ -8591,6 +8922,9 @@ bfd_elf_final_link (bfd *abfd, struct bf
812             case DT_HASH:
813               name = ".hash";
814               goto get_vma;
815 +           case DT_GNU_HASH:
816 +             name = ".gnu.hash";
817 +             goto get_vma;
818             case DT_STRTAB:
819               name = ".dynstr";
820               goto get_vma;
821 Index: gdb-6.5/bfd/elfxx-target.h
822 ===================================================================
823 --- gdb-6.5.orig/bfd/elfxx-target.h     2006-07-14 01:30:51.000000000 -0300
824 +++ gdb-6.5/bfd/elfxx-target.h  2006-07-14 01:31:26.000000000 -0300
825 @@ -553,6 +553,10 @@
826  #define elf_backend_merge_symbol NULL
827  #endif
828  
829 +#ifndef elf_backend_hash_symbol
830 +#define elf_backend_hash_symbol _bfd_elf_hash_symbol
831 +#endif
832 +
833  extern const struct elf_size_info _bfd_elfNN_size_info;
834  
835  #ifndef INCLUDED_TARGET_FILE
836 @@ -630,6 +634,7 @@ static const struct elf_backend_data elf
837    elf_backend_common_section_index,
838    elf_backend_common_section,
839    elf_backend_merge_symbol,
840 +  elf_backend_hash_symbol,
841    elf_backend_link_order_error_handler,
842    elf_backend_relplt_name,
843    ELF_MACHINE_ALT1,
844 Index: gdb-6.5/include/elf/common.h
845 ===================================================================
846 --- gdb-6.5.orig/include/elf/common.h   2006-07-14 01:30:51.000000000 -0300
847 +++ gdb-6.5/include/elf/common.h        2006-07-14 01:31:26.000000000 -0300
848 @@ -338,6 +338,7 @@
849  #define SHT_LOOS       0x60000000      /* First of OS specific semantics */
850  #define SHT_HIOS       0x6fffffff      /* Last of OS specific semantics */
851  
852 +#define SHT_GNU_HASH   0x6ffffff6      /* GNU style symbol hash table */
853  #define SHT_GNU_LIBLIST        0x6ffffff7      /* List of prelink dependencies */
854  
855  /* The next three section types are defined by Solaris, and are named
856 @@ -577,6 +578,7 @@
857  #define DT_VALRNGHI    0x6ffffdff
858  
859  #define DT_ADDRRNGLO   0x6ffffe00
860 +#define DT_GNU_HASH    0x6ffffef5
861  #define DT_TLSDESC_PLT 0x6ffffef6
862  #define DT_TLSDESC_GOT 0x6ffffef7
863  #define DT_GNU_CONFLICT        0x6ffffef8
864 Index: gdb-6.5/include/bfdlink.h
865 ===================================================================
866 --- gdb-6.5.orig/include/bfdlink.h      2006-04-06 15:52:45.000000000 -0300
867 +++ gdb-6.5/include/bfdlink.h   2006-07-14 01:31:26.000000000 -0300
868 @@ -324,6 +324,12 @@ struct bfd_link_info
869    /* TRUE if unreferenced sections should be removed.  */
870    unsigned int gc_sections: 1;
871  
872 +  /* TRUE if .hash section should be created.  */
873 +  unsigned int emit_hash: 1;
874 +
875 +  /* TRUE if .gnu.hash section should be created.  */
876 +  unsigned int emit_gnu_hash: 1;
877 +
878    /* What to do with unresolved symbols in an object file.
879       When producing executables the default is GENERATE_ERROR.
880       When producing shared libraries the default is IGNORE.  The
This page took 0.094986 seconds and 3 git commands to generate.