This is the mail archive of the
binutils@sources.redhat.com
mailing list for the binutils project.
mips unordered symbol table and relocations
- From: Nathan Sidwell <nathan at codesourcery dot com>
- To: binutils at sources dot redhat dot com
- Date: Tue, 19 Nov 2002 17:15:09 +0000
- Subject: mips unordered symbol table and relocations
- Organization: Codesourcery LLC
Hi,
A windriver customer encounted a linker crash with a library archive produced
by an old toolchain. The symbol table is unoreded, with local and global
symbols intermixed. Some relocations were against symbols with no entry
in the (global) hash table, and these caused problems. objdump shows these
as relocations agains *ABS*. It may be possible that I've misunderstood these
*ABS* relocs, and the object file is infact corrupt. However, the attached
patch allows linkage to proceed. ok?
nathan
--
Dr Nathan Sidwell :: http://www.codesourcery.com :: CodeSourcery LLC
'But that's a lie.' - 'Yes it is. What's your point?'
nathan@codesourcery.com : http://www.cs.bris.ac.uk/~nathan/ : nathan@acm.org
2002-11-19 Nathan Sidwell <nathan@codesourcery.com>
* elflink.h (elf_link_input_bfd): Relocs with no symbol are
absolute.
* elfxx-mips.c (mips_elf_local_reloctaion_p): Likewise.
(mips_elf_calculate_relocation): Relocs with no section are
absolute.
Index: bfd/elflink.h
===================================================================
RCS file: /cvs/src/src/bfd/elflink.h,v
retrieving revision 1.193
diff -c -3 -p -r1.193 elflink.h
*** bfd/elflink.h 4 Nov 2002 13:20:56 -0000 1.193
--- bfd/elflink.h 19 Nov 2002 12:02:43 -0000
*************** elf_link_input_bfd (finfo, input_bfd)
*** 6858,6864 ****
if (r_symndx >= locsymcount
|| (elf_bad_symtab (input_bfd)
! && finfo->sections[r_symndx] == NULL))
{
struct elf_link_hash_entry *h;
--- 6858,6865 ----
if (r_symndx >= locsymcount
|| (elf_bad_symtab (input_bfd)
! && finfo->sections[r_symndx] == NULL
! && sym_hashes[r_symndx - extsymoff]))
{
struct elf_link_hash_entry *h;
*************** elf_link_input_bfd (finfo, input_bfd)
*** 6968,6974 ****
--- 6969,6977 ----
Elf_Internal_Shdr *,
Elf_Internal_Rela *));
boolean rela_normal;
+ struct elf_link_hash_entry **sym_hashes;
+ sym_hashes = elf_sym_hashes (input_bfd);
input_rel_hdr = &elf_section_data (o)->rel_hdr;
rela_normal = (bed->rela_normal
&& (input_rel_hdr->sh_entsize
*************** elf_link_input_bfd (finfo, input_bfd)
*** 6986,6991 ****
--- 6989,6995 ----
unsigned long r_symndx;
asection *sec;
Elf_Internal_Sym sym;
+ unsigned long indx;
if (next_erel == bed->s->int_rels_per_ext_rel)
{
*************** elf_link_input_bfd (finfo, input_bfd)
*** 7004,7015 ****
if (r_symndx == 0)
continue;
if (r_symndx >= locsymcount
|| (elf_bad_symtab (input_bfd)
! && finfo->sections[r_symndx] == NULL))
{
struct elf_link_hash_entry *rh;
- unsigned long indx;
/* This is a reloc against a global symbol. We
have not yet output all the local symbols, so
--- 7008,7020 ----
if (r_symndx == 0)
continue;
+ indx = r_symndx - extsymoff;
if (r_symndx >= locsymcount
|| (elf_bad_symtab (input_bfd)
! && finfo->sections[r_symndx] == NULL
! && sym_hashes[indx]))
{
struct elf_link_hash_entry *rh;
/* This is a reloc against a global symbol. We
have not yet output all the local symbols, so
*************** elf_link_input_bfd (finfo, input_bfd)
*** 7018,7025 ****
reloc to point to the global hash table entry
for this symbol. The symbol index is then
set at the end of elf_bfd_final_link. */
! indx = r_symndx - extsymoff;
! rh = elf_sym_hashes (input_bfd)[indx];
while (rh->root.type == bfd_link_hash_indirect
|| rh->root.type == bfd_link_hash_warning)
rh = (struct elf_link_hash_entry *) rh->root.u.i.link;
--- 7023,7029 ----
reloc to point to the global hash table entry
for this symbol. The symbol index is then
set at the end of elf_bfd_final_link. */
! rh = sym_hashes[indx];
while (rh->root.type == bfd_link_hash_indirect
|| rh->root.type == bfd_link_hash_warning)
rh = (struct elf_link_hash_entry *) rh->root.u.i.link;
Index: bfd/elfxx-mips.c
===================================================================
RCS file: /cvs/src/src/bfd/elfxx-mips.c,v
retrieving revision 1.29
diff -c -3 -p -r1.29 elfxx-mips.c
*** bfd/elfxx-mips.c 22 Oct 2002 22:17:11 -0000 1.29
--- bfd/elfxx-mips.c 19 Nov 2002 12:03:00 -0000
*************** mips_elf_local_relocation_p (input_bfd,
*** 1770,1777 ****
if (r_symndx < extsymoff)
return true;
! if (elf_bad_symtab (input_bfd) && local_sections[r_symndx] != NULL)
! return true;
if (check_forced)
{
--- 1770,1782 ----
if (r_symndx < extsymoff)
return true;
! if (elf_bad_symtab (input_bfd))
! {
! if (local_sections[r_symndx] != NULL)
! return true;
! if (!elf_sym_hashes (input_bfd) [r_symndx - extsymoff])
! return true;
! }
if (check_forced)
{
*************** mips_elf_local_relocation_p (input_bfd,
*** 1779,1784 ****
--- 1784,1790 ----
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.root.type == bfd_link_hash_indirect
|| h->root.root.type == bfd_link_hash_warning)
*************** mips_elf_calculate_relocation (abfd, inp
*** 2089,2094 ****
--- 2095,2102 ----
sym = local_syms + r_symndx;
sec = local_sections[r_symndx];
+ if (!sec)
+ sec = &bfd_abs_section;
symbol = sec->output_section->vma + sec->output_offset;
if (ELF_ST_TYPE (sym->st_info) != STT_SECTION