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