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]

Re: Recent i386 assembler change.


Apparently PE wants relocs on all external syms.  Also, I can't see
any reason now why I excluded PE from the MD_APPLY_SYM_CHANGE.
Applying the following:

	* config/tc-i386.h (EXTERN_FORCE_RELOC): Define.
	(MD_APPLY_SYM_VALUE): Define for PE too.

There's also a need for some changes in tc-i386.c:md_apply_fix3.
I'll apply the following when I hear back from Donn, in all
likelihood with some corrections..  I'm not at all sure about
the hack inside #ifdef TE_PE, whether it's needed or should
occur prior to the previous bfd_install_relocation hack.

	* config/tc-i386.c (md_apply_fix3): Hack around bfd_install_relocation
	brain damage for PE.

Index: gas/config/tc-i386.h
===================================================================
RCS file: /cvs/src/src/gas/config/tc-i386.h,v
retrieving revision 1.35
diff -u -p -r1.35 tc-i386.h
--- gas/config/tc-i386.h	17 Sep 2002 02:24:37 -0000	1.35
+++ gas/config/tc-i386.h	15 Oct 2002 00:46:39 -0000
@@ -467,9 +467,17 @@ void i386_validate_fix PARAMS ((struct f
 #define tc_fix_adjustable(X)  tc_i386_fix_adjustable(X)
 extern int tc_i386_fix_adjustable PARAMS ((struct fix *));
 
-#ifndef TE_PE
 /* Values passed to md_apply_fix3 don't include the symbol value.  */
 #define MD_APPLY_SYM_VALUE(FIX) 0
+
+/* ELF wants external syms kept, as does PE COFF.  */
+#ifdef TE_PE
+#define EXTERN_FORCE_RELOC				\
+  (OUTPUT_FLAVOR == bfd_target_elf_flavour		\
+   || OUTPUT_FLAVOR == bfd_target_coff_flavour)
+#else
+#define EXTERN_FORCE_RELOC				\
+  (OUTPUT_FLAVOR == bfd_target_elf_flavour)
 #endif
 
 #define TC_FORCE_RELOCATION(FIX)	i386_force_relocation (FIX)
Index: gas/config/tc-i386.c
===================================================================
RCS file: /cvs/src/src/gas/config/tc-i386.c,v
retrieving revision 1.134
diff -c -p -r1.134 tc-i386.c
*** gas/config/tc-i386.c	11 Oct 2002 00:25:32 -0000	1.134
--- gas/config/tc-i386.c	15 Oct 2002 02:10:02 -0000
*************** md_apply_fix3 (fixP, valP, seg)
*** 4625,4666 ****
        && (fixP->fx_r_type == BFD_RELOC_32_PCREL
  	  || fixP->fx_r_type == BFD_RELOC_16_PCREL
  	  || fixP->fx_r_type == BFD_RELOC_8_PCREL)
!       && !use_rela_relocations)
      {
        /* This is a hack.  There should be a better way to handle this.
  	 This covers for the fact that bfd_install_relocation will
  	 subtract the current location (for partial_inplace, PC relative
  	 relocations); see more below.  */
! #ifndef OBJ_AOUT
!       if (OUTPUT_FLAVOR == bfd_target_elf_flavour
! #ifdef TE_PE
! 	  || OUTPUT_FLAVOR == bfd_target_coff_flavour
! #endif
! 	  )
! 	value += fixP->fx_where + fixP->fx_frag->fr_address;
! #endif
! #if defined (OBJ_ELF) || defined (OBJ_MAYBE_ELF)
!       if (OUTPUT_FLAVOR == bfd_target_elf_flavour)
! 	{
! 	  segT sym_seg = S_GET_SEGMENT (fixP->fx_addsy);
  
! 	  if ((sym_seg == seg
! 	       || (symbol_section_p (fixP->fx_addsy)
! 		   && sym_seg != absolute_section))
! 	      && !S_FORCE_RELOC (fixP->fx_addsy))
! 	    {
! 	      /* Yes, we add the values in twice.  This is because
! 		 bfd_install_relocation subtracts them out again.  I think
! 		 bfd_install_relocation is broken, but I don't dare change
! 		 it.  FIXME.  */
! 	      value += fixP->fx_where + fixP->fx_frag->fr_address;
! 	    }
  	}
! #endif
! #if defined (OBJ_COFF) && defined (TE_PE)
        /* For some reason, the PE format does not store a section
  	 address offset for a PC relative symbol.  */
!       if (S_GET_SEGMENT (fixP->fx_addsy) != seg)
  	value += md_pcrel_from (fixP);
  #endif
      }
--- 4625,4657 ----
        && (fixP->fx_r_type == BFD_RELOC_32_PCREL
  	  || fixP->fx_r_type == BFD_RELOC_16_PCREL
  	  || fixP->fx_r_type == BFD_RELOC_8_PCREL)
!       && !use_rela_relocations
!       && EXTERN_FORCE_RELOC)
      {
+       segT sym_seg;
+ 
        /* This is a hack.  There should be a better way to handle this.
  	 This covers for the fact that bfd_install_relocation will
  	 subtract the current location (for partial_inplace, PC relative
  	 relocations); see more below.  */
!       value += fixP->fx_where + fixP->fx_frag->fr_address;
  
!       sym_seg = S_GET_SEGMENT (fixP->fx_addsy);
!       if ((sym_seg == seg
! 	   || (symbol_section_p (fixP->fx_addsy)
! 	       && sym_seg != absolute_section))
! 	  && !S_FORCE_RELOC (fixP->fx_addsy))
! 	{
! 	  /* Yes, we add the values in twice.  This is because
! 	     bfd_install_relocation subtracts them out again.  I think
! 	     bfd_install_relocation is broken, but I don't dare change
! 	     it.  FIXME.  */
! 	  value += fixP->fx_where + fixP->fx_frag->fr_address;
  	}
! #ifdef TE_PE
        /* For some reason, the PE format does not store a section
  	 address offset for a PC relative symbol.  */
!       else if (sym_seg != seg)
  	value += md_pcrel_from (fixP);
  #endif
      }

-- 
Alan Modra
IBM OzLabs - Linux Technology Centre


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