Add support to GDB for the Renesas rl78 architecture.
[external/binutils.git] / bfd / elf32-hppa.c
index 5142d3c..dcf6df0 100644 (file)
@@ -1,6 +1,6 @@
 /* BFD back-end for HP PA-RISC ELF files.
    Copyright 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1999, 2000, 2001,
-   2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010
+   2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011
    Free Software Foundation, Inc.
 
    Original code by
@@ -336,15 +336,6 @@ struct elf32_hppa_link_hash_table
 #define eh_name(eh) \
   (eh ? eh->root.root.string : "<undef>")
 
-/* Override the generic function because we want to mark our BFDs.  */
-
-static bfd_boolean
-elf32_hppa_mkobject (bfd *abfd)
-{
-  return bfd_elf_allocate_object (abfd, sizeof (struct elf_obj_tdata),
-                                 HPPA32_ELF_DATA);
-}
-
 /* Assorted hash table functions.  */
 
 /* Initialize an entry in the stub hash table.  */
@@ -959,9 +950,9 @@ elf32_hppa_object_p (bfd *abfd)
   i_ehdrp = elf_elfheader (abfd);
   if (strcmp (bfd_get_target (abfd), "elf32-hppa-linux") == 0)
     {
-      /* GCC on hppa-linux produces binaries with OSABI=Linux,
+      /* GCC on hppa-linux produces binaries with OSABI=GNU,
         but the kernel produces corefiles with OSABI=SysV.  */
-      if (i_ehdrp->e_ident[EI_OSABI] != ELFOSABI_LINUX &&
+      if (i_ehdrp->e_ident[EI_OSABI] != ELFOSABI_GNU &&
          i_ehdrp->e_ident[EI_OSABI] != ELFOSABI_NONE) /* aka SYSV */
        return FALSE;
     }
@@ -1160,7 +1151,6 @@ elf32_hppa_check_relocs (bfd *abfd,
   const Elf_Internal_Rela *rela_end;
   struct elf32_hppa_link_hash_table *htab;
   asection *sreloc;
-  asection *stubreloc;
   int tls_type = GOT_UNKNOWN, old_tls_type = GOT_UNKNOWN;
 
   if (info->relocatable)
@@ -1172,7 +1162,6 @@ elf32_hppa_check_relocs (bfd *abfd,
   symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
   eh_syms = elf_sym_hashes (abfd);
   sreloc = NULL;
-  stubreloc = NULL;
 
   rela_end = relocs + sec->reloc_count;
   for (rela = relocs; rela < rela_end; rela++)
@@ -1738,7 +1727,7 @@ elf32_hppa_grok_prstatus (bfd *abfd, Elf_Internal_Note *note)
        elf_tdata (abfd)->core_signal = bfd_get_16 (abfd, note->descdata + 12);
 
        /* pr_pid */
-       elf_tdata (abfd)->core_pid = bfd_get_32 (abfd, note->descdata + 24);
+       elf_tdata (abfd)->core_lwpid = bfd_get_32 (abfd, note->descdata + 24);
 
        /* pr_reg */
        offset = 72;
@@ -1800,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;
     }
 }
 
@@ -1825,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
@@ -1949,9 +1947,6 @@ allocate_plt_static (struct elf_link_hash_entry *eh, void *inf)
   if (eh->root.type == bfd_link_hash_indirect)
     return TRUE;
 
-  if (eh->root.type == bfd_link_hash_warning)
-    eh = (struct elf_link_hash_entry *) eh->root.u.i.link;
-
   info = (struct bfd_link_info *) inf;
   hh = hppa_elf_hash_entry (eh);
   htab = hppa_link_hash_table (info);
@@ -2019,9 +2014,6 @@ allocate_dynrelocs (struct elf_link_hash_entry *eh, void *inf)
   if (eh->root.type == bfd_link_hash_indirect)
     return TRUE;
 
-  if (eh->root.type == bfd_link_hash_warning)
-    eh = (struct elf_link_hash_entry *) eh->root.u.i.link;
-
   info = inf;
   htab = hppa_link_hash_table (info);
   if (htab == NULL)
@@ -2181,9 +2173,6 @@ static bfd_boolean
 clobber_millicode_symbols (struct elf_link_hash_entry *eh,
                           struct bfd_link_info *info)
 {
-  if (eh->root.type == bfd_link_hash_warning)
-    eh = (struct elf_link_hash_entry *) eh->root.u.i.link;
-
   if (eh->type == STT_PARISC_MILLI
       && !eh->forced_local)
     {
@@ -2200,9 +2189,6 @@ readonly_dynrelocs (struct elf_link_hash_entry *eh, void *inf)
   struct elf32_hppa_link_hash_entry *hh;
   struct elf32_hppa_dyn_reloc_entry *hdh_p;
 
-  if (eh->root.type == bfd_link_hash_warning)
-    eh = (struct elf_link_hash_entry *) eh->root.u.i.link;
-
   hh = hppa_elf_hash_entry (eh);
   for (hdh_p = hh->dyn_relocs; hdh_p != NULL; hdh_p = hdh_p->hdh_next)
     {
@@ -3363,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;
 
@@ -3432,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)))
@@ -3495,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:
@@ -3752,17 +3742,10 @@ elf32_hppa_relocate_section (bfd *output_bfd,
        }
 
       if (sym_sec != NULL && elf_discarded_section (sym_sec))
-       {
-         /* For relocs against symbols from removed linkonce
-            sections, or sections discarded by a linker script,
-            we just want the section contents zeroed.  Avoid any
-            special processing.  */
-         _bfd_clear_contents (elf_hppa_howto_table + r_type, input_bfd,
-                              contents + rela->r_offset);
-         rela->r_info = 0;
-         rela->r_addend = 0;
-         continue;
-       }
+       RELOC_AGAINST_DISCARDED_SECTION (info, input_bfd, input_section,
+                                        rela, relend,
+                                        elf_hppa_howto_table + r_type,
+                                        contents);
 
       if (info->relocatable)
        continue;
@@ -4483,7 +4466,7 @@ static enum elf_reloc_type_class
 elf32_hppa_reloc_type_class (const Elf_Internal_Rela *rela)
 {
   /* Handle TLS relocs first; we don't want them to be marked
-     relative by the "if (ELF32_R_SYM (rela->r_info) == 0)"
+     relative by the "if (ELF32_R_SYM (rela->r_info) == STN_UNDEF)"
      check below.  */
   switch ((int) ELF32_R_TYPE (rela->r_info))
     {
@@ -4493,7 +4476,7 @@ elf32_hppa_reloc_type_class (const Elf_Internal_Rela *rela)
         return reloc_class_normal;
     }
 
-  if (ELF32_R_SYM (rela->r_info) == 0)
+  if (ELF32_R_SYM (rela->r_info) == STN_UNDEF)
     return reloc_class_relative;
 
   switch ((int) ELF32_R_TYPE (rela->r_info))
@@ -4516,6 +4499,7 @@ elf32_hppa_finish_dynamic_sections (bfd *output_bfd,
   bfd *dynobj;
   struct elf32_hppa_link_hash_table *htab;
   asection *sdyn;
+  asection * sgot;
 
   htab = hppa_link_hash_table (info);
   if (htab == NULL)
@@ -4523,6 +4507,12 @@ elf32_hppa_finish_dynamic_sections (bfd *output_bfd,
 
   dynobj = htab->etab.dynobj;
 
+  sgot = htab->sgot;
+  /* A broken linker script might have discarded the dynamic sections.
+     Catch this here so that we do not seg-fault later on.  */
+  if (sgot != NULL && bfd_is_abs_section (sgot->output_section))
+    return FALSE;
+
   sdyn = bfd_get_section_by_name (dynobj, ".dynamic");
 
   if (htab->etab.dynamic_sections_created)
@@ -4587,19 +4577,19 @@ elf32_hppa_finish_dynamic_sections (bfd *output_bfd,
        }
     }
 
-  if (htab->sgot != NULL && htab->sgot->size != 0)
+  if (sgot != NULL && sgot->size != 0)
     {
       /* Fill in the first entry in the global offset table.
         We use it to point to our dynamic section, if we have one.  */
       bfd_put_32 (output_bfd,
                  sdyn ? sdyn->output_section->vma + sdyn->output_offset : 0,
-                 htab->sgot->contents);
+                 sgot->contents);
 
       /* The second entry is reserved for use by the dynamic linker.  */
-      memset (htab->sgot->contents + GOT_ENTRY_SIZE, 0, GOT_ENTRY_SIZE);
+      memset (sgot->contents + GOT_ENTRY_SIZE, 0, GOT_ENTRY_SIZE);
 
       /* Set .got entry size.  */
-      elf_section_data (htab->sgot->output_section)
+      elf_section_data (sgot->output_section)
        ->this_hdr.sh_entsize = GOT_ENTRY_SIZE;
     }
 
@@ -4619,8 +4609,8 @@ elf32_hppa_finish_dynamic_sections (bfd *output_bfd,
          if ((htab->splt->output_offset
               + htab->splt->output_section->vma
               + htab->splt->size)
-             != (htab->sgot->output_offset
-                 + htab->sgot->output_section->vma))
+             != (sgot->output_offset
+                 + sgot->output_section->vma))
            {
              (*_bfd_error_handler)
                (_(".got section not immediately after .plt section"));
@@ -4651,7 +4641,6 @@ elf32_hppa_elf_get_symbol_type (Elf_Internal_Sym *elf_sym, int type)
 #define elf_info_to_howto_rel               elf_hppa_info_to_howto_rel
 
 /* Stuff for the BFD linker.  */
-#define bfd_elf32_mkobject                  elf32_hppa_mkobject
 #define bfd_elf32_bfd_final_link            elf32_hppa_final_link
 #define bfd_elf32_bfd_link_hash_table_create elf32_hppa_link_hash_table_create
 #define bfd_elf32_bfd_link_hash_table_free   elf32_hppa_link_hash_table_free
@@ -4689,6 +4678,7 @@ elf32_hppa_elf_get_symbol_type (Elf_Internal_Sym *elf_sym, int type)
 #define TARGET_BIG_SYM         bfd_elf32_hppa_vec
 #define TARGET_BIG_NAME                "elf32-hppa"
 #define ELF_ARCH               bfd_arch_hppa
+#define ELF_TARGET_ID          HPPA32_ELF_DATA
 #define ELF_MACHINE_CODE       EM_PARISC
 #define ELF_MAXPAGESIZE                0x1000
 #define ELF_OSABI              ELFOSABI_HPUX
@@ -4701,7 +4691,7 @@ elf32_hppa_elf_get_symbol_type (Elf_Internal_Sym *elf_sym, int type)
 #undef TARGET_BIG_NAME
 #define TARGET_BIG_NAME                "elf32-hppa-linux"
 #undef ELF_OSABI
-#define ELF_OSABI              ELFOSABI_LINUX
+#define ELF_OSABI              ELFOSABI_GNU
 #undef elf32_bed
 #define elf32_bed              elf32_hppa_linux_bed