This is the mail archive of the binutils@sourceware.org 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]

PATCH: Prevent mn10300 assembler from relaxing calls to weak symbols


Hi Guys,

I am going to apply the attached patch which fixes a bug in the mn10300 assembler. Prior to the patch the mn10300 assembler relaxation code would decide to relax a call to a defined, weak symbol. This is a bad idea since of course the symbol can be overridden during linking, possibly invalidating the relaxation.

Cheers
  Nick

gas/ChangeLog
 2008-02-18  Nick Clifton  <nickc@redhat.com>

	* config/tc-mn10300.c (has_known_symbol_location): New function.
	Do not regard weak symbols as having a known location.
	(md_estimate_size_before_relax): Use new function.
	(md_pcrel_from): Do not compute a pcrel against a weak symbol.
Index: gas/config/tc-mn10300.c
===================================================================
RCS file: /cvs/src/src/gas/config/tc-mn10300.c,v
retrieving revision 1.66
diff -c -3 -p -r1.66 tc-mn10300.c
*************** tc_gen_reloc (asection *seg ATTRIBUTE_UN
*** 2262,2285 ****
    return relocs;
  }
  
  int
  md_estimate_size_before_relax (fragS *fragp, asection *seg)
  {
    if (fragp->fr_subtype == 6
!       && (!S_IS_DEFINED (fragp->fr_symbol)
! 	  || seg != S_GET_SEGMENT (fragp->fr_symbol)))
      fragp->fr_subtype = 7;
    else if (fragp->fr_subtype == 8
! 	   && (!S_IS_DEFINED (fragp->fr_symbol)
! 	       || seg != S_GET_SEGMENT (fragp->fr_symbol)))
      fragp->fr_subtype = 9;
    else if (fragp->fr_subtype == 10
! 	   &&  (!S_IS_DEFINED (fragp->fr_symbol)
! 		|| seg != S_GET_SEGMENT (fragp->fr_symbol)))
      fragp->fr_subtype = 12;
  
    if (fragp->fr_subtype == 13)
      return 3;
    if (fragp->fr_subtype >= sizeof (md_relax_table) / sizeof (md_relax_table[0]))
      abort ();
  
--- 2268,2303 ----
    return relocs;
  }
  
+ /* Returns true iff the symbol attached to the frag is at a known location
+    in the given section, (and hence the relocation to it can be relaxed by
+    the assembler).  */
+ static inline bfd_boolean
+ has_known_symbol_location (fragS * fragp, asection * sec)
+ {
+   symbolS * sym = fragp->fr_symbol;
+   
+   return sym != NULL
+     && S_IS_DEFINED (sym)
+     && ! S_IS_WEAK (sym)
+     && S_GET_SEGMENT (sym) == sec;
+ }
+ 
  int
  md_estimate_size_before_relax (fragS *fragp, asection *seg)
  {
    if (fragp->fr_subtype == 6
!       && ! has_known_symbol_location (fragp, seg))
      fragp->fr_subtype = 7;
    else if (fragp->fr_subtype == 8
! 	   && ! has_known_symbol_location (fragp, seg))
      fragp->fr_subtype = 9;
    else if (fragp->fr_subtype == 10
! 	   && ! has_known_symbol_location (fragp, seg))
      fragp->fr_subtype = 12;
  
    if (fragp->fr_subtype == 13)
      return 3;
+ 
    if (fragp->fr_subtype >= sizeof (md_relax_table) / sizeof (md_relax_table[0]))
      abort ();
  
*************** md_estimate_size_before_relax (fragS *fr
*** 2289,2299 ****
  long
  md_pcrel_from (fixS *fixp)
  {
!   if (fixp->fx_addsy != NULL && !S_IS_DEFINED (fixp->fx_addsy))
!     {
!       /* The symbol is undefined.  Let the linker figure it out.  */
!       return 0;
!     }
    return fixp->fx_frag->fr_address + fixp->fx_where;
  }
  
--- 2307,2317 ----
  long
  md_pcrel_from (fixS *fixp)
  {
!   if (fixp->fx_addsy != (symbolS *) NULL
!       && (!S_IS_DEFINED (fixp->fx_addsy) || S_IS_WEAK (fixp->fx_addsy)))
!     /* The symbol is undefined or weak.  Let the linker figure it out.  */
!     return 0;
! 
    return fixp->fx_frag->fr_address + fixp->fx_where;
  }
  

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