Add support to GDB for the Renesas rl78 architecture.
[external/binutils.git] / bfd / elf32-hppa.c
index b7d951b..dcf6df0 100644 (file)
@@ -155,8 +155,8 @@ static const bfd_byte plt_stub[] =
 };
 
 /* Section name for stubs is the associated section name plus this
-   string.  PR 13049: Use a name that is not a valid C identifier.  */
-#define STUB_SUFFIX ".__stub"
+   string.  */
+#define STUB_SUFFIX ".stub"
 
 /* We don't need to copy certain PC- or GP-relative dynamic relocs
    into a shared object's dynamic section.  All the relocs of the
@@ -1789,10 +1789,12 @@ elf32_hppa_hide_symbol (struct bfd_link_info *info,
        }
     }
 
-  if (! hppa_elf_hash_entry (eh)->plabel)
+  /* STT_GNU_IFUNC symbol must go through PLT.  */
+  if (! hppa_elf_hash_entry (eh)->plabel
+      && eh->type != STT_GNU_IFUNC)
     {
       eh->needs_plt = 0;
-      eh->plt = elf_hash_table (info)->init_plt_refcount;
+      eh->plt = elf_hash_table (info)->init_plt_offset;
     }
 }
 
@@ -1814,6 +1816,13 @@ elf32_hppa_adjust_dynamic_symbol (struct bfd_link_info *info,
   if (eh->type == STT_FUNC
       || eh->needs_plt)
     {
+      /* If the symbol is used by a plabel, we must allocate a PLT slot.
+        The refcounts are not reliable when it has been hidden since
+        hide_symbol can be called before the plabel flag is set.  */
+      if (hppa_elf_hash_entry (eh)->plabel
+         && eh->plt.refcount <= 0)
+       eh->plt.refcount = 1;
+
       if (eh->plt.refcount <= 0
          || (eh->def_regular
              && eh->root.type != bfd_link_hash_defweak
@@ -3340,10 +3349,16 @@ final_link_relocate (asection *input_section,
       switch (r_type)
        {
          case R_PARISC_DLTIND21L:
+         case R_PARISC_TLS_GD21L:
+         case R_PARISC_TLS_LDM21L:
+         case R_PARISC_TLS_IE21L:
            r_type = R_PARISC_DPREL21L;
            break;
 
          case R_PARISC_DLTIND14R:
+         case R_PARISC_TLS_GD14R:
+         case R_PARISC_TLS_LDM14R:
+         case R_PARISC_TLS_IE14R:
            r_type = R_PARISC_DPREL14R;
            break;
 
@@ -3409,53 +3424,48 @@ final_link_relocate (asection *input_section,
     case R_PARISC_DPREL21L:
     case R_PARISC_DPREL14R:
     case R_PARISC_DPREL14F:
-    case R_PARISC_TLS_GD21L:
-    case R_PARISC_TLS_LDM21L:
-    case R_PARISC_TLS_IE21L:
       /* Convert instructions that use the linkage table pointer (r19) to
         instructions that use the global data pointer (dp).  This is the
         most efficient way of using PIC code in an incomplete executable,
         but the user must follow the standard runtime conventions for
         accessing data for this to work.  */
-      if (orig_r_type == R_PARISC_DLTIND21L
-         || (!info->shared
-             && (r_type == R_PARISC_TLS_GD21L
-                 || r_type == R_PARISC_TLS_LDM21L
-                 || r_type == R_PARISC_TLS_IE21L)))
+      if (orig_r_type != r_type)
        {
-         /* Convert addil instructions if the original reloc was a
-            DLTIND21L.  GCC sometimes uses a register other than r19 for
-            the operation, so we must convert any addil instruction
-            that uses this relocation.  */
-         if ((insn & 0xfc000000) == ((int) OP_ADDIL << 26))
-           insn = ADDIL_DP;
-         else
-           /* We must have a ldil instruction.  It's too hard to find
-              and convert the associated add instruction, so issue an
-              error.  */
-           (*_bfd_error_handler)
-             (_("%B(%A+0x%lx): %s fixup for insn 0x%x is not supported in a non-shared link"),
-              input_bfd,
-              input_section,
-              (long) offset,
-              howto->name,
-              insn);
-       }
-      else if (orig_r_type == R_PARISC_DLTIND14F)
-       {
-         /* This must be a format 1 load/store.  Change the base
-            register to dp.  */
-         insn = (insn & 0xfc1ffff) | (27 << 21);
+         if (r_type == R_PARISC_DPREL21L)
+           {
+             /* GCC sometimes uses a register other than r19 for the
+                operation, so we must convert any addil instruction
+                that uses this relocation.  */
+             if ((insn & 0xfc000000) == ((int) OP_ADDIL << 26))
+               insn = ADDIL_DP;
+             else
+               /* We must have a ldil instruction.  It's too hard to find
+                  and convert the associated add instruction, so issue an
+                  error.  */
+               (*_bfd_error_handler)
+                 (_("%B(%A+0x%lx): %s fixup for insn 0x%x is not supported in a non-shared link"),
+                  input_bfd,
+                  input_section,
+                  (long) offset,
+                  howto->name,
+                  insn);
+           }
+         else if (r_type == R_PARISC_DPREL14F)
+           {
+             /* This must be a format 1 load/store.  Change the base
+                register to dp.  */
+             insn = (insn & 0xfc1ffff) | (27 << 21);
+           }
        }
 
-    /* For all the DP relative relocations, we need to examine the symbol's
-       section.  If it has no section or if it's a code section, then
-       "data pointer relative" makes no sense.  In that case we don't
-       adjust the "value", and for 21 bit addil instructions, we change the
-       source addend register from %dp to %r0.  This situation commonly
-       arises for undefined weak symbols and when a variable's "constness"
-       is declared differently from the way the variable is defined.  For
-       instance: "extern int foo" with foo defined as "const int foo".  */
+      /* For all the DP relative relocations, we need to examine the symbol's
+        section.  If it has no section or if it's a code section, then
+        "data pointer relative" makes no sense.  In that case we don't
+        adjust the "value", and for 21 bit addil instructions, we change the
+        source addend register from %dp to %r0.  This situation commonly
+        arises for undefined weak symbols and when a variable's "constness"
+        is declared differently from the way the variable is defined.  For
+        instance: "extern int foo" with foo defined as "const int foo".  */
       if (sym_sec == NULL || (sym_sec->flags & SEC_CODE) != 0)
        {
          if ((insn & ((0x3f << 26) | (0x1f << 21)))
@@ -3472,6 +3482,9 @@ final_link_relocate (asection *input_section,
     case R_PARISC_DLTIND21L:
     case R_PARISC_DLTIND14R:
     case R_PARISC_DLTIND14F:
+    case R_PARISC_TLS_GD21L:
+    case R_PARISC_TLS_LDM21L:
+    case R_PARISC_TLS_IE21L:
     case R_PARISC_TLS_GD14R:
     case R_PARISC_TLS_LDM14R:
     case R_PARISC_TLS_IE14R: