* elf32-sparc.c (_bfd_sparc_elf_howto_table): Fix dst_mask for
[deliverable/binutils-gdb.git] / bfd / elf64-sparc.c
index d636a20943102031784c635894d5e0fdc4141aba..07c78bc9eba8fafeb12239695b5185d48344428b 100644 (file)
@@ -116,7 +116,7 @@ static reloc_howto_type sparc64_elf_howto_table[] =
   HOWTO(R_SPARC_32,        0,2,32,false,0,complain_overflow_bitfield,bfd_elf_generic_reloc,  "R_SPARC_32",      false,0,0xffffffff,true),
   HOWTO(R_SPARC_DISP8,     0,0, 8,true, 0,complain_overflow_signed,  bfd_elf_generic_reloc,  "R_SPARC_DISP8",   false,0,0x000000ff,true),
   HOWTO(R_SPARC_DISP16,    0,1,16,true, 0,complain_overflow_signed,  bfd_elf_generic_reloc,  "R_SPARC_DISP16",  false,0,0x0000ffff,true),
-  HOWTO(R_SPARC_DISP32,    0,2,32,true, 0,complain_overflow_signed,  bfd_elf_generic_reloc,  "R_SPARC_DISP32",  false,0,0x00ffffff,true),
+  HOWTO(R_SPARC_DISP32,    0,2,32,true, 0,complain_overflow_signed,  bfd_elf_generic_reloc,  "R_SPARC_DISP32",  false,0,0xffffffff,true),
   HOWTO(R_SPARC_WDISP30,   2,2,30,true, 0,complain_overflow_signed,  bfd_elf_generic_reloc,  "R_SPARC_WDISP30", false,0,0x3fffffff,true),
   HOWTO(R_SPARC_WDISP22,   2,2,22,true, 0,complain_overflow_signed,  bfd_elf_generic_reloc,  "R_SPARC_WDISP22", false,0,0x003fffff,true),
   HOWTO(R_SPARC_HI22,     10,2,22,false,0,complain_overflow_dont,    bfd_elf_generic_reloc,  "R_SPARC_HI22",    false,0,0x003fffff,true),
@@ -135,8 +135,8 @@ static reloc_howto_type sparc64_elf_howto_table[] =
   HOWTO(R_SPARC_RELATIVE,  0,0,00,false,0,complain_overflow_dont,    bfd_elf_generic_reloc,  "R_SPARC_RELATIVE",false,0,0x00000000,true),
   HOWTO(R_SPARC_UA32,      0,2,32,false,0,complain_overflow_bitfield,bfd_elf_generic_reloc,  "R_SPARC_UA32",    false,0,0xffffffff,true),
 #ifndef SPARC64_OLD_RELOCS
+  HOWTO(R_SPARC_PLT32,     0,2,32,false,0,complain_overflow_bitfield,bfd_elf_generic_reloc,  "R_SPARC_PLT32",   false,0,0xffffffff,true),
   /* These aren't implemented yet.  */
-  HOWTO(R_SPARC_PLT32,     0,0,00,false,0,complain_overflow_dont,    sparc_elf_notsup_reloc, "R_SPARC_PLT32",    false,0,0x00000000,true),
   HOWTO(R_SPARC_HIPLT22,   0,0,00,false,0,complain_overflow_dont,    sparc_elf_notsup_reloc, "R_SPARC_HIPLT22",  false,0,0x00000000,true),
   HOWTO(R_SPARC_LOPLT10,   0,0,00,false,0,complain_overflow_dont,    sparc_elf_notsup_reloc, "R_SPARC_LOPLT10",  false,0,0x00000000,true),
   HOWTO(R_SPARC_PCPLT32,   0,0,00,false,0,complain_overflow_dont,    sparc_elf_notsup_reloc, "R_SPARC_PCPLT32",  false,0,0x00000000,true),
@@ -160,7 +160,7 @@ static reloc_howto_type sparc64_elf_howto_table[] =
   HOWTO(R_SPARC_5,         0,2, 5,false,0,complain_overflow_bitfield,bfd_elf_generic_reloc,  "R_SPARC_5",       false,0,0x0000001f,true),
   HOWTO(R_SPARC_6,         0,2, 6,false,0,complain_overflow_bitfield,bfd_elf_generic_reloc,  "R_SPARC_6",       false,0,0x0000003f,true),
   HOWTO(R_SPARC_DISP64,    0,4,64,true, 0,complain_overflow_signed,  bfd_elf_generic_reloc,  "R_SPARC_DISP64",  false,0,MINUS_ONE, true),
-  HOWTO(R_SPARC_PLT64,     0,4,64,false,0,complain_overflow_bitfield,sparc_elf_notsup_reloc, "R_SPARC_PLT64",   false,0,MINUS_ONE, false),
+  HOWTO(R_SPARC_PLT64,     0,4,64,false,0,complain_overflow_bitfield,bfd_elf_generic_reloc,  "R_SPARC_PLT64",   false,0,MINUS_ONE, true),
   HOWTO(R_SPARC_HIX22,     0,4, 0,false,0,complain_overflow_bitfield,sparc_elf_hix22_reloc,  "R_SPARC_HIX22",   false,0,MINUS_ONE, false),
   HOWTO(R_SPARC_LOX10,     0,4, 0,false,0,complain_overflow_dont,    sparc_elf_lox10_reloc,  "R_SPARC_LOX10",   false,0,MINUS_ONE, false),
   HOWTO(R_SPARC_H44,      22,2,22,false,0,complain_overflow_unsigned,bfd_elf_generic_reloc,  "R_SPARC_H44",     false,0,0x003fffff,false),
@@ -180,6 +180,7 @@ static const struct elf_reloc_map sparc_reloc_map[] =
 {
   { BFD_RELOC_NONE, R_SPARC_NONE, },
   { BFD_RELOC_16, R_SPARC_16, },
+  { BFD_RELOC_16_PCREL, R_SPARC_DISP16 },
   { BFD_RELOC_8, R_SPARC_8 },
   { BFD_RELOC_8_PCREL, R_SPARC_DISP8 },
   { BFD_RELOC_CTOR, R_SPARC_64 },
@@ -188,6 +189,7 @@ static const struct elf_reloc_map sparc_reloc_map[] =
   { BFD_RELOC_HI22, R_SPARC_HI22 },
   { BFD_RELOC_LO10, R_SPARC_LO10, },
   { BFD_RELOC_32_PCREL_S2, R_SPARC_WDISP30 },
+  { BFD_RELOC_64_PCREL, R_SPARC_DISP64 },
   { BFD_RELOC_SPARC22, R_SPARC_22 },
   { BFD_RELOC_SPARC13, R_SPARC_13 },
   { BFD_RELOC_SPARC_GOT10, R_SPARC_GOT10 },
@@ -220,6 +222,9 @@ static const struct elf_reloc_map sparc_reloc_map[] =
   { BFD_RELOC_SPARC_5, R_SPARC_5 },
   { BFD_RELOC_SPARC_6, R_SPARC_6 },
   { BFD_RELOC_SPARC_DISP64, R_SPARC_DISP64 },
+#ifndef SPARC64_OLD_RELOCS
+  { BFD_RELOC_SPARC_PLT32, R_SPARC_PLT32 },
+#endif
   { BFD_RELOC_SPARC_PLT64, R_SPARC_PLT64 },
   { BFD_RELOC_SPARC_HIX22, R_SPARC_HIX22 },
   { BFD_RELOC_SPARC_LOX10, R_SPARC_LOX10 },
@@ -1167,8 +1172,10 @@ sparc64_elf_check_relocs (abfd, info, sec, relocs)
            }
 
          h->elf_link_hash_flags |= ELF_LINK_HASH_NEEDS_PLT;
-         break;
-
+         if (ELF64_R_TYPE_ID (rel->r_info) != R_SPARC_PLT32
+             && ELF64_R_TYPE_ID (rel->r_info) != R_SPARC_PLT64)
+           break;
+         /* Fall through.  */
        case R_SPARC_PC10:
        case R_SPARC_PC22:
        case R_SPARC_PC_HH22:
@@ -1929,6 +1936,7 @@ sparc64_elf_relocate_section (output_bfd, info, input_bfd, input_section,
       asection *sec;
       bfd_vma relocation;
       bfd_reloc_status_type r;
+      boolean is_plt = false;
 
       r_type = ELF64_R_TYPE_ID (rel->r_info);
       if (r_type < 0 || r_type >= (int) R_SPARC_max_std)
@@ -2105,6 +2113,7 @@ sparc64_elf_relocate_section (output_bfd, info, input_bfd, input_section,
            }
        }
 
+do_dynreloc:
       /* When generating a shared object, these relocations are copied
         into the output file to be resolved at run time.  */
       if (info->shared && r_symndx != 0 && (input_section->flags & SEC_ALLOC))
@@ -2219,7 +2228,7 @@ sparc64_elf_relocate_section (output_bfd, info, input_bfd, input_section,
                  memset (&outrel, 0, sizeof outrel);
                /* h->dynindx may be -1 if the symbol was marked to
                   become local.  */
-               else if (h != NULL
+               else if (h != NULL && ! is_plt
                         && ((! info->symbolic && h->dynindx != -1)
                             || (h->elf_link_hash_flags
                                 & ELF_LINK_HASH_DEF_REGULAR) == 0))
@@ -2243,7 +2252,9 @@ sparc64_elf_relocate_section (output_bfd, info, input_bfd, input_section,
                      {
                        long indx;
 
-                       if (h == NULL)
+                       if (is_plt)
+                         sec = splt;
+                       else if (h == NULL)
                          sec = local_sections[r_symndx];
                        else
                          {
@@ -2433,6 +2444,12 @@ sparc64_elf_relocate_section (output_bfd, info, input_bfd, input_section,
                        + sparc64_elf_plt_entry_offset (h->plt.offset));
          if (r_type == R_SPARC_WPLT30)
            goto do_wplt30;
+         if (r_type == R_SPARC_PLT32 || r_type == R_SPARC_PLT64)
+           {
+             r_type = r_type == R_SPARC_PLT32 ? R_SPARC_32 : R_SPARC_64;
+             is_plt = true;
+             goto do_dynreloc;
+           }
          goto do_default;
 
        case R_SPARC_OLO10:
This page took 0.038776 seconds and 4 git commands to generate.