This is the mail archive of the binutils@sources.redhat.com mailing list for the binutils project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Committed, CRIS: Fix bugs related to --export-dynamic.


Failures were related to linking programs dynamically, trigged
by --export-dynamic: omitted dynamic relocs for the GOT were
still emitted, overwriting other non-omitted entries if there
were any, or as in expdyn2.d, caused SEGV.  I noticed relocs
were created for weak undef references.  Other test-cases
written while fixing this.

bfd:
	* elf32-cris.c (cris_elf_relocate_section): Drop nonsensical
	dynamic reference test in assertion when initializing GOT with
	static contents.  Just assert that there are either no dynamic
	sections, the symbol is defined in the regular objects or that the
	symbol is undef weak.  Tweak comment.
	(elf_cris_finish_dynamic_symbol): Emit .got reloc for a program
	only if the symbol isn't defined in the program and isn't undef
	weak.
	(elf_cris_adjust_dynamic_symbol): Simplify condition for getting
	rid of PLT entry: only do it if the symbol isn't defined in a DSO.
	When doing so, clear ELF_LINK_HASH_NEEDS_PLT.  Tweak comments.
	(elf_cris_discard_excess_program_dynamics): Don't consider
	ELF_LINK_HASH_REF_DYNAMIC when omitting .got runtime relocs.

ld/testsuite:

	* ld-cris/nodyn4.d, ld-cris/expdyn4.d, ld-cris/comref1.s,
	ld-cris/euwref1.s, ld-cris/expdyn3.d, ld-cris/expdyn2.d,
	ld-cris/expdref1.s: New tests.

Index: ld-cris/comref1.s
===================================================================
RCS file: ld-cris/comref1.s
diff -N ld-cris/comref1.s
*** /dev/null	1 Jan 1970 00:00:00 -0000
--- ld-cris/comref1.s	12 Jul 2002 15:35:12 -0000
***************
*** 0 ****
--- 1,8 ----
+  .text
+ y:
+  .comm c1,4,1
+  .comm c2,4,1
+  .comm c3,4,1
+  move.d c1,$r10
+  move.d c2:GOT,$r10
+  move.d c3:PLT,$r10
Index: ld-cris/euwref1.s
===================================================================
RCS file: ld-cris/euwref1.s
diff -N ld-cris/euwref1.s
*** /dev/null	1 Jan 1970 00:00:00 -0000
--- ld-cris/euwref1.s	12 Jul 2002 15:35:12 -0000
***************
*** 0 ****
--- 1,8 ----
+  .text
+ y:
+  .weak uw1
+  .weak uw2
+  .weak uw3
+  move.d uw1,$r10
+  move.d uw2:GOT,$r10
+  move.d uw3:PLT,$r10
Index: ld-cris/expdref1.s
===================================================================
RCS file: ld-cris/expdref1.s
diff -N ld-cris/expdref1.s
*** /dev/null	1 Jan 1970 00:00:00 -0000
--- ld-cris/expdref1.s	12 Jul 2002 15:35:12 -0000
***************
*** 0 ****
--- 1,6 ----
+   .text
+ x:
+   move.d expobj:GOT,$r10
+   move.d expobj:PLT,$r10
+   move.d expfn:GOT,$r10
+   move.d expfn:PLT,$r10
Index: ld-cris/expdyn2.d
===================================================================
RCS file: ld-cris/expdyn2.d
diff -N ld-cris/expdyn2.d
*** /dev/null	1 Jan 1970 00:00:00 -0000
--- ld-cris/expdyn2.d	12 Jul 2002 15:35:12 -0000
***************
*** 0 ****
--- 1,16 ----
+ #source: expdyn1.s
+ #source: expdref1.s --pic
+ #as: --no-underscore
+ #ld: -m crislinux --export-dynamic tmpdir/libdso-1.so
+ #objdump: -R
+ 
+ # Programs linked with --export-dynamic threw away .rela.got for exported
+ # symbols, but since got reference counter wasn't reset, there was a SEGV
+ # trying to generate the .rela.got relocations.  In this test, we have an
+ # object in the program that has pic-relocations to an exported symbol,
+ # but those relocations can be resolved at link-time.  We link to a DSO to
+ # get dynamic linking.
+ 
+ .*:     file format elf32-cris
+ 
+ DYNAMIC RELOCATION RECORDS \(none\)
Index: ld-cris/expdyn3.d
===================================================================
RCS file: ld-cris/expdyn3.d
diff -N ld-cris/expdyn3.d
*** /dev/null	1 Jan 1970 00:00:00 -0000
--- ld-cris/expdyn3.d	12 Jul 2002 15:35:12 -0000
***************
*** 0 ****
--- 1,12 ----
+ #source: expdyn1.s
+ #source: expdref1.s --pic
+ #source: euwref1.s --pic
+ #as: --no-underscore
+ #ld: -m crislinux --export-dynamic tmpdir/libdso-1.so
+ #objdump: -R
+ 
+ # Like expdyn2.d, but also weakly referencing symbols.
+ 
+ .*:     file format elf32-cris
+ 
+ DYNAMIC RELOCATION RECORDS \(none\)
Index: ld-cris/expdyn4.d
===================================================================
RCS file: ld-cris/expdyn4.d
diff -N ld-cris/expdyn4.d
*** /dev/null	1 Jan 1970 00:00:00 -0000
--- ld-cris/expdyn4.d	12 Jul 2002 15:35:12 -0000
***************
*** 0 ****
--- 1,12 ----
+ #source: expdyn1.s
+ #source: expdref1.s --pic
+ #source: comref1.s --pic
+ #as: --no-underscore
+ #ld: -m crislinux --export-dynamic tmpdir/libdso-1.so
+ #objdump: -R
+ 
+ # Like expdyn2.d, but referencing COMMON symbols.
+ 
+ .*:     file format elf32-cris
+ 
+ DYNAMIC RELOCATION RECORDS \(none\)
Index: ld-cris/nodyn4.d
===================================================================
RCS file: ld-cris/nodyn4.d
diff -N ld-cris/nodyn4.d
*** /dev/null	1 Jan 1970 00:00:00 -0000
--- ld-cris/nodyn4.d	12 Jul 2002 15:35:12 -0000
***************
*** 0 ****
--- 1,19 ----
+ #source: expdyn1.s
+ #source: expdref1.s --pic
+ #source: comref1.s --pic
+ #as: --no-underscore
+ #ld: -m crislinux
+ #readelf: -l
+ 
+ # Like expdyn4.d, but no --export-dynamic.  Got a BFD_ASSERT at one time.
+ # Check that we get the expected sections.
+ 
+ #...
+ There are 2 program headers, .*
+ #...
+   LOAD [0-9a-fx ]+ R E 0x2000
+   LOAD [0-9a-fx ]+ RW  0x2000
+ #...
+    00     \.text[ ]*
+    01     \.data \.got \.bss[ ]*
+ #pass
Index: elf32-cris.c
===================================================================
RCS file: /cvs/src/src/bfd/elf32-cris.c,v
retrieving revision 1.33
diff -p -c -r1.33 elf32-cris.c
*** elf32-cris.c	9 Jul 2002 03:49:27 -0000	1.33
--- elf32-cris.c	12 Jul 2002 15:37:20 -0000
*************** cris_elf_relocate_section (output_bfd, i
*** 1046,1074 ****
  			&& (h->elf_link_hash_flags & ELF_LINK_HASH_DEF_REGULAR)))
  		  {
  		    /* This wasn't checked above for ! info->shared, but
! 		       must hold there if we get here; the symbol must not
! 		       be used in, or defined by a DSO.  (Note that
! 		       checking for ELF_LINK_HASH_DEF_REGULAR doesn't
! 		       catch all cases.)  */
! 		    BFD_ASSERT (info->shared
  				|| (h->elf_link_hash_flags
! 				    & (ELF_LINK_HASH_REF_DYNAMIC
! 				       | ELF_LINK_HASH_DEF_DYNAMIC)) == 0);
  
  		    /* This is actually a static link, or it is a
! 		       -Bsymbolic link and the symbol is defined
! 		       locally, or the symbol was forced to be local
! 		       because of a version file, or we're not creating a
! 		       dynamic object and the symbol isn't referred to by
! 		       a dynamic object.  We must initialize
! 		       this entry in the global offset table.  Since
! 		       the offset must always be a multiple of 4, we
! 		       use the least significant bit to record whether
! 		       we have initialized it already.
! 
! 		       When doing a dynamic link, we create a .rela.got
! 		       relocation entry to initialize the value.  This
! 		       is done in the finish_dynamic_symbol routine.  */
  		    if ((off & 1) != 0)
  		      off &= ~1;
  		    else
--- 1046,1073 ----
  			&& (h->elf_link_hash_flags & ELF_LINK_HASH_DEF_REGULAR)))
  		  {
  		    /* This wasn't checked above for ! info->shared, but
! 		       must hold there if we get here; the symbol must be
! 		       defined in the regular program, or be undefweak.  */
! 		    BFD_ASSERT (!elf_hash_table (info)->dynamic_sections_created
! 				|| info->shared
  				|| (h->elf_link_hash_flags
! 				    & ELF_LINK_HASH_DEF_REGULAR) != 0
! 				|| h->root.type == bfd_link_hash_undefweak);
  
  		    /* This is actually a static link, or it is a
! 		       -Bsymbolic link and the symbol is defined locally,
! 		       or is undefweak, or the symbol was forced to be
! 		       local because of a version file, or we're not
! 		       creating a dynamic object.  We must initialize this
! 		       entry in the global offset table.  Since the offset
! 		       must always be a multiple of 4, we use the least
! 		       significant bit to record whether we have
! 		       initialized it already.
! 
! 		       If this GOT entry should be runtime-initialized, we
! 		       will create a .rela.got relocation entry to
! 		       initialize the value.  This is done in the
! 		       finish_dynamic_symbol routine.  */
  		    if ((off & 1) != 0)
  		      off &= ~1;
  		    else
*************** elf_cris_finish_dynamic_symbol (output_b
*** 1561,1569 ****
      }
  
    /* We don't emit .got relocs for symbols that aren't in the
!      dynamic-symbols table for an ordinary program.  */
    if (h->got.offset != (bfd_vma) -1
!       && (info->shared || h->dynindx != -1))
      {
        asection *sgot;
        asection *srela;
--- 1560,1572 ----
      }
  
    /* We don't emit .got relocs for symbols that aren't in the
!      dynamic-symbols table for an ordinary program and are either defined
!      by the program or are undefined weak symbols.  */
    if (h->got.offset != (bfd_vma) -1
!       && (info->shared
! 	  || (h->dynindx != -1
! 	      && (h->elf_link_hash_flags & ELF_LINK_HASH_DEF_REGULAR) == 0
! 	      && h->root.type != bfd_link_hash_undefweak)))
      {
        asection *sgot;
        asection *srela;
*************** elf_cris_adjust_dynamic_symbol (info, h)
*** 2067,2089 ****
    if (h->type == STT_FUNC
        || (h->elf_link_hash_flags & ELF_LINK_HASH_NEEDS_PLT) != 0)
      {
        if (! info->shared
! 	  && (h->elf_link_hash_flags & ELF_LINK_HASH_DEF_DYNAMIC) == 0
! 	  && (h->elf_link_hash_flags & ELF_LINK_HASH_REF_DYNAMIC) == 0
! 	  /* We must always create the plt entry if it was referenced by a
! 	     PLT relocation.  In this case we already recorded it as a
! 	     dynamic symbol.  */
! 	  /* FIXME: m68k and i386 differ here, for unclear reasons.  */
! 	  && h->dynindx == -1)
  	{
  	  /* This case can occur if we saw a PLT reloc in an input file,
! 	     but the symbol was never referred to by a dynamic object.  In
! 	     such a case, we don't actually need to build a procedure
! 	     linkage table, and we can just do a PC reloc instead, or
  	     change a .got.plt index to a .got index for GOTPLT relocs.  */
  	  BFD_ASSERT ((h->elf_link_hash_flags & ELF_LINK_HASH_NEEDS_PLT) != 0);
  	  h->plt.offset = (bfd_vma) -1;
- 
  	  return
  	    elf_cris_adjust_gotplt_to_got ((struct
  					    elf_cris_link_hash_entry *) h,
--- 2070,2092 ----
    if (h->type == STT_FUNC
        || (h->elf_link_hash_flags & ELF_LINK_HASH_NEEDS_PLT) != 0)
      {
+       /* If we link a program (not a DSO), we'll get rid of unnecessary
+ 	 PLT entries; we point to the actual symbols -- even for pic
+ 	 relocs, because a program built with -fpic should have the same
+ 	 result as one built without -fpic, specifically considering weak
+ 	 symbols.
+ 	 FIXME: m68k and i386 differ here, for unclear reasons.  */
        if (! info->shared
! 	  && (h->elf_link_hash_flags & ELF_LINK_HASH_DEF_DYNAMIC) == 0)
  	{
  	  /* This case can occur if we saw a PLT reloc in an input file,
! 	     but the symbol was not defined by a dynamic object.  In such
! 	     a case, we don't actually need to build a procedure linkage
! 	     table, and we can just do an absolute or PC reloc instead, or
  	     change a .got.plt index to a .got index for GOTPLT relocs.  */
  	  BFD_ASSERT ((h->elf_link_hash_flags & ELF_LINK_HASH_NEEDS_PLT) != 0);
+ 	  h->elf_link_hash_flags &= ~ELF_LINK_HASH_NEEDS_PLT;
  	  h->plt.offset = (bfd_vma) -1;
  	  return
  	    elf_cris_adjust_gotplt_to_got ((struct
  					    elf_cris_link_hash_entry *) h,
*************** elf_cris_adjust_dynamic_symbol (info, h)
*** 2121,2129 ****
  
        /* If this symbol is not defined in a regular file, and we are
  	 not generating a shared library, then set the symbol to this
! 	 location in the .plt.  This is required to make function
! 	 pointers compare as equal between the normal executable and
! 	 the shared library.  */
        if (!info->shared
  	  && (h->elf_link_hash_flags & ELF_LINK_HASH_DEF_REGULAR) == 0)
  	{
--- 2124,2130 ----
  
        /* If this symbol is not defined in a regular file, and we are
  	 not generating a shared library, then set the symbol to this
! 	 location in the .plt.  */
        if (!info->shared
  	  && (h->elf_link_hash_flags & ELF_LINK_HASH_DEF_REGULAR) == 0)
  	{
*************** elf_cris_discard_excess_program_dynamics
*** 2907,2916 ****
  
    /* If we're not creating a shared library and have a symbol which is
       referred to by .got references, but the symbol is defined locally,
!      (or rather, not referred to by a DSO and not defined by a DSO) then
!      lose the reloc for the .got (don't allocate room for it).  */
!   if ((h->root.elf_link_hash_flags
!        & (ELF_LINK_HASH_REF_DYNAMIC | ELF_LINK_HASH_DEF_DYNAMIC)) == 0)
      {
        if (h->root.got.refcount > 0
  	  /* The size of this section is only valid and in sync with the
--- 2908,2916 ----
  
    /* If we're not creating a shared library and have a symbol which is
       referred to by .got references, but the symbol is defined locally,
!      (or rather, not not defined by a DSO) then lose the reloc for the
!      .got (don't allocate room for it).  */
!   if ((h->root.elf_link_hash_flags & ELF_LINK_HASH_DEF_DYNAMIC) == 0)
      {
        if (h->root.got.refcount > 0
  	  /* The size of this section is only valid and in sync with the

brgds, H-P


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]