Update copyright notices
[deliverable/binutils-gdb.git] / bfd / elf32-sh.c
index ac7309019273e3a08714668981088f940286883d..0e6be9b0151057fa0047c3384b117d5c3df28bbe 100644 (file)
@@ -1,5 +1,6 @@
 /* Hitachi SH specific support for 32-bit ELF
-   Copyright 1996, 97, 98, 1999, 2000 Free Software Foundation, Inc.
+   Copyright 1996, 1997, 1998, 1999, 2000, 2001
+   Free Software Foundation, Inc.
    Contributed by Ian Lance Taylor, Cygnus Support.
 
 This file is part of BFD, the Binary File Descriptor library.
@@ -710,7 +711,7 @@ static reloc_howto_type sh_elf_howto_table[] =
 
 static bfd_reloc_status_type
 sh_elf_reloc_loop (r_type, input_bfd, input_section, contents, addr,
-                   symbol_section, start, end)
+                  symbol_section, start, end)
      int r_type ATTRIBUTE_UNUSED;
      bfd *input_bfd;
      asection *input_section;
@@ -789,7 +790,7 @@ sh_elf_reloc_loop (r_type, input_bfd, input_section, contents, addr,
     {
       bfd_vma start0 = start - 4;
 
-      while (start0 >= 0 && IS_PPI (contents + start0))
+      while (start0 && IS_PPI (contents + start0))
        start0 -= 2;
       start0 = start - 2 - ((start - start0) & 2);
       start = start0 - cum_diff - 2;
@@ -821,7 +822,7 @@ sh_elf_reloc_loop (r_type, input_bfd, input_section, contents, addr,
 
 static bfd_reloc_status_type
 sh_elf_reloc (abfd, reloc_entry, symbol_in, data, input_section, output_bfd,
-         error_message)
+             error_message)
      bfd *abfd;
      arelent *reloc_entry;
      asymbol *symbol_in;
@@ -855,8 +856,8 @@ sh_elf_reloc (abfd, reloc_entry, symbol_in, data, input_section, output_bfd,
     return bfd_reloc_undefined;
 
   if (bfd_is_com_section (symbol_in->section))
-    sym_value = 0;                           
-  else 
+    sym_value = 0;
+  else
     sym_value = (symbol_in->value +
                 symbol_in->section->output_section->vma +
                 symbol_in->section->output_offset);
@@ -1001,7 +1002,7 @@ sh_elf_info_to_howto (abfd, cache_ptr, dst)
    values; in coff-sh.c they come from include/coff/sh.h, whereas here
    they come from enum elf_sh_reloc_type in include/elf/sh.h.  */
 
-static boolean 
+static boolean
 sh_elf_relax_section (abfd, sec, link_info, again)
      bfd *abfd;
      asection *sec;
@@ -1106,7 +1107,7 @@ sh_elf_relax_section (abfd, sec, link_info, again)
         on a four byte boundary.  */
       paddr = insn & 0xff;
       paddr *= 4;
-      paddr += (laddr + 4) &3;
+      paddr += (laddr + 4) & ~3;
       if (paddr >= sec->_raw_size)
        {
          ((*_bfd_error_handler)
@@ -1564,7 +1565,7 @@ sh_elf_relax_delete_bytes (abfd, sec, addr, count)
 
        case R_SH_DIR8WPL:
          off = insn & 0xff;
-         stop = (start &(bfd_vma) 3) + 4 + off * 4;
+         stop = (start & ~(bfd_vma) 3) + 4 + off * 4;
          break;
 
        case R_SH_SWITCH8:
@@ -2388,7 +2389,7 @@ sh_elf_create_dynamic_sections (abfd, info)
        return false;
     }
 
-  s = bfd_make_section (abfd, 
+  s = bfd_make_section (abfd,
                        bed->default_use_rela_p ? ".rela.plt" : ".rel.plt");
   if (s == NULL
       || ! bfd_set_section_flags (abfd, s, flags | SEC_READONLY)
@@ -2448,9 +2449,9 @@ sh_elf_create_dynamic_sections (abfd, info)
         copy relocs.  */
       if (! info->shared)
        {
-         s = bfd_make_section (abfd, 
-                               (bed->default_use_rela_p 
-                                ? ".rela.bss" : ".rel.bss")); 
+         s = bfd_make_section (abfd,
+                               (bed->default_use_rela_p
+                                ? ".rela.bss" : ".rel.bss"));
          if (s == NULL
              || ! bfd_set_section_flags (abfd, s, flags | SEC_READONLY)
              || ! bfd_set_section_alignment (abfd, s, ptralign))
@@ -2461,7 +2462,6 @@ sh_elf_create_dynamic_sections (abfd, info)
   return true;
 }
 \f
-
 /* Adjust a symbol defined by a dynamic object and referenced by a
    regular object.  The current definition is in some section of the
    dynamic object, but we're not including those sections.  We have to
@@ -2830,7 +2830,6 @@ sh_elf_size_dynamic_sections (output_bfd, info)
    check_relocs routine, but we won't fill them in in the
    relocate_section routine.  */
 
-/*ARGSUSED*/
 static boolean
 sh_elf_discard_copies (h, ignore)
      struct elf_sh_link_hash_entry *h;
@@ -2847,7 +2846,6 @@ sh_elf_discard_copies (h, ignore)
 
   return true;
 }
-
 \f
 /* Relocate an SH ELF section.  */
 
@@ -2892,30 +2890,11 @@ sh_elf_relocate_section (output_bfd, info, input_bfd, input_section,
       asection *sec;
       struct elf_link_hash_entry *h;
       bfd_vma relocation;
-      bfd_vma addend = (bfd_vma)0;
+      bfd_vma addend = (bfd_vma) 0;
       bfd_reloc_status_type r;
 
       r_symndx = ELF32_R_SYM (rel->r_info);
 
-      if (info->relocateable)
-       {
-         /* This is a relocateable link.  We don't have to change
-             anything, unless the reloc is against a section symbol,
-             in which case we have to adjust according to where the
-             section symbol winds up in the output section.  */
-         if (r_symndx < symtab_hdr->sh_info)
-           {
-             sym = local_syms + r_symndx;
-             if (ELF_ST_TYPE (sym->st_info) == STT_SECTION)
-               {
-                 sec = local_sections[r_symndx];
-                 rel->r_addend += sec->output_offset + sym->st_value;
-               }
-           }
-
-         continue;
-       }
-
       r_type = ELF32_R_TYPE (rel->r_info);
 
       /* Many of the relocs are only used for relaxing, and are
@@ -2923,6 +2902,8 @@ sh_elf_relocate_section (output_bfd, info, input_bfd, input_section,
       if (r_type > (int) R_SH_LAST_INVALID_RELOC
          && r_type < (int) R_SH_LOOP_START)
        continue;
+      if (r_type == (int) R_SH_NONE)
+       continue;
 
       if (r_type < 0
          || r_type >= R_SH_max
@@ -2948,9 +2929,28 @@ sh_elf_relocate_section (output_bfd, info, input_bfd, input_section,
          relocation = (sec->output_section->vma
                        + sec->output_offset
                        + sym->st_value);
+
+         if (info->relocateable)
+           {
+             /* This is a relocateable link.  We don't have to change
+                anything, unless the reloc is against a section symbol,
+                in which case we have to adjust according to where the
+                section symbol winds up in the output section.  */
+             sym = local_syms + r_symndx;
+             if (ELF_ST_TYPE (sym->st_info) == STT_SECTION)
+               goto final_link_relocate;
+
+             continue;
+           }
        }
       else
        {
+         /* Section symbol are never (?) placed in the hash table, so
+            we can just ignore hash relocations when creating a
+            relocateable object file.  */
+         if (info->relocateable)
+           continue;
+
          h = sym_hashes[r_symndx - symtab_hdr->sh_info];
          while (h->root.type == bfd_link_hash_indirect
                 || h->root.type == bfd_link_hash_warning)
@@ -2961,7 +2961,7 @@ sh_elf_relocate_section (output_bfd, info, input_bfd, input_section,
              sec = h->root.u.def.section;
              /* In these cases, we don't need the relocation value.
                 We check specially because in some obscure cases
-                sec->output_section will be NULL. */
+                sec->output_section will be NULL.  */
              if (r_type == R_SH_GOTPC
                  || (r_type == R_SH_PLT32
                      && h->plt.offset != (bfd_vma) -1)
@@ -3018,11 +3018,11 @@ sh_elf_relocate_section (output_bfd, info, input_bfd, input_section,
            }
        }
 
-      switch ((int)r_type)
+      switch ((int) r_type)
        {
        final_link_relocate:
          /* COFF relocs don't use the addend. The addend is used for
-            R_SH_DIR32 to be compatible with other compilers. */
+            R_SH_DIR32 to be compatible with other compilers.  */
          r = _bfd_final_link_relocate (howto, input_bfd, input_section,
                                        contents, rel->r_offset,
                                        relocation, addend);
@@ -3136,9 +3136,9 @@ sh_elf_relocate_section (output_bfd, info, input_bfd, input_section,
                }
 
              bfd_elf32_swap_reloca_out (output_bfd, &outrel,
-                                       (((Elf32_External_Rela *)
-                                         sreloc->contents)
-                                        + sreloc->reloc_count));
+                                        (((Elf32_External_Rela *)
+                                          sreloc->contents)
+                                         + sreloc->reloc_count));
              ++sreloc->reloc_count;
 
              /* If this reloc is against an external symbol, we do
@@ -3369,7 +3369,7 @@ sh_elf_relocate_section (output_bfd, info, input_bfd, input_section,
 
 static bfd_byte *
 sh_elf_get_relocated_section_contents (output_bfd, link_info, link_order,
-                                       data, relocateable, symbols)
+                                      data, relocateable, symbols)
      bfd *output_bfd;
      struct bfd_link_info *link_info;
      struct bfd_link_order *link_order;
@@ -3501,45 +3501,43 @@ sh_elf_get_relocated_section_contents (output_bfd, link_info, link_order,
 }
 static asection *
 sh_elf_gc_mark_hook (abfd, info, rel, h, sym)
-       bfd *abfd;
-       struct bfd_link_info *info ATTRIBUTE_UNUSED;
-       Elf_Internal_Rela *rel;
-       struct elf_link_hash_entry *h;
-       Elf_Internal_Sym *sym;
+     bfd *abfd;
+     struct bfd_link_info *info ATTRIBUTE_UNUSED;
+     Elf_Internal_Rela *rel;
+     struct elf_link_hash_entry *h;
+     Elf_Internal_Sym *sym;
 {
   if (h != NULL)
     {
       switch (ELF32_R_TYPE (rel->r_info))
-      {
-      case R_SH_GNU_VTINHERIT:
-      case R_SH_GNU_VTENTRY:
-        break;
+       {
+       case R_SH_GNU_VTINHERIT:
+       case R_SH_GNU_VTENTRY:
+         break;
 
-      default:
-        switch (h->root.type)
-          {
-          case bfd_link_hash_defined:
-          case bfd_link_hash_defweak:
-            return h->root.u.def.section;
+       default:
+         switch (h->root.type)
+           {
+           case bfd_link_hash_defined:
+           case bfd_link_hash_defweak:
+             return h->root.u.def.section;
 
-          case bfd_link_hash_common:
-            return h->root.u.c.p->section;
+           case bfd_link_hash_common:
+             return h->root.u.c.p->section;
 
-         default:
-           break;
-          }
-       }
-     }
-   else
-     {
-       if (!(elf_bad_symtab (abfd)
-           && ELF_ST_BIND (sym->st_info) != STB_LOCAL)
-         && ! ((sym->st_shndx <= 0 || sym->st_shndx >= SHN_LORESERVE)
+           default:
+             break;
+           }
+       }
+    }
+  else
+    {
+      if (!(elf_bad_symtab (abfd)
+           && ELF_ST_BIND (sym->st_info) != STB_LOCAL)
+         && ! ((sym->st_shndx <= 0 || sym->st_shndx >= SHN_LORESERVE)
                 && sym->st_shndx != SHN_COMMON))
-          {
-            return bfd_section_from_elf_index (abfd, sym->st_shndx);
-          }
-      }
+       return bfd_section_from_elf_index (abfd, sym->st_shndx);
+    }
   return NULL;
 }
 
@@ -3555,14 +3553,14 @@ sh_elf_gc_sweep_hook (abfd, info, sec, relocs)
   /* We use got and plt entries for sh, but it would seem that the
      existing SH code does no sort of reference counting or whatnot on
      its GOT and PLT entries, so it is not possible to garbage collect
-     them at this time. */
+     them at this time.  */
   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.  */
+
 static boolean
 sh_elf_check_relocs (abfd, info, sec, relocs)
      bfd *abfd;
@@ -3579,21 +3577,20 @@ sh_elf_check_relocs (abfd, info, sec, relocs)
   asection *sgot;
   asection *srelgot;
   asection *sreloc;
+
   sgot = NULL;
   srelgot = NULL;
   sreloc = NULL;
 
   if (info->relocateable)
     return true;
+
   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);
+  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;
+
   dynobj = elf_hash_table (info)->dynobj;
   local_got_offsets = elf_local_got_offsets (abfd);
 
@@ -3602,13 +3599,13 @@ sh_elf_check_relocs (abfd, info, sec, relocs)
     {
       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;
+       h = NULL;
       else
-        h = sym_hashes[r_symndx - symtab_hdr->sh_info];
+       h = sym_hashes[r_symndx - symtab_hdr->sh_info];
+
       /* Some relocs require a global offset table.  */
       if (dynobj == NULL)
        {
@@ -3631,17 +3628,17 @@ sh_elf_check_relocs (abfd, info, sec, relocs)
         {
         /* This relocation describes the C++ object vtable hierarchy.
            Reconstruct it for later use during GC.  */
-        case R_SH_GNU_VTINHERIT:
-          if (!_bfd_elf32_gc_record_vtinherit (abfd, sec, h, rel->r_offset))
-            return false;
-          break;
+       case R_SH_GNU_VTINHERIT:
+         if (!_bfd_elf32_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_SH_GNU_VTENTRY:
-          if (!_bfd_elf32_gc_record_vtentry (abfd, sec, h, rel->r_addend))
-            return false;
-          break;
+       case R_SH_GNU_VTENTRY:
+         if (!_bfd_elf32_gc_record_vtentry (abfd, sec, h, rel->r_addend))
+           return false;
+         break;
 
        case R_SH_GOT32:
          /* This symbol requires a global offset table entry.  */
@@ -3692,8 +3689,8 @@ sh_elf_check_relocs (abfd, info, sec, relocs)
            }
          else
            {
-             /* This is a global offset table entry for a local
-                symbol.  */
+             /* This is a global offset table entry for a local
+                symbol.  */
              if (local_got_offsets == NULL)
                {
                  size_t size;
@@ -3847,15 +3844,15 @@ sh_elf_check_relocs (abfd, info, sec, relocs)
            }
 
          break;
-        }
+       }
     }
+
   return true;
 }
 
 static boolean
 sh_elf_set_mach_from_flags (abfd)
-     bfd *    abfd;
+     bfd *abfd;
 {
   flagword flags = elf_elfheader (abfd)->e_flags;
 
@@ -3889,10 +3886,11 @@ sh_elf_set_mach_from_flags (abfd)
   return true;
 }
 
-/* Function to keep SH specific file flags. */
+/* Function to keep SH specific file flags.  */
+
 static boolean
 sh_elf_set_private_flags (abfd, flags)
-     bfd *    abfd;
+     bfd *abfd;
      flagword flags;
 {
   BFD_ASSERT (! elf_flags_init (abfd)
@@ -3904,6 +3902,7 @@ sh_elf_set_private_flags (abfd, flags)
 }
 
 /* Copy backend specific data from one object module to another */
+
 static boolean
 sh_elf_copy_private_data (ibfd, obfd)
      bfd * ibfd;
@@ -4007,7 +4006,7 @@ sh_elf_finish_dynamic_symbol (output_bfd, info, h, sym)
        {
          if (elf_sh_plt_entry == NULL)
            {
-             elf_sh_plt_entry = (bfd_big_endian (output_bfd)?
+             elf_sh_plt_entry = (bfd_big_endian (output_bfd) ?
                                  elf_sh_plt_entry_be : elf_sh_plt_entry_le);
            }
          memcpy (splt->contents + h->plt.offset, elf_sh_plt_entry,
@@ -4028,7 +4027,7 @@ sh_elf_finish_dynamic_symbol (output_bfd, info, h, sym)
        {
          if (elf_sh_pic_plt_entry == NULL)
            {
-             elf_sh_pic_plt_entry = (bfd_big_endian (output_bfd)?
+             elf_sh_pic_plt_entry = (bfd_big_endian (output_bfd) ?
                                      elf_sh_pic_plt_entry_be :
                                      elf_sh_pic_plt_entry_le);
            }
@@ -4108,8 +4107,8 @@ sh_elf_finish_dynamic_symbol (output_bfd, info, h, sym)
        }
 
       bfd_elf32_swap_reloca_out (output_bfd, &rel,
-                               ((Elf32_External_Rela *) srel->contents
-                                + srel->reloc_count));
+                                ((Elf32_External_Rela *) srel->contents
+                                 + srel->reloc_count));
       ++srel->reloc_count;
     }
 
@@ -4134,8 +4133,8 @@ sh_elf_finish_dynamic_symbol (output_bfd, info, h, sym)
       rel.r_info = ELF32_R_INFO (h->dynindx, R_SH_COPY);
       rel.r_addend = 0;
       bfd_elf32_swap_reloca_out (output_bfd, &rel,
-                               ((Elf32_External_Rela *) s->contents
-                                + s->reloc_count));
+                                ((Elf32_External_Rela *) s->contents
+                                 + s->reloc_count));
       ++s->reloc_count;
     }
 
@@ -4240,7 +4239,7 @@ sh_elf_finish_dynamic_sections (output_bfd, info)
            {
              if (elf_sh_pic_plt_entry == NULL)
                {
-                 elf_sh_pic_plt_entry = (bfd_big_endian (output_bfd)?
+                 elf_sh_pic_plt_entry = (bfd_big_endian (output_bfd) ?
                                          elf_sh_pic_plt_entry_be :
                                          elf_sh_pic_plt_entry_le);
                }
@@ -4251,7 +4250,7 @@ sh_elf_finish_dynamic_sections (output_bfd, info)
            {
              if (elf_sh_plt0_entry == NULL)
                {
-                 elf_sh_plt0_entry = (bfd_big_endian (output_bfd)?
+                 elf_sh_plt0_entry = (bfd_big_endian (output_bfd) ?
                                       elf_sh_plt0_entry_be :
                                       elf_sh_plt0_entry_le);
                }
@@ -4295,7 +4294,7 @@ sh_elf_finish_dynamic_sections (output_bfd, info)
 #define TARGET_LITTLE_NAME     "elf32-shl"
 #define ELF_ARCH               bfd_arch_sh
 #define ELF_MACHINE_CODE       EM_SH
-#define ELF_MAXPAGESIZE                0x1
+#define ELF_MAXPAGESIZE                128
 
 #define elf_symbol_leading_char '_'
 #endif /* ELF_ARCH */
This page took 0.033666 seconds and 4 git commands to generate.