linux-mips-fnet
[Top] [All Lists]

Re: MIPS/ELF linker

To: ralf@uni-koblenz.de
Subject: Re: MIPS/ELF linker
From: Mark Mitchell <mark@codesourcery.com>
Date: Sun, 01 Aug 1999 14:03:27 -0700
Cc: ralf@gnu.org, binutils@sourceware.cygnus.com, thockin@cobaltnet.com, linux@engr.sgi.com, linux-mips@fnet.fr, linux-mips@vger.rutgers.edu
In-reply-to: <19990801012203.U12249@uni-koblenz.de>
Organization: CodeSourcery, LLC
References: <19990731233150.Q12249@uni-koblenz.de> <19990731152842N.mitchell@codesourcery.com> <19990801012203.U12249@uni-koblenz.de>
Sender: mitchell@codesourcery.com
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

<Prev in Thread] Current Thread [Next in Thread>