This is the mail archive of the
binutils@sourceware.org
mailing list for the binutils project.
RE: elf_sym_hashes saved for --as-needed
- From: "Kyrylo Tkachov" <kyrylo dot tkachov at arm dot com>
- To: "'Alan Modra'" <amodra at gmail dot com>
- Cc: <binutils at sourceware dot org>
- Date: Wed, 8 May 2013 16:41:58 +0100
- Subject: RE: elf_sym_hashes saved for --as-needed
- References: <20130506084302 dot GE5221 at bubble dot grove dot modra dot org>
Hi Alan,
> The code loading --as-needed libraries rather uselessly saved
> uninitialized memory, the elf symbol hash array attached to an input
> bfd. This patch removes that silliness, and also arranges to reuse
> the alloc'd memory should the library be loaded again later. We can't
> release it, unfortunately.
>
> I also zero the memory initially rather than as each global symbol is
> processed. More on that in a followup powerpc64 patch.
This patch causes ld to segfault for arm and aarch64 linux targets
(arm-none-linux-gnueabi, aarch64-none-linux-gnu) on many of the gcc
testsuite cases. It seems that it is the variants that use LTO
(have -flto in the flags)
For example, I get:
$SOURCE/build-linux/obj/gcc4/gcc/xgcc -B$SOURCE/build-linux/obj/gcc4/gcc/
$SOURCE/gcc/gcc/testsuite/gcc.c-torture/execute/921029-1.c
-fno-diagnostics-show-caret -fdiagnostics-color=never -w -O2 -flto
-flto-partition=none -lm -o
$SOURCE/build-linux/obj/gcc4/gcc/testsuite/gcc/921029-1.x7 (timeout =
300)
collect2: error: ld terminated with signal 11 [Segmentation fault]
compiler exited with status 1
output is:
collect2: error: ld terminated with signal 11 [Segmentation fault]
FAIL: gcc.c-torture/execute/921029-1.c compilation, -O2 -flto
-flto-partition=none
UNRESOLVED: gcc.c-torture/execute/921029-1.c execution, -O2 -flto
-flto-partition=none
Any ideas?
Thanks,
Kyrill
>
> * elflink.c (elf_link_add_object_symbols): Don't save symbol
> hashes around loading as-needed library. Zero them on
> allocation,
> and restore to initial all-zero state if library not needed.
> Arrange to reuse hashes if we load library again later.
>
> Index: bfd/elflink.c
> ===================================================================
> RCS file: /cvs/src/src/bfd/elflink.c,v
> retrieving revision 1.492
> diff -u -p -r1.492 elflink.c
> --- bfd/elflink.c 30 Apr 2013 12:13:09 -0000 1.492
> +++ bfd/elflink.c 6 May 2013 06:14:38 -0000
> @@ -3338,14 +3338,12 @@ elf_link_add_object_symbols (bfd *abfd,
> unsigned int old_size = 0;
> unsigned int old_count = 0;
> void *old_tab = NULL;
> - void *old_hash;
> void *old_ent;
> struct bfd_link_hash_entry *old_undefs = NULL;
> struct bfd_link_hash_entry *old_undefs_tail = NULL;
> long old_dynsymcount = 0;
> bfd_size_type old_dynstr_size = 0;
> size_t tabsize = 0;
> - size_t hashsize = 0;
>
> htab = elf_hash_table (info);
> bed = get_elf_backend_data (abfd);
> @@ -3700,8 +3698,8 @@ error_free_dyn:
> extsymoff = hdr->sh_info;
> }
>
> - sym_hash = NULL;
> - if (extsymcount != 0)
> + sym_hash = elf_sym_hashes (abfd);
> + if (sym_hash == NULL && extsymcount != 0)
> {
> isymbuf = bfd_elf_get_elf_syms (abfd, hdr, extsymcount,
> extsymoff,
> NULL, NULL, NULL);
> @@ -3711,7 +3709,7 @@ error_free_dyn:
> /* We store a pointer to the hash table entry for each external
> symbol. */
> amt = extsymcount * sizeof (struct elf_link_hash_entry *);
> - sym_hash = (struct elf_link_hash_entry **) bfd_alloc (abfd,
> amt);
> + sym_hash = (struct elf_link_hash_entry **) bfd_zalloc (abfd,
> amt);
> if (sym_hash == NULL)
> goto error_free_sym;
> elf_sym_hashes (abfd) = sym_hash;
> @@ -3764,8 +3762,7 @@ error_free_dyn:
> }
>
> tabsize = htab->root.table.size * sizeof (struct bfd_hash_entry
> *);
> - hashsize = extsymcount * sizeof (struct elf_link_hash_entry *);
> - old_tab = bfd_malloc (tabsize + entsize + hashsize);
> + old_tab = bfd_malloc (tabsize + entsize);
> if (old_tab == NULL)
> goto error_free_vers;
>
> @@ -3781,12 +3778,10 @@ error_free_dyn:
> notice_as_needed, 0, NULL))
> goto error_free_vers;
>
> - /* Clone the symbol table and sym hashes. Remember some
> - pointers into the symbol table, and dynamic symbol count. */
> - old_hash = (char *) old_tab + tabsize;
> - old_ent = (char *) old_hash + hashsize;
> + /* Clone the symbol table. Remember some pointers into the
> + symbol table, and dynamic symbol count. */
> + old_ent = (char *) old_tab + tabsize;
> memcpy (old_tab, htab->root.table.table, tabsize);
> - memcpy (old_hash, sym_hash, hashsize);
> old_undefs = htab->root.undefs;
> old_undefs_tail = htab->root.undefs_tail;
> old_table = htab->root.table.table;
> @@ -3843,7 +3838,6 @@ error_free_dyn:
> flags = BSF_NO_FLAGS;
> sec = NULL;
> value = isym->st_value;
> - *sym_hash = NULL;
> common = bed->common_definition (isym);
>
> bind = ELF_ST_BIND (isym->st_info);
> @@ -4477,14 +4471,13 @@ error_free_dyn:
> /* Restore the symbol table. */
> if (bed->as_needed_cleanup)
> (*bed->as_needed_cleanup) (abfd, info);
> - old_hash = (char *) old_tab + tabsize;
> - old_ent = (char *) old_hash + hashsize;
> - sym_hash = elf_sym_hashes (abfd);
> + old_ent = (char *) old_tab + tabsize;
> + memset (elf_sym_hashes (abfd), 0,
> + extsymcount * sizeof (struct elf_link_hash_entry *));
> htab->root.table.table = old_table;
> htab->root.table.size = old_size;
> htab->root.table.count = old_count;
> memcpy (htab->root.table.table, old_tab, tabsize);
> - memcpy (sym_hash, old_hash, hashsize);
> htab->root.undefs = old_undefs;
> htab->root.undefs_tail = old_undefs_tail;
> _bfd_elf_strtab_restore_size (htab->dynstr, old_dynstr_size);
>
> --
> Alan Modra
> Australia Development Lab, IBM