dwarf2.c stash->sec_info_ptr and stash->sec
[deliverable/binutils-gdb.git] / bfd / elf32-iq2000.c
index 536826bd62bdaf6e4fa6cdfff0057703141503e3..e95f1a56eacd332f50762d41769e60ba83771710 100644 (file)
@@ -1,12 +1,11 @@
 /* IQ2000-specific support for 32-bit ELF.
 /* IQ2000-specific support for 32-bit ELF.
-   Copyright (C) 2003, 2004, 2005, 2006, 2007
-   Free Software Foundation, Inc.
+   Copyright (C) 2003-2019 Free Software Foundation, Inc.
 
    This file is part of BFD, the Binary File Descriptor library.
 
    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 file is part of BFD, the Binary File Descriptor library.
 
    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,
@@ -23,6 +22,7 @@
 #include "libbfd.h"
 #include "elf-bfd.h"
 #include "elf/iq2000.h"
 #include "libbfd.h"
 #include "elf-bfd.h"
 #include "elf/iq2000.h"
+#include "libiberty.h"
 
 /* Forward declarations.  */
 
 
 /* Forward declarations.  */
 
@@ -35,11 +35,11 @@ static reloc_howto_type iq2000_elf_howto_table [] =
 
   HOWTO (R_IQ2000_NONE,                     /* type */
         0,                          /* rightshift */
 
   HOWTO (R_IQ2000_NONE,                     /* type */
         0,                          /* rightshift */
-        2,                          /* size (0 = byte, 1 = short, 2 = long) */
-        32,                         /* bitsize */
+        3,                          /* size (0 = byte, 1 = short, 2 = long) */
+        0,                          /* bitsize */
         FALSE,                      /* pc_relative */
         0,                          /* bitpos */
         FALSE,                      /* pc_relative */
         0,                          /* bitpos */
-        complain_overflow_bitfield, /* complain_on_overflow */
+        complain_overflow_dont,     /* complain_on_overflow */
         bfd_elf_generic_reloc,      /* special_function */
         "R_IQ2000_NONE",            /* name */
         FALSE,                      /* partial_inplace */
         bfd_elf_generic_reloc,      /* special_function */
         "R_IQ2000_NONE",            /* name */
         FALSE,                      /* partial_inplace */
@@ -290,7 +290,7 @@ iq2000_elf_relocate_hi16 (bfd *input_bfd,
   bfd_vma insn;
 
   insn = bfd_get_32 (input_bfd, contents + relhi->r_offset);
   bfd_vma insn;
 
   insn = bfd_get_32 (input_bfd, contents + relhi->r_offset);
-  
+
   value += relhi->r_addend;
   value &= 0x7fffffff; /* Mask off top-bit which is Harvard mask bit.  */
 
   value += relhi->r_addend;
   value &= 0x7fffffff; /* Mask off top-bit which is Harvard mask bit.  */
 
@@ -299,13 +299,41 @@ iq2000_elf_relocate_hi16 (bfd *input_bfd,
   if (value & 0x8000)
     value += 0x10000;
 
   if (value & 0x8000)
     value += 0x10000;
 
-  value >>= 16; 
+  value >>= 16;
   insn = ((insn & ~0xFFFF) | value);
 
   bfd_put_32 (input_bfd, insn, contents + relhi->r_offset);
   return bfd_reloc_ok;
 }
 
   insn = ((insn & ~0xFFFF) | value);
 
   bfd_put_32 (input_bfd, insn, contents + relhi->r_offset);
   return bfd_reloc_ok;
 }
 
+static bfd_reloc_status_type
+iq2000_elf_relocate_offset16 (bfd *input_bfd,
+                             Elf_Internal_Rela *rel,
+                             bfd_byte *contents,
+                             bfd_vma value,
+                             bfd_vma location)
+{
+  bfd_vma insn;
+  bfd_vma jtarget;
+
+  insn = bfd_get_32 (input_bfd, contents + rel->r_offset);
+
+  value += rel->r_addend;
+
+  if (value & 3)
+    return bfd_reloc_dangerous;
+
+  jtarget = (value & 0x3fffc) | (location & 0xf0000000L);
+
+  if (jtarget != value)
+    return bfd_reloc_overflow;
+
+  insn = (insn & ~0xFFFF) | ((value >> 2) & 0xFFFF);
+
+  bfd_put_32 (input_bfd, insn, contents + rel->r_offset);
+  return bfd_reloc_ok;
+}
+
 /* Map BFD reloc types to IQ2000 ELF reloc types.  */
 
 static reloc_howto_type *
 /* Map BFD reloc types to IQ2000 ELF reloc types.  */
 
 static reloc_howto_type *
@@ -389,7 +417,7 @@ iq2000_final_link_relocate (reloc_howto_type *      howto,
 \f
 /* Set the howto pointer for a IQ2000 ELF reloc.  */
 
 \f
 /* Set the howto pointer for a IQ2000 ELF reloc.  */
 
-static void
+static bfd_boolean
 iq2000_info_to_howto_rela (bfd * abfd ATTRIBUTE_UNUSED,
                           arelent * cache_ptr,
                           Elf_Internal_Rela * dst)
 iq2000_info_to_howto_rela (bfd * abfd ATTRIBUTE_UNUSED,
                           arelent * cache_ptr,
                           Elf_Internal_Rela * dst)
@@ -408,15 +436,24 @@ iq2000_info_to_howto_rela (bfd * abfd ATTRIBUTE_UNUSED,
       break;
 
     default:
       break;
 
     default:
+      if (r_type >= ARRAY_SIZE (iq2000_elf_howto_table))
+       {
+         /* xgettext:c-format */
+         _bfd_error_handler (_("%pB: unsupported relocation type %#x"),
+                             abfd, r_type);
+         bfd_set_error (bfd_error_bad_value);
+         return FALSE;
+       }
       cache_ptr->howto = & iq2000_elf_howto_table [r_type];
       break;
     }
       cache_ptr->howto = & iq2000_elf_howto_table [r_type];
       break;
     }
+  return TRUE;
 }
 
 /* Look through the relocs for a section during the first phase.
    Since we don't do .gots or .plts, we just need to consider the
    virtual table relocs for gc.         */
 }
 
 /* Look through the relocs for a section during the first phase.
    Since we don't do .gots or .plts, we just need to consider the
    virtual table relocs for gc.         */
+
 static bfd_boolean
 iq2000_elf_check_relocs (bfd *abfd,
                         struct bfd_link_info *info,
 static bfd_boolean
 iq2000_elf_check_relocs (bfd *abfd,
                         struct bfd_link_info *info,
@@ -424,26 +461,23 @@ iq2000_elf_check_relocs (bfd *abfd,
                         const Elf_Internal_Rela *relocs)
 {
   Elf_Internal_Shdr *symtab_hdr;
                         const Elf_Internal_Rela *relocs)
 {
   Elf_Internal_Shdr *symtab_hdr;
-  struct elf_link_hash_entry **sym_hashes, **sym_hashes_end;
+  struct elf_link_hash_entry **sym_hashes;
   const Elf_Internal_Rela *rel;
   const Elf_Internal_Rela *rel_end;
   bfd_boolean changed = FALSE;
   const Elf_Internal_Rela *rel;
   const Elf_Internal_Rela *rel_end;
   bfd_boolean changed = FALSE;
-  
-  if (info->relocatable)
+
+  if (bfd_link_relocatable (info))
     return TRUE;
     return TRUE;
-  
+
   symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
   sym_hashes = elf_sym_hashes (abfd);
   symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
   sym_hashes = elf_sym_hashes (abfd);
-  sym_hashes_end = sym_hashes + symtab_hdr->sh_size / sizeof (Elf32_External_Sym);
-  if (!elf_bad_symtab (abfd))
-    sym_hashes_end -= symtab_hdr->sh_info;
-  
+
   rel_end = relocs + sec->reloc_count;
   for (rel = relocs; rel < rel_end; rel++)
     {
       struct elf_link_hash_entry *h;
       unsigned long r_symndx;
   rel_end = relocs + sec->reloc_count;
   for (rel = relocs; rel < rel_end; rel++)
     {
       struct elf_link_hash_entry *h;
       unsigned long r_symndx;
-      
+
       r_symndx = ELF32_R_SYM (rel->r_info);
       if (r_symndx < symtab_hdr->sh_info)
        h = NULL;
       r_symndx = ELF32_R_SYM (rel->r_info);
       if (r_symndx < symtab_hdr->sh_info)
        h = NULL;
@@ -454,7 +488,7 @@ iq2000_elf_check_relocs (bfd *abfd,
                 || h->root.type == bfd_link_hash_warning)
            h = (struct elf_link_hash_entry *) h->root.u.i.link;
        }
                 || h->root.type == bfd_link_hash_warning)
            h = (struct elf_link_hash_entry *) h->root.u.i.link;
        }
-      
+
       switch (ELF32_R_TYPE (rel->r_info))
        {
          /* This relocation describes the C++ object vtable
       switch (ELF32_R_TYPE (rel->r_info))
        {
          /* This relocation describes the C++ object vtable
@@ -463,7 +497,7 @@ iq2000_elf_check_relocs (bfd *abfd,
          if (!bfd_elf_gc_record_vtinherit (abfd, sec, h, rel->r_offset))
            return FALSE;
          break;
          if (!bfd_elf_gc_record_vtinherit (abfd, sec, h, rel->r_offset))
            return FALSE;
          break;
-         
+
          /* This relocation describes which C++ vtable entries
             are actually used.  Record for later use during GC.  */
        case R_IQ2000_GNU_VTENTRY:
          /* This relocation describes which C++ vtable entries
             are actually used.  Record for later use during GC.  */
        case R_IQ2000_GNU_VTENTRY:
@@ -557,57 +591,60 @@ iq2000_elf_relocate_section (bfd *                     output_bfd ATTRIBUTE_UNUSED,
       bfd_reloc_status_type       r;
       const char *                name = NULL;
       int                         r_type;
       bfd_reloc_status_type       r;
       const char *                name = NULL;
       int                         r_type;
-      
+
       r_type = ELF32_R_TYPE (rel->r_info);
       r_type = ELF32_R_TYPE (rel->r_info);
-      
+
       if (   r_type == R_IQ2000_GNU_VTINHERIT
          || r_type == R_IQ2000_GNU_VTENTRY)
        continue;
       if (   r_type == R_IQ2000_GNU_VTINHERIT
          || r_type == R_IQ2000_GNU_VTENTRY)
        continue;
-      
+
       r_symndx = ELF32_R_SYM (rel->r_info);
 
       howto  = iq2000_elf_howto_table + ELF32_R_TYPE (rel->r_info);
       h             = NULL;
       sym    = NULL;
       sec    = NULL;
       r_symndx = ELF32_R_SYM (rel->r_info);
 
       howto  = iq2000_elf_howto_table + ELF32_R_TYPE (rel->r_info);
       h             = NULL;
       sym    = NULL;
       sec    = NULL;
-      
+
       if (r_symndx < symtab_hdr->sh_info)
        {
       if (r_symndx < symtab_hdr->sh_info)
        {
+         asection *osec;
+
          sym = local_syms + r_symndx;
          sym = local_syms + r_symndx;
-         sec = local_sections [r_symndx];
+         osec = sec = local_sections [r_symndx];
+         if ((sec->flags & SEC_MERGE)
+             && ELF_ST_TYPE (sym->st_info) == STT_SECTION)
+           /* This relocation is relative to a section symbol that is
+              going to be merged.  Change it so that it is relative
+              to the merged section symbol.  */
+           rel->r_addend = _bfd_elf_rel_local_sym (output_bfd, sym, &sec,
+                                                   rel->r_addend);
+
          relocation = (sec->output_section->vma
                        + sec->output_offset
                        + sym->st_value);
          relocation = (sec->output_section->vma
                        + sec->output_offset
                        + sym->st_value);
-         
+
          name = bfd_elf_string_from_elf_section
            (input_bfd, symtab_hdr->sh_link, sym->st_name);
          name = bfd_elf_string_from_elf_section
            (input_bfd, symtab_hdr->sh_link, sym->st_name);
-         name = (name == NULL) ? bfd_section_name (input_bfd, sec) : name;
+         name = name == NULL ? bfd_section_name (osec) : name;
        }
       else
        {
          bfd_boolean unresolved_reloc;
        }
       else
        {
          bfd_boolean unresolved_reloc;
-         bfd_boolean warned;
+         bfd_boolean warned, ignored;
 
          RELOC_FOR_GLOBAL_SYMBOL (info, input_bfd, input_section, rel,
                                   r_symndx, symtab_hdr, sym_hashes,
                                   h, sec, relocation,
 
          RELOC_FOR_GLOBAL_SYMBOL (info, input_bfd, input_section, rel,
                                   r_symndx, symtab_hdr, sym_hashes,
                                   h, sec, relocation,
-                                  unresolved_reloc, warned);
+                                  unresolved_reloc, warned, ignored);
 
          name = h->root.root.string;
        }
 
 
          name = h->root.root.string;
        }
 
-      if (sec != NULL && elf_discarded_section (sec))
-       {
-         /* For relocs against symbols from removed linkonce sections,
-            or sections discarded by a linker script, we just want the
-            section contents zeroed.  Avoid any special processing.  */
-         _bfd_clear_contents (howto, input_bfd, contents + rel->r_offset);
-         rel->r_info = 0;
-         rel->r_addend = 0;
-         continue;
-       }
+      if (sec != NULL && discarded_section (sec))
+       RELOC_AGAINST_DISCARDED_SECTION (info, input_bfd, input_section,
+                                        rel, 1, relend, howto, 0, contents);
 
 
-      if (info->relocatable)
+      if (bfd_link_relocatable (info))
        continue;
 
       switch (r_type)
        continue;
 
       switch (r_type)
@@ -616,6 +653,13 @@ iq2000_elf_relocate_section (bfd *              output_bfd ATTRIBUTE_UNUSED,
          r = iq2000_elf_relocate_hi16 (input_bfd, rel, contents, relocation);
          break;
 
          r = iq2000_elf_relocate_hi16 (input_bfd, rel, contents, relocation);
          break;
 
+       case R_IQ2000_OFFSET_16:
+         r = iq2000_elf_relocate_offset16 (input_bfd, rel, contents, relocation,
+                                           input_section->output_section->vma
+                                           + input_section->output_offset
+                                           + rel->r_offset);
+         break;
+
        case R_IQ2000_PC16:
          rel->r_addend -= 4;
          /* Fall through.  */
        case R_IQ2000_PC16:
          rel->r_addend -= 4;
          /* Fall through.  */
@@ -633,16 +677,16 @@ iq2000_elf_relocate_section (bfd *                     output_bfd ATTRIBUTE_UNUSED,
          switch (r)
            {
            case bfd_reloc_overflow:
          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;
                (info, (h ? &h->root : NULL), name, howto->name,
                 (bfd_vma) 0, input_bfd, input_section, rel->r_offset);
              break;
-             
+
            case bfd_reloc_undefined:
            case bfd_reloc_undefined:
-             r = info->callbacks->undefined_symbol
+             (*info->callbacks->undefined_symbol)
                (info, name, input_bfd, input_section, rel->r_offset, TRUE);
              break;
                (info, name, input_bfd, input_section, rel->r_offset, TRUE);
              break;
-             
+
            case bfd_reloc_outofrange:
              msg = _("internal error: out of range error");
              break;
            case bfd_reloc_outofrange:
              msg = _("internal error: out of range error");
              break;
@@ -661,11 +705,8 @@ iq2000_elf_relocate_section (bfd *              output_bfd ATTRIBUTE_UNUSED,
            }
 
          if (msg)
            }
 
          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);
        }
     }
 
        }
     }
 
@@ -722,29 +763,13 @@ iq2000_elf_set_private_flags (bfd *abfd, flagword flags)
   return TRUE;
 }
 
   return TRUE;
 }
 
-/* Copy backend specific data from one object module to another.  */
-
-static bfd_boolean
-iq2000_elf_copy_private_bfd_data (bfd *ibfd, bfd *obfd)
-{
-  if (bfd_get_flavour (ibfd) != bfd_target_elf_flavour
-      || bfd_get_flavour (obfd) != bfd_target_elf_flavour)
-    return TRUE;
-
-  BFD_ASSERT (!elf_flags_init (obfd)
-             || elf_elfheader (obfd)->e_flags == elf_elfheader (ibfd)->e_flags);
-
-  elf_elfheader (obfd)->e_flags = elf_elfheader (ibfd)->e_flags;
-  elf_flags_init (obfd) = TRUE;
-  return TRUE;
-}
-
 /* Merge backend specific data from an object
    file to the output object file when linking.  */
 
 static bfd_boolean
 /* Merge backend specific data from an object
    file to the output object file when linking.  */
 
 static bfd_boolean
-iq2000_elf_merge_private_bfd_data (bfd *ibfd, bfd *obfd)
+iq2000_elf_merge_private_bfd_data (bfd *ibfd, struct bfd_link_info *info)
 {
 {
+  bfd *obfd = info->output_bfd;
   flagword old_flags, old_partial;
   flagword new_flags, new_partial;
   bfd_boolean error = FALSE;
   flagword old_flags, old_partial;
   flagword new_flags, new_partial;
   bfd_boolean error = FALSE;
@@ -795,14 +820,15 @@ iq2000_elf_merge_private_bfd_data (bfd *ibfd, bfd *obfd)
              break;
            }
        }
              break;
            }
        }
-      
+
       /* Print out any mismatches from above.  */
       if (new_opt[0])
        {
          error = TRUE;
          _bfd_error_handler
       /* Print out any mismatches from above.  */
       if (new_opt[0])
        {
          error = TRUE;
          _bfd_error_handler
-           (_("%s: compiled with %s and linked with modules compiled with %s"),
-            bfd_get_filename (ibfd), new_opt, old_opt);
+           /* xgettext:c-format */
+           (_("%pB: compiled with %s and linked with modules compiled with %s"),
+            ibfd, new_opt, old_opt);
        }
 
       new_flags &= ~ EF_IQ2000_ALL_FLAGS;
        }
 
       new_flags &= ~ EF_IQ2000_ALL_FLAGS;
@@ -814,8 +840,9 @@ iq2000_elf_merge_private_bfd_data (bfd *ibfd, bfd *obfd)
          error = TRUE;
 
          _bfd_error_handler
          error = TRUE;
 
          _bfd_error_handler
-           (_("%s: uses different e_flags (0x%lx) fields than previous modules (0x%lx)"),
-            bfd_get_filename (ibfd), (long)new_flags, (long)old_flags);
+           /* xgettext:c-format */
+           (_("%pB: uses different e_flags (%#x) fields than previous modules (%#x)"),
+            ibfd, new_flags, old_flags);
        }
     }
 
        }
     }
 
@@ -838,7 +865,7 @@ iq2000_elf_print_private_bfd_data (bfd *abfd, void * ptr)
   _bfd_elf_print_private_bfd_data (abfd, ptr);
 
   flags = elf_elfheader (abfd)->e_flags;
   _bfd_elf_print_private_bfd_data (abfd, ptr);
 
   flags = elf_elfheader (abfd)->e_flags;
-  fprintf (file, _("private flags = 0x%lx:"), (long)flags);
+  fprintf (file, _("private flags = 0x%lx:"), (unsigned long) flags);
 
   switch (flags & EF_IQ2000_CPU_MASK)
     {
 
   switch (flags & EF_IQ2000_CPU_MASK)
     {
@@ -870,7 +897,7 @@ iq2000_elf_object_p (bfd *abfd)
 #define ELF_MACHINE_CODE       EM_IQ2000
 #define ELF_MAXPAGESIZE                0x1000
 
 #define ELF_MACHINE_CODE       EM_IQ2000
 #define ELF_MAXPAGESIZE                0x1000
 
-#define TARGET_BIG_SYM         bfd_elf32_iq2000_vec
+#define TARGET_BIG_SYM         iq2000_elf32_vec
 #define TARGET_BIG_NAME                "elf32-iq2000"
 
 #define elf_info_to_howto_rel                  NULL
 #define TARGET_BIG_NAME                "elf32-iq2000"
 
 #define elf_info_to_howto_rel                  NULL
@@ -886,7 +913,6 @@ iq2000_elf_object_p (bfd *abfd)
 #define bfd_elf32_bfd_reloc_type_lookup                iq2000_reloc_type_lookup
 #define bfd_elf32_bfd_reloc_name_lookup        iq2000_reloc_name_lookup
 #define bfd_elf32_bfd_set_private_flags                iq2000_elf_set_private_flags
 #define bfd_elf32_bfd_reloc_type_lookup                iq2000_reloc_type_lookup
 #define bfd_elf32_bfd_reloc_name_lookup        iq2000_reloc_name_lookup
 #define bfd_elf32_bfd_set_private_flags                iq2000_elf_set_private_flags
-#define bfd_elf32_bfd_copy_private_bfd_data    iq2000_elf_copy_private_bfd_data
 #define bfd_elf32_bfd_merge_private_bfd_data   iq2000_elf_merge_private_bfd_data
 #define bfd_elf32_bfd_print_private_bfd_data   iq2000_elf_print_private_bfd_data
 
 #define bfd_elf32_bfd_merge_private_bfd_data   iq2000_elf_merge_private_bfd_data
 #define bfd_elf32_bfd_print_private_bfd_data   iq2000_elf_print_private_bfd_data
 
This page took 0.029326 seconds and 4 git commands to generate.