* coff-arm.c (arm_emit_base_file_entry): Check fwrite return value.
[deliverable/binutils-gdb.git] / bfd / coff-arm.c
index 6b83dc7af7fd6c7c1efee572be0114e8be3a49ee..3bf61e5b769e708b4d49208d22dcbd3d18c7d777 100644 (file)
@@ -1,6 +1,6 @@
 /* BFD back-end for ARM COFF files.
    Copyright 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
 /* BFD back-end for ARM COFF files.
    Copyright 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
-   2000, 2001, 2002, 2003, 2004, 2005, 2006
+   2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007
    Free Software Foundation, Inc.
    Written by Cygnus Support.
 
    Free Software Foundation, Inc.
    Written by Cygnus Support.
 
@@ -8,7 +8,7 @@
 
    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
 
    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
-   the Free Software Foundation; either version 2 of the License, or
+   the Free Software Foundation; either version 3 of the License, or
    (at your option) any later version.
 
    This program is distributed in the hope that it will be useful,
    (at your option) any later version.
 
    This program is distributed in the hope that it will be useful,
 
    You should have received a copy of the GNU General Public License
    along with this program; if not, write to the Free Software
 
    You should have received a copy of the GNU General Public License
    along with this program; if not, write to the Free Software
-   Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA.  */
+   Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
+   MA 02110-1301, USA.  */
 
 
-#include "bfd.h"
 #include "sysdep.h"
 #include "sysdep.h"
+#include "bfd.h"
 #include "libbfd.h"
 #include "coff/arm.h"
 #include "coff/internal.h"
 #include "libbfd.h"
 #include "coff/arm.h"
 #include "coff/internal.h"
@@ -163,6 +164,19 @@ coff_arm_reloc (bfd *abfd,
 
 /* These most certainly belong somewhere else. Just had to get rid of
    the manifest constants in the code.  */
 
 /* These most certainly belong somewhere else. Just had to get rid of
    the manifest constants in the code.  */
+
+#ifdef ARM_WINCE
+
+#define ARM_26D      0
+#define ARM_32       1
+#define ARM_RVA32    2
+#define ARM_26      3
+#define ARM_THUMB12  4
+#define ARM_SECTION  14
+#define ARM_SECREL   15
+
+#else
+
 #define ARM_8        0
 #define ARM_16       1
 #define ARM_32       2
 #define ARM_8        0
 #define ARM_16       1
 #define ARM_32       2
@@ -179,20 +193,6 @@ coff_arm_reloc (bfd *abfd,
 #define ARM_THUMB12 13
 #define ARM_THUMB23 14
 
 #define ARM_THUMB12 13
 #define ARM_THUMB23 14
 
-#ifdef ARM_WINCE
-#undef  ARM_32
-#undef  ARM_RVA32
-#undef  ARM_26
-#undef  ARM_THUMB12
-#undef  ARM_26D
-
-#define ARM_26D      0
-#define ARM_32       1
-#define ARM_RVA32    2
-#define ARM_26      3
-#define ARM_THUMB12  4
-#define ARM_SECTION  14
-#define ARM_SECREL   15
 #endif
 
 static bfd_reloc_status_type aoutarm_fix_pcrel_26_done
 #endif
 
 static bfd_reloc_status_type aoutarm_fix_pcrel_26_done
@@ -220,7 +220,7 @@ static reloc_howto_type aoutarm_std_reloc_howto[] =
           complain_overflow_dont,
           aoutarm_fix_pcrel_26_done,
           "ARM_26D",
           complain_overflow_dont,
           aoutarm_fix_pcrel_26_done,
           "ARM_26D",
-          FALSE,
+          TRUE,        /* partial_inplace.  */
           0x00ffffff,
           0x0,
           PCRELOFFSET),
           0x00ffffff,
           0x0,
           PCRELOFFSET),
@@ -233,7 +233,7 @@ static reloc_howto_type aoutarm_std_reloc_howto[] =
           complain_overflow_bitfield,
           coff_arm_reloc,
           "ARM_32",
           complain_overflow_bitfield,
           coff_arm_reloc,
           "ARM_32",
-          FALSE,
+          TRUE,        /* partial_inplace.  */
           0xffffffff,
           0xffffffff,
           PCRELOFFSET),
           0xffffffff,
           0xffffffff,
           PCRELOFFSET),
@@ -246,7 +246,7 @@ static reloc_howto_type aoutarm_std_reloc_howto[] =
           complain_overflow_bitfield,
           coff_arm_reloc,
           "ARM_RVA32",
           complain_overflow_bitfield,
           coff_arm_reloc,
           "ARM_RVA32",
-          FALSE,
+          TRUE,        /* partial_inplace.  */
           0xffffffff,
           0xffffffff,
           PCRELOFFSET),
           0xffffffff,
           0xffffffff,
           PCRELOFFSET),
@@ -294,7 +294,7 @@ static reloc_howto_type aoutarm_std_reloc_howto[] =
           complain_overflow_bitfield,
           coff_arm_reloc,
           "ARM_SECTION",
           complain_overflow_bitfield,
           coff_arm_reloc,
           "ARM_SECTION",
-          FALSE,
+          TRUE,        /* partial_inplace.  */
           0x0000ffff,
           0x0000ffff,
           PCRELOFFSET),
           0x0000ffff,
           0x0000ffff,
           PCRELOFFSET),
@@ -307,7 +307,7 @@ static reloc_howto_type aoutarm_std_reloc_howto[] =
           complain_overflow_bitfield,
           coff_arm_reloc,
           "ARM_SECREL",
           complain_overflow_bitfield,
           coff_arm_reloc,
           "ARM_SECREL",
-          FALSE,
+          TRUE,        /* partial_inplace.  */
           0xffffffff,
           0xffffffff,
           PCRELOFFSET),
           0xffffffff,
           0xffffffff,
           PCRELOFFSET),
@@ -539,6 +539,32 @@ coff_arm_rtype_to_howto (bfd *abfd ATTRIBUTE_UNUSED,
   if (rel->r_type == ARM_RVA32)
     *addendp -= pe_data (sec->output_section->owner)->pe_opthdr.ImageBase;
 
   if (rel->r_type == ARM_RVA32)
     *addendp -= pe_data (sec->output_section->owner)->pe_opthdr.ImageBase;
 
+#if defined COFF_WITH_PE && defined ARM_WINCE
+  if (rel->r_type == ARM_SECREL)
+    {
+      bfd_vma osect_vma;
+
+      if (h && (h->type == bfd_link_hash_defined
+               || h->type == bfd_link_hash_defweak))
+       osect_vma = h->root.u.def.section->output_section->vma;
+      else
+       {
+         asection *sec;
+         int i;
+
+         /* Sigh, the only way to get the section to offset against
+            is to find it the hard way.  */
+
+         for (sec = abfd->sections, i = 1; i < sym->n_scnum; i++)
+           sec = sec->next;
+
+         osect_vma = sec->output_section->vma;
+       }
+
+      *addendp -= osect_vma;
+    }
+#endif
+
   return howto;
 }
 
   return howto;
 }
 
@@ -808,6 +834,7 @@ coff_arm_reloc_type_lookup (bfd * abfd, bfd_reloc_code_real_type code)
       ASTD (BFD_RELOC_RVA,                  ARM_RVA32);
       ASTD (BFD_RELOC_ARM_PCREL_BRANCH,     ARM_26);
       ASTD (BFD_RELOC_THUMB_PCREL_BRANCH12, ARM_THUMB12);
       ASTD (BFD_RELOC_RVA,                  ARM_RVA32);
       ASTD (BFD_RELOC_ARM_PCREL_BRANCH,     ARM_26);
       ASTD (BFD_RELOC_THUMB_PCREL_BRANCH12, ARM_THUMB12);
+      ASTD (BFD_RELOC_32_SECREL,            ARM_SECREL);
 #else
       ASTD (BFD_RELOC_8,                    ARM_8);
       ASTD (BFD_RELOC_16,                   ARM_16);
 #else
       ASTD (BFD_RELOC_8,                    ARM_8);
       ASTD (BFD_RELOC_16,                   ARM_16);
@@ -827,6 +854,23 @@ coff_arm_reloc_type_lookup (bfd * abfd, bfd_reloc_code_real_type code)
     }
 }
 
     }
 }
 
+static reloc_howto_type *
+coff_arm_reloc_name_lookup (bfd *abfd ATTRIBUTE_UNUSED,
+                           const char *r_name)
+{
+  unsigned int i;
+
+  for (i = 0;
+       i < (sizeof (aoutarm_std_reloc_howto)
+           / sizeof (aoutarm_std_reloc_howto[0]));
+       i++)
+    if (aoutarm_std_reloc_howto[i].name != NULL
+       && strcasecmp (aoutarm_std_reloc_howto[i].name, r_name) == 0)
+      return &aoutarm_std_reloc_howto[i];
+
+  return NULL;
+}
+
 #define COFF_DEFAULT_SECTION_ALIGNMENT_POWER  2
 #define COFF_PAGE_SIZE                        0x1000
 
 #define COFF_DEFAULT_SECTION_ALIGNMENT_POWER  2
 #define COFF_PAGE_SIZE                        0x1000
 
@@ -895,21 +939,24 @@ coff_arm_link_hash_table_create (bfd * abfd)
   return & ret->root.root;
 }
 
   return & ret->root.root;
 }
 
-static void
+static bfd_boolean
 arm_emit_base_file_entry (struct bfd_link_info *info,
                          bfd *output_bfd,
                          asection *input_section,
                          bfd_vma reloc_offset)
 {
 arm_emit_base_file_entry (struct bfd_link_info *info,
                          bfd *output_bfd,
                          asection *input_section,
                          bfd_vma reloc_offset)
 {
-  bfd_vma addr = reloc_offset
-                - input_section->vma
-                + input_section->output_offset
-                  + input_section->output_section->vma;
+  bfd_vma addr = (reloc_offset
+                 - input_section->vma
+                 + input_section->output_offset
+                 + input_section->output_section->vma);
 
   if (coff_data (output_bfd)->pe)
      addr -= pe_data (output_bfd)->pe_opthdr.ImageBase;
 
   if (coff_data (output_bfd)->pe)
      addr -= pe_data (output_bfd)->pe_opthdr.ImageBase;
-  fwrite (& addr, 1, sizeof (addr), (FILE *) info->base_file);
+  if (fwrite (&addr, sizeof (addr), 1, (FILE *) info->base_file) == 1)
+    return TRUE;
 
 
+  bfd_set_error (bfd_error_system_call);
+  return FALSE;
 }
 \f
 #ifndef ARM_WINCE
 }
 \f
 #ifndef ARM_WINCE
@@ -1209,12 +1256,14 @@ coff_arm_relocate_section (bfd *output_bfd,
                     generation of bl's instruction offset.  */
           addend -= 8;
 #endif
                     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.  */
         }
 
 #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
 #endif
 
       /* If we are doing a relocatable link, then we can just ignore
@@ -1335,10 +1384,10 @@ coff_arm_relocate_section (bfd *output_bfd,
                          bfd_put_32 (output_bfd, h_val | a2t3_func_addr_insn,
                                      s->contents + my_offset + 8);
 
                          bfd_put_32 (output_bfd, h_val | a2t3_func_addr_insn,
                                      s->contents + my_offset + 8);
 
-                          if (info->base_file)
-                            arm_emit_base_file_entry (info, output_bfd, s,
-                                                      my_offset + 8);
-
+                          if (info->base_file
+                             && !arm_emit_base_file_entry (info, output_bfd,
+                                                           s, my_offset + 8))
+                           return FALSE;
                        }
 
                      BFD_ASSERT (my_offset <= globals->arm_glue_size);
                        }
 
                      BFD_ASSERT (my_offset <= globals->arm_glue_size);
@@ -1440,9 +1489,11 @@ coff_arm_relocate_section (bfd *output_bfd,
                              bfd_put_32 (output_bfd, h_val,
                                          s->contents + my_offset + 16);
 
                              bfd_put_32 (output_bfd, h_val,
                                          s->contents + my_offset + 16);
 
-                              if (info->base_file)
-                                arm_emit_base_file_entry (info, output_bfd, s,
-                                                         my_offset + 16);
+                              if (info->base_file
+                                 && !arm_emit_base_file_entry (info,
+                                                               output_bfd, s,
+                                                               my_offset + 16))
+                               return FALSE;
                            }
                          else
                            {
                            }
                          else
                            {
@@ -1526,13 +1577,13 @@ coff_arm_relocate_section (bfd *output_bfd,
            }
        }
 
            }
        }
 
-      if (info->base_file)
-       {
-         /* Emit a reloc if the backend thinks it needs it.  */
-         if (sym && pe_data(output_bfd)->in_reloc_p(output_bfd, howto))
-            arm_emit_base_file_entry (info, output_bfd, input_section,
-                                     rel->r_vaddr);
-       }
+      /* Emit a reloc if the backend thinks it needs it.  */
+      if (info->base_file
+         && sym
+         && pe_data(output_bfd)->in_reloc_p(output_bfd, howto)
+         && !arm_emit_base_file_entry (info, output_bfd, input_section,
+                                       rel->r_vaddr))
+       return FALSE;
 
       if (done)
        rstat = bfd_reloc_ok;
 
       if (done)
        rstat = bfd_reloc_ok;
@@ -1938,12 +1989,11 @@ bfd_arm_get_bfd_for_interworking (bfd *                  abfd,
 
   if (sec == NULL)
     {
 
   if (sec == NULL)
     {
-      flags = SEC_ALLOC | SEC_LOAD | SEC_HAS_CONTENTS | SEC_IN_MEMORY | SEC_CODE | SEC_READONLY;
-
-      sec = bfd_make_section (abfd, ARM2THUMB_GLUE_SECTION_NAME);
-
+      flags = (SEC_ALLOC | SEC_LOAD | SEC_HAS_CONTENTS | SEC_IN_MEMORY
+              | SEC_CODE | SEC_READONLY);
+      sec = bfd_make_section_with_flags (abfd, ARM2THUMB_GLUE_SECTION_NAME,
+                                        flags);
       if (sec == NULL
       if (sec == NULL
-         || ! bfd_set_section_flags (abfd, sec, flags)
          || ! bfd_set_section_alignment (abfd, sec, 2))
        return FALSE;
     }
          || ! bfd_set_section_alignment (abfd, sec, 2))
        return FALSE;
     }
@@ -1952,12 +2002,12 @@ bfd_arm_get_bfd_for_interworking (bfd *                  abfd,
 
   if (sec == NULL)
     {
 
   if (sec == NULL)
     {
-      flags = SEC_ALLOC | SEC_LOAD | SEC_HAS_CONTENTS | SEC_IN_MEMORY | SEC_CODE | SEC_READONLY;
-
-      sec = bfd_make_section (abfd, THUMB2ARM_GLUE_SECTION_NAME);
+      flags = (SEC_ALLOC | SEC_LOAD | SEC_HAS_CONTENTS | SEC_IN_MEMORY
+              | SEC_CODE | SEC_READONLY);
+      sec = bfd_make_section_with_flags (abfd, THUMB2ARM_GLUE_SECTION_NAME,
+                                        flags);
 
       if (sec == NULL
 
       if (sec == NULL
-         || ! bfd_set_section_flags (abfd, sec, flags)
          || ! bfd_set_section_alignment (abfd, sec, 2))
        return FALSE;
     }
          || ! bfd_set_section_alignment (abfd, sec, 2))
        return FALSE;
     }
@@ -2085,6 +2135,7 @@ bfd_arm_process_before_allocation (bfd *                   abfd,
 #endif /* ! defined (COFF_IMAGE_WITH_PE) */
 
 #define coff_bfd_reloc_type_lookup             coff_arm_reloc_type_lookup
 #endif /* ! defined (COFF_IMAGE_WITH_PE) */
 
 #define coff_bfd_reloc_type_lookup             coff_arm_reloc_type_lookup
+#define coff_bfd_reloc_name_lookup     coff_arm_reloc_name_lookup
 #define coff_relocate_section                  coff_arm_relocate_section
 #define coff_bfd_is_local_label_name           coff_arm_is_local_label_name
 #define coff_adjust_symndx                     coff_arm_adjust_symndx
 #define coff_relocate_section                  coff_arm_relocate_section
 #define coff_bfd_is_local_label_name           coff_arm_is_local_label_name
 #define coff_adjust_symndx                     coff_arm_adjust_symndx
@@ -2397,7 +2448,9 @@ Warning: Clearing the interworking flag of %B because non-interworking code in %
 
 /* Note:  the definitions here of LOCAL_LABEL_PREFIX and USER_LABEL_PREIFX
    *must* match the definitions in gcc/config/arm/{coff|semi|aout}.h.  */
 
 /* Note:  the definitions here of LOCAL_LABEL_PREFIX and USER_LABEL_PREIFX
    *must* match the definitions in gcc/config/arm/{coff|semi|aout}.h.  */
+#ifndef LOCAL_LABEL_PREFIX
 #define LOCAL_LABEL_PREFIX ""
 #define LOCAL_LABEL_PREFIX ""
+#endif
 #ifndef USER_LABEL_PREFIX
 #define USER_LABEL_PREFIX "_"
 #endif
 #ifndef USER_LABEL_PREFIX
 #define USER_LABEL_PREFIX "_"
 #endif
This page took 0.033841 seconds and 4 git commands to generate.