bfd/linker.c patch for ia64-linux Fortran common link error

Jim Wilson wilson@redhat.com
Thu Jul 5 15:46:00 GMT 2001


This finishes something I started in April.  I got distracted by other stuff
and didn't follow through on this until now.
See < http://sources.redhat.com/ml/binutils/2001-04/msg00247.html >.

Some Fortran programs using commons get link failures because the linker
puts commons in sbss instead of bss when the first one is small and the second
one is big.

I have checked in this patch to fix the problem by using the section of the
larger symbol when merging commons.

2001-07-05  Jim Wilson  <wilson@redhat.com>

	* linker.c (_bfd_generic_link_add_one_symbol, case BIG): Use
	the section of the bigger symbol.

Index: linker.c
===================================================================
RCS file: /cvs/src/src/bfd/linker.c,v
retrieving revision 1.9
retrieving revision 1.10
diff -p -r1.9 -r1.10
*** linker.c	2001/05/10 22:59:29	1.9
--- linker.c	2001/07/05 22:40:16	1.10
*************** _bfd_generic_link_add_one_symbol (info, 
*** 1698,1704 ****
  	case BIG:
  	  /* We have found a common definition for a symbol which
  	     already had a common definition.  Use the maximum of the
! 	     two sizes.  */
  	  BFD_ASSERT (h->type == bfd_link_hash_common);
  	  if (! ((*info->callbacks->multiple_common)
  		 (info, h->root.string,
--- 1698,1704 ----
  	case BIG:
  	  /* We have found a common definition for a symbol which
  	     already had a common definition.  Use the maximum of the
! 	     two sizes, and use the section required by the larger symbol.  */
  	  BFD_ASSERT (h->type == bfd_link_hash_common);
  	  if (! ((*info->callbacks->multiple_common)
  		 (info, h->root.string,
*************** _bfd_generic_link_add_one_symbol (info, 
*** 1717,1722 ****
--- 1717,1741 ----
  	      if (power > 4)
  		power = 4;
  	      h->u.c.p->alignment_power = power;
+ 
+ 	      /* Some systems have special treatment for small commons,
+ 		 hence we want to select the section used by the larger
+ 		 symbol.  This makes sure the symbol does not go in a
+ 		 small common section if it is now too large.  */
+ 	      if (section == bfd_com_section_ptr)
+ 		{
+ 		  h->u.c.p->section
+ 		    = bfd_make_section_old_way (abfd, "COMMON");
+ 		  h->u.c.p->section->flags = SEC_ALLOC;
+ 		}
+ 	      else if (section->owner != abfd)
+ 		{
+ 		  h->u.c.p->section
+ 		    = bfd_make_section_old_way (abfd, section->name);
+ 		  h->u.c.p->section->flags = SEC_ALLOC;
+ 		}
+ 	      else
+ 		h->u.c.p->section = section;
  	    }
  	  break;
  



More information about the Binutils mailing list