This is the mail archive of the
binutils@sourceware.org
mailing list for the binutils project.
elf_sym_hashes saved for --as-needed
- From: Alan Modra <amodra at gmail dot com>
- To: binutils at sourceware dot org
- Date: Mon, 6 May 2013 18:13:02 +0930
- Subject: elf_sym_hashes saved for --as-needed
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.
* 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