* Makefile.am (BFD32_BACKENDS): Add elf-strtab.lo.

(BFD32_BACKENDS_CFILES): Add elf-strtab.c.
	(elf-strtab.lo): Add rule.
	* Makefile.in: Rebuilt.
	* configure.in (elf): Add elf-strtab.lo.
	* configure: Rebuilt.
	* elf-bfd.h (elf_strtab_hash): Forward declare.
	(struct elf_link_hash_table): Change dynstr type to
	struct elf_strtab_hash *.
	(struct elf_obj_tdata): Change strtab_ptr type to
	struct elf_strtab_hash *.
	(_bfd_elf_strtab_init, _bfd_elf_strtab_free, _bfd_elf_strtab_add,
	_bfd_elf_strtab_addref, _bfd_elf_strtab_delref,
	_bfd_elf_strtab_clear_all_refs, _bfd_elf_strtab_size,
	_bfd_elf_strtab_offset, _bfd_elf_strtab_emit,
	_bfd_elf_strtab_finalize): New prototypes.
	* elf-strtab.c: New file.
	* elflink.h (elf_link_add_object_symbols): Use _bfd_elf_strtab_add
	and _bfd_elf_strtab_size instead of _bfd_stringtab calls.
	Call _bfd_elf_strtab_delref if DT_NEEDED entry is not needed or
	when forcing dynamic symbol to local.
	(elf_link_create_dynamic_sections): Call
	_bfd_elf_strtab_init instead of elf_stringtab_init.
	(elf_link_record_local_dynamic_symbol): Likewise, change
	dynstr type.  Use _bfd_elf_strtab functions instead of
	_bfd_stringtab calls.
	(size_dynamic_sections): Use _bfd_elf_strtab functions instead of
	_bfd_stringtab calls.  For DT_RUNPATH and Verdaux vda_name fields,
	call _bfd_elf_strtab_addref.  Call elf_finalize_dynstr.
	(elf_adjust_dynstr_offsets, elf_finalize_dynstr): New functions.
	(elf_fix_symbol_flags): Call _bfd_elf_strtab_delref when forcing
	dynamic symbol to local.
	(elf_link_assign_sym_version): Likewise.
	(elf_bfd_final_link): Call _bfd_elf_strtab_emit instead of
	_bfd_stringtab_emit.
	* elflink.c (_bfd_elf_link_record_dynamic_symbol): Change dynstr
	type.  Call _bfd_elf_strtab functions instead of
	_bfd_stringtab functions.
	* elf64-sparc.c (sparc64_elf_size_dynamic_sections): Likewise.
	* elf.c (_bfd_elf_init_reloc_shdr): Likewise.
	(elf_fake_sections): Likewise.
	(assign_section_numbers): Call _bfd_elf_strtab_clear_all_refs
	on shstrtab hash table, call _bfd_elf_strtab_addref on each section
	name in the output.  Call _bfd_elf_strtab_finalize and
	use _bfd_elf_strtab_offset to finalize sh_name section header fields.
	(_bfd_elf_compute_section_file_positions): Use _bfd_elf_strtab_size
	instead of _bfd_stringtab_size.
	(prep_headers): Change shstrtab type.
	Use _bfd_elf_strtab calls instead of _bfd_stringtab calls.
This commit is contained in:
Jakub Jelinek 2001-11-07 16:50:38 +00:00
parent ef5cdfc7dd
commit 2b0f7ef92e
11 changed files with 788 additions and 73 deletions

View File

@ -1,3 +1,55 @@
2001-11-07 Jakub Jelinek <jakub@redhat.com>
* Makefile.am (BFD32_BACKENDS): Add elf-strtab.lo.
(BFD32_BACKENDS_CFILES): Add elf-strtab.c.
(elf-strtab.lo): Add rule.
* Makefile.in: Rebuilt.
* configure.in (elf): Add elf-strtab.lo.
* configure: Rebuilt.
* elf-bfd.h (elf_strtab_hash): Forward declare.
(struct elf_link_hash_table): Change dynstr type to
struct elf_strtab_hash *.
(struct elf_obj_tdata): Change strtab_ptr type to
struct elf_strtab_hash *.
(_bfd_elf_strtab_init, _bfd_elf_strtab_free, _bfd_elf_strtab_add,
_bfd_elf_strtab_addref, _bfd_elf_strtab_delref,
_bfd_elf_strtab_clear_all_refs, _bfd_elf_strtab_size,
_bfd_elf_strtab_offset, _bfd_elf_strtab_emit,
_bfd_elf_strtab_finalize): New prototypes.
* elf-strtab.c: New file.
* elflink.h (elf_link_add_object_symbols): Use _bfd_elf_strtab_add
and _bfd_elf_strtab_size instead of _bfd_stringtab calls.
Call _bfd_elf_strtab_delref if DT_NEEDED entry is not needed or
when forcing dynamic symbol to local.
(elf_link_create_dynamic_sections): Call
_bfd_elf_strtab_init instead of elf_stringtab_init.
(elf_link_record_local_dynamic_symbol): Likewise, change
dynstr type. Use _bfd_elf_strtab functions instead of
_bfd_stringtab calls.
(size_dynamic_sections): Use _bfd_elf_strtab functions instead of
_bfd_stringtab calls. For DT_RUNPATH and Verdaux vda_name fields,
call _bfd_elf_strtab_addref. Call elf_finalize_dynstr.
(elf_adjust_dynstr_offsets, elf_finalize_dynstr): New functions.
(elf_fix_symbol_flags): Call _bfd_elf_strtab_delref when forcing
dynamic symbol to local.
(elf_link_assign_sym_version): Likewise.
(elf_bfd_final_link): Call _bfd_elf_strtab_emit instead of
_bfd_stringtab_emit.
* elflink.c (_bfd_elf_link_record_dynamic_symbol): Change dynstr
type. Call _bfd_elf_strtab functions instead of
_bfd_stringtab functions.
* elf64-sparc.c (sparc64_elf_size_dynamic_sections): Likewise.
* elf.c (_bfd_elf_init_reloc_shdr): Likewise.
(elf_fake_sections): Likewise.
(assign_section_numbers): Call _bfd_elf_strtab_clear_all_refs
on shstrtab hash table, call _bfd_elf_strtab_addref on each section
name in the output. Call _bfd_elf_strtab_finalize and
use _bfd_elf_strtab_offset to finalize sh_name section header fields.
(_bfd_elf_compute_section_file_positions): Use _bfd_elf_strtab_size
instead of _bfd_stringtab_size.
(prep_headers): Change shstrtab type.
Use _bfd_elf_strtab calls instead of _bfd_stringtab calls.
2001-11-07 Alan Modra <amodra@bigpond.net.au>
* elflink.h (elf_link_input_bfd <removed linkonce relocs>): Fix

View File

@ -215,6 +215,7 @@ BFD32_BACKENDS = \
elf32-v850.lo \
elf32.lo \
elflink.lo \
elf-strtab.lo \
epoc-pe-arm.lo \
epoc-pei-arm.lo \
hp300bsd.lo \
@ -355,6 +356,7 @@ BFD32_BACKENDS_CFILES = \
elf32-v850.c \
elf32.c \
elflink.c \
elf-strtab.c \
epoc-pe-arm.c \
epoc-pei-arm.c \
hp300bsd.c \
@ -1129,6 +1131,7 @@ elf32.lo: elf32.c elfcode.h $(INCDIR)/filenames.h $(INCDIR)/libiberty.h \
elflink.lo: elflink.c $(INCDIR)/filenames.h $(INCDIR)/bfdlink.h \
elf-bfd.h $(INCDIR)/elf/common.h $(INCDIR)/elf/internal.h \
$(INCDIR)/elf/external.h
elf-strtab.lo: elf-strtab.c $(INCDIR)/filenames.h $(INCDIR)/hashtab.h
epoc-pe-arm.lo: epoc-pe-arm.c pe-arm.c $(INCDIR)/filenames.h \
coff-arm.c $(INCDIR)/coff/arm.h $(INCDIR)/coff/external.h \
$(INCDIR)/coff/internal.h $(INCDIR)/coff/pe.h libcoff.h \

View File

@ -342,6 +342,7 @@ BFD32_BACKENDS = \
elf32-v850.lo \
elf32.lo \
elflink.lo \
elf-strtab.lo \
epoc-pe-arm.lo \
epoc-pei-arm.lo \
hp300bsd.lo \
@ -483,6 +484,7 @@ BFD32_BACKENDS_CFILES = \
elf32-v850.c \
elf32.c \
elflink.c \
elf-strtab.c \
epoc-pe-arm.c \
epoc-pei-arm.c \
hp300bsd.c \
@ -1672,6 +1674,7 @@ elf32.lo: elf32.c elfcode.h $(INCDIR)/filenames.h $(INCDIR)/libiberty.h \
elflink.lo: elflink.c $(INCDIR)/filenames.h $(INCDIR)/bfdlink.h \
elf-bfd.h $(INCDIR)/elf/common.h $(INCDIR)/elf/internal.h \
$(INCDIR)/elf/external.h
elf-strtab.lo: elf-strtab.c $(INCDIR)/filenames.h $(INCDIR)/hashtab.h
epoc-pe-arm.lo: epoc-pe-arm.c pe-arm.c $(INCDIR)/filenames.h \
coff-arm.c $(INCDIR)/coff/arm.h $(INCDIR)/coff/external.h \
$(INCDIR)/coff/internal.h $(INCDIR)/coff/pe.h libcoff.h \

2
bfd/configure vendored
View File

@ -5923,7 +5923,7 @@ selarchs="$f"
# Target backend .o files.
tb=
elf="elf.lo elflink.lo dwarf1.lo"
elf="elf.lo elflink.lo elf-strtab.lo dwarf1.lo"
for vec in $selvecs
do

View File

@ -503,7 +503,7 @@ selarchs="$f"
# Target backend .o files.
tb=
elf="elf.lo elflink.lo dwarf1.lo"
elf="elf.lo elflink.lo elf-strtab.lo dwarf1.lo"
for vec in $selvecs
do

View File

@ -79,6 +79,8 @@ typedef struct
} elf_symbol_type;
struct elf_strtab_hash;
/* ELF linker hash table entries. */
struct elf_link_hash_entry
@ -248,7 +250,7 @@ struct elf_link_hash_table
/* The string table of dynamic symbols, which becomes the .dynstr
section. */
struct bfd_strtab_hash *dynstr;
struct elf_strtab_hash *dynstr;
/* The number of buckets in the hash table in the .hash section.
This is based on the number of dynamic symbols. */
@ -891,7 +893,7 @@ struct elf_obj_tdata
Elf_Internal_Shdr **elf_sect_ptr;
Elf_Internal_Phdr *phdr;
struct elf_segment_map *segment_map;
struct bfd_strtab_hash *strtab_ptr;
struct elf_strtab_hash *strtab_ptr;
int num_locals;
int num_globals;
int num_section_syms;
@ -1202,6 +1204,28 @@ extern boolean _bfd_elf_create_dynamic_sections
PARAMS ((bfd *, struct bfd_link_info *));
extern struct bfd_strtab_hash *_bfd_elf_stringtab_init
PARAMS ((void));
extern struct elf_strtab_hash * _bfd_elf_strtab_init
PARAMS ((void));
extern void _bfd_elf_strtab_free
PARAMS ((struct elf_strtab_hash *));
extern bfd_size_type _bfd_elf_strtab_add
PARAMS ((struct elf_strtab_hash *, const char *, boolean));
extern void _bfd_elf_strtab_addref
PARAMS ((struct elf_strtab_hash *, bfd_size_type));
extern void _bfd_elf_strtab_delref
PARAMS ((struct elf_strtab_hash *, bfd_size_type));
extern void _bfd_elf_strtab_clear_all_refs
PARAMS ((struct elf_strtab_hash *));
extern bfd_size_type _bfd_elf_strtab_size
PARAMS ((struct elf_strtab_hash *));
extern bfd_size_type _bfd_elf_strtab_offset
PARAMS ((struct elf_strtab_hash *, bfd_size_type));
extern boolean _bfd_elf_strtab_emit
PARAMS ((bfd *, struct elf_strtab_hash *));
extern void _bfd_elf_strtab_finalize
PARAMS ((struct elf_strtab_hash *));
extern boolean _bfd_elf_link_record_dynamic_symbol
PARAMS ((struct bfd_link_info *, struct elf_link_hash_entry *));
extern long _bfd_elf_link_lookup_local_dynindx

459
bfd/elf-strtab.c Normal file
View File

@ -0,0 +1,459 @@
/* ELF strtab with GC and suffix merging support.
Copyright 2001 Free Software Foundation, Inc.
Written by Jakub Jelinek <jakub@redhat.com>.
This file is part of BFD, the Binary File Descriptor library.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
#include "bfd.h"
#include "sysdep.h"
#include "libbfd.h"
#include "elf-bfd.h"
#include "hashtab.h"
/* An entry in the strtab hash table. */
struct elf_strtab_hash_entry
{
struct bfd_hash_entry root;
/* Length of this entry. */
unsigned int len;
unsigned int refcount;
union {
/* Index within the merged section. */
bfd_size_type index;
/* Entry this is a suffix of (if len is 0). */
struct elf_strtab_hash_entry *suffix;
} u;
};
/* The strtab hash table. */
struct elf_strtab_hash
{
struct bfd_hash_table table;
/* Next available index. */
bfd_size_type size;
/* Number of array entries alloced. */
bfd_size_type alloced;
/* Final strtab size. */
bfd_size_type sec_size;
/* Array of pointers to strtab entries. */
struct elf_strtab_hash_entry **array;
};
static struct bfd_hash_entry *elf_strtab_hash_newfunc
PARAMS ((struct bfd_hash_entry *, struct bfd_hash_table *, const char *));
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));
/* Routine to create an entry in a section merge hashtab. */
static struct bfd_hash_entry *
elf_strtab_hash_newfunc (entry, table, string)
struct bfd_hash_entry *entry;
struct bfd_hash_table *table;
const char *string;
{
struct elf_strtab_hash_entry *ret = (struct elf_strtab_hash_entry *) entry;
/* Allocate the structure if it has not already been allocated by a
subclass. */
if (ret == (struct elf_strtab_hash_entry *) NULL)
ret = ((struct elf_strtab_hash_entry *)
bfd_hash_allocate (table, sizeof (struct elf_strtab_hash_entry)));
if (ret == (struct elf_strtab_hash_entry *) NULL)
return NULL;
/* Call the allocation method of the superclass. */
ret = ((struct elf_strtab_hash_entry *)
bfd_hash_newfunc ((struct bfd_hash_entry *) ret, table, string));
if (ret)
{
/* Initialize the local fields. */
ret->u.index = -1;
ret->refcount = 0;
ret->len = 0;
}
return (struct bfd_hash_entry *)ret;
}
/* Create a new hash table. */
struct elf_strtab_hash *
_bfd_elf_strtab_init ()
{
struct elf_strtab_hash *table;
bfd_size_type amt = sizeof (struct elf_strtab_hash);
table = (struct elf_strtab_hash *) bfd_malloc (amt);
if (table == NULL)
return NULL;
if (! bfd_hash_table_init (&table->table, elf_strtab_hash_newfunc))
{
free (table);
return NULL;
}
table->sec_size = 0;
table->size = 1;
table->alloced = 64;
amt = sizeof (struct elf_strtab_hasn_entry *);
table->array = (struct elf_strtab_hash_entry **)
bfd_malloc (table->alloced * amt);
if (table->array == NULL)
{
free (table);
return NULL;
}
table->array[0] = NULL;
return table;
}
/* Free a strtab. */
void
_bfd_elf_strtab_free (tab)
struct elf_strtab_hash *tab;
{
bfd_hash_table_free (&tab->table);
free (tab->array);
free (tab);
}
/* Get the index of an entity in a hash table, adding it if it is not
already present. */
bfd_size_type
_bfd_elf_strtab_add (tab, str, copy)
struct elf_strtab_hash *tab;
const char *str;
boolean copy;
{
register struct elf_strtab_hash_entry *entry;
/* We handle this specially, since we don't want to do refcounting
on it. */
if (*str == '\0')
return 0;
BFD_ASSERT (tab->sec_size == 0);
entry = (struct elf_strtab_hash_entry *)
bfd_hash_lookup (&tab->table, str, true, copy);
if (entry == NULL)
return (bfd_size_type) -1;
entry->refcount++;
if (entry->len == 0)
{
entry->len = strlen (str) + 1;
if (tab->size == tab->alloced)
{
bfd_size_type amt = sizeof (struct elf_strtab_hash_entry *);
tab->alloced *= 2;
tab->array = (struct elf_strtab_hash_entry **)
bfd_realloc (tab->array, tab->alloced * amt);
if (tab->array == NULL)
return (bfd_size_type) -1;
}
entry->u.index = tab->size++;
tab->array[entry->u.index] = entry;
}
return entry->u.index;
}
void
_bfd_elf_strtab_addref (tab, idx)
struct elf_strtab_hash *tab;
bfd_size_type idx;
{
if (idx == 0 || idx == (bfd_size_type) -1)
return;
BFD_ASSERT (tab->sec_size == 0);
BFD_ASSERT (idx < tab->size);
++tab->array[idx]->refcount;
}
void
_bfd_elf_strtab_delref (tab, idx)
struct elf_strtab_hash *tab;
bfd_size_type idx;
{
if (idx == 0 || idx == (bfd_size_type) -1)
return;
BFD_ASSERT (tab->sec_size == 0);
BFD_ASSERT (idx < tab->size);
BFD_ASSERT (tab->array[idx]->refcount > 0);
--tab->array[idx]->refcount;
}
void
_bfd_elf_strtab_clear_all_refs (tab)
struct elf_strtab_hash *tab;
{
bfd_size_type idx;
for (idx = 1; idx < tab->size; ++idx)
tab->array[idx]->refcount = 0;
}
bfd_size_type
_bfd_elf_strtab_size (tab)
struct elf_strtab_hash *tab;
{
return tab->sec_size ? tab->sec_size : tab->size;
}
bfd_size_type
_bfd_elf_strtab_offset (tab, idx)
struct elf_strtab_hash *tab;
bfd_size_type idx;
{
struct elf_strtab_hash_entry *entry;
if (idx == 0)
return 0;
BFD_ASSERT (idx < tab->size);
BFD_ASSERT (tab->sec_size);
entry = tab->array[idx];
BFD_ASSERT (entry->refcount > 0);
entry->refcount--;
return tab->array[idx]->u.index;
}
boolean
_bfd_elf_strtab_emit (abfd, tab)
register bfd *abfd;
struct elf_strtab_hash *tab;
{
bfd_size_type off = 1, i;
if (bfd_bwrite ("", 1, abfd) != 1)
return false;
for (i = 1; i < tab->size; ++i)
{
register const char *str;
register size_t len;
str = tab->array[i]->root.string;
len = tab->array[i]->len;
BFD_ASSERT (tab->array[i]->refcount == 0);
if (len == 0)
continue;
if (bfd_bwrite ((PTR) str, (bfd_size_type) len, abfd) != len)
return false;
off += len;
}
BFD_ASSERT (off == tab->sec_size);
return true;
}
/* Compare two elf_strtab_hash_entry structures. This is called via qsort. */
static int
cmplengthentry (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;
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 elf_strtab_hash_entry * A = (struct elf_strtab_hash_entry *) a;
struct elf_strtab_hash_entry * B = (struct elf_strtab_hash_entry *) 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
not to be equal by the hash table. */
return 0;
return memcmp (A->root.string + (A->len - B->len),
B->root.string, B->len - 5) == 0;
}
static int
last_eq (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;
if (B->len >= 5)
/* 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, B->root.string + B->len - 2, 1)
!= 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;
return memcmp (A->root.string + (A->len - B->len),
B->root.string, B->len - 2) == 0;
}
/* This function assigns final string table offsets for used strings,
merging strings matching suffixes of longer strings if possible. */
void
_bfd_elf_strtab_finalize (tab)
struct elf_strtab_hash *tab;
{
struct elf_strtab_hash_entry **array, **a, **end, *e;
htab_t lasttab = NULL, last4tab = NULL;
bfd_size_type size, amt, i;
/* Now sort the strings by length, longest first. */
array = NULL;
amt = tab->size * sizeof (struct elf_strtab_hash_entry *);
array = (struct elf_strtab_hash_entry **) 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];
else
tab->array[i]->len = 0;
size = a - array;
qsort (array, size, sizeof (struct elf_strtab_hash_entry *), cmplengthentry);
last4tab = htab_create (size * 4, NULL, last4_eq, NULL);
lasttab = htab_create (size * 4, NULL, last_eq, NULL);
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 + size; a < end; a++)
{
register hashval_t hash;
unsigned int c;
unsigned int i;
const unsigned char *s;
PTR *p;
e = *a;
if (e->len > 4)
{
s = e->root.string + e->len - 1;
hash = 0;
for (i = 0; i < 4; 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 elf_strtab_hash_entry *ent;
ent = (struct elf_strtab_hash_entry *) *p;
e->u.suffix = ent;
e->len = 0;
continue;
}
else
*p = (PTR) e;
}
c = (unsigned char) e->root.string[e->len - 1];
p = htab_find_slot_with_hash (lasttab, e, c, INSERT);
if (p == NULL)
goto alloc_failure;
if (*p)
{
struct elf_strtab_hash_entry *ent;
ent = (struct elf_strtab_hash_entry *) *p;
e->u.suffix = ent;
e->len = 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 = 1;
for (i = 1; i < tab->size; ++i)
{
e = tab->array[i];
if (e->refcount && e->len)
{
e->u.index = size;
size += e->len;
}
}
tab->sec_size = size;
/* And now adjust the rest. */
for (i = 1; i < tab->size; ++i)
{
e = tab->array[i];
if (e->refcount && ! e->len)
e->u.index = e->u.suffix->u.index
+ (e->u.suffix->len - strlen (e->root.string) - 1);
}
}

View File

@ -1939,8 +1939,8 @@ _bfd_elf_init_reloc_shdr (abfd, rel_hdr, asect, use_rela_p)
return false;
sprintf (name, "%s%s", use_rela_p ? ".rela" : ".rel", asect->name);
rel_hdr->sh_name =
(unsigned int) _bfd_stringtab_add (elf_shstrtab (abfd), name,
true, false);
(unsigned int) _bfd_elf_strtab_add (elf_shstrtab (abfd), name,
false);
if (rel_hdr->sh_name == (unsigned int) -1)
return false;
rel_hdr->sh_type = use_rela_p ? SHT_RELA : SHT_REL;
@ -1977,9 +1977,8 @@ elf_fake_sections (abfd, asect, failedptrarg)
this_hdr = &elf_section_data (asect)->this_hdr;
this_hdr->sh_name = (unsigned long) _bfd_stringtab_add (elf_shstrtab (abfd),
asect->name,
true, false);
this_hdr->sh_name = (unsigned long) _bfd_elf_strtab_add (elf_shstrtab (abfd),
asect->name, false);
if (this_hdr->sh_name == (unsigned long) -1)
{
*failedptr = true;
@ -2200,38 +2199,51 @@ assign_section_numbers (abfd)
{
struct elf_obj_tdata *t = elf_tdata (abfd);
asection *sec;
unsigned int section_number;
unsigned int section_number, secn;
Elf_Internal_Shdr **i_shdrp;
bfd_size_type amt;
section_number = 1;
_bfd_elf_strtab_clear_all_refs (elf_shstrtab (abfd));
for (sec = abfd->sections; sec; sec = sec->next)
{
struct bfd_elf_section_data *d = elf_section_data (sec);
d->this_idx = section_number++;
_bfd_elf_strtab_addref (elf_shstrtab (abfd), d->this_hdr.sh_name);
if ((sec->flags & SEC_RELOC) == 0)
d->rel_idx = 0;
else
d->rel_idx = section_number++;
{
d->rel_idx = section_number++;
_bfd_elf_strtab_addref (elf_shstrtab (abfd), d->rel_hdr.sh_name);
}
if (d->rel_hdr2)
d->rel_idx2 = section_number++;
{
d->rel_idx2 = section_number++;
_bfd_elf_strtab_addref (elf_shstrtab (abfd), d->rel_hdr2->sh_name);
}
else
d->rel_idx2 = 0;
}
t->shstrtab_section = section_number++;
_bfd_elf_strtab_addref (elf_shstrtab (abfd), t->shstrtab_hdr.sh_name);
elf_elfheader (abfd)->e_shstrndx = t->shstrtab_section;
t->shstrtab_hdr.sh_size = _bfd_stringtab_size (elf_shstrtab (abfd));
if (bfd_get_symcount (abfd) > 0)
{
t->symtab_section = section_number++;
_bfd_elf_strtab_addref (elf_shstrtab (abfd), t->symtab_hdr.sh_name);
t->strtab_section = section_number++;
_bfd_elf_strtab_addref (elf_shstrtab (abfd), t->strtab_hdr.sh_name);
}
_bfd_elf_strtab_finalize (elf_shstrtab (abfd));
t->shstrtab_hdr.sh_size = _bfd_elf_strtab_size (elf_shstrtab (abfd));
elf_elfheader (abfd)->e_shnum = section_number;
/* Set up the list of section header pointers, in agreement with the
@ -2368,6 +2380,10 @@ assign_section_numbers (abfd)
}
}
for (secn = 1; secn < section_number; ++secn)
i_shdrp[secn]->sh_name = _bfd_elf_strtab_offset (elf_shstrtab (abfd),
i_shdrp[secn]->sh_name);
return true;
}
@ -2629,7 +2645,7 @@ _bfd_elf_compute_section_file_positions (abfd, link_info)
shstrtab_hdr->sh_type = SHT_STRTAB;
shstrtab_hdr->sh_flags = 0;
shstrtab_hdr->sh_addr = 0;
shstrtab_hdr->sh_size = _bfd_stringtab_size (elf_shstrtab (abfd));
shstrtab_hdr->sh_size = _bfd_elf_strtab_size (elf_shstrtab (abfd));
shstrtab_hdr->sh_entsize = 0;
shstrtab_hdr->sh_link = 0;
shstrtab_hdr->sh_info = 0;
@ -3620,13 +3636,13 @@ prep_headers (abfd)
Elf_Internal_Phdr *i_phdrp = 0; /* Program header table, internal form */
Elf_Internal_Shdr **i_shdrp; /* Section header table, internal form */
int count;
struct bfd_strtab_hash *shstrtab;
struct elf_strtab_hash *shstrtab;
struct elf_backend_data *bed = get_elf_backend_data (abfd);
i_ehdrp = elf_elfheader (abfd);
i_shdrp = elf_elfsections (abfd);
shstrtab = _bfd_elf_stringtab_init ();
shstrtab = _bfd_elf_strtab_init ();
if (shstrtab == NULL)
return false;
@ -3712,11 +3728,11 @@ prep_headers (abfd)
}
elf_tdata (abfd)->symtab_hdr.sh_name =
(unsigned int) _bfd_stringtab_add (shstrtab, ".symtab", true, false);
(unsigned int) _bfd_elf_strtab_add (shstrtab, ".symtab", false);
elf_tdata (abfd)->strtab_hdr.sh_name =
(unsigned int) _bfd_stringtab_add (shstrtab, ".strtab", true, false);
(unsigned int) _bfd_elf_strtab_add (shstrtab, ".strtab", false);
elf_tdata (abfd)->shstrtab_hdr.sh_name =
(unsigned int) _bfd_stringtab_add (shstrtab, ".shstrtab", true, false);
(unsigned int) _bfd_elf_strtab_add (shstrtab, ".shstrtab", false);
if (elf_tdata (abfd)->symtab_hdr.sh_name == (unsigned int) -1
|| elf_tdata (abfd)->symtab_hdr.sh_name == (unsigned int) -1
|| elf_tdata (abfd)->shstrtab_hdr.sh_name == (unsigned int) -1)
@ -3795,7 +3811,7 @@ _bfd_elf_write_object_contents (abfd)
/* Write out the section header names. */
if (bfd_seek (abfd, elf_tdata (abfd)->shstrtab_hdr.sh_offset, SEEK_SET) != 0
|| ! _bfd_stringtab_emit (abfd, elf_shstrtab (abfd)))
|| ! _bfd_elf_strtab_emit (abfd, elf_shstrtab (abfd)))
return false;
if (bed->elf_backend_final_write_processing)
@ -5549,7 +5565,7 @@ _bfd_elf_close_and_cleanup (abfd)
if (bfd_get_format (abfd) == bfd_object)
{
if (elf_shstrtab (abfd) != NULL)
_bfd_stringtab_free (elf_shstrtab (abfd));
_bfd_elf_strtab_free (elf_shstrtab (abfd));
}
return _bfd_generic_close_and_cleanup (abfd);

View File

@ -1840,7 +1840,7 @@ sparc64_elf_size_dynamic_sections (output_bfd, info)
entry->isym.st_size = 0;
if (*app_regs [reg].name != '\0')
entry->isym.st_name
= _bfd_stringtab_add (dynstr, app_regs[reg].name, true, false);
= _bfd_elf_strtab_add (dynstr, app_regs[reg].name, false);
else
entry->isym.st_name = 0;
entry->isym.st_other = 0;

View File

@ -230,7 +230,7 @@ _bfd_elf_link_record_dynamic_symbol (info, h)
{
if (h->dynindx == -1)
{
struct bfd_strtab_hash *dynstr;
struct elf_strtab_hash *dynstr;
char *p, *alc;
const char *name;
boolean copy;
@ -262,7 +262,7 @@ _bfd_elf_link_record_dynamic_symbol (info, h)
if (dynstr == NULL)
{
/* Create a strtab to hold the dynamic symbol names. */
elf_hash_table (info)->dynstr = dynstr = _bfd_elf_stringtab_init ();
elf_hash_table (info)->dynstr = dynstr = _bfd_elf_strtab_init ();
if (dynstr == NULL)
return false;
}
@ -287,7 +287,7 @@ _bfd_elf_link_record_dynamic_symbol (info, h)
copy = true;
}
indx = _bfd_stringtab_add (dynstr, name, true, copy);
indx = _bfd_elf_strtab_add (dynstr, name, copy);
if (alc != NULL)
free (alc);

View File

@ -44,6 +44,8 @@ static boolean elf_merge_symbol
boolean *, boolean *, boolean *, boolean));
static boolean elf_export_symbol
PARAMS ((struct elf_link_hash_entry *, PTR));
static boolean elf_finalize_dynstr
PARAMS ((bfd *, struct bfd_link_info *));
static boolean elf_fix_symbol_flags
PARAMS ((struct elf_link_hash_entry *, struct elf_info_failed *));
static boolean elf_adjust_dynamic_symbol
@ -1294,13 +1296,12 @@ elf_link_add_object_symbols (abfd, info)
if (add_needed)
{
/* Add a DT_NEEDED entry for this dynamic object. */
oldsize = _bfd_stringtab_size (hash_table->dynstr);
strindex = _bfd_stringtab_add (hash_table->dynstr, name,
true, false);
oldsize = _bfd_elf_strtab_size (hash_table->dynstr);
strindex = _bfd_elf_strtab_add (hash_table->dynstr, name, false);
if (strindex == (bfd_size_type) -1)
goto error_return;
if (oldsize == _bfd_stringtab_size (hash_table->dynstr))
if (oldsize == _bfd_elf_strtab_size (hash_table->dynstr))
{
asection *sdyn;
Elf_External_Dyn *dyncon, *dynconend;
@ -1328,6 +1329,7 @@ elf_link_add_object_symbols (abfd, info)
free (buf);
if (extversym != NULL)
free (extversym);
_bfd_elf_strtab_delref (hash_table->dynstr, strindex);
return true;
}
}
@ -1965,6 +1967,8 @@ elf_link_add_object_symbols (abfd, info)
case STV_HIDDEN:
h->elf_link_hash_flags |= ELF_LINK_FORCED_LOCAL;
(*bed->elf_backend_hide_symbol) (info, h);
_bfd_elf_strtab_delref (hash_table->dynstr,
h->dynstr_index);
break;
}
@ -1983,15 +1987,13 @@ elf_link_add_object_symbols (abfd, info)
have to make sure there is a DT_NEEDED entry for it. */
dt_needed = false;
oldsize = _bfd_stringtab_size (hash_table->dynstr);
strindex = _bfd_stringtab_add (hash_table->dynstr,
elf_dt_soname (abfd),
true, false);
oldsize = _bfd_elf_strtab_size (hash_table->dynstr);
strindex = _bfd_elf_strtab_add (hash_table->dynstr,
elf_dt_soname (abfd), false);
if (strindex == (bfd_size_type) -1)
goto error_return;
if (oldsize
== _bfd_stringtab_size (hash_table->dynstr))
if (oldsize == _bfd_elf_strtab_size (hash_table->dynstr))
{
asection *sdyn;
Elf_External_Dyn *dyncon, *dynconend;
@ -2290,7 +2292,7 @@ elf_link_create_dynamic_sections (abfd, info)
/* Create a strtab to hold the dynamic symbol names. */
if (elf_hash_table (info)->dynstr == NULL)
{
elf_hash_table (info)->dynstr = elf_stringtab_init ();
elf_hash_table (info)->dynstr = _bfd_elf_strtab_init ();
if (elf_hash_table (info)->dynstr == NULL)
return false;
}
@ -2390,7 +2392,7 @@ elf_link_record_local_dynamic_symbol (info, input_bfd, input_indx)
{
struct elf_link_local_dynamic_entry *entry;
struct elf_link_hash_table *eht;
struct bfd_strtab_hash *dynstr;
struct elf_strtab_hash *dynstr;
Elf_External_Sym esym;
unsigned long dynstr_index;
char *name;
@ -2426,12 +2428,12 @@ elf_link_record_local_dynamic_symbol (info, input_bfd, input_indx)
if (dynstr == NULL)
{
/* Create a strtab to hold the dynamic symbol names. */
elf_hash_table (info)->dynstr = dynstr = _bfd_elf_stringtab_init ();
elf_hash_table (info)->dynstr = dynstr = _bfd_elf_strtab_init ();
if (dynstr == NULL)
return false;
}
dynstr_index = _bfd_stringtab_add (dynstr, name, true, false);
dynstr_index = _bfd_elf_strtab_add (dynstr, name, false);
if (dynstr_index == (unsigned long) -1)
return false;
entry->isym.st_name = dynstr_index;
@ -2949,8 +2951,8 @@ NAME(bfd_elf,size_dynamic_sections) (output_bfd, soname, rpath,
if (soname != NULL)
{
soname_indx = _bfd_stringtab_add (elf_hash_table (info)->dynstr,
soname, true, true);
soname_indx = _bfd_elf_strtab_add (elf_hash_table (info)->dynstr,
soname, true);
if (soname_indx == (bfd_size_type) -1
|| ! elf_add_dynamic_entry (info, (bfd_vma) DT_SONAME,
soname_indx))
@ -2969,8 +2971,10 @@ NAME(bfd_elf,size_dynamic_sections) (output_bfd, soname, rpath,
{
bfd_size_type indx;
indx = _bfd_stringtab_add (elf_hash_table (info)->dynstr, rpath,
true, true);
indx = _bfd_elf_strtab_add (elf_hash_table (info)->dynstr, rpath,
true);
if (info->new_dtags)
_bfd_elf_strtab_addref (elf_hash_table (info)->dynstr, indx);
if (indx == (bfd_size_type) -1
|| ! elf_add_dynamic_entry (info, (bfd_vma) DT_RPATH, indx)
|| (info->new_dtags
@ -2983,8 +2987,8 @@ NAME(bfd_elf,size_dynamic_sections) (output_bfd, soname, rpath,
{
bfd_size_type indx;
indx = _bfd_stringtab_add (elf_hash_table (info)->dynstr,
filter_shlib, true, true);
indx = _bfd_elf_strtab_add (elf_hash_table (info)->dynstr,
filter_shlib, true);
if (indx == (bfd_size_type) -1
|| ! elf_add_dynamic_entry (info, (bfd_vma) DT_FILTER, indx))
return false;
@ -2998,8 +3002,8 @@ NAME(bfd_elf,size_dynamic_sections) (output_bfd, soname, rpath,
{
bfd_size_type indx;
indx = _bfd_stringtab_add (elf_hash_table (info)->dynstr,
*p, true, true);
indx = _bfd_elf_strtab_add (elf_hash_table (info)->dynstr,
*p, true);
if (indx == (bfd_size_type) -1
|| ! elf_add_dynamic_entry (info, (bfd_vma) DT_AUXILIARY,
indx))
@ -3081,7 +3085,7 @@ NAME(bfd_elf,size_dynamic_sections) (output_bfd, soname, rpath,
{
bfd_size_type strsize;
strsize = _bfd_stringtab_size (elf_hash_table (info)->dynstr);
strsize = _bfd_elf_strtab_size (elf_hash_table (info)->dynstr);
if (! elf_add_dynamic_entry (info, (bfd_vma) DT_HASH, (bfd_vma) 0)
|| ! elf_add_dynamic_entry (info, (bfd_vma) DT_STRTAB, (bfd_vma) 0)
|| ! elf_add_dynamic_entry (info, (bfd_vma) DT_SYMTAB, (bfd_vma) 0)
@ -3164,6 +3168,8 @@ NAME(bfd_elf,size_dynamic_sections) (output_bfd, soname, rpath,
if (soname_indx != (bfd_size_type) -1)
{
_bfd_elf_strtab_addref (elf_hash_table (info)->dynstr,
soname_indx);
def.vd_hash = bfd_elf_hash (soname);
defaux.vda_name = soname_indx;
}
@ -3174,8 +3180,8 @@ NAME(bfd_elf,size_dynamic_sections) (output_bfd, soname, rpath,
name = basename (output_bfd->filename);
def.vd_hash = bfd_elf_hash (name);
indx = _bfd_stringtab_add (elf_hash_table (info)->dynstr,
name, true, false);
indx = _bfd_elf_strtab_add (elf_hash_table (info)->dynstr,
name, false);
if (indx == (bfd_size_type) -1)
return false;
defaux.vda_name = indx;
@ -3234,6 +3240,8 @@ NAME(bfd_elf,size_dynamic_sections) (output_bfd, soname, rpath,
p += sizeof (Elf_External_Verdef);
defaux.vda_name = h->dynstr_index;
_bfd_elf_strtab_addref (elf_hash_table (info)->dynstr,
h->dynstr_index);
if (t->deps == NULL)
defaux.vda_next = 0;
else
@ -3253,7 +3261,11 @@ NAME(bfd_elf,size_dynamic_sections) (output_bfd, soname, rpath,
defaux.vda_name = 0;
}
else
defaux.vda_name = n->version_needed->name_indx;
{
defaux.vda_name = n->version_needed->name_indx;
_bfd_elf_strtab_addref (elf_hash_table (info)->dynstr,
defaux.vda_name);
}
if (n->next == NULL)
defaux.vda_next = 0;
else
@ -3352,14 +3364,11 @@ NAME(bfd_elf,size_dynamic_sections) (output_bfd, soname, rpath,
t->vn_version = VER_NEED_CURRENT;
t->vn_cnt = caux;
if (elf_dt_name (t->vn_bfd) != NULL)
indx = _bfd_stringtab_add (elf_hash_table (info)->dynstr,
elf_dt_name (t->vn_bfd),
true, false);
else
indx = _bfd_stringtab_add (elf_hash_table (info)->dynstr,
basename (t->vn_bfd->filename),
true, false);
indx = _bfd_elf_strtab_add (elf_hash_table (info)->dynstr,
elf_dt_name (t->vn_bfd) != NULL
? elf_dt_name (t->vn_bfd)
: basename (t->vn_bfd->filename),
false);
if (indx == (bfd_size_type) -1)
return false;
t->vn_file = indx;
@ -3377,8 +3386,8 @@ NAME(bfd_elf,size_dynamic_sections) (output_bfd, soname, rpath,
for (a = t->vn_auxptr; a != NULL; a = a->vna_nextptr)
{
a->vna_hash = bfd_elf_hash (a->vna_nodename);
indx = _bfd_stringtab_add (elf_hash_table (info)->dynstr,
a->vna_nodename, true, false);
indx = _bfd_elf_strtab_add (elf_hash_table (info)->dynstr,
a->vna_nodename, false);
if (indx == (bfd_size_type) -1)
return false;
a->vna_name = indx;
@ -3482,7 +3491,10 @@ NAME(bfd_elf,size_dynamic_sections) (output_bfd, soname, rpath,
s = bfd_get_section_by_name (dynobj, ".dynstr");
BFD_ASSERT (s != NULL);
s->_raw_size = _bfd_stringtab_size (elf_hash_table (info)->dynstr);
elf_finalize_dynstr (output_bfd, info);
s->_raw_size = _bfd_elf_strtab_size (elf_hash_table (info)->dynstr);
for (dtagcount = 0; dtagcount <= info->spare_dynamic_tags; ++dtagcount)
if (! elf_add_dynamic_entry (info, (bfd_vma) DT_NULL, (bfd_vma) 0))
@ -3492,6 +3504,150 @@ NAME(bfd_elf,size_dynamic_sections) (output_bfd, soname, rpath,
return true;
}
/* This function is used to adjust offsets into .dynstr for
dynamic symbols. This is called via elf_link_hash_traverse. */
static boolean elf_adjust_dynstr_offsets
PARAMS ((struct elf_link_hash_entry *, PTR));
static boolean
elf_adjust_dynstr_offsets (h, data)
struct elf_link_hash_entry *h;
PTR data;
{
struct elf_strtab_hash *dynstr = (struct elf_strtab_hash *) data;
if (h->dynindx != -1)
h->dynstr_index = _bfd_elf_strtab_offset (dynstr, h->dynstr_index);
return true;
}
/* Assign string offsets in .dynstr, update all structures referencing
them. */
static boolean
elf_finalize_dynstr (output_bfd, info)
bfd *output_bfd;
struct bfd_link_info *info;
{
struct elf_link_local_dynamic_entry *entry;
struct elf_strtab_hash *dynstr = elf_hash_table (info)->dynstr;
bfd *dynobj = elf_hash_table (info)->dynobj;
asection *sdyn;
bfd_size_type size;
Elf_External_Dyn *dyncon, *dynconend;
_bfd_elf_strtab_finalize (dynstr);
size = _bfd_elf_strtab_size (dynstr);
/* Update all .dynamic entries referencing .dynstr strings. */
sdyn = bfd_get_section_by_name (dynobj, ".dynamic");
BFD_ASSERT (sdyn != NULL);
dyncon = (Elf_External_Dyn *) sdyn->contents;
dynconend = (Elf_External_Dyn *) (sdyn->contents +
sdyn->_raw_size);
for (; dyncon < dynconend; dyncon++)
{
Elf_Internal_Dyn dyn;
elf_swap_dyn_in (dynobj, dyncon, & dyn);
switch (dyn.d_tag)
{
case DT_STRSZ:
dyn.d_un.d_val = size;
elf_swap_dyn_out (dynobj, & dyn, dyncon);
break;
case DT_NEEDED:
case DT_SONAME:
case DT_RPATH:
case DT_RUNPATH:
case DT_FILTER:
case DT_AUXILIARY:
dyn.d_un.d_val = _bfd_elf_strtab_offset (dynstr, dyn.d_un.d_val);
elf_swap_dyn_out (dynobj, & dyn, dyncon);
break;
default:
break;
}
}
/* Now update local dynamic symbols. */
for (entry = elf_hash_table (info)->dynlocal; entry ; entry = entry->next)
entry->isym.st_name = _bfd_elf_strtab_offset (dynstr,
entry->isym.st_name);
/* And the rest of dynamic symbols. */
elf_link_hash_traverse (elf_hash_table (info),
elf_adjust_dynstr_offsets, dynstr);
/* Adjust version definitions. */
if (elf_tdata (output_bfd)->cverdefs)
{
asection *s;
bfd_byte *p;
bfd_size_type i;
Elf_Internal_Verdef def;
Elf_Internal_Verdaux defaux;
s = bfd_get_section_by_name (dynobj, ".gnu.version_d");
p = (bfd_byte *) s->contents;
do
{
_bfd_elf_swap_verdef_in (output_bfd, (Elf_External_Verdef *) p,
&def);
p += sizeof (Elf_External_Verdef);
for (i = 0; i < def.vd_cnt; ++i)
{
_bfd_elf_swap_verdaux_in (output_bfd,
(Elf_External_Verdaux *) p, &defaux);
defaux.vda_name = _bfd_elf_strtab_offset (dynstr,
defaux.vda_name);
_bfd_elf_swap_verdaux_out (output_bfd,
&defaux, (Elf_External_Verdaux *) p);
p += sizeof (Elf_External_Verdaux);
}
}
while (def.vd_next);
}
/* Adjust version references. */
if (elf_tdata (output_bfd)->verref)
{
asection *s;
bfd_byte *p;
bfd_size_type i;
Elf_Internal_Verneed need;
Elf_Internal_Vernaux needaux;
s = bfd_get_section_by_name (dynobj, ".gnu.version_r");
p = (bfd_byte *) s->contents;
do
{
_bfd_elf_swap_verneed_in (output_bfd, (Elf_External_Verneed *) p,
&need);
need.vn_file = _bfd_elf_strtab_offset (dynstr, need.vn_file);
_bfd_elf_swap_verneed_out (output_bfd, &need,
(Elf_External_Verneed *) p);
p += sizeof (Elf_External_Verneed);
for (i = 0; i < need.vn_cnt; ++i)
{
_bfd_elf_swap_vernaux_in (output_bfd,
(Elf_External_Vernaux *) p, &needaux);
needaux.vna_name = _bfd_elf_strtab_offset (dynstr,
needaux.vna_name);
_bfd_elf_swap_vernaux_out (output_bfd,
&needaux,
(Elf_External_Vernaux *) p);
p += sizeof (Elf_External_Vernaux);
}
}
while (need.vn_next);
}
return true;
}
/* Fix up the flags for a symbol. This handles various cases which
can only be fixed after all the input files are seen. This is
currently called by both adjust_dynamic_symbol and
@ -3591,7 +3747,11 @@ elf_fix_symbol_flags (h, eif)
bed = get_elf_backend_data (elf_hash_table (eif->info)->dynobj);
if (ELF_ST_VISIBILITY (h->other) == STV_INTERNAL
|| ELF_ST_VISIBILITY (h->other) == STV_HIDDEN)
h->elf_link_hash_flags |= ELF_LINK_FORCED_LOCAL;
{
h->elf_link_hash_flags |= ELF_LINK_FORCED_LOCAL;
_bfd_elf_strtab_delref (elf_hash_table (eif->info)->dynstr,
h->dynstr_index);
}
(*bed->elf_backend_hide_symbol) (eif->info, h);
}
@ -3976,9 +4136,8 @@ elf_link_assign_sym_version (h, data)
{
h->elf_link_hash_flags |= ELF_LINK_FORCED_LOCAL;
(*bed->elf_backend_hide_symbol) (info, h);
/* FIXME: The name of the symbol has
already been recorded in the dynamic
string table section. */
_bfd_elf_strtab_delref (elf_hash_table (info)->dynstr,
h->dynstr_index);
}
break;
@ -4089,9 +4248,8 @@ elf_link_assign_sym_version (h, data)
{
h->elf_link_hash_flags |= ELF_LINK_FORCED_LOCAL;
(*bed->elf_backend_hide_symbol) (info, h);
/* FIXME: The name of the symbol has already
been recorded in the dynamic string table
section. */
_bfd_elf_strtab_delref (elf_hash_table (info)->dynstr,
h->dynstr_index);
}
break;
}
@ -4111,8 +4269,8 @@ elf_link_assign_sym_version (h, data)
{
h->elf_link_hash_flags |= ELF_LINK_FORCED_LOCAL;
(*bed->elf_backend_hide_symbol) (info, h);
/* FIXME: The name of the symbol has already been
recorded in the dynamic string table section. */
_bfd_elf_strtab_delref (elf_hash_table (info)->dynstr,
h->dynstr_index);
}
}
}
@ -5308,8 +5466,8 @@ elf_bfd_final_link (abfd, info)
stringtab. */
off = elf_section_data (o->output_section)->this_hdr.sh_offset;
if (bfd_seek (abfd, off, SEEK_SET) != 0
|| ! _bfd_stringtab_emit (abfd,
elf_hash_table (info)->dynstr))
|| ! _bfd_elf_strtab_emit (abfd,
elf_hash_table (info)->dynstr))
goto error_return;
}
}