public inbox for binutils@sourceware.org
 help / color / mirror / Atom feed
* MIPS/ELF linker
@ 1999-07-31 14:49 Ralf Baechle
  1999-07-31 15:26 ` Mark Mitchell
  0 siblings, 1 reply; 10+ messages in thread
From: Ralf Baechle @ 1999-07-31 14:49 UTC (permalink / raw)
  To: binutils, Tim Hockin

Starting to play with the new MIPS backend from CVS:

[ralf@lappi binutils]$ cat x.s 
	.text
	.globl	__start
	.weak	hurz
__start:
	la	$2,hurz
[ralf@lappi binutils]$ mips-linux-as -O3 -KPIC -o x.o x.s 
[ralf@lappi binutils]$ mips-linux-ld -o x x.o
x.o(.text+0x0): undefined reference to `hurz'
mips-linux-ld: x.o: .text+0x0: jump to stub routine which is not jal
mips-linux-ld: final link failed: Bad value
[ralf@lappi binutils]$ 

Misshandling error the weak undefined reference prevents any linking
against GNU libc since crti.o has a weak undefined reference against
__gmon_start__.  A fix for elf32-mips.c is appended below.

The ``jump to stub routine which is not jal'' error message which is
obviously bogus as well is caused by mips_elf_calculate_relocation
returning without setting *require_jalxp to a defined value.  A patch
to initialize the variable at the beginning of the function is also
part of the elf32-mips.c patch below.

A third bug is triggered by attempting to link an arbitrary program like
``main(){}'' against glibc 2.0.  This results in a large number of

  /usr/bin/mips-linux-ld: not enough GOT space for local GOT entries

messages.  Obviously the calculation of the GOT size is wrong, but I'm
not yet shure what's the problem, so I just report this without a fix.

Bug #4:

[ralf@lappi bfd]$ cat y.s 
	.text
foo:	la	$2,foo
[ralf@lappi bfd]$ mips-linux-as -O3 -KPIC -o y.o y.s
[ralf@lappi bfd]$ mips-linux-ld -o y y.o
Segmentation fault (core dumped)
[ralf@lappi bfd]$ 

This is caused by g->global_gotsym in elf32-mips.c:7896

       i = elf_hash_table (info)->dynsymcount - g->global_gotsym->dynindx;

being NULL;  I also don't have a fix for this one.

  Ralf

--- elf32-mips.c-cygnus	Sat Jul 31 12:23:43 1999
+++ elf32-mips.c	Sat Jul 31 23:02:33 1999
@@ -5791,6 +5791,9 @@
   /* Assume that there will be no overflow.  */
   overflowed_p = false;
 
+  /* Assume no jalx is required  */
+  *require_jalxp = false;
+
   /* Figure out whether or not the symbol is local, and get the offset
      used in the array of hash table entries.  */
   symtab_hdr = &elf_tdata (input_bfd)->symtab_hdr;
@@ -5870,6 +5873,12 @@
 	  else
 	    symbol = h->root.root.u.def.value;
 	}
+      else if ((h->root.root.type == bfd_link_hash_undefweak)
+               || (info->shared && !info->symbolic && !info->no_undefined))
+        {
+          sec = bfd_und_section_ptr;
+          symbol = 0;
+        }
       else
 	{
 	  (*info->callbacks->undefined_symbol)

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: MIPS/ELF linker
  1999-07-31 14:49 MIPS/ELF linker Ralf Baechle
@ 1999-07-31 15:26 ` Mark Mitchell
  1999-07-31 16:23   ` Ralf Baechle
  0 siblings, 1 reply; 10+ messages in thread
From: Mark Mitchell @ 1999-07-31 15:26 UTC (permalink / raw)
  To: ralf; +Cc: binutils, thockin

Thanks for trying the MIPS backend out.  I'm eager to shake out the
bugs.  It seems pretty solid on IRIX6, now, but I'm sure there are
issues remaining on other platforms.

  +  /* Assume no jalx is required  */
  +  *require_jalxp = false;
  +

REQUIRE_JALXP is set unconditionally a few lines down.  Why doesn't
that do the trick?  The caller should not be looking at the value of
require_jalx unless calculate_relocation returns a successful error
code.

  @@ -5870,6 +5873,12 @@
	    else
	      symbol = h->root.root.u.def.value;
	  }
  +      else if ((h->root.root.type == bfd_link_hash_undefweak)
  +               || (info->shared && !info->symbolic && !info->no_undefined))
  +        {
  +          sec = bfd_und_section_ptr;
  +          symbol = 0;
  +        }
	 else
	  {
	    (*info->callbacks->undefined_symbol)

This looks right to me.  I thought I had already fixed this, but I
guess not.  Ian should give final approval, of course.

  /usr/bin/mips-linux-ld: not enough GOT space for local GOT entries

Probably some relocation is requiring a local GOT entry, but we're not
allocating it.  Look for this code in check_relocs:

      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
	     conservative, we could actually build the GOT here,
	     rather than in relocate_section.  */
	  g->local_gotno++;
	  sgot->_raw_size += MIPS_ELF_GOT_SIZE (dynobj);
	}

Probably this code is not firing in some case where it should be
firing.  Therefore, we're not adding enough GOT space.  That might
help track down the bug.  

If not, feel free to send me the files on your link-line in a giant
tar-ball, together with how your configuring binutils, and I'll try to
duplicate and fix your problem.

--
Mark Mitchell                   mark@codesourcery.com
CodeSourcery, LLC               http://www.codesourcery.com

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: MIPS/ELF linker
  1999-07-31 15:26 ` Mark Mitchell
@ 1999-07-31 16:23   ` Ralf Baechle
  1999-07-31 16:41     ` Mark Mitchell
                       ` (2 more replies)
  0 siblings, 3 replies; 10+ messages in thread
From: Ralf Baechle @ 1999-07-31 16:23 UTC (permalink / raw)
  To: Mark Mitchell; +Cc: ralf, binutils, thockin, linux, linux-mips, linux-mips

On Sat, Jul 31, 1999 at 03:28:42PM -0700, Mark Mitchell wrote:

> Thanks for trying the MIPS backend out.  I'm eager to shake out the
> bugs.  It seems pretty solid on IRIX6, now, but I'm sure there are
> issues remaining on other platforms.
> 
>   +  /* Assume no jalx is required  */
>   +  *require_jalxp = false;
>   +
> 
> REQUIRE_JALXP is set unconditionally a few lines down.  Why doesn't
> that do the trick?  The caller should not be looking at the value of
> require_jalx unless calculate_relocation returns a successful error
> code.

So the caller _bfd_mips_elf_relocate_section does not behave appropriately
when mips_elf_calculate_relocation returns bfd_reloc_undefined.  Search
for bfd_reloc_undefined in mips_elf_calculate_relocation; it's being
returned before an actual value gets assigned to *require_jalxp.

>   /usr/bin/mips-linux-ld: not enough GOT space for local GOT entries
> 
> Probably some relocation is requiring a local GOT entry, but we're not
> allocating it.  Look for this code in check_relocs:
> 
>       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
> 	     conservative, we could actually build the GOT here,
> 	     rather than in relocate_section.  */
> 	  g->local_gotno++;
> 	  sgot->_raw_size += MIPS_ELF_GOT_SIZE (dynobj);
> 	}
> 
> Probably this code is not firing in some case where it should be
> firing.  Therefore, we're not adding enough GOT space.  That might
> help track down the bug.  
> 
> If not, feel free to send me the files on your link-line in a giant
> tar-ball, together with how your configuring binutils, and I'll try to
> duplicate and fix your problem.

I'll send you a non-giant tarball of 73kb which will demonstrate the
problem.  Just run the Makefile in the archive.  The linker has been
configured for the target mips-linux which is a standard MIPS/ELF target.

  Ralf

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: MIPS/ELF linker
  1999-07-31 16:23   ` Ralf Baechle
@ 1999-07-31 16:41     ` Mark Mitchell
  1999-07-31 16:46       ` Ralf Baechle
  1999-08-01 14:01     ` Mark Mitchell
  1999-08-01 14:03     ` Mark Mitchell
  2 siblings, 1 reply; 10+ messages in thread
From: Mark Mitchell @ 1999-07-31 16:41 UTC (permalink / raw)
  To: ralf; +Cc: ralf, binutils, thockin, linux, linux-mips, linux-mips

Ralf --

  Thanks for the tarball.  I'll not be able to look at this until
tomorrow, but I will do so then.

--
Mark Mitchell                   mark@codesourcery.com
CodeSourcery, LLC               http://www.codesourcery.com

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: MIPS/ELF linker
  1999-07-31 16:41     ` Mark Mitchell
@ 1999-07-31 16:46       ` Ralf Baechle
  0 siblings, 0 replies; 10+ messages in thread
From: Ralf Baechle @ 1999-07-31 16:46 UTC (permalink / raw)
  To: Mark Mitchell; +Cc: ralf, binutils, thockin, linux, linux-mips, linux-mips

On Sat, Jul 31, 1999 at 04:42:37PM -0700, Mark Mitchell wrote:

> Ralf --
> 
>   Thanks for the tarball.  I'll not be able to look at this until
> tomorrow, but I will do so then.

Ok, I'm looking into things in parallel if I find the time.  I'll also
try to rebuild GNU libc for MIPS.  That has historically proven to be
a bone breaker for ld.  The last time I tried a few weeks ago I got
~500 assertion messages from ld just alone for the libc final link ...
Will let you know how things go.

  Ralf

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: MIPS/ELF linker
  1999-07-31 16:23   ` Ralf Baechle
  1999-07-31 16:41     ` Mark Mitchell
@ 1999-08-01 14:01     ` Mark Mitchell
  1999-08-03  9:29       ` Ian Lance Taylor
  1999-08-01 14:03     ` Mark Mitchell
  2 siblings, 1 reply; 10+ messages in thread
From: Mark Mitchell @ 1999-08-01 14:01 UTC (permalink / raw)
  To: ralf; +Cc: ralf, binutils, thockin, linux, linux-mips, linux-mips

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

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: MIPS/ELF linker
  1999-07-31 16:23   ` Ralf Baechle
  1999-07-31 16:41     ` Mark Mitchell
  1999-08-01 14:01     ` Mark Mitchell
@ 1999-08-01 14:03     ` Mark Mitchell
  2 siblings, 0 replies; 10+ messages in thread
From: Mark Mitchell @ 1999-08-01 14:03 UTC (permalink / raw)
  To: ralf; +Cc: ralf, binutils, thockin, linux, linux-mips, linux-mips

Ralf sent me another test-case in private email that pointed up a
problem in the way that we were handling relocations when there are
both REL and RELA relocations for a single section.  The bottom line
is that the attempt I took at a conservative approach (allocating too
many relocations and then ignoring some of them) is ugly; this patch
attempts to fix that problem, and seems to fix Ralf's test-case.

OK to check in?

--
Mark Mitchell                   mark@codesourcery.com
CodeSourcery, LLC               http://www.codesourcery.com

1999-08-01  Mark Mitchell  <mark@codesourcery.com>

	* elflink.h (elf_link_size_reloc_section): Use the counts in the
	elf-section data to allocate just the right amount of relocation
	space.  Don't allocate the hash space twice.
	(elf_bfd_final_link): Calculate the amount of space to allocate in
	each relocation section.

Index: elflink.h
===================================================================
RCS file: /cvs/binutils/binutils/bfd/elflink.h,v
retrieving revision 1.21
diff -c -p -r1.21 elflink.h
*** elflink.h	1999/07/30 21:34:44	1.21
--- elflink.h	1999/08/01 20:47:14
*************** elf_link_size_reloc_section (abfd, rel_h
*** 3761,3794 ****
       asection *o;
  {
    register struct elf_link_hash_entry **p, **pend;
  
!   /* We are overestimating the size required for the relocation
!      sections, in the case that we are using both REL and RELA
!      relocations for a single section.  In that case, RELOC_COUNT will
!      be the total number of relocations required, and we allocate
!      space for that many REL relocations as well as that many RELA
!      relocations.  This approximation is wasteful of disk space.
!      However, until we keep track of how many of each kind of
!      relocation is required, it's difficult to calculate the right
!      value.  */
!   rel_hdr->sh_size = rel_hdr->sh_entsize * o->reloc_count;
  
    /* The contents field must last into write_object_contents, so we
       allocate it with bfd_alloc rather than malloc.  */
    rel_hdr->contents = (PTR) bfd_alloc (abfd, rel_hdr->sh_size);
    if (rel_hdr->contents == NULL && rel_hdr->sh_size != 0)
-     return false;
- 
-   p = ((struct elf_link_hash_entry **)
-        bfd_malloc (o->reloc_count
- 		   * sizeof (struct elf_link_hash_entry *)));
-   if (p == NULL && o->reloc_count != 0)
      return false;
! 
!   elf_section_data (o)->rel_hashes = p;
!   pend = p + o->reloc_count;
!   for (; p < pend; p++)
!     *p = NULL;
  
    return true;
  }
--- 3761,3798 ----
       asection *o;
  {
    register struct elf_link_hash_entry **p, **pend;
+   unsigned reloc_count;
  
!   /* Figure out how many relocations there will be.  */
!   if (rel_hdr == &elf_section_data (o)->rel_hdr)
!     reloc_count = elf_section_data (o)->rel_count;
!   else
!     reloc_count = elf_section_data (o)->rel_count2;
! 
!   /* That allows us to calculate the size of the section.  */
!   rel_hdr->sh_size = rel_hdr->sh_entsize * reloc_count;
  
    /* The contents field must last into write_object_contents, so we
       allocate it with bfd_alloc rather than malloc.  */
    rel_hdr->contents = (PTR) bfd_alloc (abfd, rel_hdr->sh_size);
    if (rel_hdr->contents == NULL && rel_hdr->sh_size != 0)
      return false;
!   
!   /* We only allocate one set of hash entries, so we only do it the
!      first time we are called.  */
!   if (elf_section_data (o)->rel_hashes == NULL)
!     {
!       p = ((struct elf_link_hash_entry **)
! 	   bfd_malloc (o->reloc_count
! 		       * sizeof (struct elf_link_hash_entry *)));
!       if (p == NULL && o->reloc_count != 0)
! 	return false;
! 
!       elf_section_data (o)->rel_hashes = p;
!       pend = p + o->reloc_count;
!       for (; p < pend; p++)
! 	*p = NULL;
!     }
  
    return true;
  }
*************** elf_bfd_final_link (abfd, info)
*** 3997,4002 ****
--- 4001,4030 ----
    if (! _bfd_elf_compute_section_file_positions (abfd, info))
      goto error_return;
  
+   /* Figure out how many relocations we will have in each section.
+      Just using RELOC_COUNT isn't good enough since that doesn't
+      maintain a separate value for REL vs. RELA relocations.  */
+   if (info->relocateable)
+     for (sub = info->input_bfds; sub != NULL; sub = sub->link_next)
+       for (o = sub->sections; o != NULL; o = o->next)
+ 	{
+ 	  asection* output_section = o->output_section;
+ 
+ 	  if (output_section && (o->flags & SEC_RELOC) != 0)
+ 	    {
+ 	      struct bfd_elf_section_data *esdi 
+ 		= elf_section_data (o);
+ 	      struct bfd_elf_section_data *esdo 
+ 		= elf_section_data (output_section);
+ 
+ 	      esdo->rel_count += (esdi->rel_hdr.sh_size 
+ 				  / esdi->rel_hdr.sh_entsize);
+ 	      if (esdi->rel_hdr2)
+ 		esdo->rel_count2 += (esdi->rel_hdr2->sh_size 
+ 				     / esdi->rel_hdr2->sh_entsize);
+ 	    }
+ 	}
+ 
    /* That created the reloc sections.  Set their sizes, and assign
       them file positions, and allocate some buffers.  */
    for (o = abfd->sections; o != NULL; o = o->next)
*************** elf_bfd_final_link (abfd, info)
*** 4014,4019 ****
--- 4042,4052 ----
  					       o))
  	    goto error_return;
  	}
+ 
+       /* Now, reset REL_COUNT and REL_COUNT2 so that we can use them
+ 	 to count upwards while actually outputting the relocations. */
+       elf_section_data (o)->rel_count = 0;
+       elf_section_data (o)->rel_count2 = 0;
      }
  
    _bfd_elf_assign_file_positions_for_relocs (abfd);
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

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: MIPS/ELF linker
  1999-08-01 14:01     ` Mark Mitchell
@ 1999-08-03  9:29       ` Ian Lance Taylor
  1999-08-03  9:46         ` Mark Mitchell
  1999-08-03  9:48         ` Mark Mitchell
  0 siblings, 2 replies; 10+ messages in thread
From: Ian Lance Taylor @ 1999-08-03  9:29 UTC (permalink / raw)
  To: mark; +Cc: ralf, ralf, binutils, thockin, linux, linux-mips, linux-mips

   From: Mark Mitchell <mark@codesourcery.com>
   Date: Sun, 01 Aug 1999 14:03:27 -0700

   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.

When I read your paragraph above, it makes sense.  However, when I
look at the current code, I think that calculate_relocation will get
called for a reference to an undefined symbol from a shared library.

If you are proposing a different patch, to simply copy shared library
relocations against undefined symbols rather than to perform the
relocation, then I think that will indeed work correctly.  But note
that you do have to handle the info->symbolic and info->no_undefined
cases.  Something like the above code seems like a simple way to
handle all the cases.

   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".

Since this symbol is in the reserved name space, it's OK for the
linker to define it magically.  It's no more buggy for an executable
to use the symbol _DYNAMIC_LINK without a definition than it is for an
executable to use the symbol __program_header_table without a
definition.

This change was from Kazumoto Kojima; I assume that on some systems
_DYNAMIC_LINK is used to test whether the executable was linked
dynamically or not.  It's no less magic to define it in the linker
script than it is to define it in elf32-mips.c.  In this case, I don't
see how to define it correctly in the linker script.

   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?

_bfd_mips_elf_create_dynamic_sections is not called in all cases: it
is not called when doing a static link.  I believe that bit of code
got in there because some system expects _DYNAMIC_LINK to be defined
as 0 when doing a static link.  I think we do need to handle this one
way or another.

Ian

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: MIPS/ELF linker
  1999-08-03  9:29       ` Ian Lance Taylor
@ 1999-08-03  9:46         ` Mark Mitchell
  1999-08-03  9:48         ` Mark Mitchell
  1 sibling, 0 replies; 10+ messages in thread
From: Mark Mitchell @ 1999-08-03  9:46 UTC (permalink / raw)
  To: ian; +Cc: ralf, ralf, binutils, thockin, linux, linux-mips, linux-mips

Ian --

  Thanks for the commentary.  I'll address those issues later today.

--
Mark Mitchell                   mark@codesourcery.com
CodeSourcery, LLC               http://www.codesourcery.com

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: MIPS/ELF linker
  1999-08-03  9:29       ` Ian Lance Taylor
  1999-08-03  9:46         ` Mark Mitchell
@ 1999-08-03  9:48         ` Mark Mitchell
  1 sibling, 0 replies; 10+ messages in thread
From: Mark Mitchell @ 1999-08-03  9:48 UTC (permalink / raw)
  To: ian; +Cc: ralf, ralf, binutils, thockin, linux, linux-mips, linux-mips

    Ian> Since this symbol is in the reserved name space, it's OK for
    Ian> the linker to define it magically.  It's no more buggy for an
    Ian> executable to use the symbol _DYNAMIC_LINK without a
    Ian> definition than it is for an executable to use the symbol
    Ian> __program_header_table without a definition.

That's true, from an ANSI C point of view.  But, it's not true from a
system-specific point of view.  Some systems have well-known entry
points beginnning with `_'.  It seems unncessary to deal with this
_DYNAMIC_LINK trick on systems that don't need it; hence the
suggestion that the linker script is the place for it.

But, as you say, I'm not quite sure how to do that; I'll just restore
the original handling of this code.

--
Mark Mitchell                   mark@codesourcery.com
CodeSourcery, LLC               http://www.codesourcery.com

^ permalink raw reply	[flat|nested] 10+ messages in thread

end of thread, other threads:[~1999-08-03  9:48 UTC | newest]

Thread overview: 10+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
1999-07-31 14:49 MIPS/ELF linker Ralf Baechle
1999-07-31 15:26 ` Mark Mitchell
1999-07-31 16:23   ` Ralf Baechle
1999-07-31 16:41     ` Mark Mitchell
1999-07-31 16:46       ` Ralf Baechle
1999-08-01 14:01     ` Mark Mitchell
1999-08-03  9:29       ` Ian Lance Taylor
1999-08-03  9:46         ` Mark Mitchell
1999-08-03  9:48         ` Mark Mitchell
1999-08-01 14:03     ` Mark Mitchell

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).