daily update
[deliverable/binutils-gdb.git] / bfd / elf64-x86-64.c
index 373cab82b5298a2a2a7d6ec705dd6b31e4d1a76f..9da73a1f500063b85544ad8e1c4762223f3e0ecd 100644 (file)
@@ -308,7 +308,7 @@ elf64_x86_64_grok_prstatus (bfd *abfd, Elf_Internal_Note *note)
          = bfd_get_16 (abfd, note->descdata + 12);
 
        /* pr_pid */
-       elf_tdata (abfd)->core_pid
+       elf_tdata (abfd)->core_lwpid
          = bfd_get_32 (abfd, note->descdata + 32);
 
        /* pr_reg */
@@ -332,6 +332,8 @@ elf64_x86_64_grok_psinfo (bfd *abfd, Elf_Internal_Note *note)
        return FALSE;
 
       case 136:                /* sizeof(struct elf_prpsinfo) on Linux/x86_64 */
+       elf_tdata (abfd)->core_pid
+         = bfd_get_32 (abfd, note->descdata + 24);
        elf_tdata (abfd)->core_program
         = _bfd_elfcore_strndup (abfd, note->descdata + 40, 16);
        elf_tdata (abfd)->core_command
@@ -603,8 +605,6 @@ elf64_x86_64_get_local_sym_hash (struct elf64_x86_64_link_hash_table *htab,
       ret->elf.indx = sec->id;
       ret->elf.dynstr_index = ELF64_R_SYM (rel->r_info);
       ret->elf.dynindx = -1;
-      ret->elf.plt.offset = (bfd_vma) -1;
-      ret->elf.got.offset = (bfd_vma) -1;
       *slot = ret;
     }
   return &ret->elf;
@@ -639,7 +639,7 @@ elf64_x86_64_link_hash_table_create (bfd *abfd)
   ret->tls_ld_got.refcount = 0;
   ret->sgotplt_jump_table_size = 0;
   ret->tls_module_base = NULL;
-  
+
   ret->loc_hash_table = htab_try_create (1024,
                                         elf64_x86_64_local_htab_hash,
                                         elf64_x86_64_local_htab_eq,
@@ -951,6 +951,12 @@ elf64_x86_64_tls_transition (struct bfd_link_info *info, bfd *abfd,
   unsigned int to_type = from_type;
   bfd_boolean check = TRUE;
 
+  /* Skip TLS transition for functions.  */
+  if (h != NULL
+      && (h->type == STT_FUNC
+         || h->type == STT_GNU_IFUNC))
+    return TRUE;
+
   switch (from_type)
     {
     case R_X86_64_TLSGD:
@@ -1116,7 +1122,7 @@ elf64_x86_64_check_relocs (bfd *abfd, struct bfd_link_info *info,
                                                   TRUE);
              if (h == NULL)
                return FALSE;
-             
+
              /* Fake a STT_GNU_IFUNC symbol.  */
              h->type = STT_GNU_IFUNC;
              h->def_regular = 1;
@@ -1168,7 +1174,7 @@ elf64_x86_64_check_relocs (bfd *abfd, struct bfd_link_info *info,
              /* It is referenced by a non-shared object. */
              h->ref_regular = 1;
              h->needs_plt = 1;
+
              /* STT_GNU_IFUNC symbol must go through PLT.  */
              h->plt.refcount += 1;
 
@@ -1657,6 +1663,24 @@ elf64_x86_64_gc_sweep_hook (bfd *abfd, struct bfd_link_info *info,
                break;
              }
        }
+      else
+       {
+         /* A local symbol.  */
+         Elf_Internal_Sym *isym;
+
+         isym = bfd_sym_from_r_symndx (&htab->sym_cache,
+                                       abfd, r_symndx);
+
+         /* Check relocation against local STT_GNU_IFUNC symbol.  */
+         if (isym != NULL
+             && ELF64_ST_TYPE (isym->st_info) == STT_GNU_IFUNC)
+           {
+             h = elf64_x86_64_get_local_sym_hash (htab, abfd, rel,
+                                                  FALSE);
+             if (h == NULL)
+               abort ();
+           }
+       }
 
       r_type = ELF64_R_TYPE (rel->r_info);
       if (! elf64_x86_64_tls_transition (info, abfd, sec, NULL,
@@ -1687,6 +1711,11 @@ elf64_x86_64_gc_sweep_hook (bfd *abfd, struct bfd_link_info *info,
                h->plt.refcount -= 1;
              if (h->got.refcount > 0)
                h->got.refcount -= 1;
+             if (h->type == STT_GNU_IFUNC)
+               {
+                 if (h->plt.refcount > 0)
+                   h->plt.refcount -= 1;
+               }
            }
          else if (local_got_refcounts != NULL)
            {
@@ -2347,6 +2376,23 @@ elf64_x86_64_size_dynamic_sections (bfd *output_bfd ATTRIBUTE_UNUSED,
        }
     }
 
+  if (htab->elf.sgotplt)
+    {
+      /* Don't allocate .got.plt section if there are no GOT nor PLT
+         entries.  */
+      if ((htab->elf.sgotplt->size
+          == get_elf_backend_data (output_bfd)->got_header_size)
+         && (htab->elf.splt == NULL
+             || htab->elf.splt->size == 0)
+         && (htab->elf.sgot == NULL
+             || htab->elf.sgot->size == 0)
+         && (htab->elf.iplt == NULL
+             || htab->elf.iplt->size == 0)
+         && (htab->elf.igotplt == NULL
+             || htab->elf.igotplt->size == 0))
+       htab->elf.sgotplt->size = 0;
+    }
+
   /* We now have determined the sizes of the various dynamic sections.
      Allocate memory for them.  */
   relocs = FALSE;
@@ -2676,7 +2722,7 @@ elf64_x86_64_relocate_section (bfd *output_bfd, struct bfd_link_info *info,
        }
       else
        {
-         bfd_boolean warned;
+         bfd_boolean warned ATTRIBUTE_UNUSED;
 
          RELOC_FOR_GLOBAL_SYMBOL (info, input_bfd, input_section, rel,
                                   r_symndx, symtab_hdr, sym_hashes,
@@ -2685,15 +2731,8 @@ elf64_x86_64_relocate_section (bfd *output_bfd, struct bfd_link_info *info,
        }
 
       if (sec != NULL && elf_discarded_section (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;
-       }
+       RELOC_AGAINST_DISCARDED_SECTION (info, input_bfd, input_section,
+                                        rel, relend, howto, contents);
 
       if (info->relocatable)
        continue;
@@ -3319,13 +3358,11 @@ elf64_x86_64_relocate_section (bfd *output_bfd, struct bfd_link_info *info,
                     leaq x@tlsdesc(%rip), %rax
 
                     Change it to:
-                    movl $x@tpoff, %rax
-                  */
+                    movl $x@tpoff, %rax.  */
 
-                 unsigned int val, type, type2;
+                 unsigned int val, type;
 
                  type = bfd_get_8 (input_bfd, contents + roff - 3);
-                 type2 = bfd_get_8 (input_bfd, contents + roff - 2);
                  val = bfd_get_8 (input_bfd, contents + roff - 1);
                  bfd_put_8 (output_bfd, 0x48 | ((type >> 2) & 1),
                             contents + roff - 3);
@@ -3554,14 +3591,7 @@ elf64_x86_64_relocate_section (bfd *output_bfd, struct bfd_link_info *info,
                     leaq x@tlsdesc(%rip), %rax
 
                     Change it to:
-                    movq x@gottpoff(%rip), %rax # before xchg %ax,%ax
-                  */
-
-                 unsigned int val, type, type2;
-
-                 type = bfd_get_8 (input_bfd, contents + roff - 3);
-                 type2 = bfd_get_8 (input_bfd, contents + roff - 2);
-                 val = bfd_get_8 (input_bfd, contents + roff - 1);
+                    movq x@gottpoff(%rip), %rax # before xchg %ax,%ax.  */
 
                  /* Now modify the instruction as appropriate. To
                     turn a leaq into a movq in the form we use it, it
@@ -3586,12 +3616,8 @@ elf64_x86_64_relocate_section (bfd *output_bfd, struct bfd_link_info *info,
                     call *(%rax)
 
                     Change it to:
-                    xchg %ax,%ax.  */
-
-                 unsigned int val, type;
+                    xchg %ax, %ax.  */
 
-                 type = bfd_get_8 (input_bfd, contents + roff);
-                 val = bfd_get_8 (input_bfd, contents + roff + 1);
                  bfd_put_8 (output_bfd, 0x66, contents + roff);
                  bfd_put_8 (output_bfd, 0x90, contents + roff + 1);
                  continue;
@@ -3782,7 +3808,7 @@ elf64_x86_64_finish_dynamic_symbol (bfd *output_bfd,
         corresponds to this symbol.  This is the index of this symbol
         in all the symbols for which we are making plt entries.  The
         first entry in the procedure linkage table is reserved.
-        
+
         Get the offset into the .got table of the entry that
         corresponds to this function.  Each .got entry is GOT_ENTRY_SIZE
         bytes. The first three are reserved for the dynamic linker.
@@ -4162,6 +4188,13 @@ elf64_x86_64_finish_dynamic_sections (bfd *output_bfd, struct bfd_link_info *inf
 
   if (htab->elf.sgotplt)
     {
+      if (bfd_is_abs_section (htab->elf.sgotplt->output_section))
+       {
+         (*_bfd_error_handler)
+           (_("discarded output section: `%A'"), htab->elf.sgotplt);
+         return FALSE;
+       }
+
       /* Fill in the first three entries in the global offset table.  */
       if (htab->elf.sgotplt->size > 0)
        {
@@ -4254,10 +4287,11 @@ elf64_x86_64_add_symbol_hook (bfd *abfd,
        }
       *secp = lcomm;
       *valp = sym->st_size;
-      break;
+      return TRUE;
     }
 
-  if (ELF_ST_TYPE (sym->st_info) == STT_GNU_IFUNC)
+  if ((abfd->flags & DYNAMIC) == 0
+      && ELF_ST_TYPE (sym->st_info) == STT_GNU_IFUNC)
     elf_tdata (info->output_bfd)->has_ifunc_symbols = TRUE;
 
   return TRUE;
@@ -4422,6 +4456,7 @@ static const struct bfd_elf_special_section
 #define TARGET_LITTLE_SYM                  bfd_elf64_x86_64_vec
 #define TARGET_LITTLE_NAME                 "elf64-x86-64"
 #define ELF_ARCH                           bfd_arch_i386
+#define ELF_TARGET_ID                      X86_64_ELF_DATA
 #define ELF_MACHINE_CODE                   EM_X86_64
 #define ELF_MAXPAGESIZE                            0x200000
 #define ELF_MINPAGESIZE                            0x1000
@@ -4509,6 +4544,29 @@ static const struct bfd_elf_special_section
 
 #include "elf64-target.h"
 
+/* Solaris 2 support.  */
+
+#undef  TARGET_LITTLE_SYM
+#define TARGET_LITTLE_SYM                  bfd_elf64_x86_64_sol2_vec
+#undef  TARGET_LITTLE_NAME
+#define TARGET_LITTLE_NAME                 "elf64-x86-64-sol2"
+
+/* Restore default: we cannot use ELFOSABI_SOLARIS, otherwise ELFOSABI_NONE
+   objects won't be recognized.  */
+#undef ELF_OSABI
+
+#undef  elf64_bed
+#define elf64_bed                          elf64_x86_64_sol2_bed
+
+/* The Solaris 2 ABI requires a plt symbol on all platforms.
+
+   Cf. Linker and Libraries Guide, Ch. 2, Link-Editor, Generating the Output
+   File, p.63.  */
+#undef elf_backend_want_plt_sym
+#define elf_backend_want_plt_sym           1
+
+#include "elf64-target.h"
+
 /* Intel L1OM support.  */
 
 static bfd_boolean
This page took 0.02644 seconds and 4 git commands to generate.