This is the mail archive of the
binutils@sourceware.cygnus.com
mailing list for the binutils project.
MIPS*/ELF symbol versioning resolved
- To: binutils at sourceware dot cygnus dot com, "H.J. Lu" <hjl at lucon dot org>, Andreas Jaeger <aj at suse dot de>, Ralf Baechle <ralf at uni-koblenz dot de>, Florian Lohoff <flo at rfc822 dot org>
- Subject: MIPS*/ELF symbol versioning resolved
- From: "Maciej W. Rozycki" <macro at ds2 dot pg dot gda dot pl>
- Date: Wed, 10 Nov 1999 11:58:05 +0100 (MET)
- Organization: Technical University of Gdansk
- Reply-To: "Maciej W. Rozycki" <macro at ds2 dot pg dot gda dot pl>
Hi,
I believe the attached patch fixes the problems with versioned symbols on
MIPS*/ELF platforms. I am now able to compile glibc-2.1.2 for
mipsel-linux, at least. Looking at binaries, it seems both symbols and
relocations are getting set right. I cannot test runtime behaviour,
though, as I do not have an environment yet.
Any comments are welcomed.
Maciej
--
+ Maciej W. Rozycki, Technical University of Gdansk, Poland +
+--------------------------------------------------------------+
+ e-mail: macro@ds2.pg.gda.pl, PGP key available +
diff -u --recursive --new-file binutils.macro/bfd/elf32-mips.c binutils/bfd/elf32-mips.c
--- binutils.macro/bfd/elf32-mips.c Fri Oct 8 16:41:22 1999
+++ binutils/bfd/elf32-mips.c Wed Nov 10 00:37:02 1999
@@ -179,7 +179,7 @@
static struct mips_got_info *mips_elf_got_info
PARAMS ((bfd *, asection **));
static boolean mips_elf_local_relocation_p
- PARAMS ((bfd *, const Elf_Internal_Rela *, asection **));
+ PARAMS ((bfd *, const Elf_Internal_Rela *, asection **, boolean));
static bfd_vma mips_elf_create_local_got_entry
PARAMS ((bfd *, struct mips_got_info *, asection *, bfd_vma));
static bfd_vma mips_elf_got16_entry
@@ -5042,24 +5042,42 @@
/* Return whether a relocation is against a local symbol. */
static boolean
-mips_elf_local_relocation_p (input_bfd, relocation, local_sections)
+mips_elf_local_relocation_p (input_bfd, relocation, local_sections,
+ check_forced)
bfd *input_bfd;
const Elf_Internal_Rela *relocation;
asection **local_sections;
+ boolean check_forced;
{
unsigned long r_symndx;
Elf_Internal_Shdr *symtab_hdr;
+ struct mips_elf_link_hash_entry* h;
+ size_t extsymoff;
r_symndx = ELF32_R_SYM (relocation->r_info);
symtab_hdr = &elf_tdata (input_bfd)->symtab_hdr;
- if (! elf_bad_symtab (input_bfd))
- return r_symndx < symtab_hdr->sh_info;
- else
+ extsymoff = (elf_bad_symtab (input_bfd)) ? 0 : symtab_hdr->sh_info;
+
+ if (r_symndx < extsymoff)
+ return true;
+ if (elf_bad_symtab (input_bfd) && local_sections[r_symndx] != NULL)
+ return true;
+
+ if (check_forced)
{
- /* The symbol table does not follow the rule that local symbols
- must come before globals. */
- return local_sections[r_symndx] != NULL;
+ /* Look up the hash table to check whether the symbol
+ was forced local. */
+ h = (struct mips_elf_link_hash_entry *)
+ elf_sym_hashes (input_bfd) [r_symndx - extsymoff];
+ /* Find the real hash-table entry for this symbol. */
+ while (h->root.type == bfd_link_hash_indirect
+ || h->root.type == bfd_link_hash_warning)
+ h = (struct mips_elf_link_hash_entry *) h->root.root.u.i.link;
+ if ((h->root.elf_link_hash_flags & ELF_LINK_FORCED_LOCAL) != 0)
+ return true;
}
+
+ return false;
}
/* Sign-extend VALUE, which has the indicated number of BITS. */
@@ -5541,7 +5559,10 @@
& ELF_LINK_HASH_DEF_REGULAR) == 0))
{
indx = h->root.dynindx;
- BFD_ASSERT (indx != -1);
+ /* h->root.dynindx may be -1 if this symbol was marked to
+ become local. */
+ if (indx == -1)
+ indx = 0;
}
else
{
@@ -5739,7 +5760,7 @@
used in the array of hash table entries. */
symtab_hdr = &elf_tdata (input_bfd)->symtab_hdr;
local_p = mips_elf_local_relocation_p (input_bfd, relocation,
- local_sections);
+ local_sections, false);
if (! elf_bad_symtab (input_bfd))
extsymoff = symtab_hdr->sh_info;
else
@@ -5780,8 +5801,8 @@
h = ((struct mips_elf_link_hash_entry *)
elf_sym_hashes (input_bfd) [r_symndx - extsymoff]);
/* Find the real hash-table entry for this symbol. */
- while (h->root.type == bfd_link_hash_indirect
- || h->root.type == bfd_link_hash_warning)
+ while (h->root.root.type == bfd_link_hash_indirect
+ || h->root.root.type == bfd_link_hash_warning)
h = (struct mips_elf_link_hash_entry *) h->root.root.u.i.link;
/* Record the name of this symbol, for our caller. */
@@ -5907,6 +5928,9 @@
*require_jalxp = (!info->relocateable
&& ((r_type == R_MIPS16_26) != target_is_16_bit_code_p));
+ local_p = mips_elf_local_relocation_p (input_bfd, relocation,
+ local_sections, true);
+
/* If we haven't already determined the GOT offset, or the GP value,
and we're going to need it, get it now. */
switch (r_type)
@@ -6481,7 +6505,7 @@
if (r_type == R_MIPS_HI16
|| (r_type == R_MIPS_GOT16
&& mips_elf_local_relocation_p (input_bfd, rel,
- local_sections)))
+ local_sections, false)))
{
bfd_vma l;
const Elf_Internal_Rela *lo16_relocation;
@@ -6539,7 +6563,8 @@
relative in which case we need to adjust by the amount
that we're adjusting GP in this relocateable object. */
- if (!mips_elf_local_relocation_p (input_bfd, rel, local_sections))
+ if (!mips_elf_local_relocation_p (input_bfd, rel, local_sections,
+ false))
/* There's nothing to do for non-local relocations. */
continue;
@@ -8165,7 +8190,8 @@
sym->st_value = gval;
}
- BFD_ASSERT (h->dynindx != -1);
+ BFD_ASSERT (h->dynindx != -1
+ || (h->elf_link_hash_flags & ELF_LINK_FORCED_LOCAL) != 0);
sgot = mips_elf_got_section (dynobj);
BFD_ASSERT (sgot != NULL);
diff -u --recursive --new-file binutils.macro/bfd/elflink.h binutils/bfd/elflink.h
--- binutils.macro/bfd/elflink.h Fri Oct 8 16:41:22 1999
+++ binutils/bfd/elflink.h Thu Oct 28 21:52:36 1999
@@ -3597,6 +3597,7 @@
h->elf_link_hash_flags &=~
ELF_LINK_HASH_NEEDS_PLT;
h->dynindx = -1;
+ --elf_hash_table (info)->dynsymcount;
h->plt.offset = (bfd_vma) -1;
/* FIXME: The name of the symbol has
already been recorded in the dynamic
@@ -3711,6 +3712,7 @@
h->elf_link_hash_flags |= ELF_LINK_FORCED_LOCAL;
h->elf_link_hash_flags &=~ ELF_LINK_HASH_NEEDS_PLT;
h->dynindx = -1;
+ --elf_hash_table (info)->dynsymcount;
h->plt.offset = (bfd_vma) -1;
/* FIXME: The name of the symbol has already
been recorded in the dynamic string table
@@ -3735,6 +3737,7 @@
h->elf_link_hash_flags |= ELF_LINK_FORCED_LOCAL;
h->elf_link_hash_flags &=~ ELF_LINK_HASH_NEEDS_PLT;
h->dynindx = -1;
+ --elf_hash_table (info)->dynsymcount;
h->plt.offset = (bfd_vma) -1;
/* FIXME: The name of the symbol has already been
recorded in the dynamic string table section. */