RISC-V: Fix TLS copy relocs
[deliverable/binutils-gdb.git] / bfd / elfnn-riscv.c
index 69907bd241f103b7efbb1d2ea6e238032e2fe1fd..6d297cea7d73ca6ceb02d559c4a73bb5d3041780 100644 (file)
@@ -1,5 +1,5 @@
 /* RISC-V-specific support for NN-bit ELF.
-   Copyright 2011-2016 Free Software Foundation, Inc.
+   Copyright (C) 2011-2017 Free Software Foundation, Inc.
 
    Contributed by Andrew Waterman (andrew@sifive.com).
    Based on TILE-Gx and MIPS targets.
@@ -539,7 +539,7 @@ riscv_elf_check_relocs (bfd *abfd, struct bfd_link_info *info,
 
          /* PR15323, ref flags aren't set for references in the same
             object.  */
-         h->root.non_ir_ref = 1;
+         h->root.non_ir_ref_regular = 1;
        }
 
       switch (r_type)
@@ -965,7 +965,12 @@ riscv_elf_adjust_dynamic_symbol (struct bfd_link_info *info,
      to copy the initial value out of the dynamic object and into the
      runtime process image.  We need to remember the offset into the
      .rel.bss section we are going to use.  */
-  if ((h->root.u.def.section->flags & SEC_READONLY) != 0)
+  if (eh->tls_type & ~GOT_NORMAL)
+    {
+      s = htab->sdyntdata;
+      srel = htab->elf.srelbss;
+    }
+  else if ((h->root.u.def.section->flags & SEC_READONLY) != 0)
     {
       s = htab->elf.sdynrelro;
       srel = htab->elf.sreldynrelro;
@@ -981,9 +986,6 @@ riscv_elf_adjust_dynamic_symbol (struct bfd_link_info *info,
       h->needs_copy = 1;
     }
 
-  if (eh->tls_type & ~GOT_NORMAL)
-    return _bfd_elf_adjust_dynamic_copy (info, h, htab->sdyntdata);
-
   return _bfd_elf_adjust_dynamic_copy (info, h, s);
 }
 
@@ -1463,7 +1465,7 @@ riscv_global_pointer_value (struct bfd_link_info *info)
 {
   struct bfd_link_hash_entry *h;
 
-  h = bfd_link_hash_lookup (info->hash, "_gp", FALSE, FALSE, TRUE);
+  h = bfd_link_hash_lookup (info->hash, RISCV_GP_SYMBOL, FALSE, FALSE, TRUE);
   if (h == NULL || h->type != bfd_link_hash_defined)
     return 0;
 
@@ -1566,6 +1568,7 @@ perform_relocation (const reloc_howto_type *howto,
     case R_RISCV_SET8:
     case R_RISCV_SET16:
     case R_RISCV_SET32:
+    case R_RISCV_32_PCREL:
     case R_RISCV_TLS_DTPREL32:
     case R_RISCV_TLS_DTPREL64:
       break;
@@ -1849,6 +1852,7 @@ riscv_elf_relocate_section (bfd *output_bfd,
        case R_RISCV_SET8:
        case R_RISCV_SET16:
        case R_RISCV_SET32:
+       case R_RISCV_32_PCREL:
          /* These require no special handling beyond perform_relocation.  */
          break;
 
@@ -2408,7 +2412,7 @@ riscv_elf_finish_dynamic_symbol (bfd *output_bfd,
       rela.r_offset = sec_addr (h->root.u.def.section) + h->root.u.def.value;
       rela.r_info = ELFNN_R_INFO (h->dynindx, R_RISCV_COPY);
       rela.r_addend = 0;
-      if ((h->root.u.def.section->flags & SEC_READONLY) != 0)
+      if (h->root.u.def.section == htab->elf.sdynrelro)
        s = htab->elf.sreldynrelro;
       else
        s = htab->elf.srelbss;
@@ -2489,7 +2493,7 @@ riscv_elf_finish_dynamic_sections (bfd *output_bfd,
 
       ret = riscv_finish_dyn (output_bfd, info, dynobj, sdyn);
 
-      if (ret != TRUE)
+      if (!ret)
        return ret;
 
       /* Fill in the head and tail entries in the procedure linkage table.  */
@@ -2502,10 +2506,10 @@ riscv_elf_finish_dynamic_sections (bfd *output_bfd,
 
          for (i = 0; i < PLT_HEADER_INSNS; i++)
            bfd_put_32 (output_bfd, plt_header[i], splt->contents + 4*i);
-       }
 
-      elf_section_data (splt->output_section)->this_hdr.sh_entsize
-       = PLT_ENTRY_SIZE;
+         elf_section_data (splt->output_section)->this_hdr.sh_entsize
+           = PLT_ENTRY_SIZE;
+       }
     }
 
   if (htab->elf.sgotplt)
@@ -2809,6 +2813,17 @@ _bfd_riscv_relax_lui (bfd *abfd,
 
   BFD_ASSERT (rel->r_offset + 4 <= sec->size);
 
+  if (gp)
+    {
+      /* If gp and the symbol are in the same output section, then
+        consider only that section's alignment.  */
+      struct bfd_link_hash_entry *h =
+       bfd_link_hash_lookup (link_info->hash, RISCV_GP_SYMBOL, FALSE, FALSE,
+                             TRUE);
+      if (h->u.def.section->output_section == sym_sec->output_section)
+       max_alignment = (bfd_vma) 1 << sym_sec->output_section->alignment_power;
+    }
+
   /* Is the reference in range of x0 or gp?
      Valid gp range conservatively because of alignment issue.  */
   if (VALID_ITYPE_IMM (symval)
@@ -3191,6 +3206,19 @@ riscv_elf_grok_psinfo (bfd *abfd, Elf_Internal_Note *note)
   return TRUE;
 }
 
+/* Set the right mach type.  */
+static bfd_boolean
+riscv_elf_object_p (bfd *abfd)
+{
+  /* There are only two mach types in RISCV currently.  */
+  if (strcmp (abfd->xvec->name, "elf32-littleriscv") == 0)
+    bfd_default_set_arch_mach (abfd, bfd_arch_riscv, bfd_mach_riscv32);
+  else
+    bfd_default_set_arch_mach (abfd, bfd_arch_riscv, bfd_mach_riscv64);
+
+  return TRUE;
+}
+
 
 #define TARGET_LITTLE_SYM              riscv_elfNN_vec
 #define TARGET_LITTLE_NAME             "elfNN-littleriscv"
@@ -3216,6 +3244,7 @@ riscv_elf_grok_psinfo (bfd *abfd, Elf_Internal_Note *note)
 #define elf_backend_plt_sym_val                     riscv_elf_plt_sym_val
 #define elf_backend_grok_prstatus            riscv_elf_grok_prstatus
 #define elf_backend_grok_psinfo              riscv_elf_grok_psinfo
+#define elf_backend_object_p                 riscv_elf_object_p
 #define elf_info_to_howto_rel               NULL
 #define elf_info_to_howto                   riscv_info_to_howto_rela
 #define bfd_elfNN_bfd_relax_section         _bfd_riscv_relax_section
This page took 0.024953 seconds and 4 git commands to generate.