* elf32-arm.h (elf32_arm_final_link_relocate): Don't copy STN_UNDEF
[deliverable/binutils-gdb.git] / bfd / elf32-sh.c
index f8d29d1f9f16f01c02d9362cfd8636d219e2eafe..35ebf1ab6e622270274f8550d64f7773e91260c3 100644 (file)
@@ -84,7 +84,7 @@ static boolean sh_elf_gc_sweep_hook
   PARAMS ((bfd *, struct bfd_link_info *, asection *,
           const Elf_Internal_Rela *));
 static enum elf_reloc_type_class sh_elf_reloc_type_class
-  PARAMS ((int));
+  PARAMS ((const Elf_Internal_Rela *));
 
 /* The name of the dynamic interpreter.  This is put in the .interp
    section.  */
@@ -134,8 +134,8 @@ static reloc_howto_type sh_elf_howto_table[] =
         complain_overflow_signed, /* complain_on_overflow */
         sh_elf_ignore_reloc,   /* special_function */
         "R_SH_REL32",          /* name */
-        false,                 /* partial_inplace */
-        0,                     /* src_mask */
+        true,                  /* partial_inplace */
+        0xffffffff,            /* src_mask */
         0xffffffff,            /* dst_mask */
         true),                 /* pcrel_offset */
 
@@ -1096,7 +1096,7 @@ sh_elf_relax_section (abfd, sec, link_info, again)
       if (laddr >= sec->_raw_size)
        {
          (*_bfd_error_handler) (_("%s: 0x%lx: warning: bad R_SH_USES offset"),
-                                bfd_get_filename (abfd),
+                                bfd_archive_filename (abfd),
                                 (unsigned long) irel->r_offset);
          continue;
        }
@@ -1108,7 +1108,7 @@ sh_elf_relax_section (abfd, sec, link_info, again)
        {
          ((*_bfd_error_handler)
           (_("%s: 0x%lx: warning: R_SH_USES points to unrecognized insn 0x%x"),
-           bfd_get_filename (abfd), (unsigned long) irel->r_offset, insn));
+           bfd_archive_filename (abfd), (unsigned long) irel->r_offset, insn));
          continue;
        }
 
@@ -1125,7 +1125,7 @@ sh_elf_relax_section (abfd, sec, link_info, again)
        {
          ((*_bfd_error_handler)
           (_("%s: 0x%lx: warning: bad R_SH_USES load offset"),
-           bfd_get_filename (abfd), (unsigned long) irel->r_offset));
+           bfd_archive_filename (abfd), (unsigned long) irel->r_offset));
          continue;
        }
 
@@ -1140,7 +1140,7 @@ sh_elf_relax_section (abfd, sec, link_info, again)
        {
          ((*_bfd_error_handler)
           (_("%s: 0x%lx: warning: could not find expected reloc"),
-           bfd_get_filename (abfd), (unsigned long) paddr));
+           bfd_archive_filename (abfd), (unsigned long) paddr));
          continue;
        }
 
@@ -1176,7 +1176,7 @@ sh_elf_relax_section (abfd, sec, link_info, again)
            {
              ((*_bfd_error_handler)
               (_("%s: 0x%lx: warning: symbol in unexpected section"),
-               bfd_get_filename (abfd), (unsigned long) paddr));
+               bfd_archive_filename (abfd), (unsigned long) paddr));
              continue;
            }
 
@@ -1298,7 +1298,7 @@ sh_elf_relax_section (abfd, sec, link_info, again)
        {
          ((*_bfd_error_handler)
           (_("%s: 0x%lx: warning: could not find expected COUNT reloc"),
-           bfd_get_filename (abfd), (unsigned long) paddr));
+           bfd_archive_filename (abfd), (unsigned long) paddr));
          continue;
        }
 
@@ -1307,7 +1307,7 @@ sh_elf_relax_section (abfd, sec, link_info, again)
       if (irelcount->r_addend == 0)
        {
          ((*_bfd_error_handler) (_("%s: 0x%lx: warning: bad count"),
-                                 bfd_get_filename (abfd),
+                                 bfd_archive_filename (abfd),
                                  (unsigned long) paddr));
          continue;
        }
@@ -1392,7 +1392,7 @@ sh_elf_relax_section (abfd, sec, link_info, again)
       else
        {
          /* Cache the symbols for elf_link_input_bfd.  */
-         symtab_hdr->contents = extsyms;
+         symtab_hdr->contents = (unsigned char *) extsyms;
        }
       free_extsyms = NULL;
     }
@@ -1701,7 +1701,7 @@ sh_elf_relax_delete_bytes (abfd, sec, addr, count)
            {
              ((*_bfd_error_handler)
               (_("%s: 0x%lx: fatal: reloc overflow while relaxing"),
-               bfd_get_filename (abfd), (unsigned long) irel->r_offset));
+               bfd_archive_filename (abfd), (unsigned long) irel->r_offset));
              bfd_set_error (bfd_error_bad_value);
              return false;
            }
@@ -2091,7 +2091,7 @@ sh_elf_swap_insns (abfd, sec, relocs, contents, addr)
            {
              ((*_bfd_error_handler)
               (_("%s: 0x%lx: fatal: reloc overflow while relaxing"),
-               bfd_get_filename (abfd), (unsigned long) irel->r_offset));
+               bfd_archive_filename (abfd), (unsigned long) irel->r_offset));
              bfd_set_error (bfd_error_bad_value);
              return false;
            }
@@ -3026,7 +3026,11 @@ sh_elf_relocate_section (output_bfd, info, input_bfd, input_section,
 
       howto = sh_elf_howto_table + r_type;
 
-      /* This is a final link.  */
+      /* For relocs that aren't partial_inplace, we get the addend from
+         the relocation.  */
+      if (! howto->partial_inplace)
+       addend = rel->r_addend;
+
       h = NULL;
       sym = NULL;
       sec = NULL;
@@ -3046,7 +3050,32 @@ sh_elf_relocate_section (output_bfd, info, input_bfd, input_section,
                 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;
+               {
+                 if (! howto->partial_inplace)
+                   {
+                     /* For relocations with the addend in the
+                        relocation, we need just to update the addend.
+                        All real relocs are of type partial_inplace; this
+                        code is mostly for completeness.  */
+                     rel->r_addend += sec->output_offset + sym->st_value;
+
+                     continue;
+                   }
+
+                 /* Relocs of type partial_inplace need to pick up the
+                    contents in the contents and add the offset resulting
+                    from the changed location of the section symbol.
+                    Using _bfd_final_link_relocate (e.g. goto
+                    final_link_relocate) here would be wrong, because
+                    relocations marked pc_relative would get the current
+                    location subtracted, and we must only do that at the
+                    final link.  */
+                 r = _bfd_relocate_contents (howto, input_bfd,
+                                             sec->output_offset
+                                             + sym->st_value,
+                                             contents + rel->r_offset);
+                 goto relocation_done;
+               }
 
              continue;
            }
@@ -3103,7 +3132,7 @@ sh_elf_relocate_section (output_bfd, info, input_bfd, input_section,
                {
                  (*_bfd_error_handler)
                    (_("%s: warning: unresolvable relocation against symbol `%s' from %s section"),
-                    bfd_get_filename (input_bfd), h->root.root.string,
+                    bfd_archive_filename (input_bfd), h->root.root.string,
                     bfd_get_section_name (input_bfd, input_section));
                  relocation = 0;
                }
@@ -3169,7 +3198,7 @@ sh_elf_relocate_section (output_bfd, info, input_bfd, input_section,
                {
                  ((*_bfd_error_handler)
                   (_("%s: 0x%lx: fatal: unaligned branch target for relax-support relocation"),
-                   bfd_get_filename (input_section->owner),
+                   bfd_archive_filename (input_section->owner),
                    (unsigned long) rel->r_offset));
                  bfd_set_error (bfd_error_bad_value);
                  return false;
@@ -3187,6 +3216,7 @@ sh_elf_relocate_section (output_bfd, info, input_bfd, input_section,
        case R_SH_DIR32:
        case R_SH_REL32:
          if (info->shared
+             && r_symndx != 0
              && (input_section->flags & SEC_ALLOC) != 0
              && (r_type != R_SH_REL32
                  || (h != NULL
@@ -3253,7 +3283,8 @@ sh_elf_relocate_section (output_bfd, info, input_bfd, input_section,
                  BFD_ASSERT (h != NULL && h->dynindx != -1);
                  relocate = false;
                  outrel.r_info = ELF32_R_INFO (h->dynindx, R_SH_REL32);
-                 outrel.r_addend = rel->r_addend;
+                 outrel.r_addend
+                   = bfd_get_32 (input_bfd, contents + rel->r_offset);
                }
              else
                {
@@ -3266,14 +3297,18 @@ sh_elf_relocate_section (output_bfd, info, input_bfd, input_section,
                    {
                      relocate = true;
                      outrel.r_info = ELF32_R_INFO (0, R_SH_RELATIVE);
-                     outrel.r_addend = relocation + rel->r_addend;
+                     outrel.r_addend
+                       = relocation + bfd_get_32 (input_bfd,
+                                                  contents + rel->r_offset);
                    }
                  else
                    {
                      BFD_ASSERT (h->dynindx != -1);
                      relocate = false;
                      outrel.r_info = ELF32_R_INFO (h->dynindx, R_SH_DIR32);
-                     outrel.r_addend = relocation + rel->r_addend;
+                     outrel.r_addend
+                       = relocation + bfd_get_32 (input_bfd,
+                                                  contents + rel->r_offset);
                    }
                }
 
@@ -3290,8 +3325,6 @@ sh_elf_relocate_section (output_bfd, info, input_bfd, input_section,
              if (! relocate)
                continue;
            }
-         else if (r_type == R_SH_DIR32)
-           addend = rel->r_addend;
          goto final_link_relocate;
 
        case R_SH_GOT32:
@@ -3471,6 +3504,7 @@ sh_elf_relocate_section (output_bfd, info, input_bfd, input_section,
          }
        }
 
+    relocation_done:
       if (r != bfd_reloc_ok)
        {
          switch (r)
@@ -4091,7 +4125,7 @@ sh_elf_merge_private_data (ibfd, obfd)
     {
       (*_bfd_error_handler)
        ("%s: uses %s instructions while previous modules use %s instructions",
-        bfd_get_filename (ibfd),
+        bfd_archive_filename (ibfd),
         EF_SH_HAS_DSP (new_flags) ? "dsp" : "floating point",
         EF_SH_HAS_DSP (new_flags) ? "floating point" : "dsp");
       bfd_set_error (bfd_error_bad_value);
@@ -4434,10 +4468,10 @@ sh_elf_finish_dynamic_sections (output_bfd, info)
 }
 
 static enum elf_reloc_type_class
-sh_elf_reloc_type_class (type)
-     int type;
+sh_elf_reloc_type_class (rela)
+     const Elf_Internal_Rela *rela;
 {
-  switch (type)
+  switch ((int) ELF32_R_TYPE (rela->r_info))
     {
     case R_SH_RELATIVE:
       return reloc_class_relative;
This page took 0.034263 seconds and 4 git commands to generate.