]> git.pld-linux.org Git - packages/gdb.git/blame - gdb-gnu_hash.patch
- pl for -lib
[packages/gdb.git] / gdb-gnu_hash.patch
CommitLineData
82b216b8
PS
12006-07-10 Jakub Jelinek <jakub@redhat.com>
2
3include/
4 * bfdlink.h (struct bfd_link_info): Add emit_hash and
5 emit_gnu_hash bitfields.
6include/elf/
7 * common.h (SHT_GNU_HASH, DT_GNU_HASH): Define.
8bfd/
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
42Index: 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 *,
74Index: 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"
106Index: 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. */
175Index: 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
206Index: 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;
821Index: 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,
844Index: 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
864Index: 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 3.486544 seconds and 4 git commands to generate.