Add a flag to asection, linker_has_input, and use it to reliably
[deliverable/binutils-gdb.git] / bfd / elf32-sh.c
index 61df1f7c4eca83abc0f8852cdb45baf8a217b034..6d7bc2eae0fbf1fae044d6f689a3bcc8e4beabf4 100644 (file)
@@ -1,5 +1,6 @@
 /* Hitachi SH specific support for 32-bit ELF
 /* 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.
    Contributed by Ian Lance Taylor, Cygnus Support.
 
 This file is part of BFD, the Binary File Descriptor library.
@@ -77,7 +78,8 @@ static boolean sh_elf_finish_dynamic_sections
 
 #define ELF_DYNAMIC_INTERPRETER "/usr/lib/libc.so.1"
 
 
 #define ELF_DYNAMIC_INTERPRETER "/usr/lib/libc.so.1"
 
-static reloc_howto_type sh_elf_howto_table[] = {
+static reloc_howto_type sh_elf_howto_table[] =
+{
   /* No relocation.  */
   HOWTO (R_SH_NONE,            /* type */
         0,                     /* rightshift */
   /* No relocation.  */
   HOWTO (R_SH_NONE,            /* type */
         0,                     /* rightshift */
@@ -911,14 +913,16 @@ sh_elf_ignore_reloc (abfd, reloc_entry, symbol, data, input_section,
 
 /* This structure is used to map BFD reloc codes to SH ELF relocs.  */
 
 
 /* This structure is used to map BFD reloc codes to SH ELF relocs.  */
 
-struct elf_reloc_map {
+struct elf_reloc_map
+{
   bfd_reloc_code_real_type bfd_reloc_val;
   unsigned char elf_reloc_val;
 };
 
 /* An array mapping BFD reloc codes to SH ELF relocs.  */
 
   bfd_reloc_code_real_type bfd_reloc_val;
   unsigned char elf_reloc_val;
 };
 
 /* An array mapping BFD reloc codes to SH ELF relocs.  */
 
-static const struct elf_reloc_map sh_reloc_map[] = {
+static const struct elf_reloc_map sh_reloc_map[] =
+{
   { BFD_RELOC_NONE, R_SH_NONE },
   { BFD_RELOC_32, R_SH_DIR32 },
   { BFD_RELOC_CTOR, R_SH_DIR32 },
   { BFD_RELOC_NONE, R_SH_NONE },
   { BFD_RELOC_32, R_SH_DIR32 },
   { BFD_RELOC_CTOR, R_SH_DIR32 },
@@ -2087,7 +2091,8 @@ sh_elf_swap_insns (abfd, sec, relocs, contents, addr)
 
 /* First entry in an absolute procedure linkage table look like this.  */
 
 
 /* First entry in an absolute procedure linkage table look like this.  */
 
-static const bfd_byte elf_sh_plt0_entry_be[PLT_ENTRY_SIZE] = {
+static const bfd_byte elf_sh_plt0_entry_be[PLT_ENTRY_SIZE] =
+{
   0xd0, 0x04,  /* mov.l 1f,r0 */
   0xd2, 0x05,  /* mov.l 2f,r2 */
   0x60, 0x02,  /* mov.l @r0,r0 */
   0xd0, 0x04,  /* mov.l 1f,r0 */
   0xd2, 0x05,  /* mov.l 2f,r2 */
   0x60, 0x02,  /* mov.l @r0,r0 */
@@ -2102,7 +2107,8 @@ static const bfd_byte elf_sh_plt0_entry_be[PLT_ENTRY_SIZE] = {
   0, 0, 0, 0,  /* 2: replaced with address of .got.plt + 4.  */
 };
 
   0, 0, 0, 0,  /* 2: replaced with address of .got.plt + 4.  */
 };
 
-static const bfd_byte elf_sh_plt0_entry_le[PLT_ENTRY_SIZE] = {
+static const bfd_byte elf_sh_plt0_entry_le[PLT_ENTRY_SIZE] =
+{
   0x04, 0xd0,  /* mov.l 1f,r0 */
   0x05, 0xd2,  /* mov.l 2f,r2 */
   0x02, 0x60,  /* mov.l @r0,r0 */
   0x04, 0xd0,  /* mov.l 1f,r0 */
   0x05, 0xd2,  /* mov.l 2f,r2 */
   0x02, 0x60,  /* mov.l @r0,r0 */
@@ -2120,7 +2126,8 @@ static const bfd_byte elf_sh_plt0_entry_le[PLT_ENTRY_SIZE] = {
 /* Sebsequent entries in an absolute procedure linkage table look like
    this.  */
 
 /* Sebsequent entries in an absolute procedure linkage table look like
    this.  */
 
-static const bfd_byte elf_sh_plt_entry_be[PLT_ENTRY_SIZE] = {
+static const bfd_byte elf_sh_plt_entry_be[PLT_ENTRY_SIZE] =
+{
   0xd0, 0x04,  /* mov.l 1f,r0 */
   0x60, 0x02,  /* mov.l @r0,r0 */
   0xd2, 0x02,  /* mov.l 0f,r2 */
   0xd0, 0x04,  /* mov.l 1f,r0 */
   0x60, 0x02,  /* mov.l @r0,r0 */
   0xd2, 0x02,  /* mov.l 0f,r2 */
@@ -2134,7 +2141,8 @@ static const bfd_byte elf_sh_plt_entry_be[PLT_ENTRY_SIZE] = {
   0, 0, 0, 0,  /* 2: replaced with offset into relocation table.  */
 };
 
   0, 0, 0, 0,  /* 2: replaced with offset into relocation table.  */
 };
 
-static const bfd_byte elf_sh_plt_entry_le[PLT_ENTRY_SIZE] = {
+static const bfd_byte elf_sh_plt_entry_le[PLT_ENTRY_SIZE] =
+{
   0x04, 0xd0,  /* mov.l 1f,r0 */
   0x02, 0x60,  /* mov.l @r0,r0 */
   0x02, 0xd2,  /* mov.l 0f,r2 */
   0x04, 0xd0,  /* mov.l 1f,r0 */
   0x02, 0x60,  /* mov.l @r0,r0 */
   0x02, 0xd2,  /* mov.l 0f,r2 */
@@ -2150,7 +2158,8 @@ static const bfd_byte elf_sh_plt_entry_le[PLT_ENTRY_SIZE] = {
 
 /* Entries in a PIC procedure linkage table look like this.  */
 
 
 /* Entries in a PIC procedure linkage table look like this.  */
 
-static const bfd_byte elf_sh_pic_plt_entry_be[PLT_ENTRY_SIZE] = {
+static const bfd_byte elf_sh_pic_plt_entry_be[PLT_ENTRY_SIZE] =
+{
   0xd0, 0x04,  /* mov.l 1f,r0 */
   0x00, 0xce,  /* mov.l @(r0,r12),r0 */
   0x40, 0x2b,  /* jmp @r0 */
   0xd0, 0x04,  /* mov.l 1f,r0 */
   0x00, 0xce,  /* mov.l @(r0,r12),r0 */
   0x40, 0x2b,  /* jmp @r0 */
@@ -2165,7 +2174,8 @@ static const bfd_byte elf_sh_pic_plt_entry_be[PLT_ENTRY_SIZE] = {
   0, 0, 0, 0    /* 2: replaced with offset into relocation table.  */
 };
 
   0, 0, 0, 0    /* 2: replaced with offset into relocation table.  */
 };
 
-static const bfd_byte elf_sh_pic_plt_entry_le[PLT_ENTRY_SIZE] = {
+static const bfd_byte elf_sh_pic_plt_entry_le[PLT_ENTRY_SIZE] =
+{
   0x04, 0xd0,  /* mov.l 1f,r0 */
   0xce, 0x00,  /* mov.l @(r0,r12),r0 */
   0x2b, 0x40,  /* jmp @r0 */
   0x04, 0xd0,  /* mov.l 1f,r0 */
   0xce, 0x00,  /* mov.l @(r0,r12),r0 */
   0x2b, 0x40,  /* jmp @r0 */
@@ -2214,7 +2224,8 @@ static const bfd_byte *elf_sh_pic_plt_entry;
 /* This structure keeps track of the number of PC relative relocs we
    have copied for a given symbol.  */
 
 /* This structure keeps track of the number of PC relative relocs we
    have copied for a given symbol.  */
 
-struct elf_sh_pcrel_relocs_copied {
+struct elf_sh_pcrel_relocs_copied
+{
   /* Next section.  */
   struct elf_sh_pcrel_relocs_copied *next;
   /* A section in dynobj.  */
   /* Next section.  */
   struct elf_sh_pcrel_relocs_copied *next;
   /* A section in dynobj.  */
@@ -2225,7 +2236,8 @@ struct elf_sh_pcrel_relocs_copied {
 
 /* sh ELF linker hash entry.  */
 
 
 /* sh ELF linker hash entry.  */
 
-struct elf_sh_link_hash_entry {
+struct elf_sh_link_hash_entry
+{
   struct elf_link_hash_entry root;
 
   /* Number of PC relative relocs copied for this symbol.  */
   struct elf_link_hash_entry root;
 
   /* Number of PC relative relocs copied for this symbol.  */
@@ -2234,7 +2246,8 @@ struct elf_sh_link_hash_entry {
 
 /* sh ELF linker hash table.  */
 
 
 /* sh ELF linker hash table.  */
 
-struct elf_sh_link_hash_table {
+struct elf_sh_link_hash_table
+{
   struct elf_link_hash_table root;
 };
 
   struct elf_link_hash_table root;
 };
 
@@ -2833,7 +2846,6 @@ sh_elf_discard_copies (h, ignore)
 
   return true;
 }
 
   return true;
 }
-
 \f
 /* Relocate an SH ELF section.  */
 
 \f
 /* Relocate an SH ELF section.  */
 
@@ -3017,14 +3029,46 @@ sh_elf_relocate_section (output_bfd, info, input_bfd, input_section,
          break;
 
        case R_SH_IND12W:
          break;
 
        case R_SH_IND12W:
+         relocation -= 4;
+         goto final_link_relocate;
+
        case R_SH_DIR8WPN:
        case R_SH_DIR8WPZ:
        case R_SH_DIR8WPL:
        case R_SH_DIR8WPN:
        case R_SH_DIR8WPZ:
        case R_SH_DIR8WPL:
-         /* These should normally be handled by the assembler, but at
-            least IND12W is generated by ourselves, so we must deal
-            with it.  */
-         relocation -= 4;
-         goto final_link_relocate;
+         /* If the reloc is against the start of this section, then
+            the assembler has already taken care of it and the reloc
+            is here only to assist in relaxing.  If the reloc is not
+            against the start of this section, then it's against an
+            external symbol and we must deal with it ourselves.  */
+         if (input_section->output_section->vma + input_section->output_offset
+             != relocation)
+           {
+             int disp = (relocation
+                         - input_section->output_section->vma
+                         - input_section->output_offset
+                         - rel->r_offset);
+             int mask = 0;
+             switch (r_type)
+               {
+               case R_SH_DIR8WPN:
+               case R_SH_DIR8WPZ: mask = 1; break;
+               case R_SH_DIR8WPL: mask = 3; break;
+               default: mask = 0; break;
+               }
+             if (disp & mask)
+               {
+                 ((*_bfd_error_handler)
+                  (_("%s: 0x%lx: fatal: unaligned branch target for relax-support relocation"),
+                   bfd_get_filename (input_section->owner),
+                   (unsigned long) rel->r_offset));
+                 bfd_set_error (bfd_error_bad_value);
+                 return false;
+               }
+             relocation -= 4;
+             goto final_link_relocate;
+           }
+         r = bfd_reloc_ok;
+         break;
 
        default:
          bfd_set_error (bfd_error_bad_value);
 
        default:
          bfd_set_error (bfd_error_bad_value);
@@ -3524,9 +3568,7 @@ sh_elf_gc_mark_hook (abfd, info, rel, h, sym)
            && ELF_ST_BIND (sym->st_info) != STB_LOCAL)
          && ! ((sym->st_shndx <= 0 || sym->st_shndx >= SHN_LORESERVE)
                 && sym->st_shndx != SHN_COMMON))
            && 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;
 }
     }
   return NULL;
 }
@@ -3895,10 +3937,10 @@ sh_elf_set_private_flags (abfd, flags)
 
 static boolean
 sh_elf_copy_private_data (ibfd, obfd)
 
 static boolean
 sh_elf_copy_private_data (ibfd, obfd)
-     bfd *ibfd;
-     bfd *obfd;
+     bfd * ibfd;
+     bfd * obfd;
 {
 {
-  if (bfd_get_flavour (ibfd) != bfd_target_elf_flavour
+  if (   bfd_get_flavour (ibfd) != bfd_target_elf_flavour
       || bfd_get_flavour (obfd) != bfd_target_elf_flavour)
     return true;
 
       || bfd_get_flavour (obfd) != bfd_target_elf_flavour)
     return true;
 
This page took 0.025265 seconds and 4 git commands to generate.