MIPS/ELF linker
Mark Mitchell
mark@codesourcery.com
Sun Aug 1 14:01:00 GMT 1999
I've checked in the following patch to elf32-mips.c to fix these
problems.
Ian, I'd like your comments on a couple of other issues. In auditing
the current code vs. the pre-IRIX6 modifications I see that this hunk
in the current code is not preserved:
else if (info->shared && !info->symbolic && !info->no_undefined)
relocation = 0;
else if (strcmp (h->root.root.string, "_DYNAMIC_LINK") == 0)
{
/* If this is a dynamic link, we should have created
a _DYNAMIC_LINK symbol in
mips_elf_create_dynamic_sections. Otherwise, we
should define the symbol with a value of 0.
FIXME: It should probably get into the symbol
table somehow as well. */
BFD_ASSERT (! info->shared);
BFD_ASSERT (bfd_get_section_by_name (output_bfd,
".dynamic") == NULL);
relocation = 0;
}
I don't see the point of the first line (in the context of the new
code). I think that when building a shared library, a relocation
against an undefined symbol should simply be copied into the output
file (adjust as necessary); there's no need to actually perform any
relocation. So, there's no need to give values to undefined symbols.
Therefore, we don't call calculate_relocation in this case at all. If
you think that's wrong, please let me know.
I'm also unsure about the _DYNAMIC_LINK bit. On the one hand, it
would seem that this should be defined in the linker-script if it's
needed? For instance, it would seem to be a bug if an IRIX6
executable happened to use the symbol _DYNAMIC_LINK without a
definition, but then linked successfully because we created this
symbol "by magic".
But, leaving that issue aside, we define this on all systems, in the
non-shared case, in _bfd_mips_elf_create_dynamic_sections. So, I
don't think we need to handle this symbol specially when we perform
relocations against it. Do you agree?
--
Mark Mitchell mark@codesourcery.com
CodeSourcery, LLC http://www.codesourcery.com
1999-08-01 Mark Mitchell <mark@codesourcery.com>
* elf32-mips.c (mips_elf_calculate_relocation): Undefined weak
symbols are considered to have the value zero.
(_bfd_mips_elf_relocate_section): Don't try to perform a
relocation for an undefined symbol.
(_bfd_mips_elf_check_relocs): Allocate locate GOT space for local
GOT16 relocations.
Index: elf32-mips.c
===================================================================
RCS file: /cvs/binutils/binutils/bfd/elf32-mips.c,v
retrieving revision 1.36
diff -c -p -r1.36 elf32-mips.c
*** elf32-mips.c 1999/07/29 22:20:26 1.36
--- elf32-mips.c 1999/08/01 20:47:18
*************** mips_elf_calculate_relocation (abfd,
*** 5870,5875 ****
--- 5870,5881 ----
else
symbol = h->root.root.u.def.value;
}
+ else if (h->root.root.type == bfd_link_hash_undefweak)
+ /* We allow relocations against undefined weak symbols, giving
+ it the value zero, so that you can undefined weak functions
+ and check to see if they exist by looking at their
+ addresses. */
+ symbol = 0;
else
{
(*info->callbacks->undefined_symbol)
*************** _bfd_mips_elf_relocate_section (output_b
*** 6637,6644 ****
case bfd_reloc_undefined:
/* mips_elf_calculate_relocation already called the
! undefined_symbol callback. */
! break;
case bfd_reloc_notsupported:
abort ();
--- 6643,6652 ----
case bfd_reloc_undefined:
/* mips_elf_calculate_relocation already called the
! undefined_symbol callback. There's no real point in
! trying to perform the relocation at this point, so we
! just skip ahead to the next relocation. */
! continue;
case bfd_reloc_notsupported:
abort ();
*************** _bfd_mips_elf_check_relocs (abfd, info,
*** 7331,7344 ****
if (!h && (r_type == R_MIPS_CALL_LO16
|| r_type == R_MIPS_GOT_LO16
! || r_type == R_MIPS_GOT_DISP))
{
/* We may need a local GOT entry for this relocation. We
! don't count R_MIPS_HI16 or R_MIPS_GOT16 relocations
! because they are always followed by a R_MIPS_LO16
! relocation for the value. We don't R_MIPS_GOT_PAGE
! because we can estimate the maximum number of pages
! needed by looking at the size of the segment.
This estimation is very conservative since we can merge
duplicate entries in the GOT. In order to be less
--- 7339,7353 ----
if (!h && (r_type == R_MIPS_CALL_LO16
|| r_type == R_MIPS_GOT_LO16
! || r_type == R_MIPS_GOT_DISP
! || r_type == R_MIPS_GOT16))
{
/* We may need a local GOT entry for this relocation. We
! don't count R_MIPS_GOT_PAGE because we can estimate the
! maximum number of pages needed by looking at the size of
! the segment. We don't count R_MIPS_GOT_HI16, or
! R_MIPS_CALL_HI16 because these are always followed by an
! R_MIPS_GOT_LO16 or R_MIPS_CALL_LO16.
This estimation is very conservative since we can merge
duplicate entries in the GOT. In order to be less
More information about the Binutils
mailing list