Apply fixes to allow arm WinCE toolchain to produce working executables.
authorNick Clifton <nickc@redhat.com>
Thu, 11 May 2006 08:48:58 +0000 (08:48 +0000)
committerNick Clifton <nickc@redhat.com>
Thu, 11 May 2006 08:48:58 +0000 (08:48 +0000)
bfd/ChangeLog
bfd/coff-arm.c
gas/ChangeLog
gas/config/tc-arm.c
ld/ChangeLog
ld/emultempl/pe.em
ld/pe-dll.c

index e757fc5583eff89170d9b20cf43758e23723105a..414e706404cb1bfeab1c7d63b04b5b8ccc05ce9a 100644 (file)
@@ -1,3 +1,10 @@
+2006-05-11  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.
+
 2006-05-10  Alan Modra  <amodra@bigpond.net.au>
 
        PR 2342
index 6b83dc7af7fd6c7c1efee572be0114e8be3a49ee..c5b47652108af4d652dcedb1ab9f57727a6b57e9 100644 (file)
@@ -220,7 +220,7 @@ static reloc_howto_type aoutarm_std_reloc_howto[] =
           complain_overflow_dont,
           aoutarm_fix_pcrel_26_done,
           "ARM_26D",
-          FALSE,
+          TRUE,        /* partial_inplace.  */
           0x00ffffff,
           0x0,
           PCRELOFFSET),
@@ -233,7 +233,7 @@ static reloc_howto_type aoutarm_std_reloc_howto[] =
           complain_overflow_bitfield,
           coff_arm_reloc,
           "ARM_32",
-          FALSE,
+          TRUE,        /* partial_inplace.  */
           0xffffffff,
           0xffffffff,
           PCRELOFFSET),
@@ -246,7 +246,7 @@ static reloc_howto_type aoutarm_std_reloc_howto[] =
           complain_overflow_bitfield,
           coff_arm_reloc,
           "ARM_RVA32",
-          FALSE,
+          TRUE,        /* partial_inplace.  */
           0xffffffff,
           0xffffffff,
           PCRELOFFSET),
@@ -294,7 +294,7 @@ static reloc_howto_type aoutarm_std_reloc_howto[] =
           complain_overflow_bitfield,
           coff_arm_reloc,
           "ARM_SECTION",
-          FALSE,
+          TRUE,        /* partial_inplace.  */
           0x0000ffff,
           0x0000ffff,
           PCRELOFFSET),
@@ -307,7 +307,7 @@ static reloc_howto_type aoutarm_std_reloc_howto[] =
           complain_overflow_bitfield,
           coff_arm_reloc,
           "ARM_SECREL",
-          FALSE,
+          TRUE,        /* partial_inplace.  */
           0xffffffff,
           0xffffffff,
           PCRELOFFSET),
@@ -1209,12 +1209,14 @@ coff_arm_relocate_section (bfd *output_bfd,
                     generation of bl's instruction offset.  */
           addend -= 8;
 #endif
-          howto = &fake_arm26_reloc;
+          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 4596052f18af4222f733a1e72467397391379b4a..9b08640d4b55c6a3f9d9b4a49e1af1d94beaf20c 100644 (file)
@@ -1,3 +1,9 @@
+2006-05-11  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.
+
 2006-05-09  David Ung  <davidu@mips.com>
 
        * config/tc-mips.c (append_insn): Only warn about an out-of-range
index 5ccbfc1f13460b08753b1e833e1288ffa50cecfa..690f59f7bdfb20b7951c3c52e756d9334ae2e9ad 100644 (file)
@@ -15561,10 +15561,16 @@ md_pcrel_from_section (fixS * fixP, segT seg)
 
   /* 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.  */
+     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)))
+         || (arm_force_relocation (fixP)
+#ifdef TE_WINCE
+             && !S_IS_EXTERNAL (fixP->fx_addsy)
+#endif
+             )))
     base = 0;
 
   switch (fixP->fx_r_type)
@@ -15601,6 +15607,17 @@ md_pcrel_from_section (fixS * fixP, segT seg)
     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;
@@ -16512,7 +16529,11 @@ md_apply_fix (fixS *   fixP,
     case BFD_RELOC_ARM_SBREL32:
     case BFD_RELOC_32_PCREL:
       if (fixP->fx_done || !seg->use_rela_p)
-       md_number_to_chars (buf, value, 4);
+#ifdef TE_WINCE
+       /* For WinCE we only do this for pcrel fixups.  */
+       if (fixP->fx_done || fixP->fx_pcrel)
+#endif
+         md_number_to_chars (buf, value, 4);
       break;
 
 #ifdef OBJ_ELF
index 3f76d99b5faa9a54b976d266bd25d65d4177a1d8..33500491f7f7ca4d1f8de4d55f991945c560361e 100644 (file)
@@ -1,3 +1,17 @@
+2006-05-11  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.
+
 2006-05-05  Alan Modra  <amodra@bigpond.net.au>
 
        * ld.texinfo: Document PowerPC and PowerPC64 options.
index 5afa8da00fef8588a5286cdde1f8aa2ac958ffc7..33ac71e5460169654846bb761784edb5dd4f9162 100644 (file)
@@ -283,7 +283,7 @@ static definfo init[] =
   D(MajorImageVersion,"__major_image_version__", 1),
   D(MinorImageVersion,"__minor_image_version__", 0),
 #ifdef TARGET_IS_armpe
-  D(MajorSubsystemVersion,"__major_subsystem_version__", 2),
+  D(MajorSubsystemVersion,"__major_subsystem_version__", 3),
 #else
   D(MajorSubsystemVersion,"__major_subsystem_version__", 4),
 #endif
index d4d42e4d36a2ea8c37d442bde00396500f0a1424..2edfdecb710527a14f82dccb4c3c847d95b9fa3a 100644 (file)
@@ -1,5 +1,5 @@
 /* Routines to help build PEI-format DLLs (Win32 etc)
-   Copyright 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005
+   Copyright 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006
    Free Software Foundation, Inc.
    Written by DJ Delorie <dj@cygnus.com>
 
@@ -95,7 +95,7 @@
     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
+    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
@@ -216,6 +216,9 @@ static pe_details_type *pe_details;
 
 static autofilter_entry_type autofilter_symbollist[] =
 {
+  { "DllMain", 7 },
+  { "DllMainCRTStartup", 17 },
+  { "_DllMainCRTStartup", 18 },
   { "DllMain@12", 10 },
   { "DllEntryPoint@0", 15 },
   { "DllMainCRTStartup@12", 20 },
@@ -226,12 +229,14 @@ static autofilter_entry_type autofilter_symbollist[] =
   { "_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 },
@@ -261,9 +266,10 @@ static autofilter_entry_type autofilter_objlist[] =
 
 static autofilter_entry_type autofilter_symbolprefixlist[] =
 {
-  /*  { "__imp_", 6 }, */
+  { "__imp_", 6 },
   /* Do __imp_ explicitly to save time.  */
   { "__rtti_", 7 },
+  { ".idata$", 7 },
   /* Don't re-export auto-imported symbols.  */
   { "_nm_", 4 },
   { "__builtin_", 10 },
@@ -1131,8 +1137,13 @@ generate_reloc (bfd *abfd, struct bfd_link_info *info)
          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  */
@@ -1780,6 +1791,14 @@ static unsigned char jmp_mips_bytes[] =
   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)
 {
@@ -1805,6 +1824,10 @@ make_one (def_file_export *exp, bfd *parent)
       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 ();
     }
@@ -1878,6 +1901,9 @@ make_one (def_file_export *exp, bfd *parent)
          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 ();
        }
@@ -2048,7 +2074,7 @@ make_import_fixup_mark (arelent *rel)
   return fixup_name;
 }
 
-/*     .section        .idata$3
+/*     .section        .idata$2
        .rva            __nm_thnk_SYM (singleton thunk with name of func)
        .long           0
        .long           0
@@ -2061,8 +2087,8 @@ make_import_fixup_entry (const char *name,
                         const char *dll_symname,
                         bfd *parent)
 {
-  asection *id3;
-  unsigned char *d3;
+  asection *id2;
+  unsigned char *d2;
   char *oname;
   bfd *abfd;
 
@@ -2079,25 +2105,25 @@ make_import_fixup_entry (const char *name,
 
   symptr = 0;
   symtab = xmalloc (6 * sizeof (asymbol *));
-  id3 = quick_section (abfd, ".idata$3", SEC_HAS_CONTENTS, 2);
+  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, id3, 20);
-  d3 = xmalloc (20);
-  id3->contents = d3;
-  memset (d3, 0, 20);
+  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 (id3);
+  save_relocs (id2);
 
   bfd_set_symtab (abfd, symtab, symptr);
 
-  bfd_set_section_contents (abfd, id3, d3, 0, 20);
+  bfd_set_section_contents (abfd, id2, d2, 0, 20);
 
   bfd_make_readable (abfd);
   return abfd;