Fix address violation parsing a corrupt SOM binary.
[deliverable/binutils-gdb.git] / bfd / elf32-bfin.c
index 0d4d9cf6630ec09a0b88bf42d485740dc6b60248..b3e09bd9792949d6178a77fa9248aa3813865c06 100644 (file)
@@ -1,5 +1,5 @@
 /* ADI Blackfin BFD support for 32-bit ELF.
-   Copyright (C) 2005-2015 Free Software Foundation, Inc.
+   Copyright (C) 2005-2017 Free Software Foundation, Inc.
 
    This file is part of BFD, the Binary File Descriptor library.
 
@@ -103,7 +103,7 @@ bfin_pcrel24_reloc (bfd *abfd,
   /* if rightshift is 1 and the number odd, return error.  */
   if (howto->rightshift && (relocation & 0x01))
     {
-      (*_bfd_error_handler) (_("relocation should be even number"));
+      _bfd_error_handler (_("relocation should be even number"));
       return bfd_reloc_overflow;
     }
 
@@ -329,11 +329,11 @@ bfin_bfd_reloc (bfd *abfd,
   /* Here the variable relocation holds the final address of the
      symbol we are relocating against, plus any addend.  */
 
-  if (howto->pc_relative == TRUE)
+  if (howto->pc_relative)
     {
       relocation -= input_section->output_section->vma + input_section->output_offset;
 
-      if (howto->pcrel_offset == TRUE)
+      if (howto->pcrel_offset)
         relocation -= reloc_entry->address;
     }
 
@@ -359,7 +359,7 @@ bfin_bfd_reloc (bfd *abfd,
   /* If rightshift is 1 and the number odd, return error.  */
   if (howto->rightshift && (relocation & 0x01))
     {
-      (*_bfd_error_handler) (_("relocation should be even number"));
+      _bfd_error_handler (_("relocation should be even number"));
       return bfd_reloc_overflow;
     }
 
@@ -1191,7 +1191,7 @@ bfin_check_relocs (bfd * abfd,
 
          /* PR15323, ref flags aren't set for references in the same
             object.  */
-         h->root.non_ir_ref = 1;
+         h->root.non_ir_ref_regular = 1;
        }
 
       switch (ELF32_R_TYPE (rel->r_info))
@@ -1226,28 +1226,9 @@ bfin_check_relocs (bfd * abfd,
                return FALSE;
            }
 
-         if (sgot == NULL)
-           {
-             sgot = bfd_get_linker_section (dynobj, ".got");
-             BFD_ASSERT (sgot != NULL);
-           }
-
-         if (srelgot == NULL && (h != NULL || bfd_link_pic (info)))
-           {
-             srelgot = bfd_get_linker_section (dynobj, ".rela.got");
-             if (srelgot == NULL)
-               {
-                 flagword flags = (SEC_ALLOC | SEC_LOAD | SEC_HAS_CONTENTS
-                                   | SEC_IN_MEMORY | SEC_LINKER_CREATED
-                                   | SEC_READONLY);
-                 srelgot = bfd_make_section_anyway_with_flags (dynobj,
-                                                               ".rela.got",
-                                                               flags);
-                 if (srelgot == NULL
-                     || !bfd_set_section_alignment (dynobj, srelgot, 2))
-                   return FALSE;
-               }
-           }
+         sgot = elf_hash_table (info)->sgot;
+         srelgot = elf_hash_table (info)->srelgot;
+         BFD_ASSERT (sgot != NULL);
 
          if (h != NULL)
            {
@@ -1480,20 +1461,17 @@ bfin_relocate_section (bfd * output_bfd,
          {
            bfd_vma off;
 
-         if (dynobj == NULL)
-           {
-             /* Create the .got section.  */
-             elf_hash_table (info)->dynobj = dynobj = output_bfd;
-             if (!_bfd_elf_create_got_section (dynobj, info))
-               return FALSE;
-           }
-
-           if (sgot == NULL)
+           if (dynobj == NULL)
              {
-               sgot = bfd_get_linker_section (dynobj, ".got");
-               BFD_ASSERT (sgot != NULL);
+               /* Create the .got section.  */
+               elf_hash_table (info)->dynobj = dynobj = output_bfd;
+               if (!_bfd_elf_create_got_section (dynobj, info))
+                 return FALSE;
              }
 
+           sgot = elf_hash_table (info)->sgot;
+           BFD_ASSERT (sgot != NULL);
+
            if (h != NULL)
              {
                bfd_boolean dyn;
@@ -1556,7 +1534,7 @@ bfin_relocate_section (bfd * output_bfd,
                        Elf_Internal_Rela outrel;
                        bfd_byte *loc;
 
-                       s = bfd_get_linker_section (dynobj, ".rela.got");
+                       s = elf_hash_table (info)->srelgot;
                        BFD_ASSERT (s != NULL);
 
                        outrel.r_offset = (sgot->output_section->vma
@@ -1598,7 +1576,8 @@ bfin_relocate_section (bfd * output_bfd,
          && _bfd_elf_section_offset (output_bfd, info, input_section,
                                      rel->r_offset) != (bfd_vma) -1)
        {
-         (*_bfd_error_handler)
+         _bfd_error_handler
+           /* xgettext:c-format */
            (_("%B(%A+0x%lx): unresolvable relocation against symbol `%s'"),
             input_bfd,
             input_section, (long) rel->r_offset, h->root.root.string);
@@ -1623,15 +1602,13 @@ bfin_relocate_section (bfd * output_bfd,
            }
 
          if (r == bfd_reloc_overflow)
-           {
-             if (!(info->callbacks->reloc_overflow
-                   (info, (h ? &h->root : NULL), name, howto->name,
-                    (bfd_vma) 0, input_bfd, input_section, rel->r_offset)))
-               return FALSE;
-           }
+           (*info->callbacks->reloc_overflow)
+             (info, (h ? &h->root : NULL), name, howto->name,
+              (bfd_vma) 0, input_bfd, input_section, rel->r_offset);
          else
            {
-             (*_bfd_error_handler)
+             _bfd_error_handler
+               /* xgettext:c-format */
                (_("%B(%A+0x%lx): reloc against `%s': error %d"),
                 input_bfd, input_section,
                 (long) rel->r_offset, name, (int) r);
@@ -1685,8 +1662,8 @@ bfin_gc_sweep_hook (bfd * abfd,
   sym_hashes = elf_sym_hashes (abfd);
   local_got_refcounts = elf_local_got_refcounts (abfd);
 
-  sgot = bfd_get_linker_section (dynobj, ".got");
-  srelgot = bfd_get_linker_section (dynobj, ".rela.got");
+  sgot = elf_hash_table (info)->sgot;
+  srelgot = elf_hash_table (info)->srelgot;
 
   relend = relocs + sec->reloc_count;
   for (rel = relocs; rel < relend; rel++)
@@ -1743,16 +1720,8 @@ struct bfinfdpic_elf_link_hash_table
 {
   struct elf_link_hash_table elf;
 
-  /* A pointer to the .got section.  */
-  asection *sgot;
-  /* A pointer to the .rel.got section.  */
-  asection *sgotrel;
   /* A pointer to the .rofixup section.  */
   asection *sgotfixup;
-  /* A pointer to the .plt section.  */
-  asection *splt;
-  /* A pointer to the .rel.plt section.  */
-  asection *spltrel;
   /* GOT base offset.  */
   bfd_vma got0;
   /* Location of the first non-lazy PLT entry, i.e., the number of
@@ -1773,15 +1742,15 @@ struct bfinfdpic_elf_link_hash_table
   == BFIN_ELF_DATA ? ((struct bfinfdpic_elf_link_hash_table *) ((info)->hash)) : NULL)
 
 #define bfinfdpic_got_section(info) \
-  (bfinfdpic_hash_table (info)->sgot)
+  (bfinfdpic_hash_table (info)->elf.sgot)
 #define bfinfdpic_gotrel_section(info) \
-  (bfinfdpic_hash_table (info)->sgotrel)
+  (bfinfdpic_hash_table (info)->elf.srelgot)
 #define bfinfdpic_gotfixup_section(info) \
   (bfinfdpic_hash_table (info)->sgotfixup)
 #define bfinfdpic_plt_section(info) \
-  (bfinfdpic_hash_table (info)->splt)
+  (bfinfdpic_hash_table (info)->elf.splt)
 #define bfinfdpic_pltrel_section(info) \
-  (bfinfdpic_hash_table (info)->spltrel)
+  (bfinfdpic_hash_table (info)->elf.srelplt)
 #define bfinfdpic_relocs_info(info) \
   (bfinfdpic_hash_table (info)->relocs_info)
 #define bfinfdpic_got_initial_offset(info) \
@@ -2698,6 +2667,7 @@ bfinfdpic_relocate_section (bfd * output_bfd,
        case R_BFIN_BYTE4_DATA:
          if (! IS_FDPIC (output_bfd))
            goto non_fdpic;
+         /* Fall through.  */
 
        case R_BFIN_GOT17M4:
        case R_BFIN_GOTHI:
@@ -2731,7 +2701,8 @@ bfinfdpic_relocate_section (bfd * output_bfd,
                                                       osec, sym,
                                                       rel->r_addend))
            {
-             (*_bfd_error_handler)
+             _bfd_error_handler
+               /* xgettext:c-format */
                (_("%B: relocation at `%A+0x%x' references symbol `%s' with nonzero addend"),
                 input_bfd, input_section, rel->r_offset, name);
              return FALSE;
@@ -3209,13 +3180,13 @@ bfinfdpic_relocate_section (bfd * output_bfd,
          switch (r)
            {
            case bfd_reloc_overflow:
-             r = info->callbacks->reloc_overflow
+             (*info->callbacks->reloc_overflow)
                (info, (h ? &h->root : NULL), name, howto->name,
                 (bfd_vma) 0, input_bfd, input_section, rel->r_offset);
              break;
 
            case bfd_reloc_undefined:
-             r = info->callbacks->undefined_symbol
+             (*info->callbacks->undefined_symbol)
                (info, name, input_bfd, input_section, rel->r_offset, TRUE);
              break;
 
@@ -3237,11 +3208,8 @@ bfinfdpic_relocate_section (bfd * output_bfd,
            }
 
          if (msg)
-           r = info->callbacks->warning
-             (info, msg, name, input_bfd, input_section, rel->r_offset);
-
-         if (! r)
-           return FALSE;
+           (*info->callbacks->warning) (info, msg, name, input_bfd,
+                                        input_section, rel->r_offset);
        }
     }
 
@@ -3397,7 +3365,7 @@ _bfin_create_got_section (bfd *abfd, struct bfd_link_info *info)
   int ptralign;
 
   /* This function may be called more than once.  */
-  s = bfd_get_linker_section (abfd, ".got");
+  s = elf_hash_table (info)->sgot;
   if (s != NULL)
     return TRUE;
 
@@ -3412,18 +3380,11 @@ _bfin_create_got_section (bfd *abfd, struct bfd_link_info *info)
   pltflags = flags;
 
   s = bfd_make_section_anyway_with_flags (abfd, ".got", flags);
+  elf_hash_table (info)->sgot = s;
   if (s == NULL
       || !bfd_set_section_alignment (abfd, s, ptralign))
     return FALSE;
 
-  if (bed->want_got_plt)
-    {
-      s = bfd_make_section_anyway_with_flags (abfd, ".got.plt", flags);
-      if (s == NULL
-         || !bfd_set_section_alignment (abfd, s, ptralign))
-       return FALSE;
-    }
-
   if (bed->want_got_sym)
     {
       /* Define the symbol _GLOBAL_OFFSET_TABLE_ at the start of the .got
@@ -3448,7 +3409,6 @@ _bfin_create_got_section (bfd *abfd, struct bfd_link_info *info)
      data for the got.  */
   if (IS_FDPIC (abfd))
     {
-      bfinfdpic_got_section (info) = s;
       bfinfdpic_relocs_info (info) = htab_try_create (1,
                                                      bfinfdpic_relocs_info_hash,
                                                      bfinfdpic_relocs_info_eq,
@@ -4457,7 +4417,13 @@ elf32_bfinfdpic_finish_dynamic_sections (bfd *output_bfd,
   if (bfinfdpic_got_section (info))
     {
       BFD_ASSERT (bfinfdpic_gotrel_section (info)->size
-                 == (bfinfdpic_gotrel_section (info)->reloc_count
+                 /* PR 17334: It appears that the GOT section can end up
+                    being bigger than the number of relocs.  Presumably
+                    because some relocs have been deleted.  A test case has
+                    yet to be generated for verify this, but in the meantime
+                    the test below has been changed from == to >= so that
+                    applications can continue to be built.  */
+                 >= (bfinfdpic_gotrel_section (info)->reloc_count
                      * sizeof (Elf32_External_Rel)));
 
       if (bfinfdpic_gotfixup_section (info))
@@ -4473,7 +4439,7 @@ elf32_bfinfdpic_finish_dynamic_sections (bfd *output_bfd,
          if (bfinfdpic_gotfixup_section (info)->size
              != (bfinfdpic_gotfixup_section (info)->reloc_count * 4))
            {
-             (*_bfd_error_handler)
+             _bfd_error_handler
                ("LINKER BUG: .rofixup section size mismatch");
              return FALSE;
            }
@@ -4906,7 +4872,8 @@ bfinfdpic_check_relocs (bfd *abfd, struct bfd_link_info *info,
 
        default:
        bad_reloc:
-         (*_bfd_error_handler)
+         _bfd_error_handler
+           /* xgettext:c-format */
            (_("%B: unsupported relocation type %i"),
             abfd, ELF32_R_TYPE (rel->r_info));
          return FALSE;
@@ -4966,8 +4933,9 @@ elf32_bfin_print_private_bfd_data (bfd * abfd, void * ptr)
    object file when linking.  */
 
 static bfd_boolean
-elf32_bfin_merge_private_bfd_data (bfd *ibfd, bfd *obfd)
+elf32_bfin_merge_private_bfd_data (bfd *ibfd, struct bfd_link_info *info)
 {
+  bfd *obfd = info->output_bfd;
   flagword old_flags, new_flags;
   bfd_boolean error = FALSE;
 
@@ -4980,9 +4948,9 @@ elf32_bfin_merge_private_bfd_data (bfd *ibfd, bfd *obfd)
 #ifndef DEBUG
   if (0)
 #endif
-  (*_bfd_error_handler) ("old_flags = 0x%.8lx, new_flags = 0x%.8lx, init = %s, filename = %s",
-                        old_flags, new_flags, elf_flags_init (obfd) ? "yes" : "no",
-                        bfd_get_filename (ibfd));
+  _bfd_error_handler
+    ("old_flags = 0x%.8lx, new_flags = 0x%.8lx, init = %s, filename = %B",
+     old_flags, new_flags, elf_flags_init (obfd) ? "yes" : "no", ibfd);
 
   if (!elf_flags_init (obfd))                  /* First call, no flags set.  */
     {
@@ -4994,13 +4962,13 @@ elf32_bfin_merge_private_bfd_data (bfd *ibfd, bfd *obfd)
     {
       error = TRUE;
       if (IS_FDPIC (obfd))
-       (*_bfd_error_handler)
-         (_("%s: cannot link non-fdpic object file into fdpic executable"),
-          bfd_get_filename (ibfd));
+       _bfd_error_handler
+         (_("%B: cannot link non-fdpic object file into fdpic executable"),
+          ibfd);
       else
-       (*_bfd_error_handler)
-         (_("%s: cannot link fdpic object file into non-fdpic executable"),
-          bfd_get_filename (ibfd));
+       _bfd_error_handler
+         (_("%B: cannot link fdpic object file into non-fdpic executable"),
+          ibfd);
     }
 
   if (error)
@@ -5122,10 +5090,6 @@ bfin_finish_dynamic_symbol (bfd * output_bfd,
                            struct elf_link_hash_entry *h,
                            Elf_Internal_Sym * sym)
 {
-  bfd *dynobj;
-
-  dynobj = elf_hash_table (info)->dynobj;
-
   if (h->got.offset != (bfd_vma) - 1)
     {
       asection *sgot;
@@ -5136,8 +5100,8 @@ bfin_finish_dynamic_symbol (bfd * output_bfd,
       /* This symbol has an entry in the global offset table.
          Set it up.  */
 
-      sgot = bfd_get_linker_section (dynobj, ".got");
-      srela = bfd_get_linker_section (dynobj, ".rela.got");
+      sgot = elf_hash_table (info)->sgot;
+      srela = elf_hash_table (info)->srelgot;
       BFD_ASSERT (sgot != NULL && srela != NULL);
 
       rela.r_offset = (sgot->output_section->vma
@@ -5153,8 +5117,8 @@ bfin_finish_dynamic_symbol (bfd * output_bfd,
          && (info->symbolic
              || h->dynindx == -1 || h->forced_local) && h->def_regular)
        {
-         (*_bfd_error_handler) (_("*** check this relocation %s"),
-                                __FUNCTION__);
+         _bfd_error_handler (_("*** check this relocation %s"),
+                             __FUNCTION__);
          rela.r_info = ELF32_R_INFO (0, R_BFIN_PCREL24);
          rela.r_addend = bfd_get_signed_32 (output_bfd,
                                             (sgot->contents
@@ -5252,7 +5216,8 @@ bfin_adjust_dynamic_symbol (struct bfd_link_info *info,
   s = bfd_get_linker_section (dynobj, ".dynbss");
   BFD_ASSERT (s != NULL);
 
-  /* We must generate a R_68K_COPY reloc to tell the dynamic linker to
+#if 0 /* Bfin does not currently have a COPY reloc.  */
+  /* We must generate a R_BFIN_COPY reloc to tell the dynamic linker to
      copy the initial value out of the dynamic object and into the
      runtime process image.  We need to remember the offset into the
      .rela.bss section we are going to use.  */
@@ -5265,7 +5230,13 @@ bfin_adjust_dynamic_symbol (struct bfd_link_info *info,
       srel->size += sizeof (Elf32_External_Rela);
       h->needs_copy = 1;
     }
-
+#else
+  if ((h->root.u.def.section->flags & SEC_ALLOC) != 0)
+    {
+      _bfd_error_handler (_("the bfin target does not currently support the generation of copy relocations"));
+      return FALSE;
+    }
+#endif
   /* We need to figure out the alignment required for this symbol.  I
      have no idea how ELF linkers handle this.  */
   power_of_two = bfd_log2 (h->size);
@@ -5381,7 +5352,7 @@ bfin_size_dynamic_sections (bfd * output_bfd ATTRIBUTE_UNUSED,
          not actually use these entries.  Reset the size of .rela.got,
          which will cause it to get stripped from the output file
          below.  */
-      s = bfd_get_linker_section (dynobj, ".rela.got");
+      s = elf_hash_table (info)->srelgot;
       if (s != NULL)
        s->size = 0;
     }
This page took 0.029501 seconds and 4 git commands to generate.