Run --gc-sections tests only if supported.
[deliverable/binutils-gdb.git] / bfd / elf32-hppa.c
index babe9f20a21815ca2c6283ed608e28cffe8b750f..7f0f2cb10e8608497281ed4eec4e2f4075df8e21 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
+   2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011
    Free Software Foundation, Inc.
 
    Original code by
@@ -314,7 +314,8 @@ struct elf32_hppa_link_hash_table
 
 /* Various hash macros and functions.  */
 #define hppa_link_hash_table(p) \
-  ((struct elf32_hppa_link_hash_table *) ((p)->hash))
+  (elf_hash_table_id ((struct elf_link_hash_table *) ((p)->hash)) \
+  == HPPA32_ELF_DATA ? ((struct elf32_hppa_link_hash_table *) ((p)->hash)) : NULL)
 
 #define hppa_elf_hash_entry(ent) \
   ((struct elf32_hppa_link_hash_entry *)(ent))
@@ -335,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),
-                                 HPPA_ELF_TDATA);
-}
-
 /* Assorted hash table functions.  */
 
 /* Initialize an entry in the stub hash table.  */
@@ -432,7 +424,8 @@ elf32_hppa_link_hash_table_create (bfd *abfd)
     return NULL;
 
   if (!_bfd_elf_link_hash_table_init (&htab->etab, abfd, hppa_link_hash_newfunc,
-                                     sizeof (struct elf32_hppa_link_hash_entry)))
+                                     sizeof (struct elf32_hppa_link_hash_entry),
+                                     HPPA32_ELF_DATA))
     {
       free (htab);
       return NULL;
@@ -728,6 +721,9 @@ hppa_build_one_stub (struct bfd_hash_entry *bh, void *in_arg)
   info = (struct bfd_link_info *)in_arg;
 
   htab = hppa_link_hash_table (info);
+  if (htab == NULL)
+    return FALSE;
+
   stub_sec = hsh->stub_sec;
 
   /* Make a note of the offset within the stubs for this entry.  */
@@ -954,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;
     }
@@ -1000,6 +996,8 @@ elf32_hppa_create_dynamic_sections (bfd *abfd, struct bfd_link_info *info)
 
   /* Don't try to create the .plt and .got twice.  */
   htab = hppa_link_hash_table (info);
+  if (htab == NULL)
+    return FALSE;
   if (htab->splt != NULL)
     return TRUE;
 
@@ -1153,17 +1151,17 @@ 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)
     return TRUE;
 
   htab = hppa_link_hash_table (info);
+  if (htab == NULL)
+    return FALSE;
   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++)
@@ -1369,7 +1367,7 @@ elf32_hppa_check_relocs (bfd *abfd,
 
          if (r_type == R_PARISC_TLS_LDM21L
              || r_type == R_PARISC_TLS_LDM14R)
-           hppa_link_hash_table (info)->tls_ldm_got.refcount += 1;
+           htab->tls_ldm_got.refcount += 1;
          else
            {
              if (hh != NULL)
@@ -1601,10 +1599,15 @@ elf32_hppa_gc_sweep_hook (bfd *abfd,
   bfd_signed_vma *local_got_refcounts;
   bfd_signed_vma *local_plt_refcounts;
   const Elf_Internal_Rela *rela, *relend;
+  struct elf32_hppa_link_hash_table *htab;
 
   if (info->relocatable)
     return TRUE;
 
+  htab = hppa_link_hash_table (info);
+  if (htab == NULL)
+    return FALSE;
+
   elf_section_data (sec)->local_dynrel = NULL;
 
   symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
@@ -1669,7 +1672,7 @@ elf32_hppa_gc_sweep_hook (bfd *abfd,
 
        case R_PARISC_TLS_LDM21L:
        case R_PARISC_TLS_LDM14R:
-         hppa_link_hash_table (info)->tls_ldm_got.refcount -= 1;
+         htab->tls_ldm_got.refcount -= 1;
          break;
 
        case R_PARISC_PCREL12F:
@@ -1724,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;
@@ -1904,6 +1907,8 @@ elf32_hppa_adjust_dynamic_symbol (struct bfd_link_info *info,
      same memory location for the variable.  */
 
   htab = hppa_link_hash_table (info);
+  if (htab == NULL)
+    return FALSE;
 
   /* We must generate a COPY reloc to tell the dynamic linker to
      copy the initial value out of the dynamic object and into the
@@ -1933,12 +1938,12 @@ 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);
+  if (htab == NULL)
+    return FALSE;
+
   if (htab->etab.dynamic_sections_created
       && eh->plt.refcount > 0)
     {
@@ -2000,11 +2005,11 @@ 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)
+    return FALSE;
+
   hh = hppa_elf_hash_entry (eh);
   
   if (htab->etab.dynamic_sections_created
@@ -2159,9 +2164,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)
     {
@@ -2178,9 +2180,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)
     {
@@ -2212,6 +2211,9 @@ elf32_hppa_size_dynamic_sections (bfd *output_bfd ATTRIBUTE_UNUSED,
   bfd_boolean relocs;
 
   htab = hppa_link_hash_table (info);
+  if (htab == NULL)
+    return FALSE;
+
   dynobj = htab->etab.dynobj;
   if (dynobj == NULL)
     abort ();
@@ -2505,6 +2507,9 @@ elf32_hppa_setup_section_lists (bfd *output_bfd, struct bfd_link_info *info)
   bfd_size_type amt;
   struct elf32_hppa_link_hash_table *htab = hppa_link_hash_table (info);
 
+  if (htab == NULL)
+    return -1;
+
   /* Count the number of input BFDs and find the top input section id.  */
   for (input_bfd = info->input_bfds, bfd_count = 0, top_id = 0;
        input_bfd != NULL;
@@ -2572,6 +2577,9 @@ elf32_hppa_next_input_section (struct bfd_link_info *info, asection *isec)
 {
   struct elf32_hppa_link_hash_table *htab = hppa_link_hash_table (info);
 
+  if (htab == NULL)
+    return;
+
   if (isec->output_section->index <= htab->top_index)
     {
       asection **list = htab->input_list + isec->output_section->index;
@@ -2679,6 +2687,9 @@ get_local_syms (bfd *output_bfd, bfd *input_bfd, struct bfd_link_info *info)
   int stub_changed = 0;
   struct elf32_hppa_link_hash_table *htab = hppa_link_hash_table (info);
 
+  if (htab == NULL)
+    return -1;
+
   /* We want to read in symbol extension records only once.  To do this
      we need to read in the local symbols in parallel and save them for
      later use; so hold pointers to the local symbols in an array.  */
@@ -2807,6 +2818,9 @@ elf32_hppa_size_stubs
   bfd_boolean stub_changed;
   struct elf32_hppa_link_hash_table *htab = hppa_link_hash_table (info);
 
+  if (htab == NULL)
+    return FALSE;
+
   /* Stash our params away.  */
   htab->stub_bfd = stub_bfd;
   htab->multi_subspace = multi_subspace;
@@ -3092,6 +3106,9 @@ elf32_hppa_set_gp (bfd *abfd, struct bfd_link_info *info)
   struct elf32_hppa_link_hash_table *htab;
 
   htab = hppa_link_hash_table (info);
+  if (htab == NULL)
+    return FALSE;
+
   h = bfd_link_hash_lookup (&htab->etab.root, "$global$", FALSE, FALSE, FALSE);
 
   if (h != NULL
@@ -3176,6 +3193,8 @@ elf32_hppa_build_stubs (struct bfd_link_info *info)
   struct elf32_hppa_link_hash_table *htab;
 
   htab = hppa_link_hash_table (info);
+  if (htab == NULL)
+    return FALSE;
 
   for (stub_sec = htab->stub_bfd->sections;
        stub_sec != NULL;
@@ -3252,6 +3271,8 @@ hppa_record_segment_addr (bfd *abfd, asection *section, void *data)
   struct elf32_hppa_link_hash_table *htab;
 
   htab = (struct elf32_hppa_link_hash_table*) data;
+  if (htab == NULL)
+    return;
 
   if ((section->flags & (SEC_ALLOC | SEC_LOAD)) == (SEC_ALLOC | SEC_LOAD))
     {
@@ -3633,6 +3654,9 @@ elf32_hppa_relocate_section (bfd *output_bfd,
   symtab_hdr = &elf_tdata (input_bfd)->symtab_hdr;
 
   htab = hppa_link_hash_table (info);
+  if (htab == NULL)
+    return FALSE;
+
   local_got_offsets = elf_local_got_offsets (input_bfd);
 
   rela = relocs;
@@ -3705,17 +3729,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;
@@ -4300,6 +4317,8 @@ elf32_hppa_finish_dynamic_symbol (bfd *output_bfd,
   bfd_byte *loc;
 
   htab = hppa_link_hash_table (info);
+  if (htab == NULL)
+    return FALSE;
 
   if (eh->plt.offset != (bfd_vma) -1)
     {
@@ -4434,7 +4453,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))
     {
@@ -4444,7 +4463,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))
@@ -4467,10 +4486,20 @@ 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)
+    return FALSE;
+
   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)
@@ -4535,19 +4564,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;
     }
 
@@ -4567,8 +4596,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"));
@@ -4599,7 +4628,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
@@ -4637,6 +4665,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
@@ -4649,7 +4678,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
 
This page took 0.028554 seconds and 4 git commands to generate.