Package: binutils Version: 2.16.1cvs20051117-1 Severity: important Tags: patch
Ld miscalculates GOT table sizes for at least mips/mipsel. The PROVIDE_HIDDEN support missed to hide the symbols provided by the linker script (and thus adjust the local GOT symbol count) early enough. The symptoms are failing static links and a segfault in the glibc build. Since the problematic code is generic (in elf32.em) this may also explain strange build failures for other elf32.em using architectures. It is possible that this bug leads to silent breakage for some architectures, for mips/mipsel the linker emits at least BFD assertions. The appended patch is already submitted upstream and fixes at least the mips-specific issues. Thiemo bfd/ 2005-12-06 Thiemo Seufer <[EMAIL PROTECTED]> H.J. Lu <[EMAIL PROTECTED]> PR ld/1932 * bfd-in.h (bfd_elf_record_link_assignment): Add output_bfd and hidden arguments. * bfd.c (bfd_hide_symbol): Removed. * bfd-in2.h: Regenerated. * elflink.c (bfd_elf_record_link_assignment): Handle hidden symbols which were provided by a linker script. ld/ 2005-12-06 Thiemo Seufer <[EMAIL PROTECTED]> H.J. Lu <[EMAIL PROTECTED]> PR ld/1932 * emultempl/elf32.em (gld${EMULATION_NAME}_find_exp_assignment): Adjust bfd_elf_record_link_assignment call. * ldexp.c (exp_fold_tree_1): Remove call to bfd_hide_symbol. --- binutils/bfd/bfd-in.h.hide-fix 2005-09-30 08:45:10.000000000 -0700 +++ binutils/bfd/bfd-in.h 2005-12-06 13:15:37.000000000 -0800 @@ -633,7 +633,8 @@ enum dynamic_lib_link_class { }; extern bfd_boolean bfd_elf_record_link_assignment - (struct bfd_link_info *, const char *, bfd_boolean); + (bfd *, struct bfd_link_info *, const char *, bfd_boolean, + bfd_boolean); extern struct bfd_link_needed_list *bfd_elf_get_needed_list (bfd *, struct bfd_link_info *); extern bfd_boolean bfd_elf_get_bfd_needed_list --- binutils/bfd/bfd-in2.h.hide-fix 2005-12-05 14:28:41.000000000 -0800 +++ binutils/bfd/bfd-in2.h 2005-12-06 13:15:49.000000000 -0800 @@ -640,7 +640,8 @@ enum dynamic_lib_link_class { }; extern bfd_boolean bfd_elf_record_link_assignment - (struct bfd_link_info *, const char *, bfd_boolean); + (bfd *, struct bfd_link_info *, const char *, bfd_boolean, + bfd_boolean); extern struct bfd_link_needed_list *bfd_elf_get_needed_list (bfd *, struct bfd_link_info *); extern bfd_boolean bfd_elf_get_bfd_needed_list @@ -4613,11 +4614,6 @@ void bfd_preserve_restore (bfd *, struct void bfd_preserve_finish (bfd *, struct bfd_preserve *); -void bfd_hide_symbol (bfd *, - struct bfd_link_info *, - struct bfd_link_hash_entry *, - bfd_boolean); - /* Extracted from archive.c. */ symindex bfd_get_next_mapent (bfd *abfd, symindex previous, carsym **sym); --- binutils/bfd/bfd.c.hide-fix 2005-10-07 13:47:30.000000000 -0700 +++ binutils/bfd/bfd.c 2005-12-06 13:14:16.000000000 -0800 @@ -1511,29 +1511,3 @@ bfd_preserve_finish (bfd *abfd ATTRIBUTE objalloc. */ bfd_hash_table_free (&preserve->section_htab); } - -/* -FUNCTION - bfd_hide_symbol - -SYNOPSIS - void bfd_hide_symbol (bfd *, - struct bfd_link_info *, - struct bfd_link_hash_entry *, - bfd_boolean); - -DESCRIPTION - This function hides a symbol so that it won't be exported. - -*/ - -void -bfd_hide_symbol (bfd *abfd, - struct bfd_link_info *link_info, - struct bfd_link_hash_entry *h, - bfd_boolean force_local) -{ - if (bfd_get_flavour (abfd) == bfd_target_elf_flavour) - (get_elf_backend_data (abfd)->elf_backend_hide_symbol) - (link_info, (struct elf_link_hash_entry *) h, force_local); -} --- binutils/bfd/elflink.c.hide-fix 2005-11-04 11:38:00.000000000 -0800 +++ binutils/bfd/elflink.c 2005-12-06 13:13:06.000000000 -0800 @@ -424,9 +424,11 @@ bfd_elf_link_record_dynamic_symbol (stru this in case some dynamic object refers to this symbol. */ bfd_boolean -bfd_elf_record_link_assignment (struct bfd_link_info *info, +bfd_elf_record_link_assignment (bfd *output_bfd, + struct bfd_link_info *info, const char *name, - bfd_boolean provide) + bfd_boolean provide, + bfd_boolean hidden) { struct elf_link_hash_entry *h; struct elf_link_hash_table *htab; @@ -473,6 +475,14 @@ bfd_elf_record_link_assignment (struct b h->def_regular = 1; + if (provide && hidden) + { + const struct elf_backend_data *bed = get_elf_backend_data (output_bfd); + + h->other = (h->other & ~ELF_ST_VISIBILITY (-1)) | STV_HIDDEN; + (*bed->elf_backend_hide_symbol) (info, h, TRUE); + } + /* STV_HIDDEN and STV_INTERNAL symbols must be STB_LOCAL in shared objects and executables. */ if (!info->relocatable --- binutils/ld/emultempl/elf32.em.hide-fix 2005-12-05 14:28:43.000000000 -0800 +++ binutils/ld/emultempl/elf32.em 2005-12-06 13:13:06.000000000 -0800 @@ -986,8 +986,9 @@ gld${EMULATION_NAME}_find_exp_assignment will do no harm. */ if (strcmp (exp->assign.dst, ".") != 0) { - if (!bfd_elf_record_link_assignment (&link_info, exp->assign.dst, - provide)) + if (!bfd_elf_record_link_assignment (output_bfd, &link_info, + exp->assign.dst, provide, + exp->assign.hidden)) einfo ("%P%F: failed to record assignment to %s: %E\n", exp->assign.dst); } --- binutils/ld/ldexp.c.hide-fix 2005-09-26 12:14:05.000000000 -0700 +++ binutils/ld/ldexp.c 2005-12-06 13:14:16.000000000 -0800 @@ -735,8 +735,6 @@ exp_fold_tree_1 (etree_type *tree) defined by some object. */ break; } - if (tree->assign.hidden) - bfd_hide_symbol (output_bfd, &link_info, h, TRUE); } exp_fold_tree_1 (tree->assign.src); -- To UNSUBSCRIBE, email to [EMAIL PROTECTED] with a subject of "unsubscribe". Trouble? Contact [EMAIL PROTECTED]