diff options
author | Martin Schlemmer <azarah@gentoo.org> | 2003-09-13 20:14:17 +0000 |
---|---|---|
committer | Martin Schlemmer <azarah@gentoo.org> | 2003-09-13 20:14:17 +0000 |
commit | 44002c6d5b560296f4a931bed3ba21cf14df4b8f (patch) | |
tree | d18d20b40fe5ff9d57ab0a6d9dc8557a19ae5d0f /sys-devel/binutils/files | |
parent | Add patch to speedup C++ linking (diff) | |
download | gentoo-2-44002c6d5b560296f4a931bed3ba21cf14df4b8f.tar.gz gentoo-2-44002c6d5b560296f4a931bed3ba21cf14df4b8f.tar.bz2 gentoo-2-44002c6d5b560296f4a931bed3ba21cf14df4b8f.zip |
Add patch to speedup C++ linking
Diffstat (limited to 'sys-devel/binutils/files')
-rw-r--r-- | sys-devel/binutils/files/2.14/binutils-2.14.90.0.6-cxx-speedup.patch | 882 | ||||
-rw-r--r-- | sys-devel/binutils/files/digest-binutils-2.14.90.0.6-r3 | 1 |
2 files changed, 883 insertions, 0 deletions
diff --git a/sys-devel/binutils/files/2.14/binutils-2.14.90.0.6-cxx-speedup.patch b/sys-devel/binutils/files/2.14/binutils-2.14.90.0.6-cxx-speedup.patch new file mode 100644 index 000000000000..9ae5d51e223c --- /dev/null +++ b/sys-devel/binutils/files/2.14/binutils-2.14.90.0.6-cxx-speedup.patch @@ -0,0 +1,882 @@ +*** ./ld/mri.c 2003-07-23 12:08:12.000000000 -0300 +--- ./ld/mri.c.new 2003-09-04 11:44:00.000000000 -0300 +*************** +*** 227,232 **** +--- 227,233 ---- + tmp->spec.name = p->name; + tmp->spec.exclude_name_list = NULL; + tmp->spec.sorted = FALSE; ++ tmp->spec.wildcard_p = wildcardp( p->name ); + lang_add_wild (NULL, tmp, FALSE); + + /* If there is an alias for this section, add it too. */ +*************** +*** 238,243 **** +--- 239,245 ---- + tmp->spec.name = aptr->name; + tmp->spec.exclude_name_list = NULL; + tmp->spec.sorted = FALSE; ++ tmp->spec.wildcard_p = wildcardp( aptr->name ); + lang_add_wild (NULL, tmp, FALSE); + } + +*** ./ld/ld.h 2003-07-23 12:08:12.000000000 -0300 +--- ./ld/ld.h.new 2003-09-04 11:59:57.000000000 -0300 +*************** +*** 71,76 **** +--- 71,77 ---- + const char *name; + struct name_list *exclude_name_list; + bfd_boolean sorted; ++ bfd_boolean wildcard_p; + }; + + struct wildcard_list { +*** ./ld/ldgram.y 2003-08-21 12:28:48.000000000 -0300 +--- ./ld/ldgram.y.new 2003-09-04 11:58:56.000000000 -0300 +*************** +*** 411,434 **** +--- 411,438 ---- + $$.name = $1; + $$.sorted = FALSE; + $$.exclude_name_list = NULL; ++ $$.wildcard_p = wildcardp($1); + } + | EXCLUDE_FILE '(' exclude_name_list ')' wildcard_name + { + $$.name = $5; + $$.sorted = FALSE; + $$.exclude_name_list = $3; ++ $$.wildcard_p = wildcardp($5); + } + | SORT '(' wildcard_name ')' + { + $$.name = $3; + $$.sorted = TRUE; + $$.exclude_name_list = NULL; ++ $$.wildcard_p = wildcardp($3); + } + | SORT '(' EXCLUDE_FILE '(' exclude_name_list ')' wildcard_name ')' + { + $$.name = $7; + $$.sorted = TRUE; + $$.exclude_name_list = $5; ++ $$.wildcard_p = wildcardp($7); + } + ; + +*************** +*** 479,484 **** +--- 483,489 ---- + tmp.name = $1; + tmp.exclude_name_list = NULL; + tmp.sorted = FALSE; ++ tmp.wildcard_p = wildcardp($1); + lang_add_wild (&tmp, NULL, ldgram_had_keep); + } + | '[' file_NAME_list ']' +*** ./ld/ldlang.c 2003-08-21 12:28:48.000000000 -0300 +--- ./ld/ldlang.c.new 2003-09-04 11:56:26.000000000 -0300 +*************** +*** 63,69 **** + + /* Forward declarations. */ + static void exp_init_os (etree_type *); +- static bfd_boolean wildcardp (const char *); + static lang_input_statement_type *lookup_name (const char *); + static bfd_boolean load_symbols (lang_input_statement_type *, + lang_statement_list_type *); +--- 63,68 ---- +*************** +*** 191,197 **** + { + const char *sname = bfd_get_section_name (file->the_bfd, s); + +! if (wildcardp (sec->spec.name)) + skip = fnmatch (sec->spec.name, sname, 0) != 0; + else + skip = strcmp (sec->spec.name, sname) != 0; +--- 190,196 ---- + { + const char *sname = bfd_get_section_name (file->the_bfd, s); + +! if ( sec->spec.wildcard_p ) + skip = fnmatch (sec->spec.name, sname, 0) != 0; + else + skip = strcmp (sec->spec.name, sname) != 0; +*************** +*** 954,960 **** + be enough to cause the pattern to be treated as a wildcard. + That lets us handle DOS filenames more naturally. */ + +! static bfd_boolean + wildcardp (const char *pattern) + { + const char *s; +--- 953,959 ---- + be enough to cause the pattern to be treated as a wildcard. + That lets us handle DOS filenames more naturally. */ + +! bfd_boolean + wildcardp (const char *pattern) + { + const char *s; +*************** +*** 4182,4191 **** + + if (filespec != NULL && filespec->name != NULL) + { +! if (strcmp (filespec->name, "*") == 0) + filespec->name = NULL; +! else if (! wildcardp (filespec->name)) +! lang_has_input_file = TRUE; + } + + new = new_stat (lang_wild_statement, stat_ptr); +--- 4181,4192 ---- + + if (filespec != NULL && filespec->name != NULL) + { +! +! if (strcmp (filespec->name, "*") == 0) { +! filespec->wildcard_p = FALSE; + filespec->name = NULL; +! } else if (! filespec->wildcard_p ) +! lang_has_input_file = TRUE; + } + + new = new_stat (lang_wild_statement, stat_ptr); +*** ./ld/ldlang.h 2003-08-21 12:28:48.000000000 -0300 +--- ./ld/ldlang.h.new 2003-09-04 11:51:29.000000000 -0300 +*************** +*** 407,412 **** +--- 407,414 ---- + (const char *); + extern void lang_add_wild + (struct wildcard_spec *, struct wildcard_list *, bfd_boolean); ++ extern bfd_boolean wildcardp ++ PARAMS ((const char *)); + extern void lang_add_map + (const char *); + extern void lang_add_fill +*** ./bfd/elflink.h 2003-08-21 12:28:48.000000000 -0300 +--- ./bfd/elflink.h.new 2003-09-04 13:12:40.000000000 -0300 +*************** +*** 1488,1500 **** + assembler code, handling it correctly would be very time + consuming, and other ELF linkers don't handle general aliasing + either. */ + while (weaks != NULL) + { + struct elf_link_hash_entry *hlook; + asection *slook; + bfd_vma vlook; +! struct elf_link_hash_entry **hpp; +! struct elf_link_hash_entry **hppend; + + hlook = weaks; + weaks = hlook->weakdef; +--- 1488,1539 ---- + assembler code, handling it correctly would be very time + consuming, and other ELF linkers don't handle general aliasing + either. */ ++ { ++ #define HASH(h) (((h->root.u.def.value >> 3) ^ \ ++ (h->root.u.def.section->target_index<<10))%(4*extsymcount)) ++ struct hashentry { ++ struct elf_link_hash_entry *h; ++ struct hashentry *next; ++ }; ++ struct hashentry *array; ++ struct elf_link_hash_entry **hpp; ++ struct elf_link_hash_entry **hppend; ++ ++ array = (struct hashentry *) malloc(extsymcount*4*sizeof(struct hashentry)); ++ memset(array, 0, extsymcount*4*sizeof(struct hashentry)); ++ ++ hpp = elf_sym_hashes (abfd); ++ hppend = hpp + extsymcount; ++ for (; hpp < hppend; hpp++) ++ { ++ unsigned int hash; ++ struct elf_link_hash_entry *h = *hpp; ++ ++ if (!h || h->root.type != bfd_link_hash_defined) ++ continue; ++ ++ hash = HASH(h); ++ ++ if (!array[hash].h) { ++ array[hash].h = h; ++ } else { ++ struct hashentry *p = array + hash; ++ while (p->next) ++ p = p->next; ++ p->next = (struct hashentry *) malloc(sizeof(struct hashentry)); ++ p->next->h = h; ++ p->next->next = 0; ++ } ++ } ++ ++ + while (weaks != NULL) + { + struct elf_link_hash_entry *hlook; + asection *slook; + bfd_vma vlook; +! unsigned int hash; +! struct hashentry *entry; + + hlook = weaks; + weaks = hlook->weakdef; +*************** +*** 1504,1525 **** + || hlook->root.type == bfd_link_hash_defweak + || hlook->root.type == bfd_link_hash_common + || hlook->root.type == bfd_link_hash_indirect); + slook = hlook->root.u.def.section; + vlook = hlook->root.u.def.value; + +! hpp = elf_sym_hashes (abfd); +! hppend = hpp + extsymcount; +! for (; hpp < hppend; hpp++) +! { +! struct elf_link_hash_entry *h; +! +! h = *hpp; +! if (h != NULL && h != hlook +! && h->root.type == bfd_link_hash_defined +! && h->root.u.def.section == slook +! && h->root.u.def.value == vlook) +! { +! hlook->weakdef = h; + + /* If the weak definition is in the list of dynamic + symbols, make sure the real definition is put there +--- 1543,1561 ---- + || hlook->root.type == bfd_link_hash_defweak + || hlook->root.type == bfd_link_hash_common + || hlook->root.type == bfd_link_hash_indirect); ++ hash = HASH( hlook ); + slook = hlook->root.u.def.section; + vlook = hlook->root.u.def.value; + +! entry = array + hash; +! while (entry && entry->h) +! { +! struct elf_link_hash_entry *h = entry->h; +! if (h != hlook +! && h->root.u.def.section == slook +! && h->root.u.def.value == vlook) +! { +! hlook->weakdef = h; + + /* If the weak definition is in the list of dynamic + symbols, make sure the real definition is put there +*************** +*** 1544,1549 **** +--- 1580,1600 ---- + } + break; + } ++ entry = entry->next; ++ } ++ } ++ { ++ unsigned int i; ++ for (i = 0; i < 4*extsymcount; ++i) { ++ struct hashentry *h = array[i].next; ++ while (h) { ++ struct hashentry *n = h->next; ++ free(h); ++ h = n; ++ } ++ } ++ free(array); ++ + } + } + +*** ./bfd/merge.c 2002-12-16 18:22:52.000000000 -0200 +--- ./bfd/merge.c.new 2003-09-04 12:11:12.000000000 -0300 +*************** +*** 108,119 **** + struct sec_merge_sec_info *)); + static bfd_boolean sec_merge_emit + PARAMS ((bfd *, struct sec_merge_hash_entry *)); +! static int cmplengthentry +! PARAMS ((const PTR, const PTR)); +! static int last4_eq +! PARAMS ((const PTR, const PTR)); +! static int last_eq +! PARAMS ((const PTR, const PTR)); + static bfd_boolean record_section + PARAMS ((struct sec_merge_info *, struct sec_merge_sec_info *)); + static void merge_strings +--- 108,117 ---- + struct sec_merge_sec_info *)); + static bfd_boolean sec_merge_emit + PARAMS ((bfd *, struct sec_merge_hash_entry *)); +! +! static int strrevcmp PARAMS ((const PTR, const PTR)); +! static int is_suffix PARAMS ((const struct sec_merge_hash_entry *, +! const struct sec_merge_hash_entry *)); + static bfd_boolean record_section + PARAMS ((struct sec_merge_info *, struct sec_merge_sec_info *)); + static void merge_strings +*************** +*** 457,539 **** + return FALSE; + } + +! /* Compare two sec_merge_hash_entry structures. This is called via qsort. */ +! +! static int +! cmplengthentry (a, b) + const PTR a; + const PTR b; + { + struct sec_merge_hash_entry * A = *(struct sec_merge_hash_entry **) a; + struct sec_merge_hash_entry * B = *(struct sec_merge_hash_entry **) b; + +- if (A->len < B->len) +- return 1; +- else if (A->len > B->len) +- return -1; +- +- return memcmp (A->root.string, B->root.string, A->len); +- } +- +- static int +- last4_eq (a, b) +- const PTR a; +- const PTR b; +- { +- struct sec_merge_hash_entry * A = (struct sec_merge_hash_entry *) a; +- struct sec_merge_hash_entry * B = (struct sec_merge_hash_entry *) b; +- +- if (memcmp (A->root.string + A->len - 5 * A->u.entsize, +- B->root.string + B->len - 5 * A->u.entsize, +- 4 * A->u.entsize) != 0) +- /* This was a hashtable collision. */ +- return 0; +- +- if (A->len <= B->len) +- /* B cannot be a suffix of A unless A is equal to B, which is guaranteed +- not to be equal by the hash table. */ +- return 0; +- +- if (A->alignment < B->alignment +- || ((A->len - B->len) & (B->alignment - 1))) +- /* The suffix is not sufficiently aligned. */ +- return 0; +- +- return memcmp (A->root.string + (A->len - B->len), +- B->root.string, B->len - 5 * A->u.entsize) == 0; +- } +- +- static int +- last_eq (a, b) +- const PTR a; +- const PTR b; +- { +- struct sec_merge_hash_entry * A = (struct sec_merge_hash_entry *) a; +- struct sec_merge_hash_entry * B = (struct sec_merge_hash_entry *) b; +- +- if (B->len >= 5 * A->u.entsize) +- /* Longer strings are just pushed into the hash table, +- they'll be used when looking up for very short strings. */ +- return 0; +- +- if (memcmp (A->root.string + A->len - 2 * A->u.entsize, +- B->root.string + B->len - 2 * A->u.entsize, +- A->u.entsize) != 0) +- /* This was a hashtable collision. */ +- return 0; +- +- if (A->len <= B->len) +- /* B cannot be a suffix of A unless A is equal to B, which is guaranteed +- not to be equal by the hash table. */ +- return 0; +- +- if (A->alignment < B->alignment +- || ((A->len - B->len) & (B->alignment - 1))) +- /* The suffix is not sufficiently aligned. */ +- return 0; +- +- return memcmp (A->root.string + (A->len - B->len), +- B->root.string, B->len - 2 * A->u.entsize) == 0; + } + + /* Record one section into the hash table. */ +--- 456,481 ---- + return FALSE; + } + +! static int strrevcmp(a, b) + const PTR a; + const PTR b; + { + struct sec_merge_hash_entry * A = *(struct sec_merge_hash_entry **) a; + struct sec_merge_hash_entry * B = *(struct sec_merge_hash_entry **) b; ++ const unsigned char *s = A->root.string + A->len - A->u.entsize; ++ const unsigned char *t = B->root.string + B->len - B->u.entsize; ++ int l = A->len < B->len ? A->len : B->len; ++ ++ l -= (A->u.entsize - 1); ++ while (l) { ++ if (*s != *t) ++ return (int)*s - (int)*t; ++ s--; ++ t--; ++ l--; ++ } ++ return A->len - B->len; + + } + + /* Record one section into the hash table. */ +*************** +*** 620,625 **** +--- 562,581 ---- + return FALSE; + } + ++ static int is_suffix(A, B) ++ const struct sec_merge_hash_entry *A; ++ const struct sec_merge_hash_entry *B; ++ { ++ if (A->len <= B->len) ++ /* B cannot be a suffix of A unless A is equal to B, which is guaranteed ++ not to be equal by the hash table. */ ++ return 0; ++ ++ return memcmp (A->root.string + (A->len - B->len), ++ B->root.string, B->len - 1 * A->u.entsize) == 0; ++ } ++ ++ + /* This is a helper function for _bfd_merge_sections. It attempts to + merge strings matching suffixes of longer strings. */ + static void +*************** +*** 628,637 **** + { + struct sec_merge_hash_entry **array, **a, **end, *e; + struct sec_merge_sec_info *secinfo; +- htab_t lasttab = NULL, last4tab = NULL; + bfd_size_type size, amt; + +! /* Now sort the strings by length, longest first. */ + array = NULL; + amt = sinfo->htab->size * sizeof (struct sec_merge_hash_entry *); + array = (struct sec_merge_hash_entry **) bfd_malloc (amt); +--- 584,592 ---- + { + struct sec_merge_hash_entry **array, **a, **end, *e; + struct sec_merge_sec_info *secinfo; + bfd_size_type size, amt; + +! /* Now sort the strings */ + array = NULL; + amt = sinfo->htab->size * sizeof (struct sec_merge_hash_entry *); + array = (struct sec_merge_hash_entry **) bfd_malloc (amt); +*************** +*** 644,729 **** + + sinfo->htab->size = a - array; + +- qsort (array, (size_t) sinfo->htab->size, +- sizeof (struct sec_merge_hash_entry *), cmplengthentry); +- +- last4tab = htab_create_alloc ((size_t) sinfo->htab->size * 4, +- NULL, last4_eq, NULL, calloc, free); +- lasttab = htab_create_alloc ((size_t) sinfo->htab->size * 4, +- NULL, last_eq, NULL, calloc, free); +- if (lasttab == NULL || last4tab == NULL) +- goto alloc_failure; +- +- /* Now insert the strings into hash tables (strings with last 4 characters +- and strings with last character equal), look for longer strings which +- we're suffix of. */ + for (a = array, end = array + sinfo->htab->size; a < end; a++) + { +- register hashval_t hash; +- unsigned int c; +- unsigned int i; +- const unsigned char *s; +- PTR *p; +- + e = *a; + e->u.entsize = sinfo->htab->entsize; +! if (e->len <= e->u.entsize) +! break; +! if (e->len > 4 * e->u.entsize) +! { +! s = (const unsigned char *) (e->root.string + e->len - e->u.entsize); +! hash = 0; +! for (i = 0; i < 4 * e->u.entsize; i++) +! { +! c = *--s; +! hash += c + (c << 17); +! hash ^= hash >> 2; +! } +! p = htab_find_slot_with_hash (last4tab, e, hash, INSERT); +! if (p == NULL) +! goto alloc_failure; +! if (*p) +! { +! struct sec_merge_hash_entry *ent; + +- ent = (struct sec_merge_hash_entry *) *p; +- e->u.suffix = ent; +- e->alignment = 0; +- continue; +- } +- else +- *p = (PTR) e; +- } +- s = (const unsigned char *) (e->root.string + e->len - e->u.entsize); +- hash = 0; +- for (i = 0; i < e->u.entsize; i++) +- { +- c = *--s; +- hash += c + (c << 17); +- hash ^= hash >> 2; +- } +- p = htab_find_slot_with_hash (lasttab, e, hash, INSERT); +- if (p == NULL) +- goto alloc_failure; +- if (*p) +- { +- struct sec_merge_hash_entry *ent; + +! ent = (struct sec_merge_hash_entry *) *p; +! e->u.suffix = ent; +! e->alignment = 0; + } +- else +- *p = (PTR) e; + } + + alloc_failure: + if (array) + free (array); +- if (lasttab) +- htab_delete (lasttab); +- if (last4tab) +- htab_delete (last4tab); + + /* Now assign positions to the strings we want to keep. */ + size = 0; +--- 599,644 ---- + + sinfo->htab->size = a - array; + + for (a = array, end = array + sinfo->htab->size; a < end; a++) + { + e = *a; + e->u.entsize = sinfo->htab->entsize; +! } + + +! qsort (array, (size_t) sinfo->htab->size, +! sizeof (struct sec_merge_hash_entry *), strrevcmp); +! +! for (a = array, end = array + sinfo->htab->size; a < end; a++) +! { +! e = *a; +! if (e->len <= e->u.entsize) +! continue; +! { +! bfd_boolean found = FALSE; +! struct sec_merge_hash_entry **b = a+1; +! while (b < end) +! { +! struct sec_merge_hash_entry *cmp = *b; +! if (!is_suffix(cmp, e)) +! break; +! if (e->alignment >= cmp->alignment +! && !((e->len - cmp->len) & (cmp->alignment - 1))) +! /* The suffix is sufficiently aligned. */ +! { +! e->u.suffix = cmp; +! found = TRUE; +! } +! ++b; +! } +! if( found ) +! e->alignment = 0; + } + } + + alloc_failure: + if (array) + free (array); + + /* Now assign positions to the strings we want to keep. */ + size = 0; +*** ./bfd/elf-strtab.c 2003-08-21 12:28:47.000000000 -0300 +--- ./bfd/elf-strtab.c.new 2003-09-04 13:21:17.000000000 -0300 +*************** +*** 57,62 **** +--- 57,68 ---- + struct elf_strtab_hash_entry **array; + }; + ++ static int strrevcmp PARAMS ((const PTR, const PTR)); ++ static int is_suffix PARAMS ((const struct elf_strtab_hash_entry *, ++ const struct elf_strtab_hash_entry *)); ++ ++ ++ + /* Routine to create an entry in a section merge hashtab. */ + + static struct bfd_hash_entry * +*************** +*** 253,284 **** + return TRUE; + } + +! /* Compare two elf_strtab_hash_entry structures. This is called via qsort. */ +! +! static int +! cmplengthentry (const void *a, const void *b) + { + struct elf_strtab_hash_entry *A = *(struct elf_strtab_hash_entry **) a; + struct elf_strtab_hash_entry *B = *(struct elf_strtab_hash_entry **) b; + +! if (A->len < B->len) +! return 1; +! else if (A->len > B->len) +! return -1; + +- return memcmp (A->root.string, B->root.string, A->len); + } + +! static int +! last4_eq (const void *a, const void *b) +! { +! const struct elf_strtab_hash_entry *A = a; +! const struct elf_strtab_hash_entry *B = b; + +! if (memcmp (A->root.string + A->len - 5, B->root.string + B->len - 5, 4) +! != 0) +! /* This was a hashtable collision. */ +! return 0; + + if (A->len <= B->len) + /* B cannot be a suffix of A unless A is equal to B, which is guaranteed +--- 259,291 ---- + return TRUE; + } + +! static int strrevcmp( a, b ) +! const PTR a; +! const PTR b; + { + struct elf_strtab_hash_entry *A = *(struct elf_strtab_hash_entry **) a; + struct elf_strtab_hash_entry *B = *(struct elf_strtab_hash_entry **) b; + +! const unsigned char *s = A->root.string + A->len - 1; +! const unsigned char *t = B->root.string + B->len - 1; +! int l = A->len < B->len ? A->len : B->len; +! +! while (l) { +! if (*s != *t) +! return (int)*s - (int)*t; +! s--; +! t--; +! l--; +! } +! return A->len - B->len; + + } + +! static int is_suffix(A, B) +! const struct elf_strtab_hash_entry *A; +! const struct elf_strtab_hash_entry *B; + +! { + + if (A->len <= B->len) + /* B cannot be a suffix of A unless A is equal to B, which is guaranteed +*************** +*** 286,292 **** + return 0; + + return memcmp (A->root.string + (A->len - B->len), +! B->root.string, B->len - 5) == 0; + } + + /* This function assigns final string table offsets for used strings, +--- 291,297 ---- + return 0; + + return memcmp (A->root.string + (A->len - B->len), +! B->root.string, B->len - 1) == 0; + } + + /* This function assigns final string table offsets for used strings, +*************** +*** 296,304 **** + _bfd_elf_strtab_finalize (struct elf_strtab_hash *tab) + { + struct elf_strtab_hash_entry **array, **a, **end, *e; +- htab_t last4tab = NULL; + bfd_size_type size, amt; +- struct elf_strtab_hash_entry *last[256], **last_ptr[256]; + + /* GCC 2.91.66 (egcs-1.1.2) on i386 miscompiles this function when i is + a 64-bit bfd_size_type: a 64-bit target or --enable-64-bit-bfd. +--- 301,307 ---- +*************** +*** 306,321 **** + cycles. */ + size_t i; + +! /* Now sort the strings by length, longest first. */ + array = NULL; + amt = tab->size * sizeof (struct elf_strtab_hash_entry *); + array = bfd_malloc (amt); + if (array == NULL) + goto alloc_failure; + +- memset (last, 0, sizeof (last)); +- for (i = 0; i < 256; ++i) +- last_ptr[i] = &last[i]; + for (i = 1, a = array; i < tab->size; ++i) + if (tab->array[i]->refcount) + *a++ = tab->array[i]; +--- 309,321 ---- + cycles. */ + size_t i; + +! /* Now sort the strings */ + array = NULL; + amt = tab->size * sizeof (struct elf_strtab_hash_entry *); + array = bfd_malloc (amt); + if (array == NULL) + goto alloc_failure; + + for (i = 1, a = array; i < tab->size; ++i) + if (tab->array[i]->refcount) + *a++ = tab->array[i]; +*************** +*** 324,403 **** + + size = a - array; + +! qsort (array, size, sizeof (struct elf_strtab_hash_entry *), cmplengthentry); + +! last4tab = htab_create_alloc (size * 4, NULL, last4_eq, NULL, calloc, free); +! if (last4tab == NULL) +! goto alloc_failure; +! +! /* Now insert the strings into hash tables (strings with last 4 characters +! and strings with last character equal), look for longer strings which +! we're suffix of. */ + for (a = array, end = array + size; a < end; a++) + { +- register hashval_t hash; +- unsigned int c; +- unsigned int j; +- const unsigned char *s; +- void **p; +- + e = *a; +! if (e->len > 4) +! { +! s = e->root.string + e->len - 1; +! hash = 0; +! for (j = 0; j < 4; j++) +! { +! c = *--s; +! hash += c + (c << 17); +! hash ^= hash >> 2; +! } +! p = htab_find_slot_with_hash (last4tab, e, hash, INSERT); +! if (p == NULL) +! goto alloc_failure; +! if (*p) +! { +! struct elf_strtab_hash_entry *ent; +! +! ent = *p; +! e->u.suffix = ent; +! e->len = 0; + continue; +- } +- else +- *p = e; +- } +- else + { +! struct elf_strtab_hash_entry *tem; +! +! c = e->root.string[e->len - 2] & 0xff; + +- for (tem = last[c]; tem; tem = tem->u.next) +- if (tem->len > e->len +- && memcmp (tem->root.string + (tem->len - e->len), +- e->root.string, e->len - 1) == 0) + break; +! if (tem) +! { +! e->u.suffix = tem; + e->len = 0; +- continue; + } + } + +- c = e->root.string[e->len - 2] & 0xff; +- /* Put longest strings first. */ +- *last_ptr[c] = e; +- last_ptr[c] = &e->u.next; +- e->u.next = NULL; +- } + + alloc_failure: + if (array) + free (array); +- if (last4tab) +- htab_delete (last4tab); + + /* Now assign positions to the strings we want to keep. */ + size = 1; +--- 324,358 ---- + + size = a - array; + +! qsort (array, size, sizeof (struct elf_strtab_hash_entry *), strrevcmp); + +! /* now loop over the sorted array and merge suffixes */ + for (a = array, end = array + size; a < end; a++) + { + e = *a; +! if( e->len <= 1 ) + continue; + { +! struct elf_strtab_hash_entry **b = a+1; +! int found = 0; +! while (b < end) { +! struct elf_strtab_hash_entry *cmp = *b; +! if (!is_suffix(cmp, e)) + + break; +! e->u.suffix = cmp; +! found = 1; +! ++b; +! } +! if( found ) + e->len = 0; + } + } + + + alloc_failure: + if (array) + free (array); + + /* Now assign positions to the strings we want to keep. */ + size = 1; diff --git a/sys-devel/binutils/files/digest-binutils-2.14.90.0.6-r3 b/sys-devel/binutils/files/digest-binutils-2.14.90.0.6-r3 new file mode 100644 index 000000000000..26abe27b6c76 --- /dev/null +++ b/sys-devel/binutils/files/digest-binutils-2.14.90.0.6-r3 @@ -0,0 +1 @@ +MD5 71b99dba3045a359dc314dbebedcf502 binutils-2.14.90.0.6.tar.bz2 10399066 |