PR binutils/14567
[deliverable/binutils-gdb.git] / bfd / elf64-hppa.c
index 957e61a000c9efab8ee7673e0b5fd95f83854649..62efef3979dc2912a5669bb56464ace20d9b552e 100644 (file)
@@ -1,6 +1,7 @@
 /* Support for HPPA 64-bit ELF
    1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009,
-   2010  Free Software Foundation, Inc.
+   2010, 2011, 2012
+   Free Software Foundation, Inc.
 
    This file is part of BFD, the Binary File Descriptor library.
 
@@ -19,8 +20,8 @@
    Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
    MA 02110-1301, USA.  */
 
-#include "alloca-conf.h"
 #include "sysdep.h"
+#include "alloca-conf.h"
 #include "bfd.h"
 #include "libbfd.h"
 #include "elf-bfd.h"
@@ -329,9 +330,9 @@ elf64_hppa_object_p (bfd *abfd)
   i_ehdrp = elf_elfheader (abfd);
   if (strcmp (bfd_get_target (abfd), "elf64-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;
     }
@@ -371,8 +372,6 @@ elf64_hppa_section_from_shdr (bfd *abfd,
                              const char *name,
                              int shindex)
 {
-  asection *newsect;
-
   switch (hdr->sh_type)
     {
     case SHT_PARISC_EXT:
@@ -391,7 +390,6 @@ elf64_hppa_section_from_shdr (bfd *abfd,
 
   if (! _bfd_elf_make_section_from_shdr (abfd, hdr, name, shindex))
     return FALSE;
-  newsect = hdr->bfd_section;
 
   return TRUE;
 }
@@ -410,31 +408,24 @@ get_reloc_section (bfd *abfd,
 
   srel_name = (bfd_elf_string_from_elf_section
               (abfd, elf_elfheader(abfd)->e_shstrndx,
-               elf_section_data(sec)->rel_hdr.sh_name));
+               _bfd_elf_single_rel_hdr(sec)->sh_name));
   if (srel_name == NULL)
     return FALSE;
 
-  BFD_ASSERT ((CONST_STRNEQ (srel_name, ".rela")
-              && strcmp (bfd_get_section_name (abfd, sec),
-                         srel_name + 5) == 0)
-             || (CONST_STRNEQ (srel_name, ".rel")
-                 && strcmp (bfd_get_section_name (abfd, sec),
-                            srel_name + 4) == 0));
-
   dynobj = hppa_info->root.dynobj;
   if (!dynobj)
     hppa_info->root.dynobj = dynobj = abfd;
 
-  srel = bfd_get_section_by_name (dynobj, srel_name);
+  srel = bfd_get_linker_section (dynobj, srel_name);
   if (srel == NULL)
     {
-      srel = bfd_make_section_with_flags (dynobj, srel_name,
-                                         (SEC_ALLOC
-                                          | SEC_LOAD
-                                          | SEC_HAS_CONTENTS
-                                          | SEC_IN_MEMORY
-                                          | SEC_LINKER_CREATED
-                                          | SEC_READONLY));
+      srel = bfd_make_section_anyway_with_flags (dynobj, srel_name,
+                                                (SEC_ALLOC
+                                                 | SEC_LOAD
+                                                 | SEC_HAS_CONTENTS
+                                                 | SEC_IN_MEMORY
+                                                 | SEC_LINKER_CREATED
+                                                 | SEC_READONLY));
       if (srel == NULL
          || !bfd_set_section_alignment (dynobj, srel, 3))
        return FALSE;
@@ -515,9 +506,6 @@ elf64_hppa_check_relocs (bfd *abfd,
   const Elf_Internal_Rela *relend;
   Elf_Internal_Shdr *symtab_hdr;
   const Elf_Internal_Rela *rel;
-  asection *dlt, *plt, *stubs;
-  char *buf;
-  size_t buf_len;
   unsigned int sec_symndx;
 
   if (info->relocatable)
@@ -630,10 +618,6 @@ elf64_hppa_check_relocs (bfd *abfd,
   else
     sec_symndx = 0;
 
-  dlt = plt = stubs = NULL;
-  buf = NULL;
-  buf_len = 0;
-
   relend = relocs + sec->reloc_count;
   for (rel = relocs; rel < relend; ++rel)
     {
@@ -907,13 +891,9 @@ elf64_hppa_check_relocs (bfd *abfd,
        }
     }
 
-  if (buf)
-    free (buf);
   return TRUE;
 
  err_out:
-  if (buf)
-    free (buf);
   return FALSE;
 }
 
@@ -958,9 +938,6 @@ elf64_hppa_mark_exported_functions (struct elf_link_hash_entry *eh, void *data)
   if (hppa_info == NULL)
     return FALSE;
 
-  if (eh->root.type == bfd_link_hash_warning)
-    eh = (struct elf_link_hash_entry *) eh->root.u.i.link;
-
   if (eh
       && (eh->root.type == bfd_link_hash_defined
          || eh->root.type == bfd_link_hash_defweak)
@@ -1077,10 +1054,6 @@ allocate_global_data_opd (struct elf_link_hash_entry *eh, void *data)
 
   if (hh && hh->want_opd)
     {
-      while (hh->eh.root.type == bfd_link_hash_indirect
-            || hh->eh.root.type == bfd_link_hash_warning)
-       hh = hppa_elf_hash_entry (hh->eh.root.u.i.link);
-
       /* We never need an opd entry for a symbol which is not
         defined by this output file.  */
       if (hh && (hh->eh.root.type == bfd_link_hash_undefined
@@ -1184,12 +1157,12 @@ get_opd (bfd *abfd,
       if (!dynobj)
        hppa_info->root.dynobj = dynobj = abfd;
 
-      opd = bfd_make_section_with_flags (dynobj, ".opd",
-                                        (SEC_ALLOC
-                                         | SEC_LOAD
-                                         | SEC_HAS_CONTENTS
-                                         | SEC_IN_MEMORY
-                                         | SEC_LINKER_CREATED));
+      opd = bfd_make_section_anyway_with_flags (dynobj, ".opd",
+                                               (SEC_ALLOC
+                                                | SEC_LOAD
+                                                | SEC_HAS_CONTENTS
+                                                | SEC_IN_MEMORY
+                                                | SEC_LINKER_CREATED));
       if (!opd
          || !bfd_set_section_alignment (abfd, opd, 3))
        {
@@ -1220,12 +1193,12 @@ get_plt (bfd *abfd,
       if (!dynobj)
        hppa_info->root.dynobj = dynobj = abfd;
 
-      plt = bfd_make_section_with_flags (dynobj, ".plt",
-                                        (SEC_ALLOC
-                                         | SEC_LOAD
-                                         | SEC_HAS_CONTENTS
-                                         | SEC_IN_MEMORY
-                                         | SEC_LINKER_CREATED));
+      plt = bfd_make_section_anyway_with_flags (dynobj, ".plt",
+                                               (SEC_ALLOC
+                                                | SEC_LOAD
+                                                | SEC_HAS_CONTENTS
+                                                | SEC_IN_MEMORY
+                                                | SEC_LINKER_CREATED));
       if (!plt
          || !bfd_set_section_alignment (abfd, plt, 3))
        {
@@ -1256,12 +1229,12 @@ get_dlt (bfd *abfd,
       if (!dynobj)
        hppa_info->root.dynobj = dynobj = abfd;
 
-      dlt = bfd_make_section_with_flags (dynobj, ".dlt",
-                                        (SEC_ALLOC
-                                         | SEC_LOAD
-                                         | SEC_HAS_CONTENTS
-                                         | SEC_IN_MEMORY
-                                         | SEC_LINKER_CREATED));
+      dlt = bfd_make_section_anyway_with_flags (dynobj, ".dlt",
+                                               (SEC_ALLOC
+                                                | SEC_LOAD
+                                                | SEC_HAS_CONTENTS
+                                                | SEC_IN_MEMORY
+                                                | SEC_LINKER_CREATED));
       if (!dlt
          || !bfd_set_section_alignment (abfd, dlt, 3))
        {
@@ -1292,12 +1265,12 @@ get_stub (bfd *abfd,
       if (!dynobj)
        hppa_info->root.dynobj = dynobj = abfd;
 
-      stub = bfd_make_section_with_flags (dynobj, ".stub",
-                                         (SEC_ALLOC | SEC_LOAD
-                                          | SEC_HAS_CONTENTS
-                                          | SEC_IN_MEMORY
-                                          | SEC_READONLY
-                                          | SEC_LINKER_CREATED));
+      stub = bfd_make_section_anyway_with_flags (dynobj, ".stub",
+                                                (SEC_ALLOC | SEC_LOAD
+                                                 | SEC_HAS_CONTENTS
+                                                 | SEC_IN_MEMORY
+                                                 | SEC_READONLY
+                                                 | SEC_LINKER_CREATED));
       if (!stub
          || !bfd_set_section_alignment (abfd, stub, 3))
        {
@@ -1372,45 +1345,45 @@ elf64_hppa_create_dynamic_sections (bfd *abfd,
   if (! get_opd (abfd, info, hppa_info))
     return FALSE;
 
-  s = bfd_make_section_with_flags (abfd, ".rela.dlt",
-                                  (SEC_ALLOC | SEC_LOAD
-                                   | SEC_HAS_CONTENTS
-                                   | SEC_IN_MEMORY
-                                   | SEC_READONLY
-                                   | SEC_LINKER_CREATED));
+  s = bfd_make_section_anyway_with_flags (abfd, ".rela.dlt",
+                                         (SEC_ALLOC | SEC_LOAD
+                                          | SEC_HAS_CONTENTS
+                                          | SEC_IN_MEMORY
+                                          | SEC_READONLY
+                                          | SEC_LINKER_CREATED));
   if (s == NULL
       || !bfd_set_section_alignment (abfd, s, 3))
     return FALSE;
   hppa_info->dlt_rel_sec = s;
 
-  s = bfd_make_section_with_flags (abfd, ".rela.plt",
-                                  (SEC_ALLOC | SEC_LOAD
-                                   | SEC_HAS_CONTENTS
-                                   | SEC_IN_MEMORY
-                                   | SEC_READONLY
-                                   | SEC_LINKER_CREATED));
+  s = bfd_make_section_anyway_with_flags (abfd, ".rela.plt",
+                                         (SEC_ALLOC | SEC_LOAD
+                                          | SEC_HAS_CONTENTS
+                                          | SEC_IN_MEMORY
+                                          | SEC_READONLY
+                                          | SEC_LINKER_CREATED));
   if (s == NULL
       || !bfd_set_section_alignment (abfd, s, 3))
     return FALSE;
   hppa_info->plt_rel_sec = s;
 
-  s = bfd_make_section_with_flags (abfd, ".rela.data",
-                                  (SEC_ALLOC | SEC_LOAD
-                                   | SEC_HAS_CONTENTS
-                                   | SEC_IN_MEMORY
-                                   | SEC_READONLY
-                                   | SEC_LINKER_CREATED));
+  s = bfd_make_section_anyway_with_flags (abfd, ".rela.data",
+                                         (SEC_ALLOC | SEC_LOAD
+                                          | SEC_HAS_CONTENTS
+                                          | SEC_IN_MEMORY
+                                          | SEC_READONLY
+                                          | SEC_LINKER_CREATED));
   if (s == NULL
       || !bfd_set_section_alignment (abfd, s, 3))
     return FALSE;
   hppa_info->other_rel_sec = s;
 
-  s = bfd_make_section_with_flags (abfd, ".rela.opd",
-                                  (SEC_ALLOC | SEC_LOAD
-                                   | SEC_HAS_CONTENTS
-                                   | SEC_IN_MEMORY
-                                   | SEC_READONLY
-                                   | SEC_LINKER_CREATED));
+  s = bfd_make_section_anyway_with_flags (abfd, ".rela.opd",
+                                         (SEC_ALLOC | SEC_LOAD
+                                          | SEC_HAS_CONTENTS
+                                          | SEC_IN_MEMORY
+                                          | SEC_READONLY
+                                          | SEC_LINKER_CREATED));
   if (s == NULL
       || !bfd_set_section_alignment (abfd, s, 3))
     return FALSE;
@@ -1533,19 +1506,15 @@ static bfd_boolean
 elf64_hppa_mark_milli_and_exported_functions (struct elf_link_hash_entry *eh,
                                              void *data)
 {
-  struct elf_link_hash_entry *elf = eh;
-  struct bfd_link_info *info = (struct bfd_link_info *)data;
-
-  if (elf->root.type == bfd_link_hash_warning)
-    elf = (struct elf_link_hash_entry *) elf->root.u.i.link;
+  struct bfd_link_info *info = (struct bfd_link_info *) data;
 
-  if (elf->type == STT_PARISC_MILLI)
+  if (eh->type == STT_PARISC_MILLI)
     {
-      if (elf->dynindx != -1)
+      if (eh->dynindx != -1)
        {
-         elf->dynindx = -1;
+         eh->dynindx = -1;
          _bfd_elf_strtab_delref (elf_hash_table (info)->dynstr,
-                                 elf->dynstr_index);
+                                 eh->dynstr_index);
        }
       return TRUE;
     }
@@ -1593,7 +1562,7 @@ elf64_hppa_size_dynamic_sections (bfd *output_bfd, struct bfd_link_info *info)
       /* Set the contents of the .interp section to the interpreter.  */
       if (info->executable)
        {
-         sec = bfd_get_section_by_name (dynobj, ".interp");
+         sec = bfd_get_linker_section (dynobj, ".interp");
          BFD_ASSERT (sec != NULL);
          sec->size = sizeof ELF_DYNAMIC_INTERPRETER;
          sec->contents = (unsigned char *) ELF_DYNAMIC_INTERPRETER;
@@ -1606,7 +1575,7 @@ elf64_hppa_size_dynamic_sections (bfd *output_bfd, struct bfd_link_info *info)
         not actually use these entries.  Reset the size of .rela.dlt,
         which will cause it to get stripped from the output file
         below.  */
-      sec = bfd_get_section_by_name (dynobj, ".rela.dlt");
+      sec = bfd_get_linker_section (dynobj, ".rela.dlt");
       if (sec != NULL)
        sec->size = 0;
     }
@@ -1979,7 +1948,7 @@ elf64_hppa_finish_dynamic_symbol (bfd *output_bfd,
                                  Elf_Internal_Sym *sym)
 {
   struct elf64_hppa_link_hash_entry *hh = hppa_elf_hash_entry (eh);
-  asection *stub, *splt, *sdlt, *sopd, *spltrel, *sdltrel;
+  asection *stub, *splt, *sopd, *spltrel;
   struct elf64_hppa_link_hash_table *hppa_info;
 
   hppa_info = hppa_link_hash_table (info);
@@ -1988,10 +1957,8 @@ elf64_hppa_finish_dynamic_symbol (bfd *output_bfd,
 
   stub = hppa_info->stub_sec;
   splt = hppa_info->plt_sec;
-  sdlt = hppa_info->dlt_sec;
   sopd = hppa_info->opd_sec;
   spltrel = hppa_info->plt_rel_sec;
-  sdltrel = hppa_info->dlt_rel_sec;
 
   /* Incredible.  It is actually necessary to NOT use the symbol's real
      value when building the dynamic symbol table for a shared library.
@@ -2481,7 +2448,7 @@ elf64_hppa_finalize_dynreloc (struct elf_link_hash_entry *eh,
 static enum elf_reloc_type_class
 elf64_hppa_reloc_type_class (const Elf_Internal_Rela *rela)
 {
-  if (ELF64_R_SYM (rela->r_info) == 0)
+  if (ELF64_R_SYM (rela->r_info) == STN_UNDEF)
     return reloc_class_relative;
 
   switch ((int) ELF64_R_TYPE (rela->r_info))
@@ -2525,7 +2492,7 @@ elf64_hppa_finish_dynamic_sections (bfd *output_bfd,
                          elf64_hppa_finalize_dlt,
                          info);
 
-  sdyn = bfd_get_section_by_name (dynobj, ".dynamic");
+  sdyn = bfd_get_linker_section (dynobj, ".dynamic");
 
   if (elf_hash_table (info)->dynamic_sections_created)
     {
@@ -2627,7 +2594,7 @@ elf64_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 + 32);
+       elf_tdata (abfd)->core_lwpid = bfd_get_32 (abfd, note->descdata + 32);
 
        /* pr_reg */
        offset = 112;
@@ -2862,9 +2829,6 @@ elf_hppa_unmark_useless_dynamic_symbols (struct elf_link_hash_entry *h,
 {
   struct bfd_link_info *info = data;
 
-  if (h->root.type == bfd_link_hash_warning)
-    h = (struct elf_link_hash_entry *) h->root.u.i.link;
-
   /* If we are not creating a shared library, and this symbol is
      referenced by a shared library but is not defined anywhere, then
      the generic code will warn that it is undefined.
@@ -2896,9 +2860,6 @@ elf_hppa_remark_useless_dynamic_symbols (struct elf_link_hash_entry *h,
 {
   struct bfd_link_info *info = data;
 
-  if (h->root.type == bfd_link_hash_warning)
-    h = (struct elf_link_hash_entry *) h->root.u.i.link;
-
   /* If we are not creating a shared library, and this symbol is
      referenced by a shared library but is not defined anywhere, then
      the generic code will warn that it is undefined.
@@ -3312,13 +3273,13 @@ elf_hppa_final_link_relocate (Elf_Internal_Rela *rel,
            && value + addend + max_branch_offset >= 2*max_branch_offset)
          {
            (*_bfd_error_handler)
-             (_("%B(%A+0x%lx): cannot reach %s"),
+             (_("%B(%A+0x" BFD_VMA_FMT "x): cannot reach %s"),
              input_bfd,
              input_section,
              offset,
-             eh->root.root.string);
+             eh ? eh->root.root.string : "unknown");
            bfd_set_error (bfd_error_bad_value);
-           return bfd_reloc_notsupported;
+           return bfd_reloc_overflow;
          }
 
        /* Adjust for any field selectors.  */
@@ -3870,7 +3831,6 @@ elf64_hppa_relocate_section (bfd *output_bfd,
       asection *sym_sec;
       bfd_vma relocation;
       bfd_reloc_status_type r;
-      bfd_boolean warned_undef;
 
       r_type = ELF_R_TYPE (rel->r_info);
       if (r_type < 0 || r_type >= (int) R_PARISC_UNIMPLEMENTED)
@@ -3887,7 +3847,6 @@ elf64_hppa_relocate_section (bfd *output_bfd,
       eh = NULL;
       sym = NULL;
       sym_sec = NULL;
-      warned_undef = FALSE;
       if (r_symndx < symtab_hdr->sh_info)
        {
          /* This is a local symbol, hh defaults to NULL.  */
@@ -3898,7 +3857,6 @@ elf64_hppa_relocate_section (bfd *output_bfd,
       else
        {
          /* This is not a local symbol.  */
-         bfd_boolean unresolved_reloc;
          struct elf_link_hash_entry **sym_hashes = elf_sym_hashes (input_bfd);
 
          /* It seems this can happen with erroneous or unsupported 
@@ -3912,21 +3870,13 @@ elf64_hppa_relocate_section (bfd *output_bfd,
                 || eh->root.type == bfd_link_hash_warning)
            eh = (struct elf_link_hash_entry *) eh->root.u.i.link;
 
-         warned_undef = FALSE;
-         unresolved_reloc = FALSE;
          relocation = 0;
          if (eh->root.type == bfd_link_hash_defined
              || eh->root.type == bfd_link_hash_defweak)
            {
              sym_sec = eh->root.u.def.section;
-             if (sym_sec == NULL
-                 || sym_sec->output_section == NULL)
-               /* Set a flag that will be cleared later if we find a
-                  relocation value for this symbol.  output_section
-                  is typically NULL for symbols satisfied by a shared
-                  library.  */
-               unresolved_reloc = TRUE;
-             else
+             if (sym_sec != NULL
+                 && sym_sec->output_section != NULL)
                relocation = (eh->root.u.def.value
                              + sym_sec->output_section->vma
                              + sym_sec->output_offset);
@@ -3950,7 +3900,6 @@ elf64_hppa_relocate_section (bfd *output_bfd,
                                                      input_section,
                                                      rel->r_offset, err))
                return FALSE;
-             warned_undef = TRUE;
            }
 
           if (!info->relocatable
@@ -3967,21 +3916,13 @@ elf64_hppa_relocate_section (bfd *output_bfd,
                       (info, eh_name (eh), input_bfd,
                        input_section, rel->r_offset, FALSE))
                     return FALSE;
-                  warned_undef = TRUE;
                 }
             }
        }
 
-      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 (howto, input_bfd, contents + rel->r_offset);
-         rel->r_info = 0;
-         rel->r_addend = 0;
-         continue;
-       }
+      if (sym_sec != NULL && discarded_section (sym_sec))
+       RELOC_AGAINST_DISCARDED_SECTION (info, input_bfd, input_section,
+                                        rel, 1, relend, howto, 0, contents);
 
       if (info->relocatable)
        continue;
@@ -4074,6 +4015,7 @@ const struct elf_size_info hppa64_elf_size_info =
 #define TARGET_BIG_SYM                 bfd_elf64_hppa_vec
 #define TARGET_BIG_NAME                        "elf64-hppa"
 #define ELF_ARCH                       bfd_arch_hppa
+#define ELF_TARGET_ID                  HPPA64_ELF_DATA
 #define ELF_MACHINE_CODE               EM_PARISC
 /* This is not strictly correct.  The maximum page size for PA2.0 is
    64M.  But everything still uses 4k.  */
@@ -4156,7 +4098,7 @@ const struct elf_size_info hppa64_elf_size_info =
 #undef TARGET_BIG_NAME
 #define TARGET_BIG_NAME                        "elf64-hppa-linux"
 #undef ELF_OSABI
-#define ELF_OSABI                      ELFOSABI_LINUX
+#define ELF_OSABI                      ELFOSABI_GNU
 #undef elf_backend_post_process_headers
 #define elf_backend_post_process_headers _bfd_elf_set_osabi
 #undef elf64_bed
This page took 0.032655 seconds and 4 git commands to generate.