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]

Re: Binutils on arm : pls advice me how to proceed


Hi Pedro, Hi Danny,

Please accept my apologies in taking so long to reply to your emails. I have now had a chance to go over them and the patches that they contained and then seemed quite reasonable to me. I have applied them to my local source tree and checked to see if there were any regressions - there were not.

Unfortunately I do not have an arm-wince system at my disposal, so I cannot check that the (slightly revised) versions of the patches that I applied allow working binaries to be created, so please can I ask for your help ?

I am attaching a unified patch which I think contains all of the changes that you suggested, along with a little bit of code tidying. Please could you try applying them to a set of binutils sources (from the mainline of the CVS repository) and testing them to see if they produce working binaries ?

One thing I am quite worried about is whether partial linking will work. (ie using the "ld -r ...." file to create an object file that is an amalgam of several other object files). I suspect that there might be problems with the -8 bias to branch relocations, but without a test environment I cannot tell for sure.

Thanks very much for perserving with your work, and assuming that you can confirm that the patch works, I will be happy to check it in with the ChangeLogs below.

Cheers
  Nick

bfd/ChangeLog
2006-05-10  Pedro Alves  <pedro_alves@portugalmail.pt>

	* coff-arm.c (ARM_26D, ARM_32, ARM_RVA_32, ARM_SECTION,
        ARM_SECREL): Mark WinCE versions of these relocs as partial
	inplace.
	(coff_arm_relocate_section): Adjust addend for WinCE.

gas/ChangeLog
2006-05-10  Pedro Alves  <pedro_alves@portugalmail.pt>

* config/tc-arm.c (md_pcrel_from_section): Force a bias for relocs against external symbols for WinCE targets.
(md_apply_fix): Likewise.


ld/ChangeLog
2006-05-10  Pedro Alves  <pedro_alves@portugalmail.pt>

	* pe-dll.c (autofilter_symbollist): Add Dllmain, 		
	DllMainCRTStartup, _DllMainCRTStartup and .text.
	(autofilter_liblist): Add libcegcc.
	(autofilter_symbolprefixlist): Add __imp_ and .idata$.
	(generate_reloc): Do not skip sections without a SEC_LOAD flag, 	
	they can still contain relocs that need processing.
	Skip the .idata$6 section.
	(jmp_arm_bytes): New array: Contains byte codes for an ARM jump.
	(make_one): Use the new array.
	(make_import_fixup_entry): Use .idata$2 instead of .idata$3.
	* emultempl/pe.em (MajorSubsystemVersion): Set to 3 for armpe.


Index: bfd/coff-arm.c
===================================================================
RCS file: /cvs/src/src/bfd/coff-arm.c,v
retrieving revision 1.63
diff -c -3 -p -r1.63 coff-arm.c
*** bfd/coff-arm.c	16 Mar 2006 12:20:15 -0000	1.63
--- bfd/coff-arm.c	10 May 2006 10:05:35 -0000
*************** static reloc_howto_type aoutarm_std_relo
*** 220,226 ****
  	   complain_overflow_dont,
  	   aoutarm_fix_pcrel_26_done,
  	   "ARM_26D",
! 	   FALSE,
  	   0x00ffffff,
  	   0x0,
  	   PCRELOFFSET),
--- 220,226 ----
  	   complain_overflow_dont,
  	   aoutarm_fix_pcrel_26_done,
  	   "ARM_26D",
! 	   TRUE, 	/* partial_inplace.  */
  	   0x00ffffff,
  	   0x0,
  	   PCRELOFFSET),
*************** static reloc_howto_type aoutarm_std_relo
*** 233,239 ****
  	   complain_overflow_bitfield,
  	   coff_arm_reloc,
  	   "ARM_32",
! 	   FALSE,
  	   0xffffffff,
  	   0xffffffff,
  	   PCRELOFFSET),
--- 233,239 ----
  	   complain_overflow_bitfield,
  	   coff_arm_reloc,
  	   "ARM_32",
! 	   TRUE, 	/* partial_inplace.  */
  	   0xffffffff,
  	   0xffffffff,
  	   PCRELOFFSET),
*************** static reloc_howto_type aoutarm_std_relo
*** 246,252 ****
  	   complain_overflow_bitfield,
  	   coff_arm_reloc,
  	   "ARM_RVA32",
! 	   FALSE,
  	   0xffffffff,
  	   0xffffffff,
  	   PCRELOFFSET),
--- 246,252 ----
  	   complain_overflow_bitfield,
  	   coff_arm_reloc,
  	   "ARM_RVA32",
! 	   TRUE, 	/* partial_inplace.  */
  	   0xffffffff,
  	   0xffffffff,
  	   PCRELOFFSET),
*************** static reloc_howto_type aoutarm_std_relo
*** 294,300 ****
  	   complain_overflow_bitfield,
  	   coff_arm_reloc,
  	   "ARM_SECTION",
! 	   FALSE,
  	   0x0000ffff,
  	   0x0000ffff,
  	   PCRELOFFSET),
--- 294,300 ----
  	   complain_overflow_bitfield,
  	   coff_arm_reloc,
  	   "ARM_SECTION",
! 	   TRUE, 	/* partial_inplace.  */
  	   0x0000ffff,
  	   0x0000ffff,
  	   PCRELOFFSET),
*************** static reloc_howto_type aoutarm_std_relo
*** 307,313 ****
  	   complain_overflow_bitfield,
  	   coff_arm_reloc,
  	   "ARM_SECREL",
! 	   FALSE,
  	   0xffffffff,
  	   0xffffffff,
  	   PCRELOFFSET),
--- 307,313 ----
  	   complain_overflow_bitfield,
  	   coff_arm_reloc,
  	   "ARM_SECREL",
! 	   TRUE, 	/* partial_inplace.  */
  	   0xffffffff,
  	   0xffffffff,
  	   PCRELOFFSET),
*************** coff_arm_relocate_section (bfd *output_b
*** 1209,1220 ****
                      generation of bl's instruction offset.  */
            addend -= 8;
  #endif
!           howto = &fake_arm26_reloc;
          }
  
  #ifdef ARM_WINCE
        /* MS ARM-CE makes the reloc relative to the opcode's pc, not
  	 the next opcode's pc, so is off by one.  */
  #endif
  
        /* If we are doing a relocatable link, then we can just ignore
--- 1209,1222 ----
                      generation of bl's instruction offset.  */
            addend -= 8;
  #endif
!           howto = & fake_arm26_reloc;
          }
  
  #ifdef ARM_WINCE
        /* MS ARM-CE makes the reloc relative to the opcode's pc, not
  	 the next opcode's pc, so is off by one.  */
+       if (howto->pc_relative && !info->relocatable)
+ 	addend -= 8;
  #endif
  
        /* If we are doing a relocatable link, then we can just ignore
Index: gas/config/tc-arm.c
===================================================================
RCS file: /cvs/src/src/gas/config/tc-arm.c,v
retrieving revision 1.267
diff -c -3 -p -r1.267 tc-arm.c
*** gas/config/tc-arm.c	9 May 2006 15:13:22 -0000	1.267
--- gas/config/tc-arm.c	10 May 2006 10:05:39 -0000
*************** md_pcrel_from_section (fixS * fixP, segT
*** 15561,15570 ****
  
    /* If this is pc-relative and we are going to emit a relocation
       then we just want to put out any pipeline compensation that the linker
!      will need.  Otherwise we want to use the calculated base.  */
    if (fixP->fx_pcrel 
        && ((fixP->fx_addsy && S_GET_SEGMENT (fixP->fx_addsy) != seg)
! 	  || arm_force_relocation (fixP)))
      base = 0;
  
    switch (fixP->fx_r_type)
--- 15561,15576 ----
  
    /* If this is pc-relative and we are going to emit a relocation
       then we just want to put out any pipeline compensation that the linker
!      will need.  Otherwise we want to use the calculated base.
!      For WinCE we skip the bias for externals as well, since this
!      is how the MS ARM-CE assembler behaves and we want to be compatible.  */
    if (fixP->fx_pcrel 
        && ((fixP->fx_addsy && S_GET_SEGMENT (fixP->fx_addsy) != seg)
! 	  || (arm_force_relocation (fixP)
! #ifdef TE_WINCE
! 	      && !S_IS_EXTERNAL (fixP->fx_addsy)
! #endif
! 	      )))
      base = 0;
  
    switch (fixP->fx_r_type)
*************** md_pcrel_from_section (fixS * fixP, segT
*** 15601,15606 ****
--- 15607,15623 ----
      case BFD_RELOC_ARM_PCREL_BLX:
      case BFD_RELOC_ARM_PLT32:
  #ifdef TE_WINCE
+       /* When handling fixups immediately, because we have already 
+          discovered the value of a symbol, or the address of the frag involved
+ 	 we must account for the offset by +8, as the OS loader will never see the reloc.
+          see fixup_segment() in write.c
+          The S_IS_EXTERNAL test handles the case of global symbols.
+          Those need the calculated base, not just the pipe compensation the linker will need.  */
+       if (fixP->fx_pcrel
+ 	  && fixP->fx_addsy != NULL
+ 	  && (S_GET_SEGMENT (fixP->fx_addsy) == seg)
+ 	  && (S_IS_EXTERNAL (fixP->fx_addsy) || !arm_force_relocation (fixP)))
+ 	return base + 8;
        return base;
  #else
        return base + 8;
*************** md_apply_fix (fixS *	fixP,
*** 16511,16518 ****
--- 16528,16542 ----
      case BFD_RELOC_ARM_ROSEGREL32:
      case BFD_RELOC_ARM_SBREL32:
      case BFD_RELOC_32_PCREL:
+ #ifdef TE_WINCE
+       if (!fixP->fx_done && seg->use_rela_p)
+         break;
+       if (fixP->fx_done || fixP->fx_pcrel)
+         md_number_to_chars (buf, value, 4);
+ #else
        if (fixP->fx_done || !seg->use_rela_p)
  	md_number_to_chars (buf, value, 4);
+ #endif
        break;
  
  #ifdef OBJ_ELF
Index: ld/pe-dll.c
===================================================================
RCS file: /cvs/src/src/ld/pe-dll.c,v
retrieving revision 1.83
diff -c -3 -p -r1.83 pe-dll.c
*** ld/pe-dll.c	31 Jan 2006 22:08:14 -0000	1.83
--- ld/pe-dll.c	10 May 2006 10:05:40 -0000
***************
*** 1,5 ****
  /* Routines to help build PEI-format DLLs (Win32 etc)
!    Copyright 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005
     Free Software Foundation, Inc.
     Written by DJ Delorie <dj@cygnus.com>
  
--- 1,5 ----
  /* Routines to help build PEI-format DLLs (Win32 etc)
!    Copyright 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006
     Free Software Foundation, Inc.
     Written by DJ Delorie <dj@cygnus.com>
  
***************
*** 95,101 ****
      For each reference of data symbol to be imported from DLL (to set of which
      belong symbols with name <sym>, if __imp_<sym> is found in implib), the
      import fixup entry is generated. That entry is of type
!     IMAGE_IMPORT_DESCRIPTOR and stored in .idata$3 subsection. Each
      fixup entry contains pointer to symbol's address within .text section
      (marked with __fuN_<sym> symbol, where N is integer), pointer to DLL name
      (so, DLL name is referenced by multiple entries), and pointer to symbol
--- 95,101 ----
      For each reference of data symbol to be imported from DLL (to set of which
      belong symbols with name <sym>, if __imp_<sym> is found in implib), the
      import fixup entry is generated. That entry is of type
!     IMAGE_IMPORT_DESCRIPTOR and stored in .idata$2 subsection. Each
      fixup entry contains pointer to symbol's address within .text section
      (marked with __fuN_<sym> symbol, where N is integer), pointer to DLL name
      (so, DLL name is referenced by multiple entries), and pointer to symbol
*************** static pe_details_type *pe_details;
*** 216,221 ****
--- 216,224 ----
  
  static autofilter_entry_type autofilter_symbollist[] =
  {
+   { "DllMain", 7 },
+   { "DllMainCRTStartup", 17 },
+   { "_DllMainCRTStartup", 18 },
    { "DllMain@12", 10 },
    { "DllEntryPoint@0", 15 },
    { "DllMainCRTStartup@12", 20 },
*************** static autofilter_entry_type autofilter_
*** 226,237 ****
--- 229,242 ----
    { "_pei386_runtime_relocator", 25 },
    { "do_pseudo_reloc", 15 },
    { "cygwin_crt0", 11 },
+   { ".text", 5 },
    { NULL, 0 }
  };
  
  /* Do not specify library suffix explicitly, to allow for dllized versions.  */
  static autofilter_entry_type autofilter_liblist[] =
  {
+   { "libcegcc", 8 },
    { "libcygwin", 9 },
    { "libgcc", 6 },
    { "libstdc++", 9 },
*************** static autofilter_entry_type autofilter_
*** 261,269 ****
  
  static autofilter_entry_type autofilter_symbolprefixlist[] =
  {
!   /*  { "__imp_", 6 }, */
    /* Do __imp_ explicitly to save time.  */
    { "__rtti_", 7 },
    /* Don't re-export auto-imported symbols.  */
    { "_nm_", 4 },
    { "__builtin_", 10 },
--- 266,275 ----
  
  static autofilter_entry_type autofilter_symbolprefixlist[] =
  {
!   { "__imp_", 6 },
    /* Do __imp_ explicitly to save time.  */
    { "__rtti_", 7 },
+   { ".idata$", 7 },
    /* Don't re-export auto-imported symbols.  */
    { "_nm_", 4 },
    { "__builtin_", 10 },
*************** generate_reloc (bfd *abfd, struct bfd_li
*** 1131,1138 ****
--- 1137,1149 ----
  	  int nsyms, symsize;
  
  	  /* If it's not loaded, we don't need to relocate it this way.  */
+ #if 0	  /* Some toolchains can generate .data sections without a SEC_LOAD flag but with relocs.  */
  	  if (!(s->output_section->flags & SEC_LOAD))
  	    continue;
+ #endif
+ 	  /* Huh ?  */
+ 	  if (strncmp (bfd_get_section_name (abfd, s), ".idata",6) == 0)
+ 	    continue;
  
  	  /* I don't know why there would be a reloc for these, but I've
  	     seen it happen - DJ  */
*************** static unsigned char jmp_mips_bytes[] =
*** 1780,1785 ****
--- 1791,1804 ----
    0x08, 0x00, 0x00, 0x01,  0x00, 0x00, 0x00, 0x00
  };
  
+ static unsigned char jmp_arm_bytes[] =
+ {
+   0x00, 0xc0, 0x9f, 0xe5,	/* ldr  ip, [pc] */
+   0x00, 0xf0, 0x9c, 0xe5,	/* ldr  pc, [ip] */
+   0,    0,    0,    0
+ };
+ 
+ 
  static bfd *
  make_one (def_file_export *exp, bfd *parent)
  {
*************** make_one (def_file_export *exp, bfd *par
*** 1805,1810 ****
--- 1824,1833 ----
        jmp_bytes = jmp_mips_bytes;
        jmp_byte_count = sizeof (jmp_mips_bytes);
        break;
+     case PE_ARCH_arm:
+       jmp_bytes = jmp_arm_bytes;
+       jmp_byte_count = sizeof (jmp_arm_bytes);
+       break;
      default:
        abort ();
      }
*************** make_one (def_file_export *exp, bfd *par
*** 1878,1883 ****
--- 1901,1909 ----
  	  quick_reloc (abfd, 0, BFD_RELOC_LO16, 0); /* MIPS_R_PAIR */
  	  quick_reloc (abfd, 4, BFD_RELOC_LO16, 2);
  	  break;
+ 	case PE_ARCH_arm:
+ 	  quick_reloc (abfd, 8, BFD_RELOC_32, 2);
+ 	  break;
  	default:
  	  abort ();
  	}
*************** make_import_fixup_mark (arelent *rel)
*** 2048,2054 ****
    return fixup_name;
  }
  
! /*	.section	.idata$3
    	.rva		__nm_thnk_SYM (singleton thunk with name of func)
   	.long		0
   	.long		0
--- 2074,2080 ----
    return fixup_name;
  }
  
! /*	.section	.idata$2
    	.rva		__nm_thnk_SYM (singleton thunk with name of func)
   	.long		0
   	.long		0
*************** make_import_fixup_entry (const char *nam
*** 2061,2068 ****
  			 const char *dll_symname,
  			 bfd *parent)
  {
!   asection *id3;
!   unsigned char *d3;
    char *oname;
    bfd *abfd;
  
--- 2087,2094 ----
  			 const char *dll_symname,
  			 bfd *parent)
  {
!   asection *id2;
!   unsigned char *d2;
    char *oname;
    bfd *abfd;
  
*************** make_import_fixup_entry (const char *nam
*** 2079,2103 ****
  
    symptr = 0;
    symtab = xmalloc (6 * sizeof (asymbol *));
!   id3 = quick_section (abfd, ".idata$3", SEC_HAS_CONTENTS, 2);
  
    quick_symbol (abfd, U ("_nm_thnk_"), name, "", UNDSEC, BSF_GLOBAL, 0);
    quick_symbol (abfd, U (""), dll_symname, "_iname", UNDSEC, BSF_GLOBAL, 0);
    quick_symbol (abfd, "", fixup_name, "", UNDSEC, BSF_GLOBAL, 0);
  
!   bfd_set_section_size (abfd, id3, 20);
!   d3 = xmalloc (20);
!   id3->contents = d3;
!   memset (d3, 0, 20);
  
    quick_reloc (abfd, 0, BFD_RELOC_RVA, 1);
    quick_reloc (abfd, 12, BFD_RELOC_RVA, 2);
    quick_reloc (abfd, 16, BFD_RELOC_RVA, 3);
!   save_relocs (id3);
  
    bfd_set_symtab (abfd, symtab, symptr);
  
!   bfd_set_section_contents (abfd, id3, d3, 0, 20);
  
    bfd_make_readable (abfd);
    return abfd;
--- 2105,2129 ----
  
    symptr = 0;
    symtab = xmalloc (6 * sizeof (asymbol *));
!   id2 = quick_section (abfd, ".idata$2", SEC_HAS_CONTENTS, 2);
  
    quick_symbol (abfd, U ("_nm_thnk_"), name, "", UNDSEC, BSF_GLOBAL, 0);
    quick_symbol (abfd, U (""), dll_symname, "_iname", UNDSEC, BSF_GLOBAL, 0);
    quick_symbol (abfd, "", fixup_name, "", UNDSEC, BSF_GLOBAL, 0);
  
!   bfd_set_section_size (abfd, id2, 20);
!   d2 = xmalloc (20);
!   id2->contents = d2;
!   memset (d2, 0, 20);
  
    quick_reloc (abfd, 0, BFD_RELOC_RVA, 1);
    quick_reloc (abfd, 12, BFD_RELOC_RVA, 2);
    quick_reloc (abfd, 16, BFD_RELOC_RVA, 3);
!   save_relocs (id2);
  
    bfd_set_symtab (abfd, symtab, symptr);
  
!   bfd_set_section_contents (abfd, id2, d2, 0, 20);
  
    bfd_make_readable (abfd);
    return abfd;
Index: ld/emultempl/pe.em
===================================================================
RCS file: /cvs/src/src/ld/emultempl/pe.em,v
retrieving revision 1.113
diff -c -3 -p -r1.113 pe.em
*** ld/emultempl/pe.em	24 Nov 2005 06:02:08 -0000	1.113
--- ld/emultempl/pe.em	10 May 2006 10:05:40 -0000
*************** static definfo init[] =
*** 283,289 ****
    D(MajorImageVersion,"__major_image_version__", 1),
    D(MinorImageVersion,"__minor_image_version__", 0),
  #ifdef TARGET_IS_armpe
!   D(MajorSubsystemVersion,"__major_subsystem_version__", 2),
  #else
    D(MajorSubsystemVersion,"__major_subsystem_version__", 4),
  #endif
--- 283,289 ----
    D(MajorImageVersion,"__major_image_version__", 1),
    D(MinorImageVersion,"__minor_image_version__", 0),
  #ifdef TARGET_IS_armpe
!   D(MajorSubsystemVersion,"__major_subsystem_version__", 3),
  #else
    D(MajorSubsystemVersion,"__major_subsystem_version__", 4),
  #endif

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