gdb: add target_ops::supports_displaced_step
[deliverable/binutils-gdb.git] / bfd / elf32-h8300.c
index 4cfc30e3ada6129e896c1f49e5899eed32c95a79..5488500b1712d685788d2d168da5e196bb531bb9 100644 (file)
@@ -1,5 +1,5 @@
 /* BFD back-end for Renesas H8/300 ELF binaries.
-   Copyright 1993-2013 Free Software Foundation, Inc.
+   Copyright (C) 1993-2020 Free Software Foundation, Inc.
 
    This file is part of BFD, the Binary File Descriptor library.
 
 #include "libbfd.h"
 #include "elf-bfd.h"
 #include "elf/h8.h"
+#include "cpu-h8300.h"
 
 static reloc_howto_type *elf32_h8_reloc_type_lookup
   (bfd *abfd, bfd_reloc_code_real_type code);
-static void elf32_h8_info_to_howto
+static bfd_boolean elf32_h8_info_to_howto
   (bfd *, arelent *, Elf_Internal_Rela *);
-static void elf32_h8_info_to_howto_rel
+static bfd_boolean elf32_h8_info_to_howto_rel
   (bfd *, arelent *, Elf_Internal_Rela *);
 static unsigned long elf32_h8_mach (flagword);
-static void elf32_h8_final_write_processing (bfd *, bfd_boolean);
 static bfd_boolean elf32_h8_object_p (bfd *);
-static bfd_boolean elf32_h8_merge_private_bfd_data (bfd *, bfd *);
+static bfd_boolean elf32_h8_merge_private_bfd_data
+  (bfd *, struct bfd_link_info *);
 static bfd_boolean elf32_h8_relax_section
   (bfd *, asection *, struct bfd_link_info *, bfd_boolean *);
 static bfd_boolean elf32_h8_relax_delete_bytes
@@ -61,7 +62,7 @@ static reloc_howto_type h8_elf_howto_table[] =
 #define R_H8_NONE_X 0
   HOWTO (R_H8_NONE,            /* type */
         0,                     /* rightshift */
-        0,                     /* size (0 = byte, 1 = short, 2 = long) */
+        3,                     /* size (0 = byte, 1 = short, 2 = long) */
         0,                     /* bitsize */
         FALSE,                 /* pc_relative */
         0,                     /* bitpos */
@@ -283,7 +284,7 @@ elf32_h8_reloc_name_lookup (bfd *abfd ATTRIBUTE_UNUSED,
   return NULL;
 }
 
-static void
+static bfd_boolean
 elf32_h8_info_to_howto (bfd *abfd ATTRIBUTE_UNUSED, arelent *bfd_reloc,
                        Elf_Internal_Rela *elf_reloc)
 {
@@ -295,20 +296,20 @@ elf32_h8_info_to_howto (bfd *abfd ATTRIBUTE_UNUSED, arelent *bfd_reloc,
     if (h8_elf_howto_table[i].type == r)
       {
        bfd_reloc->howto = &h8_elf_howto_table[i];
-       return;
+       return TRUE;
       }
-  abort ();
+  /* xgettext:c-format */
+  _bfd_error_handler (_("%pB: unsupported relocation type %#x"), abfd, r);
+  bfd_set_error (bfd_error_bad_value);
+  return FALSE;
 }
 
-static void
-elf32_h8_info_to_howto_rel (bfd *abfd ATTRIBUTE_UNUSED, arelent *bfd_reloc,
+static bfd_boolean
+elf32_h8_info_to_howto_rel (bfd *abfd ATTRIBUTE_UNUSED,
+                           arelent *bfd_reloc ATTRIBUTE_UNUSED,
                            Elf_Internal_Rela *elf_reloc ATTRIBUTE_UNUSED)
 {
-  unsigned int r;
-
-  abort ();
-  r = ELF32_R_TYPE (elf_reloc->r_info);
-  bfd_reloc->howto = &h8_elf_howto_table[r];
+  return FALSE;
 }
 
 /* Special handling for H8/300 relocs.
@@ -452,7 +453,8 @@ elf32_h8_relocate_section (bfd *output_bfd, struct bfd_link_info *info,
       arelent bfd_reloc;
       reloc_howto_type *howto;
 
-      elf32_h8_info_to_howto (input_bfd, &bfd_reloc, rel);
+      if (! elf32_h8_info_to_howto (input_bfd, &bfd_reloc, rel))
+       continue;
       howto = bfd_reloc.howto;
 
       r_symndx = ELF32_R_SYM (rel->r_info);
@@ -468,19 +470,19 @@ elf32_h8_relocate_section (bfd *output_bfd, struct bfd_link_info *info,
        }
       else
        {
-         bfd_boolean unresolved_reloc, warned;
+         bfd_boolean unresolved_reloc, warned, ignored;
 
          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);
        }
 
       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;
 
       r = elf32_h8_final_link_relocate (r_type, input_bfd, output_bfd,
@@ -501,24 +503,20 @@ elf32_h8_relocate_section (bfd *output_bfd, struct bfd_link_info *info,
              name = (bfd_elf_string_from_elf_section
                      (input_bfd, symtab_hdr->sh_link, sym->st_name));
              if (name == NULL || *name == '\0')
-               name = bfd_section_name (input_bfd, sec);
+               name = bfd_section_name (sec);
            }
 
          switch (r)
            {
            case 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);
              break;
 
            case bfd_reloc_undefined:
-             if (! ((*info->callbacks->undefined_symbol)
-                    (info, name, input_bfd, input_section,
-                     rel->r_offset, TRUE)))
-               return FALSE;
+             (*info->callbacks->undefined_symbol)
+               (info, name, input_bfd, input_section, rel->r_offset, TRUE);
              break;
 
            case bfd_reloc_outofrange:
@@ -538,10 +536,8 @@ elf32_h8_relocate_section (bfd *output_bfd, struct bfd_link_info *info,
              /* fall through */
 
            common_error:
-             if (!((*info->callbacks->warning)
-                   (info, msg, name, input_bfd, input_section,
-                    rel->r_offset)))
-               return FALSE;
+             (*info->callbacks->warning) (info, msg, name, input_bfd,
+                                          input_section, rel->r_offset);
              break;
            }
        }
@@ -588,9 +584,8 @@ elf32_h8_mach (flagword flags)
    file.  We use this opportunity to encode the BFD machine type
    into the flags field in the object file.  */
 
-static void
-elf32_h8_final_write_processing (bfd *abfd,
-                                bfd_boolean linker ATTRIBUTE_UNUSED)
+static bfd_boolean
+elf32_h8_final_write_processing (bfd *abfd)
 {
   unsigned long val;
 
@@ -628,6 +623,7 @@ elf32_h8_final_write_processing (bfd *abfd,
 
   elf_elfheader (abfd)->e_flags &= ~ (EF_H8_MACH);
   elf_elfheader (abfd)->e_flags |= val;
+  return _bfd_elf_final_write_processing (abfd);
 }
 
 /* Return nonzero if ABFD represents a valid H8 ELF object file; also
@@ -646,8 +642,10 @@ elf32_h8_object_p (bfd *abfd)
    time is the architecture/machine information.  */
 
 static bfd_boolean
-elf32_h8_merge_private_bfd_data (bfd *ibfd, bfd *obfd)
+elf32_h8_merge_private_bfd_data (bfd *ibfd, struct bfd_link_info *info)
 {
+  bfd *obfd = info->output_bfd;
+
   if (bfd_get_flavour (ibfd) != bfd_target_elf_flavour
       || bfd_get_flavour (obfd) != bfd_target_elf_flavour)
     return TRUE;
@@ -667,27 +665,27 @@ elf32_h8_merge_private_bfd_data (bfd *ibfd, bfd *obfd)
 
    There are a few relaxing opportunities available on the H8:
 
-     jmp/jsr:24    ->    bra/bsr:8             2 bytes
+     jmp/jsr:24           ->    bra/bsr:8              2 bytes
      The jmp may be completely eliminated if the previous insn is a
      conditional branch to the insn after the jump.  In that case
      we invert the branch and delete the jump and save 4 bytes.
 
-     bCC:16          ->    bCC:8                  2 bytes
-     bsr:16          ->    bsr:8                  2 bytes
+     bCC:16         ->    bCC:8                  2 bytes
+     bsr:16         ->    bsr:8                  2 bytes
 
-     bset:16        ->    bset:8                 2 bytes
-     bset:24/32             ->    bset:8                 4 bytes
+     bset:16        ->    bset:8                 2 bytes
+     bset:24/32             ->    bset:8                 4 bytes
      (also applicable to other bit manipulation instructions)
 
-     mov.b:16       ->    mov.b:8                2 bytes
-     mov.b:24/32     ->    mov.b:8                4 bytes
+     mov.b:16       ->    mov.b:8                2 bytes
+     mov.b:24/32     ->           mov.b:8                4 bytes
 
-     bset:24/32             ->    bset:16                2 bytes
+     bset:24/32             ->    bset:16                2 bytes
      (also applicable to other bit manipulation instructions)
 
-     mov.[bwl]:24/32 ->    mov.[bwl]:16           2 bytes
+     mov.[bwl]:24/32 ->           mov.[bwl]:16           2 bytes
 
-     mov.[bwl] @(displ:24/32+ERx) -> mov.[bwl] @(displ:16+ERx)  4 bytes.  */
+     mov.[bwl] @(displ:24/32+ERx) -> mov.[bwl] @(displ:16+ERx) 4 bytes.  */
 
 static bfd_boolean
 elf32_h8_relax_section (bfd *abfd, asection *sec,
@@ -707,7 +705,7 @@ elf32_h8_relax_section (bfd *abfd, asection *sec,
   /* We don't have to do anything for a relocatable link, if
      this section does not have relocs, or if this is not a
      code section.  */
-  if (link_info->relocatable
+  if (bfd_link_relocatable (link_info)
       || (sec->flags & SEC_RELOC) == 0
       || sec->reloc_count == 0
       || (sec->flags & SEC_CODE) == 0)
@@ -736,13 +734,14 @@ elf32_h8_relax_section (bfd *abfd, asection *sec,
       {
        arelent bfd_reloc;
 
-       elf32_h8_info_to_howto (abfd, &bfd_reloc, irel);
+       if (! elf32_h8_info_to_howto (abfd, &bfd_reloc, irel))
+         continue;
       }
       /* Keep track of the previous reloc so that we can delete
         some long jumps created by the compiler.  */
       if (irel != internal_relocs)
        last_reloc = irel - 1;
-      
+
       switch(ELF32_R_TYPE (irel->r_info))
        {
        case R_H8_DIR24R8:
@@ -811,8 +810,8 @@ elf32_h8_relax_section (bfd *abfd, asection *sec,
              && h->root.type != bfd_link_hash_defweak)
            {
              /* This appears to be a reference to an undefined
-                 symbol.  Just ignore it--it will be caught by the
-                 regular reloc processing.  */
+                symbol.  Just ignore it--it will be caught by the
+                regular reloc processing.  */
              continue;
            }
 
@@ -1252,7 +1251,8 @@ elf32_h8_relax_section (bfd *abfd, asection *sec,
                        reloc_howto_type *h;
                        bfd_vma last_reloc_size;
 
-                       elf32_h8_info_to_howto (abfd, &bfd_reloc, last_reloc);
+                       if (! elf32_h8_info_to_howto (abfd, &bfd_reloc, last_reloc))
+                         break;
                        h = bfd_reloc.howto;
                        last_reloc_size = 1 << h->size;
                        if (last_reloc->r_offset + last_reloc_size
@@ -1270,7 +1270,8 @@ elf32_h8_relax_section (bfd *abfd, asection *sec,
                        reloc_howto_type *h;
                        bfd_vma next_reloc_size;
 
-                       elf32_h8_info_to_howto (abfd, &bfd_reloc, next_reloc);
+                       if (! elf32_h8_info_to_howto (abfd, &bfd_reloc, next_reloc))
+                         break;
                        h = bfd_reloc.howto;
                        next_reloc_size = 1 << h->size;
                        if (next_reloc->r_offset + next_reloc_size
@@ -1464,21 +1465,17 @@ elf32_h8_relax_section (bfd *abfd, asection *sec,
        }
     }
 
-  if (internal_relocs != NULL
-      && elf_section_data (sec)->relocs != internal_relocs)
+  if (elf_section_data (sec)->relocs != internal_relocs)
     free (internal_relocs);
 
   return TRUE;
 
  error_return:
-  if (isymbuf != NULL
-      && symtab_hdr->contents != (unsigned char *) isymbuf)
+  if (symtab_hdr->contents != (unsigned char *) isymbuf)
     free (isymbuf);
-  if (contents != NULL
-      && elf_section_data (sec)->this_hdr.contents != contents)
+  if (elf_section_data (sec)->this_hdr.contents != contents)
     free (contents);
-  if (internal_relocs != NULL
-      && elf_section_data (sec)->relocs != internal_relocs)
+  if (elf_section_data (sec)->relocs != internal_relocs)
     free (internal_relocs);
   return FALSE;
 }
@@ -1518,7 +1515,7 @@ elf32_h8_relax_delete_bytes (bfd *abfd, asection *sec, bfd_vma addr, int count)
     {
       /* Get the new reloc address.  */
       if ((irel->r_offset > addr
-          && irel->r_offset < toaddr))
+          && irel->r_offset <= toaddr))
        irel->r_offset -= count;
     }
 
@@ -1530,7 +1527,7 @@ elf32_h8_relax_delete_bytes (bfd *abfd, asection *sec, bfd_vma addr, int count)
     {
       if (isym->st_shndx == sec_shndx
          && isym->st_value > addr
-         && isym->st_value < toaddr)
+         && isym->st_value <= toaddr)
        isym->st_value -= count;
     }
 
@@ -1542,14 +1539,13 @@ elf32_h8_relax_delete_bytes (bfd *abfd, asection *sec, bfd_vma addr, int count)
   for (; sym_hashes < end_hashes; sym_hashes++)
     {
       struct elf_link_hash_entry *sym_hash = *sym_hashes;
+
       if ((sym_hash->root.type == bfd_link_hash_defined
           || sym_hash->root.type == bfd_link_hash_defweak)
          && sym_hash->root.u.def.section == sec
          && sym_hash->root.u.def.value > addr
-         && sym_hash->root.u.def.value < toaddr)
-       {
-         sym_hash->root.u.def.value -= count;
-       }
+         && sym_hash->root.u.def.value <= toaddr)
+       sym_hash->root.u.def.value -= count;
     }
 
   return TRUE;
@@ -1682,10 +1678,8 @@ elf32_h8_get_relocated_section_contents (bfd *output_bfd,
                                       isymbuf, sections))
        goto error_return;
 
-      if (sections != NULL)
-       free (sections);
-      if (isymbuf != NULL
-         && symtab_hdr->contents != (unsigned char *) isymbuf)
+      free (sections);
+      if (symtab_hdr->contents != (unsigned char *) isymbuf)
        free (isymbuf);
       if (elf_section_data (input_section)->relocs != internal_relocs)
        free (internal_relocs);
@@ -1694,19 +1688,16 @@ elf32_h8_get_relocated_section_contents (bfd *output_bfd,
   return data;
 
  error_return:
-  if (sections != NULL)
-    free (sections);
-  if (isymbuf != NULL
-      && symtab_hdr->contents != (unsigned char *) isymbuf)
+  free (sections);
+  if (symtab_hdr->contents != (unsigned char *) isymbuf)
     free (isymbuf);
-  if (internal_relocs != NULL
-      && elf_section_data (input_section)->relocs != internal_relocs)
+  if (elf_section_data (input_section)->relocs != internal_relocs)
     free (internal_relocs);
   return NULL;
 }
 
 
-#define TARGET_BIG_SYM                 bfd_elf32_h8300_vec
+#define TARGET_BIG_SYM                 h8300_elf32_vec
 #define TARGET_BIG_NAME                        "elf32-h8300"
 #define ELF_ARCH                       bfd_arch_h8300
 #define ELF_MACHINE_CODE               EM_H8_300
@@ -1740,8 +1731,17 @@ elf32_h8_get_relocated_section_contents (bfd *output_bfd,
 /* And relaxing stuff.  */
 #define bfd_elf32_bfd_relax_section     elf32_h8_relax_section
 #define bfd_elf32_bfd_get_relocated_section_contents \
-                                elf32_h8_get_relocated_section_contents
+                               elf32_h8_get_relocated_section_contents
 
 #define elf_symbol_leading_char '_'
 
 #include "elf32-target.h"
+
+#undef  TARGET_BIG_SYM
+#define TARGET_BIG_SYM                 h8300_elf32_linux_vec
+#undef  TARGET_BIG_NAME
+#define TARGET_BIG_NAME                        "elf32-h8300-linux"
+#undef  elf_symbol_leading_char
+#define elf32_bed                      elf32_h8300_linux_bed
+
+#include "elf32-target.h"
This page took 0.028269 seconds and 4 git commands to generate.