* elflink.h (elf_link_add_object_symbols): Use extsymoff when
setting ever. Sanity check the version number. Sort out copying flags and other information when adding an indirect symbol. (NAME(bfd_elf,size_dynamic_sections)): Preserve any dynamic symbols added by the backend. Clear the entire contents of the versym section. (elf_export_symbol): Ignore indirect symbols. (elf_link_output_extsym): Accept a section without an owner in an assert. * elfcode.h (elf_slurp_symbol_table): Add a sanity check on the version count. Correct the allocation of x_versymp.
This commit is contained in:
parent
7d996a75d2
commit
e549b1d2a3
3 changed files with 274 additions and 38 deletions
|
@ -1,3 +1,45 @@
|
|||
Wed Mar 12 21:36:05 1997 Ian Lance Taylor <ian@cygnus.com>
|
||||
|
||||
* elflink.h (elf_link_add_object_symbols): Use extsymoff when
|
||||
setting ever. Sanity check the version number. Sort out copying
|
||||
flags and other information when adding an indirect symbol.
|
||||
(NAME(bfd_elf,size_dynamic_sections)): Preserve any dynamic
|
||||
symbols added by the backend. Clear the entire contents of the
|
||||
versym section.
|
||||
(elf_export_symbol): Ignore indirect symbols.
|
||||
(elf_link_output_extsym): Accept a section without an owner in an
|
||||
assert.
|
||||
* elfcode.h (elf_slurp_symbol_table): Add a sanity check on the
|
||||
version count. Correct the allocation of x_versymp.
|
||||
|
||||
* elf32-mips.c (mips_elf_add_symbol_hook): Don't set the owner of
|
||||
the magic sections used for SHN_MIPS_TEXT and SHN_MIPS_DATA.
|
||||
Don't return bfd_und_section_ptr when info->shared.
|
||||
(mips_elf_final_link): Set the alignment of .rtproc to 4, not 12.
|
||||
(mips_elf_create_dynamic_sections): Correct type: ^= for &=.
|
||||
(mips_elf_check_relocs): Resolve an indirect symbol in
|
||||
sym_hashes.
|
||||
(mips_elf_finish_dynamic_symbol): Don't change SHN_ABS into
|
||||
SHN_MIPS_TEXT or SHN_MIPS_DATA.
|
||||
|
||||
* elf.c (bfd_elf_print_symbol): Tweak version output slightly.
|
||||
|
||||
Tue Mar 11 01:38:36 1997 Ian Lance Taylor <ian@cygnus.com>
|
||||
|
||||
From Eric Youngdale <eric@andante.jic.com>:
|
||||
* elf-bfd.h (ELF_LINK_FORCED_LOCAL): Define.
|
||||
* elf.c (bfd_elf_print_symbol): Correct errors in last change.
|
||||
* elflink.h (elf_link_add_object_symbols): Handle cases in which a
|
||||
versioned symbol appears in both a regular and a shared object.
|
||||
(elf_link_assign_sym_version): Set ELF_LINK_FORCED_LOCAL when
|
||||
appropriate. Improve error message.
|
||||
(struct elf_outext_info): Rename from elf_finfo_failed. Change
|
||||
all uses. Add localsyms field.
|
||||
(elf_bfd_final_link): When generating a shared library, call
|
||||
elf_link_output_extsym to output all local symbols.
|
||||
(elf_link_output_extsym): Handle symbols which were forced to
|
||||
become local.
|
||||
|
||||
Sun Mar 9 23:08:49 1997 Ian Lance Taylor <ian@cygnus.com>
|
||||
|
||||
From Eric Youngdale <eric@andante.jic.com>:
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/* ELF executable support for BFD.
|
||||
Copyright 1991, 1992, 1993, 1994, 1995, 1996 Free Software Foundation, Inc.
|
||||
Copyright 1991, 92, 93, 94, 95, 96, 1997 Free Software Foundation, Inc.
|
||||
|
||||
Written by Fred Fish @ Cygnus Support, from information published
|
||||
in "UNIX System V Release 4, Programmers Guide: ANSI C and
|
||||
|
@ -68,6 +68,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
|
|||
#include "bfdlink.h"
|
||||
#include "libbfd.h"
|
||||
#include "elf-bfd.h"
|
||||
#include "fnmatch.h"
|
||||
|
||||
/* Renaming structures, typedefs, macros and functions to be size-specific. */
|
||||
#define Elf_External_Ehdr NAME(Elf,External_Ehdr)
|
||||
|
@ -455,6 +456,7 @@ elf_object_p (abfd)
|
|||
struct elf_backend_data *ebd;
|
||||
struct elf_obj_tdata *preserved_tdata = elf_tdata (abfd);
|
||||
struct elf_obj_tdata *new_tdata = NULL;
|
||||
asection *s;
|
||||
|
||||
/* Read in the ELF header in external format. */
|
||||
|
||||
|
@ -658,6 +660,25 @@ elf_object_p (abfd)
|
|||
goto got_wrong_format_error;
|
||||
}
|
||||
|
||||
/* If we have created any reloc sections that are associated with
|
||||
debugging sections, mark the reloc sections as debugging as well. */
|
||||
for (s = abfd->sections; s != NULL; s = s->next)
|
||||
{
|
||||
if ((elf_section_data (s)->this_hdr.sh_type == SHT_REL
|
||||
|| elf_section_data (s)->this_hdr.sh_type == SHT_RELA)
|
||||
&& elf_section_data (s)->this_hdr.sh_info > 0)
|
||||
{
|
||||
unsigned long targ_index;
|
||||
asection *targ_sec;
|
||||
|
||||
targ_index = elf_section_data (s)->this_hdr.sh_info;
|
||||
targ_sec = bfd_section_from_elf_index (abfd, targ_index);
|
||||
if (targ_sec != NULL
|
||||
&& (targ_sec->flags & SEC_DEBUGGING) != 0)
|
||||
s->flags |= SEC_DEBUGGING;
|
||||
}
|
||||
}
|
||||
|
||||
return (abfd->xvec);
|
||||
|
||||
got_wrong_format_error:
|
||||
|
@ -902,11 +923,13 @@ elf_slurp_symbol_table (abfd, symptrs, dynamic)
|
|||
boolean dynamic;
|
||||
{
|
||||
Elf_Internal_Shdr *hdr;
|
||||
Elf_Internal_Shdr *verhdr;
|
||||
long symcount; /* Number of external ELF symbols */
|
||||
elf_symbol_type *sym; /* Pointer to current bfd symbol */
|
||||
elf_symbol_type *symbase; /* Buffer for generated bfd symbols */
|
||||
Elf_Internal_Sym i_sym;
|
||||
Elf_External_Sym *x_symp = NULL;
|
||||
Elf_External_Versym *x_versymp = NULL;
|
||||
|
||||
/* Read each raw ELF symbol, converting from external ELF form to
|
||||
internal ELF form, and then using the information to create a
|
||||
|
@ -918,10 +941,25 @@ elf_slurp_symbol_table (abfd, symptrs, dynamic)
|
|||
space left over at the end. When we have all the symbols, we
|
||||
build the caller's pointer vector. */
|
||||
|
||||
if (dynamic)
|
||||
hdr = &elf_tdata (abfd)->dynsymtab_hdr;
|
||||
if (! dynamic)
|
||||
{
|
||||
hdr = &elf_tdata (abfd)->symtab_hdr;
|
||||
verhdr = NULL;
|
||||
}
|
||||
else
|
||||
hdr = &elf_tdata (abfd)->symtab_hdr;
|
||||
{
|
||||
hdr = &elf_tdata (abfd)->dynsymtab_hdr;
|
||||
verhdr = &elf_tdata (abfd)->dynversym_hdr;
|
||||
if ((elf_tdata (abfd)->dynverdef_section != 0
|
||||
&& elf_tdata (abfd)->verdef == NULL)
|
||||
|| (elf_tdata (abfd)->dynverref_section != 0
|
||||
&& elf_tdata (abfd)->verref == NULL))
|
||||
{
|
||||
if (! _bfd_elf_slurp_version_tables (abfd))
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
if (bfd_seek (abfd, hdr->sh_offset, SEEK_SET) == -1)
|
||||
return -1;
|
||||
|
||||
|
@ -951,6 +989,38 @@ elf_slurp_symbol_table (abfd, symptrs, dynamic)
|
|||
if (bfd_read ((PTR) x_symp, sizeof (Elf_External_Sym), symcount, abfd)
|
||||
!= symcount * sizeof (Elf_External_Sym))
|
||||
goto error_return;
|
||||
|
||||
/* Read the raw ELF version symbol information. */
|
||||
|
||||
if (elf_dynversym (abfd) != 0
|
||||
&& verhdr != NULL
|
||||
&& verhdr->sh_size / sizeof (Elf_External_Versym) != symcount)
|
||||
{
|
||||
(*_bfd_error_handler)
|
||||
("%s: version count (%ld) does not match symbol count (%ld)",
|
||||
abfd->filename,
|
||||
(long) (verhdr->sh_size / sizeof (Elf_External_Versym)),
|
||||
symcount);
|
||||
|
||||
/* Slurp in the symbols without the version information,
|
||||
since that is more helpful than just quitting. */
|
||||
verhdr = NULL;
|
||||
}
|
||||
|
||||
if (verhdr != NULL)
|
||||
{
|
||||
if (bfd_seek (abfd, verhdr->sh_offset, SEEK_SET) != 0)
|
||||
goto error_return;
|
||||
|
||||
x_versymp = (Elf_External_Versym *) bfd_malloc (verhdr->sh_size);
|
||||
if (x_versymp == NULL && symcount != 0)
|
||||
goto error_return;
|
||||
|
||||
if (bfd_read ((PTR) x_versymp, 1, verhdr->sh_size, abfd)
|
||||
!= verhdr->sh_size)
|
||||
goto error_return;
|
||||
}
|
||||
|
||||
/* Skip first symbol, which is a null dummy. */
|
||||
for (i = 1; i < symcount; i++)
|
||||
{
|
||||
|
@ -1035,6 +1105,14 @@ elf_slurp_symbol_table (abfd, symptrs, dynamic)
|
|||
if (dynamic)
|
||||
sym->symbol.flags |= BSF_DYNAMIC;
|
||||
|
||||
if (x_versymp != NULL)
|
||||
{
|
||||
Elf_Internal_Versym iversym;
|
||||
|
||||
_bfd_elf_swap_versym_in (abfd, x_versymp + i, &iversym);
|
||||
sym->version = iversym.vs_vers;
|
||||
}
|
||||
|
||||
/* Do some backend-specific processing on this symbol. */
|
||||
{
|
||||
struct elf_backend_data *ebd = get_elf_backend_data (abfd);
|
||||
|
@ -1071,10 +1149,14 @@ elf_slurp_symbol_table (abfd, symptrs, dynamic)
|
|||
*symptrs = 0; /* Final null pointer */
|
||||
}
|
||||
|
||||
if (x_versymp != NULL)
|
||||
free (x_versymp);
|
||||
if (x_symp != NULL)
|
||||
free (x_symp);
|
||||
return symcount;
|
||||
error_return:
|
||||
if (x_versymp != NULL)
|
||||
free (x_versymp);
|
||||
if (x_symp != NULL)
|
||||
free (x_symp);
|
||||
return -1;
|
||||
|
|
180
bfd/elflink.h
180
bfd/elflink.h
|
@ -679,7 +679,7 @@ elf_link_add_object_symbols (abfd, info)
|
|||
|
||||
weaks = NULL;
|
||||
|
||||
ever = extversym != NULL ? extversym + hdr->sh_info : NULL;
|
||||
ever = extversym != NULL ? extversym + extsymoff : NULL;
|
||||
esymend = buf + extsymcount;
|
||||
for (esym = buf;
|
||||
esym < esymend;
|
||||
|
@ -805,7 +805,16 @@ elf_link_add_object_symbols (abfd, info)
|
|||
int namelen, newlen;
|
||||
char *newname, *p;
|
||||
|
||||
if (vernum > 1)
|
||||
if (vernum > elf_tdata (abfd)->dynverdef_hdr.sh_info)
|
||||
{
|
||||
(*_bfd_error_handler)
|
||||
("%s: %s: invalid version %d (max %d)",
|
||||
abfd->filename, name, vernum,
|
||||
elf_tdata (abfd)->dynverdef_hdr.sh_info);
|
||||
bfd_set_error (bfd_error_bad_value);
|
||||
goto error_return;
|
||||
}
|
||||
else if (vernum > 1)
|
||||
verstr = elf_tdata (abfd)->verdef[vernum - 1].vd_nodename;
|
||||
else
|
||||
verstr = "";
|
||||
|
@ -1128,15 +1137,64 @@ elf_link_add_object_symbols (abfd, info)
|
|||
if (hi->root.type == bfd_link_hash_indirect)
|
||||
{
|
||||
hi->elf_link_hash_flags &= ~ ELF_LINK_NON_ELF;
|
||||
if (dynamic)
|
||||
hi->elf_link_hash_flags |=
|
||||
ELF_LINK_HASH_DEF_DYNAMIC;
|
||||
/* We don't set DEF_REGULAR because we don't
|
||||
the symbol to get exported even if we are
|
||||
exporting all defined symbols. FIXME:
|
||||
What a hack. */
|
||||
/* FIXME: Do we need to copy any flags from
|
||||
H to HI? */
|
||||
|
||||
/* If the symbol became indirect, then we
|
||||
assume that we have not seen a definition
|
||||
before. */
|
||||
BFD_ASSERT ((hi->elf_link_hash_flags
|
||||
& (ELF_LINK_HASH_DEF_DYNAMIC
|
||||
| ELF_LINK_HASH_DEF_REGULAR))
|
||||
== 0);
|
||||
|
||||
/* Copy down any references that we may have
|
||||
already seen to the symbol which just
|
||||
became indirect. */
|
||||
h->elf_link_hash_flags |=
|
||||
(hi->elf_link_hash_flags
|
||||
& (ELF_LINK_HASH_REF_DYNAMIC
|
||||
| ELF_LINK_HASH_REF_REGULAR));
|
||||
|
||||
/* Copy over the global table offset entry.
|
||||
This may have been already set up by a
|
||||
check_relocs routine. */
|
||||
if (h->got_offset == (bfd_vma) -1)
|
||||
{
|
||||
h->got_offset = hi->got_offset;
|
||||
hi->got_offset = (bfd_vma) -1;
|
||||
}
|
||||
BFD_ASSERT (hi->got_offset == (bfd_vma) -1);
|
||||
|
||||
if (h->dynindx == -1)
|
||||
{
|
||||
h->dynindx = hi->dynindx;
|
||||
h->dynstr_index = hi->dynstr_index;
|
||||
hi->dynindx = -1;
|
||||
hi->dynstr_index = 0;
|
||||
}
|
||||
BFD_ASSERT (hi->dynindx == -1);
|
||||
|
||||
/* FIXME: There may be other information to
|
||||
copy over for particular targets. */
|
||||
|
||||
/* See if the new flags lead us to realize
|
||||
that the symbol must be dynamic. */
|
||||
if (! dynsym)
|
||||
{
|
||||
if (! dynamic)
|
||||
{
|
||||
if (info->shared
|
||||
|| ((hi->elf_link_hash_flags
|
||||
& ELF_LINK_HASH_REF_DYNAMIC)
|
||||
!= 0))
|
||||
dynsym = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
if ((hi->elf_link_hash_flags
|
||||
& ELF_LINK_HASH_REF_REGULAR) != 0)
|
||||
dynsym = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1211,15 +1269,64 @@ elf_link_add_object_symbols (abfd, info)
|
|||
if (hi->root.type == bfd_link_hash_indirect)
|
||||
{
|
||||
hi->elf_link_hash_flags &= ~ ELF_LINK_NON_ELF;
|
||||
if (dynamic)
|
||||
hi->elf_link_hash_flags |=
|
||||
ELF_LINK_HASH_DEF_DYNAMIC;
|
||||
/* We don't set DEF_REGULAR because we don't
|
||||
the symbol to get exported even if we are
|
||||
exporting all defined symbols. FIXME:
|
||||
What a hack. */
|
||||
/* FIXME: Do we need to copy any flags from
|
||||
H to HI? */
|
||||
|
||||
/* If the symbol became indirect, then we
|
||||
assume that we have not seen a definition
|
||||
before. */
|
||||
BFD_ASSERT ((hi->elf_link_hash_flags
|
||||
& (ELF_LINK_HASH_DEF_DYNAMIC
|
||||
| ELF_LINK_HASH_DEF_REGULAR))
|
||||
== 0);
|
||||
|
||||
/* Copy down any references that we may have
|
||||
already seen to the symbol which just
|
||||
became indirect. */
|
||||
h->elf_link_hash_flags |=
|
||||
(hi->elf_link_hash_flags
|
||||
& (ELF_LINK_HASH_REF_DYNAMIC
|
||||
| ELF_LINK_HASH_REF_REGULAR));
|
||||
|
||||
/* Copy over the global table offset entry.
|
||||
This may have been already set up by a
|
||||
check_relocs routine. */
|
||||
if (h->got_offset == (bfd_vma) -1)
|
||||
{
|
||||
h->got_offset = hi->got_offset;
|
||||
hi->got_offset = (bfd_vma) -1;
|
||||
}
|
||||
BFD_ASSERT (hi->got_offset == (bfd_vma) -1);
|
||||
|
||||
if (h->dynindx == -1)
|
||||
{
|
||||
h->dynindx = hi->dynindx;
|
||||
h->dynstr_index = hi->dynstr_index;
|
||||
hi->dynindx = -1;
|
||||
hi->dynstr_index = 0;
|
||||
}
|
||||
BFD_ASSERT (hi->dynindx == -1);
|
||||
|
||||
/* FIXME: There may be other information to
|
||||
copy over for particular targets. */
|
||||
|
||||
/* See if the new flags lead us to realize
|
||||
that the symbol must be dynamic. */
|
||||
if (! dynsym)
|
||||
{
|
||||
if (! dynamic)
|
||||
{
|
||||
if (info->shared
|
||||
|| ((hi->elf_link_hash_flags
|
||||
& ELF_LINK_HASH_REF_DYNAMIC)
|
||||
!= 0))
|
||||
dynsym = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
if ((hi->elf_link_hash_flags
|
||||
& ELF_LINK_HASH_REF_REGULAR) != 0)
|
||||
dynsym = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1818,6 +1925,7 @@ NAME(bfd_elf,size_dynamic_sections) (output_bfd, soname, rpath,
|
|||
bfd_size_type soname_indx;
|
||||
bfd *dynobj;
|
||||
struct elf_backend_data *bed;
|
||||
bfd_size_type old_dynsymcount;
|
||||
|
||||
*sinterpptr = NULL;
|
||||
|
||||
|
@ -1959,6 +2067,7 @@ NAME(bfd_elf,size_dynamic_sections) (output_bfd, soname, rpath,
|
|||
|
||||
/* The backend must work out the sizes of all the other dynamic
|
||||
sections. */
|
||||
old_dynsymcount = elf_hash_table (info)->dynsymcount;
|
||||
if (! (*bed->elf_backend_size_dynamic_sections) (output_bfd, info))
|
||||
return false;
|
||||
|
||||
|
@ -2018,11 +2127,15 @@ NAME(bfd_elf,size_dynamic_sections) (output_bfd, soname, rpath,
|
|||
if (sinfo.removed_dynamic)
|
||||
{
|
||||
/* Some dynamic symbols were changed to be local
|
||||
symbols. In this case, we renumber all of the
|
||||
dynamic symbols, so that we don't have a hole.
|
||||
FIXME: The names of the removed symbols will still be
|
||||
in the dynamic string table, wasting space. */
|
||||
elf_hash_table (info)->dynsymcount = 1;
|
||||
symbols. In this case, we renumber all of the
|
||||
dynamic symbols, so that we don't have a hole. If
|
||||
the backend changed dynsymcount, then assume that the
|
||||
new symbols are at the start. This is the case on
|
||||
the MIPS. FIXME: The names of the removed symbols
|
||||
will still be in the dynamic string table, wasting
|
||||
space. */
|
||||
elf_hash_table (info)->dynsymcount =
|
||||
1 + (elf_hash_table (info)->dynsymcount - old_dynsymcount);
|
||||
elf_link_hash_traverse (elf_hash_table (info),
|
||||
elf_link_renumber_dynsyms,
|
||||
(PTR) info);
|
||||
|
@ -2307,17 +2420,11 @@ NAME(bfd_elf,size_dynamic_sections) (output_bfd, soname, rpath,
|
|||
}
|
||||
else
|
||||
{
|
||||
Elf_Internal_Versym intversym;
|
||||
|
||||
s->_raw_size = dynsymcount * sizeof (Elf_External_Versym);
|
||||
s->contents = (bfd_byte *) bfd_alloc (output_bfd, s->_raw_size);
|
||||
s->contents = (bfd_byte *) bfd_zalloc (output_bfd, s->_raw_size);
|
||||
if (s->contents == NULL)
|
||||
return false;
|
||||
|
||||
intversym.vs_vers = 0;
|
||||
_bfd_elf_swap_versym_out (output_bfd, &intversym,
|
||||
(Elf_External_Versym *) s->contents);
|
||||
|
||||
if (! elf_add_dynamic_entry (info, DT_VERSYM, 0))
|
||||
return false;
|
||||
}
|
||||
|
@ -2389,7 +2496,7 @@ elf_adjust_dynamic_symbol (h, data)
|
|||
bfd *dynobj;
|
||||
struct elf_backend_data *bed;
|
||||
|
||||
/* Ignore indirect symbols. There are added by the versioning code. */
|
||||
/* Ignore indirect symbols. These are added by the versioning code. */
|
||||
if (h->root.type == bfd_link_hash_indirect)
|
||||
return true;
|
||||
|
||||
|
@ -2546,6 +2653,10 @@ elf_export_symbol (h, data)
|
|||
{
|
||||
struct elf_info_failed *eif = (struct elf_info_failed *) data;
|
||||
|
||||
/* Ignore indirect symbols. These are added by the versioning code. */
|
||||
if (h->root.type == bfd_link_hash_indirect)
|
||||
return true;
|
||||
|
||||
if (h->dynindx == -1
|
||||
&& (h->elf_link_hash_flags
|
||||
& (ELF_LINK_HASH_DEF_REGULAR | ELF_LINK_HASH_REF_REGULAR)) != 0)
|
||||
|
@ -3853,7 +3964,8 @@ elf_link_output_extsym (h, data)
|
|||
}
|
||||
else
|
||||
{
|
||||
BFD_ASSERT ((input_sec->owner->flags & DYNAMIC) != 0);
|
||||
BFD_ASSERT (input_sec->owner == NULL
|
||||
|| (input_sec->owner->flags & DYNAMIC) != 0);
|
||||
sym.st_shndx = SHN_UNDEF;
|
||||
input_sec = bfd_und_section_ptr;
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue