| Line 1... | Line 1... | 
      
        | /* X86-64 specific support for 64-bit ELF
 | /* X86-64 specific support for 64-bit ELF
 | 
      
        |    Copyright 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008
 |    Copyright 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009
 | 
      
        |    Free Software Foundation, Inc.
 |    Free Software Foundation, Inc.
 | 
      
        |    Contributed by Jan Hubicka <jh@suse.cz>.
 |    Contributed by Jan Hubicka <jh@suse.cz>.
 | 
      
        |  
 |  
 | 
      
        |    This file is part of BFD, the Binary File Descriptor library.
 |    This file is part of BFD, the Binary File Descriptor library.
 | 
      
        |  
 |  
 | 
      
        | Line 24... | Line 24... | 
      
        | #include "bfd.h"
 | #include "bfd.h"
 | 
      
        | #include "bfdlink.h"
 | #include "bfdlink.h"
 | 
      
        | #include "libbfd.h"
 | #include "libbfd.h"
 | 
      
        | #include "elf-bfd.h"
 | #include "elf-bfd.h"
 | 
      
        | #include "bfd_stdint.h"
 | #include "bfd_stdint.h"
 | 
      
        |   | #include "objalloc.h"
 | 
      
        |   | #include "hashtab.h"
 | 
      
        |  
 |  
 | 
      
        | #include "elf/x86-64.h"
 | #include "elf/x86-64.h"
 | 
      
        |  
 |  
 | 
      
        | /* In case we're on a 32-bit machine, construct a 64-bit "-1" value.  */
 | /* In case we're on a 32-bit machine, construct a 64-bit "-1" value.  */
 | 
      
        | #define MINUS_ONE (~ (bfd_vma) 0)
 | #define MINUS_ONE (~ (bfd_vma) 0)
 | 
      
        | Line 141... | Line 143... | 
      
        |         FALSE, 0, 0, FALSE),
 |         FALSE, 0, 0, FALSE),
 | 
      
        |   HOWTO(R_X86_64_TLSDESC, 0, 4, 64, FALSE, 0,
 |   HOWTO(R_X86_64_TLSDESC, 0, 4, 64, FALSE, 0,
 | 
      
        |         complain_overflow_bitfield, bfd_elf_generic_reloc,
 |         complain_overflow_bitfield, bfd_elf_generic_reloc,
 | 
      
        |         "R_X86_64_TLSDESC",
 |         "R_X86_64_TLSDESC",
 | 
      
        |         FALSE, MINUS_ONE, MINUS_ONE, FALSE),
 |         FALSE, MINUS_ONE, MINUS_ONE, FALSE),
 | 
      
        |   |   HOWTO(R_X86_64_IRELATIVE, 0, 4, 64, FALSE, 0, complain_overflow_bitfield,
 | 
      
        |   |         bfd_elf_generic_reloc, "R_X86_64_IRELATIVE", FALSE, MINUS_ONE,
 | 
      
        |   |         MINUS_ONE, FALSE),
 | 
      
        |  
 |  
 | 
      
        |   /* We have a gap in the reloc numbers here.
 |   /* We have a gap in the reloc numbers here.
 | 
      
        |      R_X86_64_standard counts the number up to this point, and
 |      R_X86_64_standard counts the number up to this point, and
 | 
      
        |      R_X86_64_vt_offset is the value to subtract from a reloc type of
 |      R_X86_64_vt_offset is the value to subtract from a reloc type of
 | 
      
        |      R_X86_64_GNU_VT* to form an index into this table.  */
 |      R_X86_64_GNU_VT* to form an index into this table.  */
 | 
      
        | #define R_X86_64_standard (R_X86_64_TLSDESC + 1)
 | #define R_X86_64_standard (R_X86_64_IRELATIVE + 1)
 | 
      
        | #define R_X86_64_vt_offset (R_X86_64_GNU_VTINHERIT - R_X86_64_standard)
 | #define R_X86_64_vt_offset (R_X86_64_GNU_VTINHERIT - R_X86_64_standard)
 | 
      
        |  
 |  
 | 
      
        | /* GNU extension to record C++ vtable hierarchy.  */
 | /* GNU extension to record C++ vtable hierarchy.  */
 | 
      
        |   HOWTO (R_X86_64_GNU_VTINHERIT, 0, 4, 0, FALSE, 0, complain_overflow_dont,
 |   HOWTO (R_X86_64_GNU_VTINHERIT, 0, 4, 0, FALSE, 0, complain_overflow_dont,
 | 
      
        |          NULL, "R_X86_64_GNU_VTINHERIT", FALSE, 0, 0, FALSE),
 |          NULL, "R_X86_64_GNU_VTINHERIT", FALSE, 0, 0, FALSE),
 | 
      
        | Line 159... | Line 164... | 
      
        |   HOWTO (R_X86_64_GNU_VTENTRY, 0, 4, 0, FALSE, 0, complain_overflow_dont,
 |   HOWTO (R_X86_64_GNU_VTENTRY, 0, 4, 0, FALSE, 0, complain_overflow_dont,
 | 
      
        |          _bfd_elf_rel_vtable_reloc_fn, "R_X86_64_GNU_VTENTRY", FALSE, 0, 0,
 |          _bfd_elf_rel_vtable_reloc_fn, "R_X86_64_GNU_VTENTRY", FALSE, 0, 0,
 | 
      
        |          FALSE)
 |          FALSE)
 | 
      
        | };
 | };
 | 
      
        |  
 |  
 | 
      
        |   | #define IS_X86_64_PCREL_TYPE(TYPE)      \
 | 
      
        |   |   (   ((TYPE) == R_X86_64_PC8)          \
 | 
      
        |   |    || ((TYPE) == R_X86_64_PC16)         \
 | 
      
        |   |    || ((TYPE) == R_X86_64_PC32)         \
 | 
      
        |   |    || ((TYPE) == R_X86_64_PC64))
 | 
      
        |   |  
 | 
      
        | /* Map BFD relocs to the x86_64 elf relocs.  */
 | /* Map BFD relocs to the x86_64 elf relocs.  */
 | 
      
        | struct elf_reloc_map
 | struct elf_reloc_map
 | 
      
        | {
 | {
 | 
      
        |   bfd_reloc_code_real_type bfd_reloc_val;
 |   bfd_reloc_code_real_type bfd_reloc_val;
 | 
      
        |   unsigned char elf_reloc_val;
 |   unsigned char elf_reloc_val;
 | 
      
        | Line 203... | Line 214... | 
      
        |   { BFD_RELOC_X86_64_GOTPLT64,  R_X86_64_GOTPLT64, },
 |   { BFD_RELOC_X86_64_GOTPLT64,  R_X86_64_GOTPLT64, },
 | 
      
        |   { BFD_RELOC_X86_64_PLTOFF64,  R_X86_64_PLTOFF64, },
 |   { BFD_RELOC_X86_64_PLTOFF64,  R_X86_64_PLTOFF64, },
 | 
      
        |   { BFD_RELOC_X86_64_GOTPC32_TLSDESC, R_X86_64_GOTPC32_TLSDESC, },
 |   { BFD_RELOC_X86_64_GOTPC32_TLSDESC, R_X86_64_GOTPC32_TLSDESC, },
 | 
      
        |   { BFD_RELOC_X86_64_TLSDESC_CALL, R_X86_64_TLSDESC_CALL, },
 |   { BFD_RELOC_X86_64_TLSDESC_CALL, R_X86_64_TLSDESC_CALL, },
 | 
      
        |   { BFD_RELOC_X86_64_TLSDESC,   R_X86_64_TLSDESC, },
 |   { BFD_RELOC_X86_64_TLSDESC,   R_X86_64_TLSDESC, },
 | 
      
        |   |   { BFD_RELOC_X86_64_IRELATIVE, R_X86_64_IRELATIVE, },
 | 
      
        |   { BFD_RELOC_VTABLE_INHERIT,   R_X86_64_GNU_VTINHERIT, },
 |   { BFD_RELOC_VTABLE_INHERIT,   R_X86_64_GNU_VTINHERIT, },
 | 
      
        |   { BFD_RELOC_VTABLE_ENTRY,     R_X86_64_GNU_VTENTRY, },
 |   { BFD_RELOC_VTABLE_ENTRY,     R_X86_64_GNU_VTENTRY, },
 | 
      
        | };
 | };
 | 
      
        |  
 |  
 | 
      
        | static reloc_howto_type *
 | static reloc_howto_type *
 | 
      
        | Line 382... | Line 394... | 
      
        |   0, 0, 0, 0,       /* replaced with index into relocation table.  */
 |   0, 0, 0, 0,       /* replaced with index into relocation table.  */
 | 
      
        |   0xe9,         /* jmp relative */
 |   0xe9,         /* jmp relative */
 | 
      
        |   0, 0, 0, 0        /* replaced with offset to start of .plt0.  */
 |   0, 0, 0, 0        /* replaced with offset to start of .plt0.  */
 | 
      
        | };
 | };
 | 
      
        |  
 |  
 | 
      
        | /* The x86-64 linker needs to keep track of the number of relocs that
 |   | 
      
        |    it decides to copy as dynamic relocs in check_relocs for each symbol.
 |   | 
      
        |    This is so that it can later discard them if they are found to be
 |   | 
      
        |    unnecessary.  We store the information in a field extending the
 |   | 
      
        |    regular ELF linker hash table.  */
 |   | 
      
        |  
 |   | 
      
        | struct elf64_x86_64_dyn_relocs
 |   | 
      
        | {
 |   | 
      
        |   /* Next section.  */
 |   | 
      
        |   struct elf64_x86_64_dyn_relocs *next;
 |   | 
      
        |  
 |   | 
      
        |   /* The input section of the reloc.  */
 |   | 
      
        |   asection *sec;
 |   | 
      
        |  
 |   | 
      
        |   /* Total number of relocs copied for the input section.  */
 |   | 
      
        |   bfd_size_type count;
 |   | 
      
        |  
 |   | 
      
        |   /* Number of pc-relative relocs copied for the input section.  */
 |   | 
      
        |   bfd_size_type pc_count;
 |   | 
      
        | };
 |   | 
      
        |  
 |   | 
      
        | /* x86-64 ELF linker hash entry.  */
 | /* x86-64 ELF linker hash entry.  */
 | 
      
        |  
 |  
 | 
      
        | struct elf64_x86_64_link_hash_entry
 | struct elf64_x86_64_link_hash_entry
 | 
      
        | {
 | {
 | 
      
        |   struct elf_link_hash_entry elf;
 |   struct elf_link_hash_entry elf;
 | 
      
        |  
 |  
 | 
      
        |   /* Track dynamic relocs copied for this symbol.  */
 |   /* Track dynamic relocs copied for this symbol.  */
 | 
      
        |   struct elf64_x86_64_dyn_relocs *dyn_relocs;
 |   struct elf_dyn_relocs *dyn_relocs;
 | 
      
        |  
 |  
 | 
      
        | #define GOT_UNKNOWN     0
 | #define GOT_UNKNOWN     0
 | 
      
        | #define GOT_NORMAL      1
 | #define GOT_NORMAL      1
 | 
      
        | #define GOT_TLS_GD      2
 | #define GOT_TLS_GD      2
 | 
      
        | #define GOT_TLS_IE      3
 | #define GOT_TLS_IE      3
 | 
      
        | Line 474... | Line 465... | 
      
        | struct elf64_x86_64_link_hash_table
 | struct elf64_x86_64_link_hash_table
 | 
      
        | {
 | {
 | 
      
        |   struct elf_link_hash_table elf;
 |   struct elf_link_hash_table elf;
 | 
      
        |  
 |  
 | 
      
        |   /* Short-cuts to get to dynamic linker sections.  */
 |   /* Short-cuts to get to dynamic linker sections.  */
 | 
      
        |   asection *sgot;
 |   | 
      
        |   asection *sgotplt;
 |   | 
      
        |   asection *srelgot;
 |   | 
      
        |   asection *splt;
 |   | 
      
        |   asection *srelplt;
 |   | 
      
        |   asection *sdynbss;
 |   asection *sdynbss;
 | 
      
        |   asection *srelbss;
 |   asection *srelbss;
 | 
      
        |  
 |  
 | 
      
        |   /* The offset into splt of the PLT entry for the TLS descriptor
 |   /* The offset into splt of the PLT entry for the TLS descriptor
 | 
      
        |      resolver.  Special values are 0, if not necessary (or not found
 |      resolver.  Special values are 0, if not necessary (or not found
 | 
      
        | Line 499... | Line 485... | 
      
        |   } tls_ld_got;
 |   } tls_ld_got;
 | 
      
        |  
 |  
 | 
      
        |   /* The amount of space used by the jump slots in the GOT.  */
 |   /* The amount of space used by the jump slots in the GOT.  */
 | 
      
        |   bfd_vma sgotplt_jump_table_size;
 |   bfd_vma sgotplt_jump_table_size;
 | 
      
        |  
 |  
 | 
      
        |   /* Small local sym to section mapping cache.  */
 |   /* Small local sym cache.  */
 | 
      
        |   struct sym_sec_cache sym_sec;
 |   struct sym_cache sym_cache;
 | 
      
        |   |  
 | 
      
        |   |   /* _TLS_MODULE_BASE_ symbol.  */
 | 
      
        |   |   struct bfd_link_hash_entry *tls_module_base;
 | 
      
        |   |  
 | 
      
        |   |   /* Used by local STT_GNU_IFUNC symbols.  */
 | 
      
        |   |   htab_t loc_hash_table;
 | 
      
        |   |   void *loc_hash_memory;
 | 
      
        | };
 | };
 | 
      
        |  
 |  
 | 
      
        | /* Get the x86-64 ELF linker hash table from a link_info structure.  */
 | /* Get the x86-64 ELF linker hash table from a link_info structure.  */
 | 
      
        |  
 |  
 | 
      
        | #define elf64_x86_64_hash_table(p) \
 | #define elf64_x86_64_hash_table(p) \
 | 
      
        |   ((struct elf64_x86_64_link_hash_table *) ((p)->hash))
 |   ((struct elf64_x86_64_link_hash_table *) ((p)->hash))
 | 
      
        |  
 |  
 | 
      
        | #define elf64_x86_64_compute_jump_table_size(htab) \
 | #define elf64_x86_64_compute_jump_table_size(htab) \
 | 
      
        |   ((htab)->srelplt->reloc_count * GOT_ENTRY_SIZE)
 |   ((htab)->elf.srelplt->reloc_count * GOT_ENTRY_SIZE)
 | 
      
        |  
 |  
 | 
      
        | /* Create an entry in an x86-64 ELF linker hash table.  */
 | /* Create an entry in an x86-64 ELF linker hash table.  */
 | 
      
        |  
 |  
 | 
      
        | static struct bfd_hash_entry *
 | static struct bfd_hash_entry *
 | 
      
        | link_hash_newfunc (struct bfd_hash_entry *entry, struct bfd_hash_table *table,
 | elf64_x86_64_link_hash_newfunc (struct bfd_hash_entry *entry,
 | 
      
        |   |                                 struct bfd_hash_table *table,
 | 
      
        |                    const char *string)
 |                    const char *string)
 | 
      
        | {
 | {
 | 
      
        |   /* Allocate the structure if it has not already been allocated by a
 |   /* Allocate the structure if it has not already been allocated by a
 | 
      
        |      subclass.  */
 |      subclass.  */
 | 
      
        |   if (entry == NULL)
 |   if (entry == NULL)
 | 
      
        |     {
 |     {
 | 
      
        |       entry = bfd_hash_allocate (table,
 |       entry = (struct bfd_hash_entry *)
 | 
      
        |   |           bfd_hash_allocate (table,
 | 
      
        |                                  sizeof (struct elf64_x86_64_link_hash_entry));
 |                                  sizeof (struct elf64_x86_64_link_hash_entry));
 | 
      
        |       if (entry == NULL)
 |       if (entry == NULL)
 | 
      
        |         return entry;
 |         return entry;
 | 
      
        |     }
 |     }
 | 
      
        |  
 |  
 | 
      
        | Line 542... | Line 537... | 
      
        |     }
 |     }
 | 
      
        |  
 |  
 | 
      
        |   return entry;
 |   return entry;
 | 
      
        | }
 | }
 | 
      
        |  
 |  
 | 
      
        |   | /* Compute a hash of a local hash entry.  We use elf_link_hash_entry
 | 
      
        |   |   for local symbol so that we can handle local STT_GNU_IFUNC symbols
 | 
      
        |   |   as global symbol.  We reuse indx and dynstr_index for local symbol
 | 
      
        |   |   hash since they aren't used by global symbols in this backend.  */
 | 
      
        |   |  
 | 
      
        |   | static hashval_t
 | 
      
        |   | elf64_x86_64_local_htab_hash (const void *ptr)
 | 
      
        |   | {
 | 
      
        |   |   struct elf_link_hash_entry *h
 | 
      
        |   |     = (struct elf_link_hash_entry *) ptr;
 | 
      
        |   |   return ELF_LOCAL_SYMBOL_HASH (h->indx, h->dynstr_index);
 | 
      
        |   | }
 | 
      
        |   |  
 | 
      
        |   | /* Compare local hash entries.  */
 | 
      
        |   |  
 | 
      
        |   | static int
 | 
      
        |   | elf64_x86_64_local_htab_eq (const void *ptr1, const void *ptr2)
 | 
      
        |   | {
 | 
      
        |   |   struct elf_link_hash_entry *h1
 | 
      
        |   |      = (struct elf_link_hash_entry *) ptr1;
 | 
      
        |   |   struct elf_link_hash_entry *h2
 | 
      
        |   |     = (struct elf_link_hash_entry *) ptr2;
 | 
      
        |   |  
 | 
      
        |   |   return h1->indx == h2->indx && h1->dynstr_index == h2->dynstr_index;
 | 
      
        |   | }
 | 
      
        |   |  
 | 
      
        |   | /* Find and/or create a hash entry for local symbol.  */
 | 
      
        |   |  
 | 
      
        |   | static struct elf_link_hash_entry *
 | 
      
        |   | elf64_x86_64_get_local_sym_hash (struct elf64_x86_64_link_hash_table *htab,
 | 
      
        |   |                                  bfd *abfd, const Elf_Internal_Rela *rel,
 | 
      
        |   |                                  bfd_boolean create)
 | 
      
        |   | {
 | 
      
        |   |   struct elf64_x86_64_link_hash_entry e, *ret;
 | 
      
        |   |   asection *sec = abfd->sections;
 | 
      
        |   |   hashval_t h = ELF_LOCAL_SYMBOL_HASH (sec->id,
 | 
      
        |   |                                        ELF64_R_SYM (rel->r_info));
 | 
      
        |   |   void **slot;
 | 
      
        |   |  
 | 
      
        |   |   e.elf.indx = sec->id;
 | 
      
        |   |   e.elf.dynstr_index = ELF64_R_SYM (rel->r_info);
 | 
      
        |   |   slot = htab_find_slot_with_hash (htab->loc_hash_table, &e, h,
 | 
      
        |   |                                    create ? INSERT : NO_INSERT);
 | 
      
        |   |  
 | 
      
        |   |   if (!slot)
 | 
      
        |   |     return NULL;
 | 
      
        |   |  
 | 
      
        |   |   if (*slot)
 | 
      
        |   |     {
 | 
      
        |   |       ret = (struct elf64_x86_64_link_hash_entry *) *slot;
 | 
      
        |   |       return &ret->elf;
 | 
      
        |   |     }
 | 
      
        |   |  
 | 
      
        |   |   ret = (struct elf64_x86_64_link_hash_entry *)
 | 
      
        |   |         objalloc_alloc ((struct objalloc *) htab->loc_hash_memory,
 | 
      
        |   |                         sizeof (struct elf64_x86_64_link_hash_entry));
 | 
      
        |   |   if (ret)
 | 
      
        |   |     {
 | 
      
        |   |       memset (ret, 0, sizeof (*ret));
 | 
      
        |   |       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;
 | 
      
        |   | }
 | 
      
        |   |  
 | 
      
        | /* Create an X86-64 ELF linker hash table.  */
 | /* Create an X86-64 ELF linker hash table.  */
 | 
      
        |  
 |  
 | 
      
        | static struct bfd_link_hash_table *
 | static struct bfd_link_hash_table *
 | 
      
        | elf64_x86_64_link_hash_table_create (bfd *abfd)
 | elf64_x86_64_link_hash_table_create (bfd *abfd)
 | 
      
        | {
 | {
 | 
      
        | Line 554... | Line 618... | 
      
        |  
 |  
 | 
      
        |   ret = (struct elf64_x86_64_link_hash_table *) bfd_malloc (amt);
 |   ret = (struct elf64_x86_64_link_hash_table *) bfd_malloc (amt);
 | 
      
        |   if (ret == NULL)
 |   if (ret == NULL)
 | 
      
        |     return NULL;
 |     return NULL;
 | 
      
        |  
 |  
 | 
      
        |   if (!_bfd_elf_link_hash_table_init (&ret->elf, abfd, link_hash_newfunc,
 |   if (!_bfd_elf_link_hash_table_init (&ret->elf, abfd,
 | 
      
        |   |                                       elf64_x86_64_link_hash_newfunc,
 | 
      
        |                                       sizeof (struct elf64_x86_64_link_hash_entry)))
 |                                       sizeof (struct elf64_x86_64_link_hash_entry)))
 | 
      
        |     {
 |     {
 | 
      
        |       free (ret);
 |       free (ret);
 | 
      
        |       return NULL;
 |       return NULL;
 | 
      
        |     }
 |     }
 | 
      
        |  
 |  
 | 
      
        |   ret->sgot = NULL;
 |   | 
      
        |   ret->sgotplt = NULL;
 |   | 
      
        |   ret->srelgot = NULL;
 |   | 
      
        |   ret->splt = NULL;
 |   | 
      
        |   ret->srelplt = NULL;
 |   | 
      
        |   ret->sdynbss = NULL;
 |   ret->sdynbss = NULL;
 | 
      
        |   ret->srelbss = NULL;
 |   ret->srelbss = NULL;
 | 
      
        |   ret->sym_sec.abfd = NULL;
 |   ret->sym_cache.abfd = NULL;
 | 
      
        |   ret->tlsdesc_plt = 0;
 |   ret->tlsdesc_plt = 0;
 | 
      
        |   ret->tlsdesc_got = 0;
 |   ret->tlsdesc_got = 0;
 | 
      
        |   ret->tls_ld_got.refcount = 0;
 |   ret->tls_ld_got.refcount = 0;
 | 
      
        |   ret->sgotplt_jump_table_size = 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,
 | 
      
        |   |                                          NULL);
 | 
      
        |   |   ret->loc_hash_memory = objalloc_create ();
 | 
      
        |   |   if (!ret->loc_hash_table || !ret->loc_hash_memory)
 | 
      
        |   |     {
 | 
      
        |   |       free (ret);
 | 
      
        |   |       return NULL;
 | 
      
        |   |     }
 | 
      
        |  
 |  
 | 
      
        |   return &ret->elf.root;
 |   return &ret->elf.root;
 | 
      
        | }
 | }
 | 
      
        |  
 |  
 | 
      
        | /* Create .got, .gotplt, and .rela.got sections in DYNOBJ, and set up
 | /* Destroy an X86-64 ELF linker hash table.  */
 | 
      
        |    shortcuts to them in our hash table.  */
 |   | 
      
        |  
 |  
 | 
      
        | static bfd_boolean
 | static void
 | 
      
        | create_got_section (bfd *dynobj, struct bfd_link_info *info)
 | elf64_x86_64_link_hash_table_free (struct bfd_link_hash_table *hash)
 | 
      
        | {
 | {
 | 
      
        |   struct elf64_x86_64_link_hash_table *htab;
 |   struct elf64_x86_64_link_hash_table *htab
 | 
      
        |  
 |     = (struct elf64_x86_64_link_hash_table *) hash;
 | 
      
        |   if (! _bfd_elf_create_got_section (dynobj, info))
 |   | 
      
        |     return FALSE;
 |   | 
      
        |  
 |  
 | 
      
        |   htab = elf64_x86_64_hash_table (info);
 |   if (htab->loc_hash_table)
 | 
      
        |   htab->sgot = bfd_get_section_by_name (dynobj, ".got");
 |     htab_delete (htab->loc_hash_table);
 | 
      
        |   htab->sgotplt = bfd_get_section_by_name (dynobj, ".got.plt");
 |   if (htab->loc_hash_memory)
 | 
      
        |   if (!htab->sgot || !htab->sgotplt)
 |     objalloc_free ((struct objalloc *) htab->loc_hash_memory);
 | 
      
        |     abort ();
 |   _bfd_generic_link_hash_table_free (hash);
 | 
      
        |  
 |   | 
      
        |   htab->srelgot = bfd_make_section_with_flags (dynobj, ".rela.got",
 |   | 
      
        |                                                (SEC_ALLOC | SEC_LOAD
 |   | 
      
        |                                                 | SEC_HAS_CONTENTS
 |   | 
      
        |                                                 | SEC_IN_MEMORY
 |   | 
      
        |                                                 | SEC_LINKER_CREATED
 |   | 
      
        |                                                 | SEC_READONLY));
 |   | 
      
        |   if (htab->srelgot == NULL
 |   | 
      
        |       || ! bfd_set_section_alignment (dynobj, htab->srelgot, 3))
 |   | 
      
        |     return FALSE;
 |   | 
      
        |   return TRUE;
 |   | 
      
        | }
 | }
 | 
      
        |  
 |  
 | 
      
        | /* Create .plt, .rela.plt, .got, .got.plt, .rela.got, .dynbss, and
 | /* Create .plt, .rela.plt, .got, .got.plt, .rela.got, .dynbss, and
 | 
      
        |    .rela.bss sections in DYNOBJ, and set up shortcuts to them in our
 |    .rela.bss sections in DYNOBJ, and set up shortcuts to them in our
 | 
      
        |    hash table.  */
 |    hash table.  */
 | 
      
        | Line 615... | Line 673... | 
      
        | static bfd_boolean
 | static bfd_boolean
 | 
      
        | elf64_x86_64_create_dynamic_sections (bfd *dynobj, struct bfd_link_info *info)
 | elf64_x86_64_create_dynamic_sections (bfd *dynobj, struct bfd_link_info *info)
 | 
      
        | {
 | {
 | 
      
        |   struct elf64_x86_64_link_hash_table *htab;
 |   struct elf64_x86_64_link_hash_table *htab;
 | 
      
        |  
 |  
 | 
      
        |   htab = elf64_x86_64_hash_table (info);
 |   | 
      
        |   if (!htab->sgot && !create_got_section (dynobj, info))
 |   | 
      
        |     return FALSE;
 |   | 
      
        |  
 |   | 
      
        |   if (!_bfd_elf_create_dynamic_sections (dynobj, info))
 |   if (!_bfd_elf_create_dynamic_sections (dynobj, info))
 | 
      
        |     return FALSE;
 |     return FALSE;
 | 
      
        |  
 |  
 | 
      
        |   htab->splt = bfd_get_section_by_name (dynobj, ".plt");
 |   htab = elf64_x86_64_hash_table (info);
 | 
      
        |   htab->srelplt = bfd_get_section_by_name (dynobj, ".rela.plt");
 |   | 
      
        |   htab->sdynbss = bfd_get_section_by_name (dynobj, ".dynbss");
 |   htab->sdynbss = bfd_get_section_by_name (dynobj, ".dynbss");
 | 
      
        |   if (!info->shared)
 |   if (!info->shared)
 | 
      
        |     htab->srelbss = bfd_get_section_by_name (dynobj, ".rela.bss");
 |     htab->srelbss = bfd_get_section_by_name (dynobj, ".rela.bss");
 | 
      
        |  
 |  
 | 
      
        |   if (!htab->splt || !htab->srelplt || !htab->sdynbss
 |   if (!htab->sdynbss
 | 
      
        |       || (!info->shared && !htab->srelbss))
 |       || (!info->shared && !htab->srelbss))
 | 
      
        |     abort ();
 |     abort ();
 | 
      
        |  
 |  
 | 
      
        |   return TRUE;
 |   return TRUE;
 | 
      
        | }
 | }
 | 
      
        | Line 651... | Line 704... | 
      
        |  
 |  
 | 
      
        |   if (eind->dyn_relocs != NULL)
 |   if (eind->dyn_relocs != NULL)
 | 
      
        |     {
 |     {
 | 
      
        |       if (edir->dyn_relocs != NULL)
 |       if (edir->dyn_relocs != NULL)
 | 
      
        |         {
 |         {
 | 
      
        |           struct elf64_x86_64_dyn_relocs **pp;
 |           struct elf_dyn_relocs **pp;
 | 
      
        |           struct elf64_x86_64_dyn_relocs *p;
 |           struct elf_dyn_relocs *p;
 | 
      
        |  
 |  
 | 
      
        |           /* Add reloc counts against the indirect sym to the direct sym
 |           /* Add reloc counts against the indirect sym to the direct sym
 | 
      
        |              list.  Merge any entries against the same section.  */
 |              list.  Merge any entries against the same section.  */
 | 
      
        |           for (pp = &eind->dyn_relocs; (p = *pp) != NULL; )
 |           for (pp = &eind->dyn_relocs; (p = *pp) != NULL; )
 | 
      
        |             {
 |             {
 | 
      
        |               struct elf64_x86_64_dyn_relocs *q;
 |               struct elf_dyn_relocs *q;
 | 
      
        |  
 |  
 | 
      
        |               for (q = edir->dyn_relocs; q != NULL; q = q->next)
 |               for (q = edir->dyn_relocs; q != NULL; q = q->next)
 | 
      
        |                 if (q->sec == p->sec)
 |                 if (q->sec == p->sec)
 | 
      
        |                   {
 |                   {
 | 
      
        |                     q->pc_count += p->pc_count;
 |                     q->pc_count += p->pc_count;
 | 
      
        | Line 804... | Line 857... | 
      
        |       r_symndx = ELF64_R_SYM (rel[1].r_info);
 |       r_symndx = ELF64_R_SYM (rel[1].r_info);
 | 
      
        |       if (r_symndx < symtab_hdr->sh_info)
 |       if (r_symndx < symtab_hdr->sh_info)
 | 
      
        |         return FALSE;
 |         return FALSE;
 | 
      
        |  
 |  
 | 
      
        |       h = sym_hashes[r_symndx - symtab_hdr->sh_info];
 |       h = sym_hashes[r_symndx - symtab_hdr->sh_info];
 | 
      
        |   |       /* Use strncmp to check __tls_get_addr since __tls_get_addr
 | 
      
        |   |          may be versioned.  */
 | 
      
        |       return (h != NULL
 |       return (h != NULL
 | 
      
        |               && h->root.root.string != NULL
 |               && h->root.root.string != NULL
 | 
      
        |               && (ELF64_R_TYPE (rel[1].r_info) == R_X86_64_PC32
 |               && (ELF64_R_TYPE (rel[1].r_info) == R_X86_64_PC32
 | 
      
        |                   || ELF64_R_TYPE (rel[1].r_info) == R_X86_64_PLT32)
 |                   || ELF64_R_TYPE (rel[1].r_info) == R_X86_64_PLT32)
 | 
      
        |               && (strcmp (h->root.root.string, "__tls_get_addr") == 0));
 |               && (strncmp (h->root.root.string,
 | 
      
        |   |                            "__tls_get_addr", 14) == 0));
 | 
      
        |  
 |  
 | 
      
        |     case R_X86_64_GOTTPOFF:
 |     case R_X86_64_GOTTPOFF:
 | 
      
        |       /* Check transition from IE access model:
 |       /* Check transition from IE access model:
 | 
      
        |                 movq foo@gottpoff(%rip), %reg
 |                 movq foo@gottpoff(%rip), %reg
 | 
      
        |                 addq foo@gottpoff(%rip), %reg
 |                 addq foo@gottpoff(%rip), %reg
 | 
      
        | Line 880... | Line 936... | 
      
        |                              Elf_Internal_Shdr *symtab_hdr,
 |                              Elf_Internal_Shdr *symtab_hdr,
 | 
      
        |                              struct elf_link_hash_entry **sym_hashes,
 |                              struct elf_link_hash_entry **sym_hashes,
 | 
      
        |                              unsigned int *r_type, int tls_type,
 |                              unsigned int *r_type, int tls_type,
 | 
      
        |                              const Elf_Internal_Rela *rel,
 |                              const Elf_Internal_Rela *rel,
 | 
      
        |                              const Elf_Internal_Rela *relend,
 |                              const Elf_Internal_Rela *relend,
 | 
      
        |                              struct elf_link_hash_entry *h)
 |                              struct elf_link_hash_entry *h,
 | 
      
        |   |                              unsigned long r_symndx)
 | 
      
        | {
 | {
 | 
      
        |   unsigned int from_type = *r_type;
 |   unsigned int from_type = *r_type;
 | 
      
        |   unsigned int to_type = from_type;
 |   unsigned int to_type = from_type;
 | 
      
        |   bfd_boolean check = TRUE;
 |   bfd_boolean check = TRUE;
 | 
      
        |  
 |  
 | 
      
        | Line 892... | Line 949... | 
      
        |     {
 |     {
 | 
      
        |     case R_X86_64_TLSGD:
 |     case R_X86_64_TLSGD:
 | 
      
        |     case R_X86_64_GOTPC32_TLSDESC:
 |     case R_X86_64_GOTPC32_TLSDESC:
 | 
      
        |     case R_X86_64_TLSDESC_CALL:
 |     case R_X86_64_TLSDESC_CALL:
 | 
      
        |     case R_X86_64_GOTTPOFF:
 |     case R_X86_64_GOTTPOFF:
 | 
      
        |       if (!info->shared)
 |       if (info->executable)
 | 
      
        |         {
 |         {
 | 
      
        |           if (h == NULL)
 |           if (h == NULL)
 | 
      
        |             to_type = R_X86_64_TPOFF32;
 |             to_type = R_X86_64_TPOFF32;
 | 
      
        |           else
 |           else
 | 
      
        |             to_type = R_X86_64_GOTTPOFF;
 |             to_type = R_X86_64_GOTTPOFF;
 | 
      
        | Line 907... | Line 964... | 
      
        |          based on TLS_TYPE.  */
 |          based on TLS_TYPE.  */
 | 
      
        |       if (contents != NULL)
 |       if (contents != NULL)
 | 
      
        |         {
 |         {
 | 
      
        |           unsigned int new_to_type = to_type;
 |           unsigned int new_to_type = to_type;
 | 
      
        |  
 |  
 | 
      
        |           if (!info->shared
 |           if (info->executable
 | 
      
        |               && h != NULL
 |               && h != NULL
 | 
      
        |               && h->dynindx == -1
 |               && h->dynindx == -1
 | 
      
        |               && tls_type == GOT_TLS_IE)
 |               && tls_type == GOT_TLS_IE)
 | 
      
        |             new_to_type = R_X86_64_TPOFF32;
 |             new_to_type = R_X86_64_TPOFF32;
 | 
      
        |  
 |  
 | 
      
        | Line 931... | Line 988... | 
      
        |         }
 |         }
 | 
      
        |  
 |  
 | 
      
        |       break;
 |       break;
 | 
      
        |  
 |  
 | 
      
        |     case R_X86_64_TLSLD:
 |     case R_X86_64_TLSLD:
 | 
      
        |       if (!info->shared)
 |       if (info->executable)
 | 
      
        |         to_type = R_X86_64_TPOFF32;
 |         to_type = R_X86_64_TPOFF32;
 | 
      
        |       break;
 |       break;
 | 
      
        |  
 |  
 | 
      
        |     default:
 |     default:
 | 
      
        |       return TRUE;
 |       return TRUE;
 | 
      
        | Line 950... | Line 1007... | 
      
        |       && ! elf64_x86_64_check_tls_transition (abfd, sec, contents,
 |       && ! elf64_x86_64_check_tls_transition (abfd, sec, contents,
 | 
      
        |                                               symtab_hdr, sym_hashes,
 |                                               symtab_hdr, sym_hashes,
 | 
      
        |                                               from_type, rel, relend))
 |                                               from_type, rel, relend))
 | 
      
        |     {
 |     {
 | 
      
        |       reloc_howto_type *from, *to;
 |       reloc_howto_type *from, *to;
 | 
      
        |   |       const char *name;
 | 
      
        |  
 |  
 | 
      
        |       from = elf64_x86_64_rtype_to_howto (abfd, from_type);
 |       from = elf64_x86_64_rtype_to_howto (abfd, from_type);
 | 
      
        |       to = elf64_x86_64_rtype_to_howto (abfd, to_type);
 |       to = elf64_x86_64_rtype_to_howto (abfd, to_type);
 | 
      
        |  
 |  
 | 
      
        |   |       if (h)
 | 
      
        |   |         name = h->root.root.string;
 | 
      
        |   |       else
 | 
      
        |   |         {
 | 
      
        |   |           Elf_Internal_Sym *isym;
 | 
      
        |   |           struct elf64_x86_64_link_hash_table *htab;
 | 
      
        |   |           htab = elf64_x86_64_hash_table (info);
 | 
      
        |   |           isym = bfd_sym_from_r_symndx (&htab->sym_cache,
 | 
      
        |   |                                         abfd, r_symndx);
 | 
      
        |   |           name = bfd_elf_sym_name (abfd, symtab_hdr, isym, NULL);
 | 
      
        |   |         }
 | 
      
        |   |  
 | 
      
        |       (*_bfd_error_handler)
 |       (*_bfd_error_handler)
 | 
      
        |         (_("%B: TLS transition from %s to %s against `%s' at 0x%lx "
 |         (_("%B: TLS transition from %s to %s against `%s' at 0x%lx "
 | 
      
        |            "in section `%A' failed"),
 |            "in section `%A' failed"),
 | 
      
        |          abfd, sec, from->name, to->name,
 |          abfd, sec, from->name, to->name, name,
 | 
      
        |          h ? h->root.root.string : "a local symbol",
 |   | 
      
        |          (unsigned long) rel->r_offset);
 |          (unsigned long) rel->r_offset);
 | 
      
        |       bfd_set_error (bfd_error_bad_value);
 |       bfd_set_error (bfd_error_bad_value);
 | 
      
        |       return FALSE;
 |       return FALSE;
 | 
      
        |     }
 |     }
 | 
      
        |  
 |  
 | 
      
        | Line 1001... | Line 1070... | 
      
        |   for (rel = relocs; rel < rel_end; rel++)
 |   for (rel = relocs; rel < rel_end; rel++)
 | 
      
        |     {
 |     {
 | 
      
        |       unsigned int r_type;
 |       unsigned int r_type;
 | 
      
        |       unsigned long r_symndx;
 |       unsigned long r_symndx;
 | 
      
        |       struct elf_link_hash_entry *h;
 |       struct elf_link_hash_entry *h;
 | 
      
        |   |       Elf_Internal_Sym *isym;
 | 
      
        |   |       const char *name;
 | 
      
        |  
 |  
 | 
      
        |       r_symndx = ELF64_R_SYM (rel->r_info);
 |       r_symndx = ELF64_R_SYM (rel->r_info);
 | 
      
        |       r_type = ELF64_R_TYPE (rel->r_info);
 |       r_type = ELF64_R_TYPE (rel->r_info);
 | 
      
        |  
 |  
 | 
      
        |       if (r_symndx >= NUM_SHDR_ENTRIES (symtab_hdr))
 |       if (r_symndx >= NUM_SHDR_ENTRIES (symtab_hdr))
 | 
      
        | Line 1013... | Line 1084... | 
      
        |                                  abfd, r_symndx);
 |                                  abfd, r_symndx);
 | 
      
        |           return FALSE;
 |           return FALSE;
 | 
      
        |         }
 |         }
 | 
      
        |  
 |  
 | 
      
        |       if (r_symndx < symtab_hdr->sh_info)
 |       if (r_symndx < symtab_hdr->sh_info)
 | 
      
        |   |         {
 | 
      
        |   |           /* A local symbol.  */
 | 
      
        |   |           isym = bfd_sym_from_r_symndx (&htab->sym_cache,
 | 
      
        |   |                                         abfd, r_symndx);
 | 
      
        |   |           if (isym == NULL)
 | 
      
        |   |             return FALSE;
 | 
      
        |   |  
 | 
      
        |   |           /* Check relocation against local STT_GNU_IFUNC symbol.  */
 | 
      
        |   |           if (ELF64_ST_TYPE (isym->st_info) == STT_GNU_IFUNC)
 | 
      
        |   |             {
 | 
      
        |   |               h = elf64_x86_64_get_local_sym_hash (htab, abfd, rel,
 | 
      
        |   |                                                    TRUE);
 | 
      
        |   |               if (h == NULL)
 | 
      
        |   |                 return FALSE;
 | 
      
        |   |  
 | 
      
        |   |               /* Fake a STT_GNU_IFUNC symbol.  */
 | 
      
        |   |               h->type = STT_GNU_IFUNC;
 | 
      
        |   |               h->def_regular = 1;
 | 
      
        |   |               h->ref_regular = 1;
 | 
      
        |   |               h->forced_local = 1;
 | 
      
        |   |               h->root.type = bfd_link_hash_defined;
 | 
      
        |   |             }
 | 
      
        |   |           else
 | 
      
        |         h = NULL;
 |         h = NULL;
 | 
      
        |   |         }
 | 
      
        |       else
 |       else
 | 
      
        |         {
 |         {
 | 
      
        |   |           isym = NULL;
 | 
      
        |           h = sym_hashes[r_symndx - symtab_hdr->sh_info];
 |           h = sym_hashes[r_symndx - symtab_hdr->sh_info];
 | 
      
        |           while (h->root.type == bfd_link_hash_indirect
 |           while (h->root.type == bfd_link_hash_indirect
 | 
      
        |                  || h->root.type == bfd_link_hash_warning)
 |                  || h->root.type == bfd_link_hash_warning)
 | 
      
        |             h = (struct elf_link_hash_entry *) h->root.u.i.link;
 |             h = (struct elf_link_hash_entry *) h->root.u.i.link;
 | 
      
        |         }
 |         }
 | 
      
        |  
 |  
 | 
      
        |   |       if (h != NULL)
 | 
      
        |   |         {
 | 
      
        |   |           /* Create the ifunc sections for static executables.  If we
 | 
      
        |   |              never see an indirect function symbol nor we are building
 | 
      
        |   |              a static executable, those sections will be empty and
 | 
      
        |   |              won't appear in output.  */
 | 
      
        |   |           switch (r_type)
 | 
      
        |   |             {
 | 
      
        |   |             default:
 | 
      
        |   |               break;
 | 
      
        |   |  
 | 
      
        |   |             case R_X86_64_32S:
 | 
      
        |   |             case R_X86_64_32:
 | 
      
        |   |             case R_X86_64_64:
 | 
      
        |   |             case R_X86_64_PC32:
 | 
      
        |   |             case R_X86_64_PC64:
 | 
      
        |   |             case R_X86_64_PLT32:
 | 
      
        |   |             case R_X86_64_GOTPCREL:
 | 
      
        |   |             case R_X86_64_GOTPCREL64:
 | 
      
        |   |               if (!_bfd_elf_create_ifunc_sections (abfd, info))
 | 
      
        |   |                 return FALSE;
 | 
      
        |   |               break;
 | 
      
        |   |             }
 | 
      
        |   |  
 | 
      
        |   |           /* Since STT_GNU_IFUNC symbol must go through PLT, we handle
 | 
      
        |   |              it here if it is defined in a non-shared object.  */
 | 
      
        |   |           if (h->type == STT_GNU_IFUNC
 | 
      
        |   |               && h->def_regular)
 | 
      
        |   |             {
 | 
      
        |   |               /* 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;
 | 
      
        |   |  
 | 
      
        |   |               /* STT_GNU_IFUNC needs dynamic sections.  */
 | 
      
        |   |               if (htab->elf.dynobj == NULL)
 | 
      
        |   |                 htab->elf.dynobj = abfd;
 | 
      
        |   |  
 | 
      
        |   |               switch (r_type)
 | 
      
        |   |                 {
 | 
      
        |   |                 default:
 | 
      
        |   |                   if (h->root.root.string)
 | 
      
        |   |                     name = h->root.root.string;
 | 
      
        |   |                   else
 | 
      
        |   |                     name = bfd_elf_sym_name (abfd, symtab_hdr, isym,
 | 
      
        |   |                                              NULL);
 | 
      
        |   |                   (*_bfd_error_handler)
 | 
      
        |   |                     (_("%B: relocation %s against STT_GNU_IFUNC "
 | 
      
        |   |                        "symbol `%s' isn't handled by %s"), abfd,
 | 
      
        |   |                      x86_64_elf_howto_table[r_type].name,
 | 
      
        |   |                      name, __FUNCTION__);
 | 
      
        |   |                   bfd_set_error (bfd_error_bad_value);
 | 
      
        |   |                   return FALSE;
 | 
      
        |   |  
 | 
      
        |   |                 case R_X86_64_64:
 | 
      
        |   |                   h->non_got_ref = 1;
 | 
      
        |   |                   h->pointer_equality_needed = 1;
 | 
      
        |   |                   if (info->shared)
 | 
      
        |   |                     {
 | 
      
        |   |                       /* We must copy these reloc types into the output
 | 
      
        |   |                          file.  Create a reloc section in dynobj and
 | 
      
        |   |                          make room for this reloc.  */
 | 
      
        |   |                       sreloc = _bfd_elf_create_ifunc_dyn_reloc
 | 
      
        |   |                         (abfd, info, sec, sreloc,
 | 
      
        |   |                          &((struct elf64_x86_64_link_hash_entry *) h)->dyn_relocs);
 | 
      
        |   |                       if (sreloc == NULL)
 | 
      
        |   |                         return FALSE;
 | 
      
        |   |                     }
 | 
      
        |   |                   break;
 | 
      
        |   |  
 | 
      
        |   |                 case R_X86_64_32S:
 | 
      
        |   |                 case R_X86_64_32:
 | 
      
        |   |                 case R_X86_64_PC32:
 | 
      
        |   |                 case R_X86_64_PC64:
 | 
      
        |   |                   h->non_got_ref = 1;
 | 
      
        |   |                   if (r_type != R_X86_64_PC32
 | 
      
        |   |                       && r_type != R_X86_64_PC64)
 | 
      
        |   |                     h->pointer_equality_needed = 1;
 | 
      
        |   |                   break;
 | 
      
        |   |  
 | 
      
        |   |                 case R_X86_64_PLT32:
 | 
      
        |   |                   break;
 | 
      
        |   |  
 | 
      
        |   |                 case R_X86_64_GOTPCREL:
 | 
      
        |   |                 case R_X86_64_GOTPCREL64:
 | 
      
        |   |                   h->got.refcount += 1;
 | 
      
        |   |                   if (htab->elf.sgot == NULL
 | 
      
        |   |                       && !_bfd_elf_create_got_section (htab->elf.dynobj,
 | 
      
        |   |                                                        info))
 | 
      
        |   |                     return FALSE;
 | 
      
        |   |                   break;
 | 
      
        |   |                 }
 | 
      
        |   |  
 | 
      
        |   |               continue;
 | 
      
        |   |             }
 | 
      
        |   |         }
 | 
      
        |   |  
 | 
      
        |       if (! elf64_x86_64_tls_transition (info, abfd, sec, NULL,
 |       if (! elf64_x86_64_tls_transition (info, abfd, sec, NULL,
 | 
      
        |                                          symtab_hdr, sym_hashes,
 |                                          symtab_hdr, sym_hashes,
 | 
      
        |                                          &r_type, GOT_UNKNOWN,
 |                                          &r_type, GOT_UNKNOWN,
 | 
      
        |                                          rel, rel_end, h))
 |                                          rel, rel_end, h, r_symndx))
 | 
      
        |         return FALSE;
 |         return FALSE;
 | 
      
        |  
 |  
 | 
      
        |       switch (r_type)
 |       switch (r_type)
 | 
      
        |         {
 |         {
 | 
      
        |         case R_X86_64_TLSLD:
 |         case R_X86_64_TLSLD:
 | 
      
        |           htab->tls_ld_got.refcount += 1;
 |           htab->tls_ld_got.refcount += 1;
 | 
      
        |           goto create_got;
 |           goto create_got;
 | 
      
        |  
 |  
 | 
      
        |         case R_X86_64_TPOFF32:
 |         case R_X86_64_TPOFF32:
 | 
      
        |           if (info->shared)
 |           if (!info->executable)
 | 
      
        |             {
 |             {
 | 
      
        |   |               if (h)
 | 
      
        |   |                 name = h->root.root.string;
 | 
      
        |   |               else
 | 
      
        |   |                 name = bfd_elf_sym_name (abfd, symtab_hdr, isym,
 | 
      
        |   |                                          NULL);
 | 
      
        |               (*_bfd_error_handler)
 |               (*_bfd_error_handler)
 | 
      
        |                 (_("%B: relocation %s against `%s' can not be used when making a shared object; recompile with -fPIC"),
 |                 (_("%B: relocation %s against `%s' can not be used when making a shared object; recompile with -fPIC"),
 | 
      
        |                  abfd,
 |                  abfd,
 | 
      
        |                  x86_64_elf_howto_table[r_type].name,
 |                  x86_64_elf_howto_table[r_type].name, name);
 | 
      
        |                  (h) ? h->root.root.string : "a local symbol");
 |   | 
      
        |               bfd_set_error (bfd_error_bad_value);
 |               bfd_set_error (bfd_error_bad_value);
 | 
      
        |               return FALSE;
 |               return FALSE;
 | 
      
        |             }
 |             }
 | 
      
        |           break;
 |           break;
 | 
      
        |  
 |  
 | 
      
        |         case R_X86_64_GOTTPOFF:
 |         case R_X86_64_GOTTPOFF:
 | 
      
        |           if (info->shared)
 |           if (!info->executable)
 | 
      
        |             info->flags |= DF_STATIC_TLS;
 |             info->flags |= DF_STATIC_TLS;
 | 
      
        |           /* Fall through */
 |           /* Fall through */
 | 
      
        |  
 |  
 | 
      
        |         case R_X86_64_GOT32:
 |         case R_X86_64_GOT32:
 | 
      
        |         case R_X86_64_GOTPCREL:
 |         case R_X86_64_GOTPCREL:
 | 
      
        | Line 1128... | Line 1327... | 
      
        |                 else if (GOT_TLS_GD_ANY_P (old_tls_type)
 |                 else if (GOT_TLS_GD_ANY_P (old_tls_type)
 | 
      
        |                          && GOT_TLS_GD_ANY_P (tls_type))
 |                          && GOT_TLS_GD_ANY_P (tls_type))
 | 
      
        |                   tls_type |= old_tls_type;
 |                   tls_type |= old_tls_type;
 | 
      
        |                 else
 |                 else
 | 
      
        |                   {
 |                   {
 | 
      
        |   |                     if (h)
 | 
      
        |   |                       name = h->root.root.string;
 | 
      
        |   |                     else
 | 
      
        |   |                       name = bfd_elf_sym_name (abfd, symtab_hdr,
 | 
      
        |   |                                                isym, NULL);
 | 
      
        |                     (*_bfd_error_handler)
 |                     (*_bfd_error_handler)
 | 
      
        |                       (_("%B: '%s' accessed both as normal and thread local symbol"),
 |                       (_("%B: '%s' accessed both as normal and thread local symbol"),
 | 
      
        |                        abfd, h ? h->root.root.string : "<local>");
 |                        abfd, name);
 | 
      
        |                     return FALSE;
 |                     return FALSE;
 | 
      
        |                   }
 |                   }
 | 
      
        |               }
 |               }
 | 
      
        |  
 |  
 | 
      
        |             if (old_tls_type != tls_type)
 |             if (old_tls_type != tls_type)
 | 
      
        | Line 1149... | Line 1353... | 
      
        |  
 |  
 | 
      
        |         case R_X86_64_GOTOFF64:
 |         case R_X86_64_GOTOFF64:
 | 
      
        |         case R_X86_64_GOTPC32:
 |         case R_X86_64_GOTPC32:
 | 
      
        |         case R_X86_64_GOTPC64:
 |         case R_X86_64_GOTPC64:
 | 
      
        |         create_got:
 |         create_got:
 | 
      
        |           if (htab->sgot == NULL)
 |           if (htab->elf.sgot == NULL)
 | 
      
        |             {
 |             {
 | 
      
        |               if (htab->elf.dynobj == NULL)
 |               if (htab->elf.dynobj == NULL)
 | 
      
        |                 htab->elf.dynobj = abfd;
 |                 htab->elf.dynobj = abfd;
 | 
      
        |               if (!create_got_section (htab->elf.dynobj, info))
 |               if (!_bfd_elf_create_got_section (htab->elf.dynobj,
 | 
      
        |   |                                                 info))
 | 
      
        |                 return FALSE;
 |                 return FALSE;
 | 
      
        |             }
 |             }
 | 
      
        |           break;
 |           break;
 | 
      
        |  
 |  
 | 
      
        |         case R_X86_64_PLT32:
 |         case R_X86_64_PLT32:
 | 
      
        | Line 1197... | Line 1402... | 
      
        |              non-constant sections.  */
 |              non-constant sections.  */
 | 
      
        |           if (info->shared
 |           if (info->shared
 | 
      
        |               && (sec->flags & SEC_ALLOC) != 0
 |               && (sec->flags & SEC_ALLOC) != 0
 | 
      
        |               && (sec->flags & SEC_READONLY) != 0)
 |               && (sec->flags & SEC_READONLY) != 0)
 | 
      
        |             {
 |             {
 | 
      
        |   |               if (h)
 | 
      
        |   |                 name = h->root.root.string;
 | 
      
        |   |               else
 | 
      
        |   |                 name = bfd_elf_sym_name (abfd, symtab_hdr, isym, NULL);
 | 
      
        |               (*_bfd_error_handler)
 |               (*_bfd_error_handler)
 | 
      
        |                 (_("%B: relocation %s against `%s' can not be used when making a shared object; recompile with -fPIC"),
 |                 (_("%B: relocation %s against `%s' can not be used when making a shared object; recompile with -fPIC"),
 | 
      
        |                  abfd,
 |                  abfd, x86_64_elf_howto_table[r_type].name, name);
 | 
      
        |                  x86_64_elf_howto_table[r_type].name,
 |   | 
      
        |                  (h) ? h->root.root.string : "a local symbol");
 |   | 
      
        |               bfd_set_error (bfd_error_bad_value);
 |               bfd_set_error (bfd_error_bad_value);
 | 
      
        |               return FALSE;
 |               return FALSE;
 | 
      
        |             }
 |             }
 | 
      
        |           /* Fall through.  */
 |           /* Fall through.  */
 | 
      
        |  
 |  
 | 
      
        |         case R_X86_64_PC8:
 |         case R_X86_64_PC8:
 | 
      
        |         case R_X86_64_PC16:
 |         case R_X86_64_PC16:
 | 
      
        |         case R_X86_64_PC32:
 |         case R_X86_64_PC32:
 | 
      
        |         case R_X86_64_PC64:
 |         case R_X86_64_PC64:
 | 
      
        |         case R_X86_64_64:
 |         case R_X86_64_64:
 | 
      
        |           if (h != NULL && !info->shared)
 |           if (h != NULL && info->executable)
 | 
      
        |             {
 |             {
 | 
      
        |               /* If this reloc is in a read-only section, we might
 |               /* If this reloc is in a read-only section, we might
 | 
      
        |                  need a copy reloc.  We can't check reliably at this
 |                  need a copy reloc.  We can't check reliably at this
 | 
      
        |                  stage whether the section is read-only, as input
 |                  stage whether the section is read-only, as input
 | 
      
        |                  sections have not yet been mapped to output sections.
 |                  sections have not yet been mapped to output sections.
 | 
      
        | Line 1252... | Line 1459... | 
      
        |              may need to keep relocations for symbols satisfied by a
 |              may need to keep relocations for symbols satisfied by a
 | 
      
        |              dynamic library if we manage to avoid copy relocs for the
 |              dynamic library if we manage to avoid copy relocs for the
 | 
      
        |              symbol.  */
 |              symbol.  */
 | 
      
        |           if ((info->shared
 |           if ((info->shared
 | 
      
        |                && (sec->flags & SEC_ALLOC) != 0
 |                && (sec->flags & SEC_ALLOC) != 0
 | 
      
        |                && (((r_type != R_X86_64_PC8)
 |                && (! IS_X86_64_PCREL_TYPE (r_type)
 | 
      
        |                     && (r_type != R_X86_64_PC16)
 |   | 
      
        |                     && (r_type != R_X86_64_PC32)
 |   | 
      
        |                     && (r_type != R_X86_64_PC64))
 |   | 
      
        |                    || (h != NULL
 |                    || (h != NULL
 | 
      
        |                        && (! SYMBOLIC_BIND (info, h)
 |                        && (! SYMBOLIC_BIND (info, h)
 | 
      
        |                            || h->root.type == bfd_link_hash_defweak
 |                            || h->root.type == bfd_link_hash_defweak
 | 
      
        |                            || !h->def_regular))))
 |                            || !h->def_regular))))
 | 
      
        |               || (ELIMINATE_COPY_RELOCS
 |               || (ELIMINATE_COPY_RELOCS
 | 
      
        | Line 1267... | Line 1471... | 
      
        |                   && (sec->flags & SEC_ALLOC) != 0
 |                   && (sec->flags & SEC_ALLOC) != 0
 | 
      
        |                   && h != NULL
 |                   && h != NULL
 | 
      
        |                   && (h->root.type == bfd_link_hash_defweak
 |                   && (h->root.type == bfd_link_hash_defweak
 | 
      
        |                       || !h->def_regular)))
 |                       || !h->def_regular)))
 | 
      
        |             {
 |             {
 | 
      
        |               struct elf64_x86_64_dyn_relocs *p;
 |               struct elf_dyn_relocs *p;
 | 
      
        |               struct elf64_x86_64_dyn_relocs **head;
 |               struct elf_dyn_relocs **head;
 | 
      
        |  
 |  
 | 
      
        |               /* We must copy these reloc types into the output file.
 |               /* We must copy these reloc types into the output file.
 | 
      
        |                  Create a reloc section in dynobj and make room for
 |                  Create a reloc section in dynobj and make room for
 | 
      
        |                  this reloc.  */
 |                  this reloc.  */
 | 
      
        |               if (sreloc == NULL)
 |               if (sreloc == NULL)
 | 
      
        |                 {
 |                 {
 | 
      
        |                   const char *name;
 |   | 
      
        |                   bfd *dynobj;
 |   | 
      
        |  
 |   | 
      
        |                   name = (bfd_elf_string_from_elf_section
 |   | 
      
        |                           (abfd,
 |   | 
      
        |                            elf_elfheader (abfd)->e_shstrndx,
 |   | 
      
        |                            elf_section_data (sec)->rel_hdr.sh_name));
 |   | 
      
        |                   if (name == NULL)
 |   | 
      
        |                     return FALSE;
 |   | 
      
        |  
 |   | 
      
        |                   if (! CONST_STRNEQ (name, ".rela")
 |   | 
      
        |                       || strcmp (bfd_get_section_name (abfd, sec),
 |   | 
      
        |                                  name + 5) != 0)
 |   | 
      
        |                     {
 |   | 
      
        |                       (*_bfd_error_handler)
 |   | 
      
        |                         (_("%B: bad relocation section name `%s\'"),
 |   | 
      
        |                          abfd, name);
 |   | 
      
        |                     }
 |   | 
      
        |  
 |   | 
      
        |                   if (htab->elf.dynobj == NULL)
 |                   if (htab->elf.dynobj == NULL)
 | 
      
        |                     htab->elf.dynobj = abfd;
 |                     htab->elf.dynobj = abfd;
 | 
      
        |  
 |  
 | 
      
        |                   dynobj = htab->elf.dynobj;
 |                   sreloc = _bfd_elf_make_dynamic_reloc_section
 | 
      
        |   |                     (sec, htab->elf.dynobj, 3, abfd, /*rela?*/ TRUE);
 | 
      
        |  
 |  
 | 
      
        |                   sreloc = bfd_get_section_by_name (dynobj, name);
 |   | 
      
        |                   if (sreloc == NULL)
 |                   if (sreloc == NULL)
 | 
      
        |                     {
 |   | 
      
        |                       flagword flags;
 |   | 
      
        |  
 |   | 
      
        |                       flags = (SEC_HAS_CONTENTS | SEC_READONLY
 |   | 
      
        |                                | SEC_IN_MEMORY | SEC_LINKER_CREATED);
 |   | 
      
        |                       if ((sec->flags & SEC_ALLOC) != 0)
 |   | 
      
        |                         flags |= SEC_ALLOC | SEC_LOAD;
 |   | 
      
        |                       sreloc = bfd_make_section_with_flags (dynobj,
 |   | 
      
        |                                                             name,
 |   | 
      
        |                                                             flags);
 |   | 
      
        |                       if (sreloc == NULL
 |   | 
      
        |                           || ! bfd_set_section_alignment (dynobj, sreloc, 3))
 |   | 
      
        |                         return FALSE;
 |                         return FALSE;
 | 
      
        |                     }
 |                     }
 | 
      
        |                   elf_section_data (sec)->sreloc = sreloc;
 |   | 
      
        |                 }
 |   | 
      
        |  
 |  
 | 
      
        |               /* If this is a global symbol, we count the number of
 |               /* If this is a global symbol, we count the number of
 | 
      
        |                  relocations we need for this symbol.  */
 |                  relocations we need for this symbol.  */
 | 
      
        |               if (h != NULL)
 |               if (h != NULL)
 | 
      
        |                 {
 |                 {
 | 
      
        |                   head = &((struct elf64_x86_64_link_hash_entry *) h)->dyn_relocs;
 |                   head = &((struct elf64_x86_64_link_hash_entry *) h)->dyn_relocs;
 | 
      
        |                 }
 |                 }
 | 
      
        |               else
 |               else
 | 
      
        |                 {
 |                 {
 | 
      
        |                   void **vpp;
 |   | 
      
        |                   /* Track dynamic relocs needed for local syms too.
 |                   /* Track dynamic relocs needed for local syms too.
 | 
      
        |                      We really need local syms available to do this
 |                      We really need local syms available to do this
 | 
      
        |                      easily.  Oh well.  */
 |                      easily.  Oh well.  */
 | 
      
        |  
 |   | 
      
        |                   asection *s;
 |                   asection *s;
 | 
      
        |                   s = bfd_section_from_r_symndx (abfd, &htab->sym_sec,
 |                   void **vpp;
 | 
      
        |                                                  sec, r_symndx);
 |                   Elf_Internal_Sym *isym;
 | 
      
        |                   if (s == NULL)
 |  
 | 
      
        |   |                   isym = bfd_sym_from_r_symndx (&htab->sym_cache,
 | 
      
        |   |                                                 abfd, r_symndx);
 | 
      
        |   |                   if (isym == NULL)
 | 
      
        |                     return FALSE;
 |                     return FALSE;
 | 
      
        |  
 |  
 | 
      
        |   |                   s = bfd_section_from_elf_index (abfd, isym->st_shndx);
 | 
      
        |   |                   if (s == NULL)
 | 
      
        |   |                     s = sec;
 | 
      
        |   |  
 | 
      
        |                   /* Beware of type punned pointers vs strict aliasing
 |                   /* Beware of type punned pointers vs strict aliasing
 | 
      
        |                      rules.  */
 |                      rules.  */
 | 
      
        |                   vpp = &(elf_section_data (s)->local_dynrel);
 |                   vpp = &(elf_section_data (s)->local_dynrel);
 | 
      
        |                   head = (struct elf64_x86_64_dyn_relocs **)vpp;
 |                   head = (struct elf_dyn_relocs **)vpp;
 | 
      
        |                 }
 |                 }
 | 
      
        |  
 |  
 | 
      
        |               p = *head;
 |               p = *head;
 | 
      
        |               if (p == NULL || p->sec != sec)
 |               if (p == NULL || p->sec != sec)
 | 
      
        |                 {
 |                 {
 | 
      
        |                   bfd_size_type amt = sizeof *p;
 |                   bfd_size_type amt = sizeof *p;
 | 
      
        |                   p = ((struct elf64_x86_64_dyn_relocs *)
 |  
 | 
      
        |   |                   p = ((struct elf_dyn_relocs *)
 | 
      
        |                        bfd_alloc (htab->elf.dynobj, amt));
 |                        bfd_alloc (htab->elf.dynobj, amt));
 | 
      
        |                   if (p == NULL)
 |                   if (p == NULL)
 | 
      
        |                     return FALSE;
 |                     return FALSE;
 | 
      
        |                   p->next = *head;
 |                   p->next = *head;
 | 
      
        |                   *head = p;
 |                   *head = p;
 | 
      
        | Line 1359... | Line 1536... | 
      
        |                   p->count = 0;
 |                   p->count = 0;
 | 
      
        |                   p->pc_count = 0;
 |                   p->pc_count = 0;
 | 
      
        |                 }
 |                 }
 | 
      
        |  
 |  
 | 
      
        |               p->count += 1;
 |               p->count += 1;
 | 
      
        |               if (r_type == R_X86_64_PC8
 |               if (IS_X86_64_PCREL_TYPE (r_type))
 | 
      
        |                   || r_type == R_X86_64_PC16
 |   | 
      
        |                   || r_type == R_X86_64_PC32
 |   | 
      
        |                   || r_type == R_X86_64_PC64)
 |   | 
      
        |                 p->pc_count += 1;
 |                 p->pc_count += 1;
 | 
      
        |             }
 |             }
 | 
      
        |           break;
 |           break;
 | 
      
        |  
 |  
 | 
      
        |           /* This relocation describes the C++ object vtable hierarchy.
 |           /* This relocation describes the C++ object vtable hierarchy.
 | 
      
        | Line 1444... | Line 1618... | 
      
        |  
 |  
 | 
      
        |       r_symndx = ELF64_R_SYM (rel->r_info);
 |       r_symndx = ELF64_R_SYM (rel->r_info);
 | 
      
        |       if (r_symndx >= symtab_hdr->sh_info)
 |       if (r_symndx >= symtab_hdr->sh_info)
 | 
      
        |         {
 |         {
 | 
      
        |           struct elf64_x86_64_link_hash_entry *eh;
 |           struct elf64_x86_64_link_hash_entry *eh;
 | 
      
        |           struct elf64_x86_64_dyn_relocs **pp;
 |           struct elf_dyn_relocs **pp;
 | 
      
        |           struct elf64_x86_64_dyn_relocs *p;
 |           struct elf_dyn_relocs *p;
 | 
      
        |  
 |  
 | 
      
        |           h = sym_hashes[r_symndx - symtab_hdr->sh_info];
 |           h = sym_hashes[r_symndx - symtab_hdr->sh_info];
 | 
      
        |           while (h->root.type == bfd_link_hash_indirect
 |           while (h->root.type == bfd_link_hash_indirect
 | 
      
        |                  || h->root.type == bfd_link_hash_warning)
 |                  || h->root.type == bfd_link_hash_warning)
 | 
      
        |             h = (struct elf_link_hash_entry *) h->root.u.i.link;
 |             h = (struct elf_link_hash_entry *) h->root.u.i.link;
 | 
      
        | Line 1466... | Line 1640... | 
      
        |  
 |  
 | 
      
        |       r_type = ELF64_R_TYPE (rel->r_info);
 |       r_type = ELF64_R_TYPE (rel->r_info);
 | 
      
        |       if (! elf64_x86_64_tls_transition (info, abfd, sec, NULL,
 |       if (! elf64_x86_64_tls_transition (info, abfd, sec, NULL,
 | 
      
        |                                          symtab_hdr, sym_hashes,
 |                                          symtab_hdr, sym_hashes,
 | 
      
        |                                          &r_type, GOT_UNKNOWN,
 |                                          &r_type, GOT_UNKNOWN,
 | 
      
        |                                          rel, relend, h))
 |                                          rel, relend, h, r_symndx))
 | 
      
        |         return FALSE;
 |         return FALSE;
 | 
      
        |  
 |  
 | 
      
        |       switch (r_type)
 |       switch (r_type)
 | 
      
        |         {
 |         {
 | 
      
        |         case R_X86_64_TLSLD:
 |         case R_X86_64_TLSLD:
 | 
      
        | Line 1542... | Line 1716... | 
      
        |                                     struct elf_link_hash_entry *h)
 |                                     struct elf_link_hash_entry *h)
 | 
      
        | {
 | {
 | 
      
        |   struct elf64_x86_64_link_hash_table *htab;
 |   struct elf64_x86_64_link_hash_table *htab;
 | 
      
        |   asection *s;
 |   asection *s;
 | 
      
        |  
 |  
 | 
      
        |   |   /* STT_GNU_IFUNC symbol must go through PLT. */
 | 
      
        |   |   if (h->type == STT_GNU_IFUNC)
 | 
      
        |   |     {
 | 
      
        |   |       if (h->plt.refcount <= 0)
 | 
      
        |   |         {
 | 
      
        |   |           h->plt.offset = (bfd_vma) -1;
 | 
      
        |   |           h->needs_plt = 0;
 | 
      
        |   |         }
 | 
      
        |   |       return TRUE;
 | 
      
        |   |     }
 | 
      
        |   |  
 | 
      
        |   /* If this is a function, put it in the procedure linkage table.  We
 |   /* If this is a function, put it in the procedure linkage table.  We
 | 
      
        |      will fill in the contents of the procedure linkage table later,
 |      will fill in the contents of the procedure linkage table later,
 | 
      
        |      when we know the address of the .got section.  */
 |      when we know the address of the .got section.  */
 | 
      
        |   if (h->type == STT_FUNC
 |   if (h->type == STT_FUNC
 | 
      
        |       || h->needs_plt)
 |       || h->needs_plt)
 | 
      
        | Line 1611... | Line 1796... | 
      
        |     }
 |     }
 | 
      
        |  
 |  
 | 
      
        |   if (ELIMINATE_COPY_RELOCS)
 |   if (ELIMINATE_COPY_RELOCS)
 | 
      
        |     {
 |     {
 | 
      
        |       struct elf64_x86_64_link_hash_entry * eh;
 |       struct elf64_x86_64_link_hash_entry * eh;
 | 
      
        |       struct elf64_x86_64_dyn_relocs *p;
 |       struct elf_dyn_relocs *p;
 | 
      
        |  
 |  
 | 
      
        |       eh = (struct elf64_x86_64_link_hash_entry *) h;
 |       eh = (struct elf64_x86_64_link_hash_entry *) h;
 | 
      
        |       for (p = eh->dyn_relocs; p != NULL; p = p->next)
 |       for (p = eh->dyn_relocs; p != NULL; p = p->next)
 | 
      
        |         {
 |         {
 | 
      
        |           s = p->sec->output_section;
 |           s = p->sec->output_section;
 | 
      
        | Line 1667... | Line 1852... | 
      
        |  
 |  
 | 
      
        | /* Allocate space in .plt, .got and associated reloc sections for
 | /* Allocate space in .plt, .got and associated reloc sections for
 | 
      
        |    dynamic relocs.  */
 |    dynamic relocs.  */
 | 
      
        |  
 |  
 | 
      
        | static bfd_boolean
 | static bfd_boolean
 | 
      
        | allocate_dynrelocs (struct elf_link_hash_entry *h, void * inf)
 | elf64_x86_64_allocate_dynrelocs (struct elf_link_hash_entry *h, void * inf)
 | 
      
        | {
 | {
 | 
      
        |   struct bfd_link_info *info;
 |   struct bfd_link_info *info;
 | 
      
        |   struct elf64_x86_64_link_hash_table *htab;
 |   struct elf64_x86_64_link_hash_table *htab;
 | 
      
        |   struct elf64_x86_64_link_hash_entry *eh;
 |   struct elf64_x86_64_link_hash_entry *eh;
 | 
      
        |   struct elf64_x86_64_dyn_relocs *p;
 |   struct elf_dyn_relocs *p;
 | 
      
        |  
 |  
 | 
      
        |   if (h->root.type == bfd_link_hash_indirect)
 |   if (h->root.type == bfd_link_hash_indirect)
 | 
      
        |     return TRUE;
 |     return TRUE;
 | 
      
        |  
 |  
 | 
      
        |   if (h->root.type == bfd_link_hash_warning)
 |   if (h->root.type == bfd_link_hash_warning)
 | 
      
        |     h = (struct elf_link_hash_entry *) h->root.u.i.link;
 |     h = (struct elf_link_hash_entry *) h->root.u.i.link;
 | 
      
        |   |   eh = (struct elf64_x86_64_link_hash_entry *) h;
 | 
      
        |  
 |  
 | 
      
        |   info = (struct bfd_link_info *) inf;
 |   info = (struct bfd_link_info *) inf;
 | 
      
        |   htab = elf64_x86_64_hash_table (info);
 |   htab = elf64_x86_64_hash_table (info);
 | 
      
        |  
 |  
 | 
      
        |   if (htab->elf.dynamic_sections_created
 |   /* Since STT_GNU_IFUNC symbol must go through PLT, we handle it
 | 
      
        |   |      here if it is defined and referenced in a non-shared object.  */
 | 
      
        |   |   if (h->type == STT_GNU_IFUNC
 | 
      
        |   |       && h->def_regular)
 | 
      
        |   |     return _bfd_elf_allocate_ifunc_dyn_relocs (info, h,
 | 
      
        |   |                                                &eh->dyn_relocs,
 | 
      
        |   |                                                PLT_ENTRY_SIZE,
 | 
      
        |   |                                                GOT_ENTRY_SIZE);
 | 
      
        |   |   else if (htab->elf.dynamic_sections_created
 | 
      
        |       && h->plt.refcount > 0)
 |       && h->plt.refcount > 0)
 | 
      
        |     {
 |     {
 | 
      
        |       /* Make sure this symbol is output as a dynamic symbol.
 |       /* Make sure this symbol is output as a dynamic symbol.
 | 
      
        |          Undefined weak syms won't yet be marked as dynamic.  */
 |          Undefined weak syms won't yet be marked as dynamic.  */
 | 
      
        |       if (h->dynindx == -1
 |       if (h->dynindx == -1
 | 
      
        | Line 1698... | Line 1892... | 
      
        |         }
 |         }
 | 
      
        |  
 |  
 | 
      
        |       if (info->shared
 |       if (info->shared
 | 
      
        |           || WILL_CALL_FINISH_DYNAMIC_SYMBOL (1, 0, h))
 |           || WILL_CALL_FINISH_DYNAMIC_SYMBOL (1, 0, h))
 | 
      
        |         {
 |         {
 | 
      
        |           asection *s = htab->splt;
 |           asection *s = htab->elf.splt;
 | 
      
        |  
 |  
 | 
      
        |           /* If this is the first .plt entry, make room for the special
 |           /* If this is the first .plt entry, make room for the special
 | 
      
        |              first entry.  */
 |              first entry.  */
 | 
      
        |           if (s->size == 0)
 |           if (s->size == 0)
 | 
      
        |             s->size += PLT_ENTRY_SIZE;
 |             s->size += PLT_ENTRY_SIZE;
 | 
      
        | Line 1724... | Line 1918... | 
      
        |           /* Make room for this entry.  */
 |           /* Make room for this entry.  */
 | 
      
        |           s->size += PLT_ENTRY_SIZE;
 |           s->size += PLT_ENTRY_SIZE;
 | 
      
        |  
 |  
 | 
      
        |           /* We also need to make an entry in the .got.plt section, which
 |           /* We also need to make an entry in the .got.plt section, which
 | 
      
        |              will be placed in the .got section by the linker script.  */
 |              will be placed in the .got section by the linker script.  */
 | 
      
        |           htab->sgotplt->size += GOT_ENTRY_SIZE;
 |           htab->elf.sgotplt->size += GOT_ENTRY_SIZE;
 | 
      
        |  
 |  
 | 
      
        |           /* We also need to make an entry in the .rela.plt section.  */
 |           /* We also need to make an entry in the .rela.plt section.  */
 | 
      
        |           htab->srelplt->size += sizeof (Elf64_External_Rela);
 |           htab->elf.srelplt->size += sizeof (Elf64_External_Rela);
 | 
      
        |           htab->srelplt->reloc_count++;
 |           htab->elf.srelplt->reloc_count++;
 | 
      
        |         }
 |         }
 | 
      
        |       else
 |       else
 | 
      
        |         {
 |         {
 | 
      
        |           h->plt.offset = (bfd_vma) -1;
 |           h->plt.offset = (bfd_vma) -1;
 | 
      
        |           h->needs_plt = 0;
 |           h->needs_plt = 0;
 | 
      
        | Line 1742... | Line 1936... | 
      
        |     {
 |     {
 | 
      
        |       h->plt.offset = (bfd_vma) -1;
 |       h->plt.offset = (bfd_vma) -1;
 | 
      
        |       h->needs_plt = 0;
 |       h->needs_plt = 0;
 | 
      
        |     }
 |     }
 | 
      
        |  
 |  
 | 
      
        |   eh = (struct elf64_x86_64_link_hash_entry *) h;
 |   | 
      
        |   eh->tlsdesc_got = (bfd_vma) -1;
 |   eh->tlsdesc_got = (bfd_vma) -1;
 | 
      
        |  
 |  
 | 
      
        |   /* If R_X86_64_GOTTPOFF symbol is now local to the binary,
 |   /* If R_X86_64_GOTTPOFF symbol is now local to the binary,
 | 
      
        |      make it a R_X86_64_TPOFF32 requiring no GOT entry.  */
 |      make it a R_X86_64_TPOFF32 requiring no GOT entry.  */
 | 
      
        |   if (h->got.refcount > 0
 |   if (h->got.refcount > 0
 | 
      
        |       && !info->shared
 |       && info->executable
 | 
      
        |       && h->dynindx == -1
 |       && h->dynindx == -1
 | 
      
        |       && elf64_x86_64_hash_entry (h)->tls_type == GOT_TLS_IE)
 |       && elf64_x86_64_hash_entry (h)->tls_type == GOT_TLS_IE)
 | 
      
        |   |     {
 | 
      
        |     h->got.offset = (bfd_vma) -1;
 |     h->got.offset = (bfd_vma) -1;
 | 
      
        |   |     }
 | 
      
        |   else if (h->got.refcount > 0)
 |   else if (h->got.refcount > 0)
 | 
      
        |     {
 |     {
 | 
      
        |       asection *s;
 |       asection *s;
 | 
      
        |       bfd_boolean dyn;
 |       bfd_boolean dyn;
 | 
      
        |       int tls_type = elf64_x86_64_hash_entry (h)->tls_type;
 |       int tls_type = elf64_x86_64_hash_entry (h)->tls_type;
 | 
      
        | Line 1769... | Line 1964... | 
      
        |             return FALSE;
 |             return FALSE;
 | 
      
        |         }
 |         }
 | 
      
        |  
 |  
 | 
      
        |       if (GOT_TLS_GDESC_P (tls_type))
 |       if (GOT_TLS_GDESC_P (tls_type))
 | 
      
        |         {
 |         {
 | 
      
        |           eh->tlsdesc_got = htab->sgotplt->size
 |           eh->tlsdesc_got = htab->elf.sgotplt->size
 | 
      
        |             - elf64_x86_64_compute_jump_table_size (htab);
 |             - elf64_x86_64_compute_jump_table_size (htab);
 | 
      
        |           htab->sgotplt->size += 2 * GOT_ENTRY_SIZE;
 |           htab->elf.sgotplt->size += 2 * GOT_ENTRY_SIZE;
 | 
      
        |           h->got.offset = (bfd_vma) -2;
 |           h->got.offset = (bfd_vma) -2;
 | 
      
        |         }
 |         }
 | 
      
        |       if (! GOT_TLS_GDESC_P (tls_type)
 |       if (! GOT_TLS_GDESC_P (tls_type)
 | 
      
        |           || GOT_TLS_GD_P (tls_type))
 |           || GOT_TLS_GD_P (tls_type))
 | 
      
        |         {
 |         {
 | 
      
        |           s = htab->sgot;
 |           s = htab->elf.sgot;
 | 
      
        |           h->got.offset = s->size;
 |           h->got.offset = s->size;
 | 
      
        |           s->size += GOT_ENTRY_SIZE;
 |           s->size += GOT_ENTRY_SIZE;
 | 
      
        |           if (GOT_TLS_GD_P (tls_type))
 |           if (GOT_TLS_GD_P (tls_type))
 | 
      
        |             s->size += GOT_ENTRY_SIZE;
 |             s->size += GOT_ENTRY_SIZE;
 | 
      
        |         }
 |         }
 | 
      
        | Line 1789... | Line 1984... | 
      
        |       /* R_X86_64_TLSGD needs one dynamic relocation if local symbol
 |       /* R_X86_64_TLSGD needs one dynamic relocation if local symbol
 | 
      
        |          and two if global.
 |          and two if global.
 | 
      
        |          R_X86_64_GOTTPOFF needs one dynamic relocation.  */
 |          R_X86_64_GOTTPOFF needs one dynamic relocation.  */
 | 
      
        |       if ((GOT_TLS_GD_P (tls_type) && h->dynindx == -1)
 |       if ((GOT_TLS_GD_P (tls_type) && h->dynindx == -1)
 | 
      
        |           || tls_type == GOT_TLS_IE)
 |           || tls_type == GOT_TLS_IE)
 | 
      
        |         htab->srelgot->size += sizeof (Elf64_External_Rela);
 |         htab->elf.srelgot->size += sizeof (Elf64_External_Rela);
 | 
      
        |       else if (GOT_TLS_GD_P (tls_type))
 |       else if (GOT_TLS_GD_P (tls_type))
 | 
      
        |         htab->srelgot->size += 2 * sizeof (Elf64_External_Rela);
 |         htab->elf.srelgot->size += 2 * sizeof (Elf64_External_Rela);
 | 
      
        |       else if (! GOT_TLS_GDESC_P (tls_type)
 |       else if (! GOT_TLS_GDESC_P (tls_type)
 | 
      
        |                && (ELF_ST_VISIBILITY (h->other) == STV_DEFAULT
 |                && (ELF_ST_VISIBILITY (h->other) == STV_DEFAULT
 | 
      
        |                    || h->root.type != bfd_link_hash_undefweak)
 |                    || h->root.type != bfd_link_hash_undefweak)
 | 
      
        |                && (info->shared
 |                && (info->shared
 | 
      
        |                    || WILL_CALL_FINISH_DYNAMIC_SYMBOL (dyn, 0, h)))
 |                    || WILL_CALL_FINISH_DYNAMIC_SYMBOL (dyn, 0, h)))
 | 
      
        |         htab->srelgot->size += sizeof (Elf64_External_Rela);
 |         htab->elf.srelgot->size += sizeof (Elf64_External_Rela);
 | 
      
        |       if (GOT_TLS_GDESC_P (tls_type))
 |       if (GOT_TLS_GDESC_P (tls_type))
 | 
      
        |         {
 |         {
 | 
      
        |           htab->srelplt->size += sizeof (Elf64_External_Rela);
 |           htab->elf.srelplt->size += sizeof (Elf64_External_Rela);
 | 
      
        |           htab->tlsdesc_plt = (bfd_vma) -1;
 |           htab->tlsdesc_plt = (bfd_vma) -1;
 | 
      
        |         }
 |         }
 | 
      
        |     }
 |     }
 | 
      
        |   else
 |   else
 | 
      
        |     h->got.offset = (bfd_vma) -1;
 |     h->got.offset = (bfd_vma) -1;
 | 
      
        | Line 1826... | Line 2021... | 
      
        |          function rather than going via the plt.  If people want
 |          function rather than going via the plt.  If people want
 | 
      
        |          function pointer comparisons to work as expected then they
 |          function pointer comparisons to work as expected then they
 | 
      
        |          should avoid writing weird assembly.  */
 |          should avoid writing weird assembly.  */
 | 
      
        |       if (SYMBOL_CALLS_LOCAL (info, h))
 |       if (SYMBOL_CALLS_LOCAL (info, h))
 | 
      
        |         {
 |         {
 | 
      
        |           struct elf64_x86_64_dyn_relocs **pp;
 |           struct elf_dyn_relocs **pp;
 | 
      
        |  
 |  
 | 
      
        |           for (pp = &eh->dyn_relocs; (p = *pp) != NULL; )
 |           for (pp = &eh->dyn_relocs; (p = *pp) != NULL; )
 | 
      
        |             {
 |             {
 | 
      
        |               p->count -= p->pc_count;
 |               p->count -= p->pc_count;
 | 
      
        |               p->pc_count = 0;
 |               p->pc_count = 0;
 | 
      
        | Line 1850... | Line 2045... | 
      
        |             eh->dyn_relocs = NULL;
 |             eh->dyn_relocs = NULL;
 | 
      
        |  
 |  
 | 
      
        |           /* Make sure undefined weak symbols are output as a dynamic
 |           /* Make sure undefined weak symbols are output as a dynamic
 | 
      
        |              symbol in PIEs.  */
 |              symbol in PIEs.  */
 | 
      
        |           else if (h->dynindx == -1
 |           else if (h->dynindx == -1
 | 
      
        |                    && !h->forced_local)
 |                    && ! h->forced_local
 | 
      
        |             {
 |                    && ! bfd_elf_link_record_dynamic_symbol (info, h))
 | 
      
        |               if (! bfd_elf_link_record_dynamic_symbol (info, h))
 |   | 
      
        |                 return FALSE;
 |                 return FALSE;
 | 
      
        |             }
 |             }
 | 
      
        |         }
 |  
 | 
      
        |     }
 |     }
 | 
      
        |   else if (ELIMINATE_COPY_RELOCS)
 |   else if (ELIMINATE_COPY_RELOCS)
 | 
      
        |     {
 |     {
 | 
      
        |       /* For the non-shared case, discard space for relocs against
 |       /* For the non-shared case, discard space for relocs against
 | 
      
        |          symbols which turn out to need copy relocs or are not
 |          symbols which turn out to need copy relocs or are not
 | 
      
        | Line 1873... | Line 2067... | 
      
        |                       || h->root.type == bfd_link_hash_undefined))))
 |                       || h->root.type == bfd_link_hash_undefined))))
 | 
      
        |         {
 |         {
 | 
      
        |           /* Make sure this symbol is output as a dynamic symbol.
 |           /* Make sure this symbol is output as a dynamic symbol.
 | 
      
        |              Undefined weak syms won't yet be marked as dynamic.  */
 |              Undefined weak syms won't yet be marked as dynamic.  */
 | 
      
        |           if (h->dynindx == -1
 |           if (h->dynindx == -1
 | 
      
        |               && !h->forced_local)
 |               && ! h->forced_local
 | 
      
        |             {
 |               && ! bfd_elf_link_record_dynamic_symbol (info, h))
 | 
      
        |               if (! bfd_elf_link_record_dynamic_symbol (info, h))
 |   | 
      
        |                 return FALSE;
 |                 return FALSE;
 | 
      
        |             }
 |   | 
      
        |  
 |  
 | 
      
        |           /* If that succeeded, we know we'll be keeping all the
 |           /* If that succeeded, we know we'll be keeping all the
 | 
      
        |              relocs.  */
 |              relocs.  */
 | 
      
        |           if (h->dynindx != -1)
 |           if (h->dynindx != -1)
 | 
      
        |             goto keep;
 |             goto keep;
 | 
      
        | Line 1893... | Line 2085... | 
      
        |     }
 |     }
 | 
      
        |  
 |  
 | 
      
        |   /* Finally, allocate space.  */
 |   /* Finally, allocate space.  */
 | 
      
        |   for (p = eh->dyn_relocs; p != NULL; p = p->next)
 |   for (p = eh->dyn_relocs; p != NULL; p = p->next)
 | 
      
        |     {
 |     {
 | 
      
        |       asection *sreloc = elf_section_data (p->sec)->sreloc;
 |       asection * sreloc;
 | 
      
        |   |  
 | 
      
        |   |       sreloc = elf_section_data (p->sec)->sreloc;
 | 
      
        |   |  
 | 
      
        |   |       BFD_ASSERT (sreloc != NULL);
 | 
      
        |   |  
 | 
      
        |       sreloc->size += p->count * sizeof (Elf64_External_Rela);
 |       sreloc->size += p->count * sizeof (Elf64_External_Rela);
 | 
      
        |     }
 |     }
 | 
      
        |  
 |  
 | 
      
        |   return TRUE;
 |   return TRUE;
 | 
      
        | }
 | }
 | 
      
        |  
 |  
 | 
      
        |   | /* Allocate space in .plt, .got and associated reloc sections for
 | 
      
        |   |    local dynamic relocs.  */
 | 
      
        |   |  
 | 
      
        |   | static bfd_boolean
 | 
      
        |   | elf64_x86_64_allocate_local_dynrelocs (void **slot, void *inf)
 | 
      
        |   | {
 | 
      
        |   |   struct elf_link_hash_entry *h
 | 
      
        |   |     = (struct elf_link_hash_entry *) *slot;
 | 
      
        |   |  
 | 
      
        |   |   if (h->type != STT_GNU_IFUNC
 | 
      
        |   |       || !h->def_regular
 | 
      
        |   |       || !h->ref_regular
 | 
      
        |   |       || !h->forced_local
 | 
      
        |   |       || h->root.type != bfd_link_hash_defined)
 | 
      
        |   |     abort ();
 | 
      
        |   |  
 | 
      
        |   |   return elf64_x86_64_allocate_dynrelocs (h, inf);
 | 
      
        |   | }
 | 
      
        |   |  
 | 
      
        | /* Find any dynamic relocs that apply to read-only sections.  */
 | /* Find any dynamic relocs that apply to read-only sections.  */
 | 
      
        |  
 |  
 | 
      
        | static bfd_boolean
 | static bfd_boolean
 | 
      
        | readonly_dynrelocs (struct elf_link_hash_entry *h, void * inf)
 | elf64_x86_64_readonly_dynrelocs (struct elf_link_hash_entry *h, void * inf)
 | 
      
        | {
 | {
 | 
      
        |   struct elf64_x86_64_link_hash_entry *eh;
 |   struct elf64_x86_64_link_hash_entry *eh;
 | 
      
        |   struct elf64_x86_64_dyn_relocs *p;
 |   struct elf_dyn_relocs *p;
 | 
      
        |  
 |  
 | 
      
        |   if (h->root.type == bfd_link_hash_warning)
 |   if (h->root.type == bfd_link_hash_warning)
 | 
      
        |     h = (struct elf_link_hash_entry *) h->root.u.i.link;
 |     h = (struct elf_link_hash_entry *) h->root.u.i.link;
 | 
      
        |  
 |  
 | 
      
        |   eh = (struct elf64_x86_64_link_hash_entry *) h;
 |   eh = (struct elf64_x86_64_link_hash_entry *) h;
 | 
      
        | Line 1976... | Line 2192... | 
      
        |       if (! is_x86_64_elf (ibfd))
 |       if (! is_x86_64_elf (ibfd))
 | 
      
        |         continue;
 |         continue;
 | 
      
        |  
 |  
 | 
      
        |       for (s = ibfd->sections; s != NULL; s = s->next)
 |       for (s = ibfd->sections; s != NULL; s = s->next)
 | 
      
        |         {
 |         {
 | 
      
        |           struct elf64_x86_64_dyn_relocs *p;
 |           struct elf_dyn_relocs *p;
 | 
      
        |  
 |  
 | 
      
        |           for (p = (struct elf64_x86_64_dyn_relocs *)
 |           for (p = (struct elf_dyn_relocs *)
 | 
      
        |                     (elf_section_data (s)->local_dynrel);
 |                     (elf_section_data (s)->local_dynrel);
 | 
      
        |                p != NULL;
 |                p != NULL;
 | 
      
        |                p = p->next)
 |                p = p->next)
 | 
      
        |             {
 |             {
 | 
      
        |               if (!bfd_is_abs_section (p->sec)
 |               if (!bfd_is_abs_section (p->sec)
 | 
      
        | Line 1997... | Line 2213... | 
      
        |                 {
 |                 {
 | 
      
        |                   srel = elf_section_data (p->sec)->sreloc;
 |                   srel = elf_section_data (p->sec)->sreloc;
 | 
      
        |                   srel->size += p->count * sizeof (Elf64_External_Rela);
 |                   srel->size += p->count * sizeof (Elf64_External_Rela);
 | 
      
        |                   if ((p->sec->output_section->flags & SEC_READONLY) != 0)
 |                   if ((p->sec->output_section->flags & SEC_READONLY) != 0)
 | 
      
        |                     info->flags |= DF_TEXTREL;
 |                     info->flags |= DF_TEXTREL;
 | 
      
        |  
 |   | 
      
        |                 }
 |                 }
 | 
      
        |             }
 |             }
 | 
      
        |         }
 |         }
 | 
      
        |  
 |  
 | 
      
        |       local_got = elf_local_got_refcounts (ibfd);
 |       local_got = elf_local_got_refcounts (ibfd);
 | 
      
        | Line 2011... | Line 2226... | 
      
        |       symtab_hdr = &elf_symtab_hdr (ibfd);
 |       symtab_hdr = &elf_symtab_hdr (ibfd);
 | 
      
        |       locsymcount = symtab_hdr->sh_info;
 |       locsymcount = symtab_hdr->sh_info;
 | 
      
        |       end_local_got = local_got + locsymcount;
 |       end_local_got = local_got + locsymcount;
 | 
      
        |       local_tls_type = elf64_x86_64_local_got_tls_type (ibfd);
 |       local_tls_type = elf64_x86_64_local_got_tls_type (ibfd);
 | 
      
        |       local_tlsdesc_gotent = elf64_x86_64_local_tlsdesc_gotent (ibfd);
 |       local_tlsdesc_gotent = elf64_x86_64_local_tlsdesc_gotent (ibfd);
 | 
      
        |       s = htab->sgot;
 |       s = htab->elf.sgot;
 | 
      
        |       srel = htab->srelgot;
 |       srel = htab->elf.srelgot;
 | 
      
        |       for (; local_got < end_local_got;
 |       for (; local_got < end_local_got;
 | 
      
        |            ++local_got, ++local_tls_type, ++local_tlsdesc_gotent)
 |            ++local_got, ++local_tls_type, ++local_tlsdesc_gotent)
 | 
      
        |         {
 |         {
 | 
      
        |           *local_tlsdesc_gotent = (bfd_vma) -1;
 |           *local_tlsdesc_gotent = (bfd_vma) -1;
 | 
      
        |           if (*local_got > 0)
 |           if (*local_got > 0)
 | 
      
        |             {
 |             {
 | 
      
        |               if (GOT_TLS_GDESC_P (*local_tls_type))
 |               if (GOT_TLS_GDESC_P (*local_tls_type))
 | 
      
        |                 {
 |                 {
 | 
      
        |                   *local_tlsdesc_gotent = htab->sgotplt->size
 |                   *local_tlsdesc_gotent = htab->elf.sgotplt->size
 | 
      
        |                     - elf64_x86_64_compute_jump_table_size (htab);
 |                     - elf64_x86_64_compute_jump_table_size (htab);
 | 
      
        |                   htab->sgotplt->size += 2 * GOT_ENTRY_SIZE;
 |                   htab->elf.sgotplt->size += 2 * GOT_ENTRY_SIZE;
 | 
      
        |                   *local_got = (bfd_vma) -2;
 |                   *local_got = (bfd_vma) -2;
 | 
      
        |                 }
 |                 }
 | 
      
        |               if (! GOT_TLS_GDESC_P (*local_tls_type)
 |               if (! GOT_TLS_GDESC_P (*local_tls_type)
 | 
      
        |                   || GOT_TLS_GD_P (*local_tls_type))
 |                   || GOT_TLS_GD_P (*local_tls_type))
 | 
      
        |                 {
 |                 {
 | 
      
        | Line 2040... | Line 2255... | 
      
        |                   || GOT_TLS_GD_ANY_P (*local_tls_type)
 |                   || GOT_TLS_GD_ANY_P (*local_tls_type)
 | 
      
        |                   || *local_tls_type == GOT_TLS_IE)
 |                   || *local_tls_type == GOT_TLS_IE)
 | 
      
        |                 {
 |                 {
 | 
      
        |                   if (GOT_TLS_GDESC_P (*local_tls_type))
 |                   if (GOT_TLS_GDESC_P (*local_tls_type))
 | 
      
        |                     {
 |                     {
 | 
      
        |                       htab->srelplt->size += sizeof (Elf64_External_Rela);
 |                       htab->elf.srelplt->size
 | 
      
        |   |                         += sizeof (Elf64_External_Rela);
 | 
      
        |                       htab->tlsdesc_plt = (bfd_vma) -1;
 |                       htab->tlsdesc_plt = (bfd_vma) -1;
 | 
      
        |                     }
 |                     }
 | 
      
        |                   if (! GOT_TLS_GDESC_P (*local_tls_type)
 |                   if (! GOT_TLS_GDESC_P (*local_tls_type)
 | 
      
        |                       || GOT_TLS_GD_P (*local_tls_type))
 |                       || GOT_TLS_GD_P (*local_tls_type))
 | 
      
        |                     srel->size += sizeof (Elf64_External_Rela);
 |                     srel->size += sizeof (Elf64_External_Rela);
 | 
      
        | Line 2057... | Line 2273... | 
      
        |  
 |  
 | 
      
        |   if (htab->tls_ld_got.refcount > 0)
 |   if (htab->tls_ld_got.refcount > 0)
 | 
      
        |     {
 |     {
 | 
      
        |       /* Allocate 2 got entries and 1 dynamic reloc for R_X86_64_TLSLD
 |       /* Allocate 2 got entries and 1 dynamic reloc for R_X86_64_TLSLD
 | 
      
        |          relocs.  */
 |          relocs.  */
 | 
      
        |       htab->tls_ld_got.offset = htab->sgot->size;
 |       htab->tls_ld_got.offset = htab->elf.sgot->size;
 | 
      
        |       htab->sgot->size += 2 * GOT_ENTRY_SIZE;
 |       htab->elf.sgot->size += 2 * GOT_ENTRY_SIZE;
 | 
      
        |       htab->srelgot->size += sizeof (Elf64_External_Rela);
 |       htab->elf.srelgot->size += sizeof (Elf64_External_Rela);
 | 
      
        |     }
 |     }
 | 
      
        |   else
 |   else
 | 
      
        |     htab->tls_ld_got.offset = -1;
 |     htab->tls_ld_got.offset = -1;
 | 
      
        |  
 |  
 | 
      
        |   /* Allocate global sym .plt and .got entries, and space for global
 |   /* Allocate global sym .plt and .got entries, and space for global
 | 
      
        |      sym dynamic relocs.  */
 |      sym dynamic relocs.  */
 | 
      
        |   elf_link_hash_traverse (&htab->elf, allocate_dynrelocs, (PTR) info);
 |   elf_link_hash_traverse (&htab->elf, elf64_x86_64_allocate_dynrelocs,
 | 
      
        |   |                           info);
 | 
      
        |   |  
 | 
      
        |   |   /* Allocate .plt and .got entries, and space for local symbols.  */
 | 
      
        |   |   htab_traverse (htab->loc_hash_table,
 | 
      
        |   |                  elf64_x86_64_allocate_local_dynrelocs,
 | 
      
        |   |                  info);
 | 
      
        |  
 |  
 | 
      
        |   /* For every jump slot reserved in the sgotplt, reloc_count is
 |   /* For every jump slot reserved in the sgotplt, reloc_count is
 | 
      
        |      incremented.  However, when we reserve space for TLS descriptors,
 |      incremented.  However, when we reserve space for TLS descriptors,
 | 
      
        |      it's not incremented, so in order to compute the space reserved
 |      it's not incremented, so in order to compute the space reserved
 | 
      
        |      for them, it suffices to multiply the reloc count by the jump
 |      for them, it suffices to multiply the reloc count by the jump
 | 
      
        |      slot size.  */
 |      slot size.  */
 | 
      
        |   if (htab->srelplt)
 |   if (htab->elf.srelplt)
 | 
      
        |     htab->sgotplt_jump_table_size
 |     htab->sgotplt_jump_table_size
 | 
      
        |       = elf64_x86_64_compute_jump_table_size (htab);
 |       = elf64_x86_64_compute_jump_table_size (htab);
 | 
      
        |  
 |  
 | 
      
        |   if (htab->tlsdesc_plt)
 |   if (htab->tlsdesc_plt)
 | 
      
        |     {
 |     {
 | 
      
        | Line 2085... | Line 2307... | 
      
        |          PLT and GOT entries they require.  */
 |          PLT and GOT entries they require.  */
 | 
      
        |       if ((info->flags & DF_BIND_NOW))
 |       if ((info->flags & DF_BIND_NOW))
 | 
      
        |         htab->tlsdesc_plt = 0;
 |         htab->tlsdesc_plt = 0;
 | 
      
        |       else
 |       else
 | 
      
        |         {
 |         {
 | 
      
        |           htab->tlsdesc_got = htab->sgot->size;
 |           htab->tlsdesc_got = htab->elf.sgot->size;
 | 
      
        |           htab->sgot->size += GOT_ENTRY_SIZE;
 |           htab->elf.sgot->size += GOT_ENTRY_SIZE;
 | 
      
        |           /* Reserve room for the initial entry.
 |           /* Reserve room for the initial entry.
 | 
      
        |              FIXME: we could probably do away with it in this case.  */
 |              FIXME: we could probably do away with it in this case.  */
 | 
      
        |           if (htab->splt->size == 0)
 |           if (htab->elf.splt->size == 0)
 | 
      
        |             htab->splt->size += PLT_ENTRY_SIZE;
 |             htab->elf.splt->size += PLT_ENTRY_SIZE;
 | 
      
        |           htab->tlsdesc_plt = htab->splt->size;
 |           htab->tlsdesc_plt = htab->elf.splt->size;
 | 
      
        |           htab->splt->size += PLT_ENTRY_SIZE;
 |           htab->elf.splt->size += PLT_ENTRY_SIZE;
 | 
      
        |         }
 |         }
 | 
      
        |     }
 |     }
 | 
      
        |  
 |  
 | 
      
        |   /* We now have determined the sizes of the various dynamic sections.
 |   /* We now have determined the sizes of the various dynamic sections.
 | 
      
        |      Allocate memory for them.  */
 |      Allocate memory for them.  */
 | 
      
        | Line 2104... | Line 2326... | 
      
        |   for (s = dynobj->sections; s != NULL; s = s->next)
 |   for (s = dynobj->sections; s != NULL; s = s->next)
 | 
      
        |     {
 |     {
 | 
      
        |       if ((s->flags & SEC_LINKER_CREATED) == 0)
 |       if ((s->flags & SEC_LINKER_CREATED) == 0)
 | 
      
        |         continue;
 |         continue;
 | 
      
        |  
 |  
 | 
      
        |       if (s == htab->splt
 |       if (s == htab->elf.splt
 | 
      
        |           || s == htab->sgot
 |           || s == htab->elf.sgot
 | 
      
        |           || s == htab->sgotplt
 |           || s == htab->elf.sgotplt
 | 
      
        |   |           || s == htab->elf.iplt
 | 
      
        |   |           || s == htab->elf.igotplt
 | 
      
        |           || s == htab->sdynbss)
 |           || s == htab->sdynbss)
 | 
      
        |         {
 |         {
 | 
      
        |           /* Strip this section if we don't need it; see the
 |           /* Strip this section if we don't need it; see the
 | 
      
        |              comment below.  */
 |              comment below.  */
 | 
      
        |         }
 |         }
 | 
      
        |       else if (CONST_STRNEQ (bfd_get_section_name (dynobj, s), ".rela"))
 |       else if (CONST_STRNEQ (bfd_get_section_name (dynobj, s), ".rela"))
 | 
      
        |         {
 |         {
 | 
      
        |           if (s->size != 0 && s != htab->srelplt)
 |           if (s->size != 0 && s != htab->elf.srelplt)
 | 
      
        |             relocs = TRUE;
 |             relocs = TRUE;
 | 
      
        |  
 |  
 | 
      
        |           /* We use the reloc_count field as a counter if we need
 |           /* We use the reloc_count field as a counter if we need
 | 
      
        |              to copy relocs into the output file.  */
 |              to copy relocs into the output file.  */
 | 
      
        |           if (s != htab->srelplt)
 |           if (s != htab->elf.srelplt)
 | 
      
        |             s->reloc_count = 0;
 |             s->reloc_count = 0;
 | 
      
        |         }
 |         }
 | 
      
        |       else
 |       else
 | 
      
        |         {
 |         {
 | 
      
        |           /* It's not one of our sections, so don't allocate space.  */
 |           /* It's not one of our sections, so don't allocate space.  */
 | 
      
        | Line 2173... | Line 2397... | 
      
        |         {
 |         {
 | 
      
        |           if (!add_dynamic_entry (DT_DEBUG, 0))
 |           if (!add_dynamic_entry (DT_DEBUG, 0))
 | 
      
        |             return FALSE;
 |             return FALSE;
 | 
      
        |         }
 |         }
 | 
      
        |  
 |  
 | 
      
        |       if (htab->splt->size != 0)
 |       if (htab->elf.splt->size != 0)
 | 
      
        |         {
 |         {
 | 
      
        |           if (!add_dynamic_entry (DT_PLTGOT, 0)
 |           if (!add_dynamic_entry (DT_PLTGOT, 0)
 | 
      
        |               || !add_dynamic_entry (DT_PLTRELSZ, 0)
 |               || !add_dynamic_entry (DT_PLTRELSZ, 0)
 | 
      
        |               || !add_dynamic_entry (DT_PLTREL, DT_RELA)
 |               || !add_dynamic_entry (DT_PLTREL, DT_RELA)
 | 
      
        |               || !add_dynamic_entry (DT_JMPREL, 0))
 |               || !add_dynamic_entry (DT_JMPREL, 0))
 | 
      
        | Line 2197... | Line 2421... | 
      
        |             return FALSE;
 |             return FALSE;
 | 
      
        |  
 |  
 | 
      
        |           /* If any dynamic relocs apply to a read-only section,
 |           /* If any dynamic relocs apply to a read-only section,
 | 
      
        |              then we need a DT_TEXTREL entry.  */
 |              then we need a DT_TEXTREL entry.  */
 | 
      
        |           if ((info->flags & DF_TEXTREL) == 0)
 |           if ((info->flags & DF_TEXTREL) == 0)
 | 
      
        |             elf_link_hash_traverse (&htab->elf, readonly_dynrelocs,
 |             elf_link_hash_traverse (&htab->elf,
 | 
      
        |                                     (PTR) info);
 |                                     elf64_x86_64_readonly_dynrelocs,
 | 
      
        |   |                                     info);
 | 
      
        |  
 |  
 | 
      
        |           if ((info->flags & DF_TEXTREL) != 0)
 |           if ((info->flags & DF_TEXTREL) != 0)
 | 
      
        |             {
 |             {
 | 
      
        |               if (!add_dynamic_entry (DT_TEXTREL, 0))
 |               if (!add_dynamic_entry (DT_TEXTREL, 0))
 | 
      
        |                 return FALSE;
 |                 return FALSE;
 | 
      
        | Line 2237... | Line 2462... | 
      
        |           if (!(_bfd_generic_link_add_one_symbol
 |           if (!(_bfd_generic_link_add_one_symbol
 | 
      
        |                 (info, output_bfd, "_TLS_MODULE_BASE_", BSF_LOCAL,
 |                 (info, output_bfd, "_TLS_MODULE_BASE_", BSF_LOCAL,
 | 
      
        |                  tls_sec, 0, NULL, FALSE,
 |                  tls_sec, 0, NULL, FALSE,
 | 
      
        |                  bed->collect, &bh)))
 |                  bed->collect, &bh)))
 | 
      
        |             return FALSE;
 |             return FALSE;
 | 
      
        |   |  
 | 
      
        |   |           elf64_x86_64_hash_table (info)->tls_module_base = bh;
 | 
      
        |   |  
 | 
      
        |           tlsbase = (struct elf_link_hash_entry *)bh;
 |           tlsbase = (struct elf_link_hash_entry *)bh;
 | 
      
        |           tlsbase->def_regular = 1;
 |           tlsbase->def_regular = 1;
 | 
      
        |           tlsbase->other = STV_HIDDEN;
 |           tlsbase->other = STV_HIDDEN;
 | 
      
        |           (*bed->elf_backend_hide_symbol) (info, tlsbase, TRUE);
 |           (*bed->elf_backend_hide_symbol) (info, tlsbase, TRUE);
 | 
      
        |         }
 |         }
 | 
      
        |     }
 |     }
 | 
      
        |  
 |  
 | 
      
        |   return TRUE;
 |   return TRUE;
 | 
      
        | }
 | }
 | 
      
        |  
 |  
 | 
      
        |   | /* _TLS_MODULE_BASE_ needs to be treated especially when linking
 | 
      
        |   |    executables.  Rather than setting it to the beginning of the TLS
 | 
      
        |   |    section, we have to set it to the end.  This function may be called
 | 
      
        |   |    multiple times, it is idempotent.  */
 | 
      
        |   |  
 | 
      
        |   | static void
 | 
      
        |   | elf64_x86_64_set_tls_module_base (struct bfd_link_info *info)
 | 
      
        |   | {
 | 
      
        |   |   struct bfd_link_hash_entry *base;
 | 
      
        |   |  
 | 
      
        |   |   if (!info->executable)
 | 
      
        |   |     return;
 | 
      
        |   |  
 | 
      
        |   |   base = elf64_x86_64_hash_table (info)->tls_module_base;
 | 
      
        |   |  
 | 
      
        |   |   if (!base)
 | 
      
        |   |     return;
 | 
      
        |   |  
 | 
      
        |   |   base->u.def.value = elf_hash_table (info)->tls_size;
 | 
      
        |   | }
 | 
      
        |   |  
 | 
      
        | /* Return the base VMA address which should be subtracted from real addresses
 | /* Return the base VMA address which should be subtracted from real addresses
 | 
      
        |    when resolving @dtpoff relocation.
 |    when resolving @dtpoff relocation.
 | 
      
        |    This is PT_TLS segment p_vaddr.  */
 |    This is PT_TLS segment p_vaddr.  */
 | 
      
        |  
 |  
 | 
      
        | static bfd_vma
 | static bfd_vma
 | 
      
        | dtpoff_base (struct bfd_link_info *info)
 | elf64_x86_64_dtpoff_base (struct bfd_link_info *info)
 | 
      
        | {
 | {
 | 
      
        |   /* If tls_sec is NULL, we should have signalled an error already.  */
 |   /* If tls_sec is NULL, we should have signalled an error already.  */
 | 
      
        |   if (elf_hash_table (info)->tls_sec == NULL)
 |   if (elf_hash_table (info)->tls_sec == NULL)
 | 
      
        |     return 0;
 |     return 0;
 | 
      
        |   return elf_hash_table (info)->tls_sec->vma;
 |   return elf_hash_table (info)->tls_sec->vma;
 | 
      
        | Line 2264... | Line 2513... | 
      
        |  
 |  
 | 
      
        | /* Return the relocation value for @tpoff relocation
 | /* Return the relocation value for @tpoff relocation
 | 
      
        |    if STT_TLS virtual address is ADDRESS.  */
 |    if STT_TLS virtual address is ADDRESS.  */
 | 
      
        |  
 |  
 | 
      
        | static bfd_vma
 | static bfd_vma
 | 
      
        | tpoff (struct bfd_link_info *info, bfd_vma address)
 | elf64_x86_64_tpoff (struct bfd_link_info *info, bfd_vma address)
 | 
      
        | {
 | {
 | 
      
        |   struct elf_link_hash_table *htab = elf_hash_table (info);
 |   struct elf_link_hash_table *htab = elf_hash_table (info);
 | 
      
        |  
 |  
 | 
      
        |   /* If tls_segment is NULL, we should have signalled an error already.  */
 |   /* If tls_segment is NULL, we should have signalled an error already.  */
 | 
      
        |   if (htab->tls_sec == NULL)
 |   if (htab->tls_sec == NULL)
 | 
      
        | Line 2317... | Line 2566... | 
      
        |   symtab_hdr = &elf_symtab_hdr (input_bfd);
 |   symtab_hdr = &elf_symtab_hdr (input_bfd);
 | 
      
        |   sym_hashes = elf_sym_hashes (input_bfd);
 |   sym_hashes = elf_sym_hashes (input_bfd);
 | 
      
        |   local_got_offsets = elf_local_got_offsets (input_bfd);
 |   local_got_offsets = elf_local_got_offsets (input_bfd);
 | 
      
        |   local_tlsdesc_gotents = elf64_x86_64_local_tlsdesc_gotent (input_bfd);
 |   local_tlsdesc_gotents = elf64_x86_64_local_tlsdesc_gotent (input_bfd);
 | 
      
        |  
 |  
 | 
      
        |   |   elf64_x86_64_set_tls_module_base (info);
 | 
      
        |   |  
 | 
      
        |   rel = relocs;
 |   rel = relocs;
 | 
      
        |   relend = relocs + input_section->reloc_count;
 |   relend = relocs + input_section->reloc_count;
 | 
      
        |   for (; rel < relend; rel++)
 |   for (; rel < relend; rel++)
 | 
      
        |     {
 |     {
 | 
      
        |       unsigned int r_type;
 |       unsigned int r_type;
 | 
      
        | Line 2332... | Line 2583... | 
      
        |       bfd_vma off, offplt;
 |       bfd_vma off, offplt;
 | 
      
        |       bfd_vma relocation;
 |       bfd_vma relocation;
 | 
      
        |       bfd_boolean unresolved_reloc;
 |       bfd_boolean unresolved_reloc;
 | 
      
        |       bfd_reloc_status_type r;
 |       bfd_reloc_status_type r;
 | 
      
        |       int tls_type;
 |       int tls_type;
 | 
      
        |   |       asection *base_got;
 | 
      
        |  
 |  
 | 
      
        |       r_type = ELF64_R_TYPE (rel->r_info);
 |       r_type = ELF64_R_TYPE (rel->r_info);
 | 
      
        |       if (r_type == (int) R_X86_64_GNU_VTINHERIT
 |       if (r_type == (int) R_X86_64_GNU_VTINHERIT
 | 
      
        |           || r_type == (int) R_X86_64_GNU_VTENTRY)
 |           || r_type == (int) R_X86_64_GNU_VTENTRY)
 | 
      
        |         continue;
 |         continue;
 | 
      
        | Line 2355... | Line 2607... | 
      
        |       if (r_symndx < symtab_hdr->sh_info)
 |       if (r_symndx < symtab_hdr->sh_info)
 | 
      
        |         {
 |         {
 | 
      
        |           sym = local_syms + r_symndx;
 |           sym = local_syms + r_symndx;
 | 
      
        |           sec = local_sections[r_symndx];
 |           sec = local_sections[r_symndx];
 | 
      
        |  
 |  
 | 
      
        |           relocation = _bfd_elf_rela_local_sym (output_bfd, sym, &sec, rel);
 |           relocation = _bfd_elf_rela_local_sym (output_bfd, sym,
 | 
      
        |   |                                                 &sec, rel);
 | 
      
        |   |  
 | 
      
        |   |           /* Relocate against local STT_GNU_IFUNC symbol.  */
 | 
      
        |   |           if (!info->relocatable
 | 
      
        |   |               && ELF64_ST_TYPE (sym->st_info) == STT_GNU_IFUNC)
 | 
      
        |   |             {
 | 
      
        |   |               h = elf64_x86_64_get_local_sym_hash (htab, input_bfd,
 | 
      
        |   |                                                    rel, FALSE);
 | 
      
        |   |               if (h == NULL)
 | 
      
        |   |                 abort ();
 | 
      
        |   |  
 | 
      
        |   |               /* Set STT_GNU_IFUNC symbol value.  */
 | 
      
        |   |               h->root.u.def.value = sym->st_value;
 | 
      
        |   |               h->root.u.def.section = sec;
 | 
      
        |   |             }
 | 
      
        |         }
 |         }
 | 
      
        |       else
 |       else
 | 
      
        |         {
 |         {
 | 
      
        |           bfd_boolean warned;
 |           bfd_boolean warned;
 | 
      
        |  
 |  
 | 
      
        | Line 2381... | Line 2648... | 
      
        |         }
 |         }
 | 
      
        |  
 |  
 | 
      
        |       if (info->relocatable)
 |       if (info->relocatable)
 | 
      
        |         continue;
 |         continue;
 | 
      
        |  
 |  
 | 
      
        |   |       /* Since STT_GNU_IFUNC symbol must go through PLT, we handle
 | 
      
        |   |          it here if it is defined in a non-shared object.  */
 | 
      
        |   |       if (h != NULL
 | 
      
        |   |           && h->type == STT_GNU_IFUNC
 | 
      
        |   |           && h->def_regular)
 | 
      
        |   |         {
 | 
      
        |   |           asection *plt;
 | 
      
        |   |           bfd_vma plt_index;
 | 
      
        |   |           const char *name;
 | 
      
        |   |  
 | 
      
        |   |           if ((input_section->flags & SEC_ALLOC) == 0
 | 
      
        |   |               || h->plt.offset == (bfd_vma) -1)
 | 
      
        |   |             abort ();
 | 
      
        |   |  
 | 
      
        |   |           /* STT_GNU_IFUNC symbol must go through PLT.  */
 | 
      
        |   |           plt = htab->elf.splt ? htab->elf.splt : htab->elf.iplt;
 | 
      
        |   |           relocation = (plt->output_section->vma
 | 
      
        |   |                         + plt->output_offset + h->plt.offset);
 | 
      
        |   |  
 | 
      
        |   |           switch (r_type)
 | 
      
        |   |             {
 | 
      
        |   |             default:
 | 
      
        |   |               if (h->root.root.string)
 | 
      
        |   |                 name = h->root.root.string;
 | 
      
        |   |               else
 | 
      
        |   |                 name = bfd_elf_sym_name (input_bfd, symtab_hdr, sym,
 | 
      
        |   |                                          NULL);
 | 
      
        |   |               (*_bfd_error_handler)
 | 
      
        |   |                 (_("%B: relocation %s against STT_GNU_IFUNC "
 | 
      
        |   |                    "symbol `%s' isn't handled by %s"), input_bfd,
 | 
      
        |   |                  x86_64_elf_howto_table[r_type].name,
 | 
      
        |   |                  name, __FUNCTION__);
 | 
      
        |   |               bfd_set_error (bfd_error_bad_value);
 | 
      
        |   |               return FALSE;
 | 
      
        |   |  
 | 
      
        |   |             case R_X86_64_32S:
 | 
      
        |   |               if (info->shared)
 | 
      
        |   |                 abort ();
 | 
      
        |   |               goto do_relocation;
 | 
      
        |   |  
 | 
      
        |   |             case R_X86_64_64:
 | 
      
        |   |               if (rel->r_addend != 0)
 | 
      
        |   |                 {
 | 
      
        |   |                   if (h->root.root.string)
 | 
      
        |   |                     name = h->root.root.string;
 | 
      
        |   |                   else
 | 
      
        |   |                     name = bfd_elf_sym_name (input_bfd, symtab_hdr,
 | 
      
        |   |                                              sym, NULL);
 | 
      
        |   |                   (*_bfd_error_handler)
 | 
      
        |   |                     (_("%B: relocation %s against STT_GNU_IFUNC "
 | 
      
        |   |                        "symbol `%s' has non-zero addend: %d"),
 | 
      
        |   |                      input_bfd, x86_64_elf_howto_table[r_type].name,
 | 
      
        |   |                      name, rel->r_addend);
 | 
      
        |   |                   bfd_set_error (bfd_error_bad_value);
 | 
      
        |   |                   return FALSE;
 | 
      
        |   |                 }
 | 
      
        |   |  
 | 
      
        |   |               /* Generate dynamic relcoation only when there is a
 | 
      
        |   |                  non-GOF reference in a shared object.  */
 | 
      
        |   |               if (info->shared && h->non_got_ref)
 | 
      
        |   |                 {
 | 
      
        |   |                   Elf_Internal_Rela outrel;
 | 
      
        |   |                   bfd_byte *loc;
 | 
      
        |   |                   asection *sreloc;
 | 
      
        |   |  
 | 
      
        |   |                   /* Need a dynamic relocation to get the real function
 | 
      
        |   |                      address.  */
 | 
      
        |   |                   outrel.r_offset = _bfd_elf_section_offset (output_bfd,
 | 
      
        |   |                                                              info,
 | 
      
        |   |                                                              input_section,
 | 
      
        |   |                                                              rel->r_offset);
 | 
      
        |   |                   if (outrel.r_offset == (bfd_vma) -1
 | 
      
        |   |                       || outrel.r_offset == (bfd_vma) -2)
 | 
      
        |   |                     abort ();
 | 
      
        |   |  
 | 
      
        |   |                   outrel.r_offset += (input_section->output_section->vma
 | 
      
        |   |                                       + input_section->output_offset);
 | 
      
        |   |  
 | 
      
        |   |                   if (h->dynindx == -1
 | 
      
        |   |                       || h->forced_local
 | 
      
        |   |                       || info->executable)
 | 
      
        |   |                     {
 | 
      
        |   |                       /* This symbol is resolved locally.  */
 | 
      
        |   |                       outrel.r_info = ELF64_R_INFO (0, R_X86_64_IRELATIVE);
 | 
      
        |   |                       outrel.r_addend = (h->root.u.def.value
 | 
      
        |   |                                          + h->root.u.def.section->output_section->vma
 | 
      
        |   |                                          + h->root.u.def.section->output_offset);
 | 
      
        |   |                     }
 | 
      
        |   |                   else
 | 
      
        |   |                     {
 | 
      
        |   |                       outrel.r_info = ELF64_R_INFO (h->dynindx, r_type);
 | 
      
        |   |                       outrel.r_addend = 0;
 | 
      
        |   |                     }
 | 
      
        |   |  
 | 
      
        |   |                   sreloc = htab->elf.irelifunc;
 | 
      
        |   |                   loc = sreloc->contents;
 | 
      
        |   |                   loc += (sreloc->reloc_count++
 | 
      
        |   |                           * sizeof (Elf64_External_Rela));
 | 
      
        |   |                   bfd_elf64_swap_reloca_out (output_bfd, &outrel, loc);
 | 
      
        |   |  
 | 
      
        |   |                   /* If this reloc is against an external symbol, we
 | 
      
        |   |                      do not want to fiddle with the addend.  Otherwise,
 | 
      
        |   |                      we need to include the symbol value so that it
 | 
      
        |   |                      becomes an addend for the dynamic reloc.  For an
 | 
      
        |   |                      internal symbol, we have updated addend.  */
 | 
      
        |   |                   continue;
 | 
      
        |   |                 }
 | 
      
        |   |  
 | 
      
        |   |             case R_X86_64_32:
 | 
      
        |   |             case R_X86_64_PC32:
 | 
      
        |   |             case R_X86_64_PC64:
 | 
      
        |   |             case R_X86_64_PLT32:
 | 
      
        |   |               goto do_relocation;
 | 
      
        |   |  
 | 
      
        |   |             case R_X86_64_GOTPCREL:
 | 
      
        |   |             case R_X86_64_GOTPCREL64:
 | 
      
        |   |               base_got = htab->elf.sgot;
 | 
      
        |   |               off = h->got.offset;
 | 
      
        |   |  
 | 
      
        |   |               if (base_got == NULL)
 | 
      
        |   |                 abort ();
 | 
      
        |   |  
 | 
      
        |   |               if (off == (bfd_vma) -1)
 | 
      
        |   |                 {
 | 
      
        |   |                   /* We can't use h->got.offset here to save state, or
 | 
      
        |   |                      even just remember the offset, as finish_dynamic_symbol
 | 
      
        |   |                      would use that as offset into .got.  */
 | 
      
        |   |  
 | 
      
        |   |                   if (htab->elf.splt != NULL)
 | 
      
        |   |                     {
 | 
      
        |   |                       plt_index = h->plt.offset / PLT_ENTRY_SIZE - 1;
 | 
      
        |   |                       off = (plt_index + 3) * GOT_ENTRY_SIZE;
 | 
      
        |   |                       base_got = htab->elf.sgotplt;
 | 
      
        |   |                     }
 | 
      
        |   |                   else
 | 
      
        |   |                     {
 | 
      
        |   |                       plt_index = h->plt.offset / PLT_ENTRY_SIZE;
 | 
      
        |   |                       off = plt_index * GOT_ENTRY_SIZE;
 | 
      
        |   |                       base_got = htab->elf.igotplt;
 | 
      
        |   |                     }
 | 
      
        |   |  
 | 
      
        |   |                   if (h->dynindx == -1
 | 
      
        |   |                       || h->forced_local
 | 
      
        |   |                       || info->symbolic)
 | 
      
        |   |                     {
 | 
      
        |   |                       /* This references the local defitionion.  We must
 | 
      
        |   |                          initialize this entry in the global offset table.
 | 
      
        |   |                          Since the offset must always be a multiple of 8,
 | 
      
        |   |                          we use the least significant bit to record
 | 
      
        |   |                          whether we have initialized it already.
 | 
      
        |   |  
 | 
      
        |   |                          When doing a dynamic link, we create a .rela.got
 | 
      
        |   |                          relocation entry to initialize the value.  This
 | 
      
        |   |                          is done in the finish_dynamic_symbol routine.   */
 | 
      
        |   |                       if ((off & 1) != 0)
 | 
      
        |   |                         off &= ~1;
 | 
      
        |   |                       else
 | 
      
        |   |                         {
 | 
      
        |   |                           bfd_put_64 (output_bfd, relocation,
 | 
      
        |   |                                       base_got->contents + off);
 | 
      
        |   |                           /* Note that this is harmless for the GOTPLT64
 | 
      
        |   |                              case, as -1 | 1 still is -1.  */
 | 
      
        |   |                           h->got.offset |= 1;
 | 
      
        |   |                         }
 | 
      
        |   |                     }
 | 
      
        |   |                 }
 | 
      
        |   |  
 | 
      
        |   |               relocation = (base_got->output_section->vma
 | 
      
        |   |                             + base_got->output_offset + off);
 | 
      
        |   |  
 | 
      
        |   |               if (r_type != R_X86_64_GOTPCREL
 | 
      
        |   |                   && r_type != R_X86_64_GOTPCREL64)
 | 
      
        |   |                 {
 | 
      
        |   |                   asection *gotplt;
 | 
      
        |   |                   if (htab->elf.splt != NULL)
 | 
      
        |   |                     gotplt = htab->elf.sgotplt;
 | 
      
        |   |                   else
 | 
      
        |   |                     gotplt = htab->elf.igotplt;
 | 
      
        |   |                   relocation -= (gotplt->output_section->vma
 | 
      
        |   |                                  - gotplt->output_offset);
 | 
      
        |   |                 }
 | 
      
        |   |  
 | 
      
        |   |               goto do_relocation;
 | 
      
        |   |             }
 | 
      
        |   |         }
 | 
      
        |   |  
 | 
      
        |       /* When generating a shared object, the relocations handled here are
 |       /* When generating a shared object, the relocations handled here are
 | 
      
        |          copied into the output file to be resolved at run time.  */
 |          copied into the output file to be resolved at run time.  */
 | 
      
        |       switch (r_type)
 |       switch (r_type)
 | 
      
        |         {
 |         {
 | 
      
        |         asection *base_got;
 |   | 
      
        |         case R_X86_64_GOT32:
 |         case R_X86_64_GOT32:
 | 
      
        |         case R_X86_64_GOT64:
 |         case R_X86_64_GOT64:
 | 
      
        |           /* Relocation is to the entry for this symbol in the global
 |           /* Relocation is to the entry for this symbol in the global
 | 
      
        |              offset table.  */
 |              offset table.  */
 | 
      
        |         case R_X86_64_GOTPCREL:
 |         case R_X86_64_GOTPCREL:
 | 
      
        | Line 2400... | Line 2852... | 
      
        |              indicates the existence of a PLT entry.  The difficulty is,
 |              indicates the existence of a PLT entry.  The difficulty is,
 | 
      
        |              that we must calculate the GOT slot offset from the PLT
 |              that we must calculate the GOT slot offset from the PLT
 | 
      
        |              offset, if this symbol got a PLT entry (it was global).
 |              offset, if this symbol got a PLT entry (it was global).
 | 
      
        |              Additionally if it's computed from the PLT entry, then that
 |              Additionally if it's computed from the PLT entry, then that
 | 
      
        |              GOT offset is relative to .got.plt, not to .got.  */
 |              GOT offset is relative to .got.plt, not to .got.  */
 | 
      
        |           base_got = htab->sgot;
 |           base_got = htab->elf.sgot;
 | 
      
        |  
 |  
 | 
      
        |           if (htab->sgot == NULL)
 |           if (htab->elf.sgot == NULL)
 | 
      
        |             abort ();
 |             abort ();
 | 
      
        |  
 |  
 | 
      
        |           if (h != NULL)
 |           if (h != NULL)
 | 
      
        |             {
 |             {
 | 
      
        |               bfd_boolean dyn;
 |               bfd_boolean dyn;
 | 
      
        | Line 2420... | Line 2872... | 
      
        |                      state, or even just remember the offset, as
 |                      state, or even just remember the offset, as
 | 
      
        |                      finish_dynamic_symbol would use that as offset into
 |                      finish_dynamic_symbol would use that as offset into
 | 
      
        |                      .got.  */
 |                      .got.  */
 | 
      
        |                   bfd_vma plt_index = h->plt.offset / PLT_ENTRY_SIZE - 1;
 |                   bfd_vma plt_index = h->plt.offset / PLT_ENTRY_SIZE - 1;
 | 
      
        |                   off = (plt_index + 3) * GOT_ENTRY_SIZE;
 |                   off = (plt_index + 3) * GOT_ENTRY_SIZE;
 | 
      
        |                   base_got = htab->sgotplt;
 |                   base_got = htab->elf.sgotplt;
 | 
      
        |                 }
 |                 }
 | 
      
        |  
 |  
 | 
      
        |               dyn = htab->elf.dynamic_sections_created;
 |               dyn = htab->elf.dynamic_sections_created;
 | 
      
        |  
 |  
 | 
      
        |               if (! WILL_CALL_FINISH_DYNAMIC_SYMBOL (dyn, info->shared, h)
 |               if (! WILL_CALL_FINISH_DYNAMIC_SYMBOL (dyn, info->shared, h)
 | 
      
        | Line 2481... | Line 2933... | 
      
        |                       Elf_Internal_Rela outrel;
 |                       Elf_Internal_Rela outrel;
 | 
      
        |                       bfd_byte *loc;
 |                       bfd_byte *loc;
 | 
      
        |  
 |  
 | 
      
        |                       /* We need to generate a R_X86_64_RELATIVE reloc
 |                       /* We need to generate a R_X86_64_RELATIVE reloc
 | 
      
        |                          for the dynamic linker.  */
 |                          for the dynamic linker.  */
 | 
      
        |                       s = htab->srelgot;
 |                       s = htab->elf.srelgot;
 | 
      
        |                       if (s == NULL)
 |                       if (s == NULL)
 | 
      
        |                         abort ();
 |                         abort ();
 | 
      
        |  
 |  
 | 
      
        |                       outrel.r_offset = (base_got->output_section->vma
 |                       outrel.r_offset = (base_got->output_section->vma
 | 
      
        |                                          + base_got->output_offset
 |                                          + base_got->output_offset
 | 
      
        | Line 2505... | Line 2957... | 
      
        |             abort ();
 |             abort ();
 | 
      
        |  
 |  
 | 
      
        |           relocation = base_got->output_section->vma
 |           relocation = base_got->output_section->vma
 | 
      
        |                        + base_got->output_offset + off;
 |                        + base_got->output_offset + off;
 | 
      
        |           if (r_type != R_X86_64_GOTPCREL && r_type != R_X86_64_GOTPCREL64)
 |           if (r_type != R_X86_64_GOTPCREL && r_type != R_X86_64_GOTPCREL64)
 | 
      
        |             relocation -= htab->sgotplt->output_section->vma
 |             relocation -= htab->elf.sgotplt->output_section->vma
 | 
      
        |                           - htab->sgotplt->output_offset;
 |                           - htab->elf.sgotplt->output_offset;
 | 
      
        |  
 |  
 | 
      
        |           break;
 |           break;
 | 
      
        |  
 |  
 | 
      
        |         case R_X86_64_GOTOFF64:
 |         case R_X86_64_GOTOFF64:
 | 
      
        |           /* Relocation is relative to the start of the global offset
 |           /* Relocation is relative to the start of the global offset
 | 
      
        | Line 2535... | Line 2987... | 
      
        |           /* Note that sgot is not involved in this
 |           /* Note that sgot is not involved in this
 | 
      
        |              calculation.  We always want the start of .got.plt.  If we
 |              calculation.  We always want the start of .got.plt.  If we
 | 
      
        |              defined _GLOBAL_OFFSET_TABLE_ in a different way, as is
 |              defined _GLOBAL_OFFSET_TABLE_ in a different way, as is
 | 
      
        |              permitted by the ABI, we might have to change this
 |              permitted by the ABI, we might have to change this
 | 
      
        |              calculation.  */
 |              calculation.  */
 | 
      
        |           relocation -= htab->sgotplt->output_section->vma
 |           relocation -= htab->elf.sgotplt->output_section->vma
 | 
      
        |                         + htab->sgotplt->output_offset;
 |                         + htab->elf.sgotplt->output_offset;
 | 
      
        |           break;
 |           break;
 | 
      
        |  
 |  
 | 
      
        |         case R_X86_64_GOTPC32:
 |         case R_X86_64_GOTPC32:
 | 
      
        |         case R_X86_64_GOTPC64:
 |         case R_X86_64_GOTPC64:
 | 
      
        |           /* Use global offset table as symbol value.  */
 |           /* Use global offset table as symbol value.  */
 | 
      
        |           relocation = htab->sgotplt->output_section->vma
 |           relocation = htab->elf.sgotplt->output_section->vma
 | 
      
        |                        + htab->sgotplt->output_offset;
 |                        + htab->elf.sgotplt->output_offset;
 | 
      
        |           unresolved_reloc = FALSE;
 |           unresolved_reloc = FALSE;
 | 
      
        |           break;
 |           break;
 | 
      
        |  
 |  
 | 
      
        |         case R_X86_64_PLTOFF64:
 |         case R_X86_64_PLTOFF64:
 | 
      
        |           /* Relocation is PLT entry relative to GOT.  For local
 |           /* Relocation is PLT entry relative to GOT.  For local
 | 
      
        |              symbols it's the symbol itself relative to GOT.  */
 |              symbols it's the symbol itself relative to GOT.  */
 | 
      
        |           if (h != NULL
 |           if (h != NULL
 | 
      
        |               /* See PLT32 handling.  */
 |               /* See PLT32 handling.  */
 | 
      
        |               && h->plt.offset != (bfd_vma) -1
 |               && h->plt.offset != (bfd_vma) -1
 | 
      
        |               && htab->splt != NULL)
 |               && htab->elf.splt != NULL)
 | 
      
        |             {
 |             {
 | 
      
        |               relocation = (htab->splt->output_section->vma
 |               relocation = (htab->elf.splt->output_section->vma
 | 
      
        |                             + htab->splt->output_offset
 |                             + htab->elf.splt->output_offset
 | 
      
        |                             + h->plt.offset);
 |                             + h->plt.offset);
 | 
      
        |               unresolved_reloc = FALSE;
 |               unresolved_reloc = FALSE;
 | 
      
        |             }
 |             }
 | 
      
        |  
 |  
 | 
      
        |           relocation -= htab->sgotplt->output_section->vma
 |           relocation -= htab->elf.sgotplt->output_section->vma
 | 
      
        |                         + htab->sgotplt->output_offset;
 |                         + htab->elf.sgotplt->output_offset;
 | 
      
        |           break;
 |           break;
 | 
      
        |  
 |  
 | 
      
        |         case R_X86_64_PLT32:
 |         case R_X86_64_PLT32:
 | 
      
        |           /* Relocation is to the entry for this symbol in the
 |           /* Relocation is to the entry for this symbol in the
 | 
      
        |              procedure linkage table.  */
 |              procedure linkage table.  */
 | 
      
        | Line 2575... | Line 3027... | 
      
        |              without using the procedure linkage table.  */
 |              without using the procedure linkage table.  */
 | 
      
        |           if (h == NULL)
 |           if (h == NULL)
 | 
      
        |             break;
 |             break;
 | 
      
        |  
 |  
 | 
      
        |           if (h->plt.offset == (bfd_vma) -1
 |           if (h->plt.offset == (bfd_vma) -1
 | 
      
        |               || htab->splt == NULL)
 |               || htab->elf.splt == NULL)
 | 
      
        |             {
 |             {
 | 
      
        |               /* We didn't make a PLT entry for this symbol.  This
 |               /* We didn't make a PLT entry for this symbol.  This
 | 
      
        |                  happens when statically linking PIC code, or when
 |                  happens when statically linking PIC code, or when
 | 
      
        |                  using -Bsymbolic.  */
 |                  using -Bsymbolic.  */
 | 
      
        |               break;
 |               break;
 | 
      
        |             }
 |             }
 | 
      
        |  
 |  
 | 
      
        |           relocation = (htab->splt->output_section->vma
 |           relocation = (htab->elf.splt->output_section->vma
 | 
      
        |                         + htab->splt->output_offset
 |                         + htab->elf.splt->output_offset
 | 
      
        |                         + h->plt.offset);
 |                         + h->plt.offset);
 | 
      
        |           unresolved_reloc = FALSE;
 |           unresolved_reloc = FALSE;
 | 
      
        |           break;
 |           break;
 | 
      
        |  
 |  
 | 
      
        |         case R_X86_64_PC8:
 |         case R_X86_64_PC8:
 | 
      
        |         case R_X86_64_PC16:
 |         case R_X86_64_PC16:
 | 
      
        |         case R_X86_64_PC32:
 |         case R_X86_64_PC32:
 | 
      
        |           if (info->shared
 |           if (info->shared
 | 
      
        |               && !SYMBOL_REFERENCES_LOCAL (info, h)
 |   | 
      
        |               && (input_section->flags & SEC_ALLOC) != 0
 |               && (input_section->flags & SEC_ALLOC) != 0
 | 
      
        |               && (input_section->flags & SEC_READONLY) != 0
 |               && (input_section->flags & SEC_READONLY) != 0
 | 
      
        |               && (!h->def_regular
 |               && h != NULL)
 | 
      
        |                   || r_type != R_X86_64_PC32
 |   | 
      
        |                   || h->type != STT_FUNC
 |   | 
      
        |                   || ELF_ST_VISIBILITY (h->other) != STV_PROTECTED
 |   | 
      
        |                   || !is_32bit_relative_branch (contents,
 |   | 
      
        |                                                 rel->r_offset)))
 |   | 
      
        |             {
 |             {
 | 
      
        |               if (h->def_regular
 |               bfd_boolean fail = FALSE;
 | 
      
        |                   && r_type == R_X86_64_PC32
 |               bfd_boolean branch
 | 
      
        |                   && h->type == STT_FUNC
 |                 = (r_type == R_X86_64_PC32
 | 
      
        |                   && ELF_ST_VISIBILITY (h->other) == STV_PROTECTED)
 |                    && is_32bit_relative_branch (contents, rel->r_offset));
 | 
      
        |                 (*_bfd_error_handler)
 |  
 | 
      
        |                    (_("%B: relocation R_X86_64_PC32 against protected function `%s' can not be used when making a shared object"),
 |               if (SYMBOL_REFERENCES_LOCAL (info, h))
 | 
      
        |                     input_bfd, h->root.root.string);
 |                 {
 | 
      
        |   |                   /* Symbol is referenced locally.  Make sure it is
 | 
      
        |   |                      defined locally or for a branch.  */
 | 
      
        |   |                   fail = !h->def_regular && !branch;
 | 
      
        |   |                 }
 | 
      
        |               else
 |               else
 | 
      
        |                 (*_bfd_error_handler)
 |                 {
 | 
      
        |                   (_("%B: relocation %s against `%s' can not be used when making a shared object; recompile with -fPIC"),
 |                   /* Symbol isn't referenced locally.  We only allow
 | 
      
        |                    input_bfd, x86_64_elf_howto_table[r_type].name,
 |                      branch to symbol with non-default visibility. */
 | 
      
        |                    h->root.root.string);
 |                   fail = (!branch
 | 
      
        |   |                           || ELF_ST_VISIBILITY (h->other) == STV_DEFAULT);
 | 
      
        |   |                 }
 | 
      
        |   |  
 | 
      
        |   |               if (fail)
 | 
      
        |   |                 {
 | 
      
        |   |                   const char *fmt;
 | 
      
        |   |                   const char *v;
 | 
      
        |   |                   const char *pic = "";
 | 
      
        |   |  
 | 
      
        |   |                   switch (ELF_ST_VISIBILITY (h->other))
 | 
      
        |   |                     {
 | 
      
        |   |                     case STV_HIDDEN:
 | 
      
        |   |                       v = _("hidden symbol");
 | 
      
        |   |                       break;
 | 
      
        |   |                     case STV_INTERNAL:
 | 
      
        |   |                       v = _("internal symbol");
 | 
      
        |   |                       break;
 | 
      
        |   |                     case STV_PROTECTED:
 | 
      
        |   |                       v = _("protected symbol");
 | 
      
        |   |                       break;
 | 
      
        |   |                     default:
 | 
      
        |   |                       v = _("symbol");
 | 
      
        |   |                       pic = _("; recompile with -fPIC");
 | 
      
        |   |                       break;
 | 
      
        |   |                     }
 | 
      
        |   |  
 | 
      
        |   |                   if (h->def_regular)
 | 
      
        |   |                     fmt = _("%B: relocation %s against %s `%s' can not be used when making a shared object%s");
 | 
      
        |   |                   else
 | 
      
        |   |                     fmt = _("%B: relocation %s against undefined %s `%s' can not be used when making a shared object%s");
 | 
      
        |   |  
 | 
      
        |   |                   (*_bfd_error_handler) (fmt, input_bfd,
 | 
      
        |   |                                          x86_64_elf_howto_table[r_type].name,
 | 
      
        |   |                                          v,  h->root.root.string, pic);
 | 
      
        |               bfd_set_error (bfd_error_bad_value);
 |               bfd_set_error (bfd_error_bad_value);
 | 
      
        |               return FALSE;
 |               return FALSE;
 | 
      
        |             }
 |             }
 | 
      
        |   |             }
 | 
      
        |           /* Fall through.  */
 |           /* Fall through.  */
 | 
      
        |  
 |  
 | 
      
        |         case R_X86_64_8:
 |         case R_X86_64_8:
 | 
      
        |         case R_X86_64_16:
 |         case R_X86_64_16:
 | 
      
        |         case R_X86_64_32:
 |         case R_X86_64_32:
 | 
      
        | Line 2635... | Line 3120... | 
      
        |  
 |  
 | 
      
        |           if ((info->shared
 |           if ((info->shared
 | 
      
        |                && (h == NULL
 |                && (h == NULL
 | 
      
        |                    || ELF_ST_VISIBILITY (h->other) == STV_DEFAULT
 |                    || ELF_ST_VISIBILITY (h->other) == STV_DEFAULT
 | 
      
        |                    || h->root.type != bfd_link_hash_undefweak)
 |                    || h->root.type != bfd_link_hash_undefweak)
 | 
      
        |                && ((r_type != R_X86_64_PC8
 |                && (! IS_X86_64_PCREL_TYPE (r_type)
 | 
      
        |                     && r_type != R_X86_64_PC16
 |   | 
      
        |                     && r_type != R_X86_64_PC32
 |   | 
      
        |                     && r_type != R_X86_64_PC64)
 |   | 
      
        |                    || !SYMBOL_CALLS_LOCAL (info, h)))
 |                    || !SYMBOL_CALLS_LOCAL (info, h)))
 | 
      
        |               || (ELIMINATE_COPY_RELOCS
 |               || (ELIMINATE_COPY_RELOCS
 | 
      
        |                   && !info->shared
 |                   && !info->shared
 | 
      
        |                   && h != NULL
 |                   && h != NULL
 | 
      
        |                   && h->dynindx != -1
 |                   && h->dynindx != -1
 | 
      
        | Line 2679... | Line 3161... | 
      
        |  
 |  
 | 
      
        |               /* h->dynindx may be -1 if this symbol was marked to
 |               /* h->dynindx may be -1 if this symbol was marked to
 | 
      
        |                  become local.  */
 |                  become local.  */
 | 
      
        |               else if (h != NULL
 |               else if (h != NULL
 | 
      
        |                        && h->dynindx != -1
 |                        && h->dynindx != -1
 | 
      
        |                        && (r_type == R_X86_64_PC8
 |                        && (IS_X86_64_PCREL_TYPE (r_type)
 | 
      
        |                            || r_type == R_X86_64_PC16
 |   | 
      
        |                            || r_type == R_X86_64_PC32
 |   | 
      
        |                            || r_type == R_X86_64_PC64
 |   | 
      
        |                            || !info->shared
 |                            || !info->shared
 | 
      
        |                            || !SYMBOLIC_BIND (info, h)
 |                            || !SYMBOLIC_BIND (info, h)
 | 
      
        |                            || !h->def_regular))
 |                            || !h->def_regular))
 | 
      
        |                 {
 |                 {
 | 
      
        |                   outrel.r_info = ELF64_R_INFO (h->dynindx, r_type);
 |                   outrel.r_info = ELF64_R_INFO (h->dynindx, r_type);
 | 
      
        | Line 2735... | Line 3214... | 
      
        |                       outrel.r_addend = relocation + rel->r_addend;
 |                       outrel.r_addend = relocation + rel->r_addend;
 | 
      
        |                     }
 |                     }
 | 
      
        |                 }
 |                 }
 | 
      
        |  
 |  
 | 
      
        |               sreloc = elf_section_data (input_section)->sreloc;
 |               sreloc = elf_section_data (input_section)->sreloc;
 | 
      
        |               if (sreloc == NULL)
 |  
 | 
      
        |                 abort ();
 |               BFD_ASSERT (sreloc != NULL && sreloc->contents != NULL);
 | 
      
        |  
 |  
 | 
      
        |               loc = sreloc->contents;
 |               loc = sreloc->contents;
 | 
      
        |               loc += sreloc->reloc_count++ * sizeof (Elf64_External_Rela);
 |               loc += sreloc->reloc_count++ * sizeof (Elf64_External_Rela);
 | 
      
        |               bfd_elf64_swap_reloca_out (output_bfd, &outrel, loc);
 |               bfd_elf64_swap_reloca_out (output_bfd, &outrel, loc);
 | 
      
        |  
 |  
 | 
      
        | Line 2766... | Line 3245... | 
      
        |  
 |  
 | 
      
        |           if (! elf64_x86_64_tls_transition (info, input_bfd,
 |           if (! elf64_x86_64_tls_transition (info, input_bfd,
 | 
      
        |                                              input_section, contents,
 |                                              input_section, contents,
 | 
      
        |                                              symtab_hdr, sym_hashes,
 |                                              symtab_hdr, sym_hashes,
 | 
      
        |                                              &r_type, tls_type, rel,
 |                                              &r_type, tls_type, rel,
 | 
      
        |                                              relend, h))
 |                                              relend, h, r_symndx))
 | 
      
        |             return FALSE;
 |             return FALSE;
 | 
      
        |  
 |  
 | 
      
        |           if (r_type == R_X86_64_TPOFF32)
 |           if (r_type == R_X86_64_TPOFF32)
 | 
      
        |             {
 |             {
 | 
      
        |               bfd_vma roff = rel->r_offset;
 |               bfd_vma roff = rel->r_offset;
 | 
      
        | Line 2786... | Line 3265... | 
      
        |                      movq %fs:0, %rax
 |                      movq %fs:0, %rax
 | 
      
        |                      leaq foo@tpoff(%rax), %rax */
 |                      leaq foo@tpoff(%rax), %rax */
 | 
      
        |                   memcpy (contents + roff - 4,
 |                   memcpy (contents + roff - 4,
 | 
      
        |                           "\x64\x48\x8b\x04\x25\0\0\0\0\x48\x8d\x80\0\0\0",
 |                           "\x64\x48\x8b\x04\x25\0\0\0\0\x48\x8d\x80\0\0\0",
 | 
      
        |                           16);
 |                           16);
 | 
      
        |                   bfd_put_32 (output_bfd, tpoff (info, relocation),
 |                   bfd_put_32 (output_bfd,
 | 
      
        |   |                               elf64_x86_64_tpoff (info, relocation),
 | 
      
        |                               contents + roff + 8);
 |                               contents + roff + 8);
 | 
      
        |                   /* Skip R_X86_64_PC32/R_X86_64_PLT32.  */
 |                   /* Skip R_X86_64_PC32/R_X86_64_PLT32.  */
 | 
      
        |                   rel++;
 |                   rel++;
 | 
      
        |                   continue;
 |                   continue;
 | 
      
        |                 }
 |                 }
 | 
      
        | Line 2812... | Line 3292... | 
      
        |                   bfd_put_8 (output_bfd, 0x48 | ((type >> 2) & 1),
 |                   bfd_put_8 (output_bfd, 0x48 | ((type >> 2) & 1),
 | 
      
        |                              contents + roff - 3);
 |                              contents + roff - 3);
 | 
      
        |                   bfd_put_8 (output_bfd, 0xc7, contents + roff - 2);
 |                   bfd_put_8 (output_bfd, 0xc7, contents + roff - 2);
 | 
      
        |                   bfd_put_8 (output_bfd, 0xc0 | ((val >> 3) & 7),
 |                   bfd_put_8 (output_bfd, 0xc0 | ((val >> 3) & 7),
 | 
      
        |                              contents + roff - 1);
 |                              contents + roff - 1);
 | 
      
        |                   bfd_put_32 (output_bfd, tpoff (info, relocation),
 |                   bfd_put_32 (output_bfd,
 | 
      
        |   |                               elf64_x86_64_tpoff (info, relocation),
 | 
      
        |                               contents + roff);
 |                               contents + roff);
 | 
      
        |                   continue;
 |                   continue;
 | 
      
        |                 }
 |                 }
 | 
      
        |               else if (ELF64_R_TYPE (rel->r_info) == R_X86_64_TLSDESC_CALL)
 |               else if (ELF64_R_TYPE (rel->r_info) == R_X86_64_TLSDESC_CALL)
 | 
      
        |                 {
 |                 {
 | 
      
        | Line 2878... | Line 3359... | 
      
        |                       bfd_put_8 (output_bfd, 0x8d,
 |                       bfd_put_8 (output_bfd, 0x8d,
 | 
      
        |                                  contents + roff - 2);
 |                                  contents + roff - 2);
 | 
      
        |                       bfd_put_8 (output_bfd, 0x80 | reg | (reg << 3),
 |                       bfd_put_8 (output_bfd, 0x80 | reg | (reg << 3),
 | 
      
        |                                  contents + roff - 1);
 |                                  contents + roff - 1);
 | 
      
        |                     }
 |                     }
 | 
      
        |                   bfd_put_32 (output_bfd, tpoff (info, relocation),
 |                   bfd_put_32 (output_bfd,
 | 
      
        |   |                               elf64_x86_64_tpoff (info, relocation),
 | 
      
        |                               contents + roff);
 |                               contents + roff);
 | 
      
        |                   continue;
 |                   continue;
 | 
      
        |                 }
 |                 }
 | 
      
        |               else
 |               else
 | 
      
        |                 BFD_ASSERT (FALSE);
 |                 BFD_ASSERT (FALSE);
 | 
      
        |             }
 |             }
 | 
      
        |  
 |  
 | 
      
        |           if (htab->sgot == NULL)
 |           if (htab->elf.sgot == NULL)
 | 
      
        |             abort ();
 |             abort ();
 | 
      
        |  
 |  
 | 
      
        |           if (h != NULL)
 |           if (h != NULL)
 | 
      
        |             {
 |             {
 | 
      
        |               off = h->got.offset;
 |               off = h->got.offset;
 | 
      
        | Line 2912... | Line 3394... | 
      
        |               Elf_Internal_Rela outrel;
 |               Elf_Internal_Rela outrel;
 | 
      
        |               bfd_byte *loc;
 |               bfd_byte *loc;
 | 
      
        |               int dr_type, indx;
 |               int dr_type, indx;
 | 
      
        |               asection *sreloc;
 |               asection *sreloc;
 | 
      
        |  
 |  
 | 
      
        |               if (htab->srelgot == NULL)
 |               if (htab->elf.srelgot == NULL)
 | 
      
        |                 abort ();
 |                 abort ();
 | 
      
        |  
 |  
 | 
      
        |               indx = h && h->dynindx != -1 ? h->dynindx : 0;
 |               indx = h && h->dynindx != -1 ? h->dynindx : 0;
 | 
      
        |  
 |  
 | 
      
        |               if (GOT_TLS_GDESC_P (tls_type))
 |               if (GOT_TLS_GDESC_P (tls_type))
 | 
      
        |                 {
 |                 {
 | 
      
        |                   outrel.r_info = ELF64_R_INFO (indx, R_X86_64_TLSDESC);
 |                   outrel.r_info = ELF64_R_INFO (indx, R_X86_64_TLSDESC);
 | 
      
        |                   BFD_ASSERT (htab->sgotplt_jump_table_size + offplt
 |                   BFD_ASSERT (htab->sgotplt_jump_table_size + offplt
 | 
      
        |                               + 2 * GOT_ENTRY_SIZE <= htab->sgotplt->size);
 |                               + 2 * GOT_ENTRY_SIZE <= htab->elf.sgotplt->size);
 | 
      
        |                   outrel.r_offset = (htab->sgotplt->output_section->vma
 |                   outrel.r_offset = (htab->elf.sgotplt->output_section->vma
 | 
      
        |                                      + htab->sgotplt->output_offset
 |                                      + htab->elf.sgotplt->output_offset
 | 
      
        |                                      + offplt
 |                                      + offplt
 | 
      
        |                                      + htab->sgotplt_jump_table_size);
 |                                      + htab->sgotplt_jump_table_size);
 | 
      
        |                   sreloc = htab->srelplt;
 |                   sreloc = htab->elf.srelplt;
 | 
      
        |                   loc = sreloc->contents;
 |                   loc = sreloc->contents;
 | 
      
        |                   loc += sreloc->reloc_count++
 |                   loc += sreloc->reloc_count++
 | 
      
        |                     * sizeof (Elf64_External_Rela);
 |                     * sizeof (Elf64_External_Rela);
 | 
      
        |                   BFD_ASSERT (loc + sizeof (Elf64_External_Rela)
 |                   BFD_ASSERT (loc + sizeof (Elf64_External_Rela)
 | 
      
        |                               <= sreloc->contents + sreloc->size);
 |                               <= sreloc->contents + sreloc->size);
 | 
      
        |                   if (indx == 0)
 |                   if (indx == 0)
 | 
      
        |                     outrel.r_addend = relocation - dtpoff_base (info);
 |                     outrel.r_addend = relocation - elf64_x86_64_dtpoff_base (info);
 | 
      
        |                   else
 |                   else
 | 
      
        |                     outrel.r_addend = 0;
 |                     outrel.r_addend = 0;
 | 
      
        |                   bfd_elf64_swap_reloca_out (output_bfd, &outrel, loc);
 |                   bfd_elf64_swap_reloca_out (output_bfd, &outrel, loc);
 | 
      
        |                 }
 |                 }
 | 
      
        |  
 |  
 | 
      
        |               sreloc = htab->srelgot;
 |               sreloc = htab->elf.srelgot;
 | 
      
        |  
 |  
 | 
      
        |               outrel.r_offset = (htab->sgot->output_section->vma
 |               outrel.r_offset = (htab->elf.sgot->output_section->vma
 | 
      
        |                                  + htab->sgot->output_offset + off);
 |                                  + htab->elf.sgot->output_offset + off);
 | 
      
        |  
 |  
 | 
      
        |               if (GOT_TLS_GD_P (tls_type))
 |               if (GOT_TLS_GD_P (tls_type))
 | 
      
        |                 dr_type = R_X86_64_DTPMOD64;
 |                 dr_type = R_X86_64_DTPMOD64;
 | 
      
        |               else if (GOT_TLS_GDESC_P (tls_type))
 |               else if (GOT_TLS_GDESC_P (tls_type))
 | 
      
        |                 goto dr_done;
 |                 goto dr_done;
 | 
      
        |               else
 |               else
 | 
      
        |                 dr_type = R_X86_64_TPOFF64;
 |                 dr_type = R_X86_64_TPOFF64;
 | 
      
        |  
 |  
 | 
      
        |               bfd_put_64 (output_bfd, 0, htab->sgot->contents + off);
 |               bfd_put_64 (output_bfd, 0, htab->elf.sgot->contents + off);
 | 
      
        |               outrel.r_addend = 0;
 |               outrel.r_addend = 0;
 | 
      
        |               if ((dr_type == R_X86_64_TPOFF64
 |               if ((dr_type == R_X86_64_TPOFF64
 | 
      
        |                    || dr_type == R_X86_64_TLSDESC) && indx == 0)
 |                    || dr_type == R_X86_64_TLSDESC) && indx == 0)
 | 
      
        |                 outrel.r_addend = relocation - dtpoff_base (info);
 |                 outrel.r_addend = relocation - elf64_x86_64_dtpoff_base (info);
 | 
      
        |               outrel.r_info = ELF64_R_INFO (indx, dr_type);
 |               outrel.r_info = ELF64_R_INFO (indx, dr_type);
 | 
      
        |  
 |  
 | 
      
        |               loc = sreloc->contents;
 |               loc = sreloc->contents;
 | 
      
        |               loc += sreloc->reloc_count++ * sizeof (Elf64_External_Rela);
 |               loc += sreloc->reloc_count++ * sizeof (Elf64_External_Rela);
 | 
      
        |               BFD_ASSERT (loc + sizeof (Elf64_External_Rela)
 |               BFD_ASSERT (loc + sizeof (Elf64_External_Rela)
 | 
      
        | Line 2970... | Line 3452... | 
      
        |                 {
 |                 {
 | 
      
        |                   if (indx == 0)
 |                   if (indx == 0)
 | 
      
        |                     {
 |                     {
 | 
      
        |                       BFD_ASSERT (! unresolved_reloc);
 |                       BFD_ASSERT (! unresolved_reloc);
 | 
      
        |                       bfd_put_64 (output_bfd,
 |                       bfd_put_64 (output_bfd,
 | 
      
        |                                   relocation - dtpoff_base (info),
 |                                   relocation - elf64_x86_64_dtpoff_base (info),
 | 
      
        |                                   htab->sgot->contents + off + GOT_ENTRY_SIZE);
 |                                   htab->elf.sgot->contents + off + GOT_ENTRY_SIZE);
 | 
      
        |                     }
 |                     }
 | 
      
        |                   else
 |                   else
 | 
      
        |                     {
 |                     {
 | 
      
        |                       bfd_put_64 (output_bfd, 0,
 |                       bfd_put_64 (output_bfd, 0,
 | 
      
        |                                   htab->sgot->contents + off + GOT_ENTRY_SIZE);
 |                                   htab->elf.sgot->contents + off + GOT_ENTRY_SIZE);
 | 
      
        |                       outrel.r_info = ELF64_R_INFO (indx,
 |                       outrel.r_info = ELF64_R_INFO (indx,
 | 
      
        |                                                     R_X86_64_DTPOFF64);
 |                                                     R_X86_64_DTPOFF64);
 | 
      
        |                       outrel.r_offset += GOT_ENTRY_SIZE;
 |                       outrel.r_offset += GOT_ENTRY_SIZE;
 | 
      
        |                       sreloc->reloc_count++;
 |                       sreloc->reloc_count++;
 | 
      
        |                       loc += sizeof (Elf64_External_Rela);
 |                       loc += sizeof (Elf64_External_Rela);
 | 
      
        | Line 3002... | Line 3484... | 
      
        |             abort ();
 |             abort ();
 | 
      
        |           if (r_type == ELF64_R_TYPE (rel->r_info))
 |           if (r_type == ELF64_R_TYPE (rel->r_info))
 | 
      
        |             {
 |             {
 | 
      
        |               if (r_type == R_X86_64_GOTPC32_TLSDESC
 |               if (r_type == R_X86_64_GOTPC32_TLSDESC
 | 
      
        |                   || r_type == R_X86_64_TLSDESC_CALL)
 |                   || r_type == R_X86_64_TLSDESC_CALL)
 | 
      
        |                 relocation = htab->sgotplt->output_section->vma
 |                 relocation = htab->elf.sgotplt->output_section->vma
 | 
      
        |                   + htab->sgotplt->output_offset
 |                   + htab->elf.sgotplt->output_offset
 | 
      
        |                   + offplt + htab->sgotplt_jump_table_size;
 |                   + offplt + htab->sgotplt_jump_table_size;
 | 
      
        |               else
 |               else
 | 
      
        |                 relocation = htab->sgot->output_section->vma
 |                 relocation = htab->elf.sgot->output_section->vma
 | 
      
        |                   + htab->sgot->output_offset + off;
 |                   + htab->elf.sgot->output_offset + off;
 | 
      
        |               unresolved_reloc = FALSE;
 |               unresolved_reloc = FALSE;
 | 
      
        |             }
 |             }
 | 
      
        |           else
 |           else
 | 
      
        |             {
 |             {
 | 
      
        |               bfd_vma roff = rel->r_offset;
 |               bfd_vma roff = rel->r_offset;
 | 
      
        | Line 3026... | Line 3508... | 
      
        |                      addq foo@gottpoff(%rip), %rax */
 |                      addq foo@gottpoff(%rip), %rax */
 | 
      
        |                   memcpy (contents + roff - 4,
 |                   memcpy (contents + roff - 4,
 | 
      
        |                           "\x64\x48\x8b\x04\x25\0\0\0\0\x48\x03\x05\0\0\0",
 |                           "\x64\x48\x8b\x04\x25\0\0\0\0\x48\x03\x05\0\0\0",
 | 
      
        |                           16);
 |                           16);
 | 
      
        |  
 |  
 | 
      
        |                   relocation = (htab->sgot->output_section->vma
 |                   relocation = (htab->elf.sgot->output_section->vma
 | 
      
        |                                 + htab->sgot->output_offset + off
 |                                 + htab->elf.sgot->output_offset + off
 | 
      
        |                                 - roff
 |                                 - roff
 | 
      
        |                                 - input_section->output_section->vma
 |                                 - input_section->output_section->vma
 | 
      
        |                                 - input_section->output_offset
 |                                 - input_section->output_offset
 | 
      
        |                                 - 12);
 |                                 - 12);
 | 
      
        |                   bfd_put_32 (output_bfd, relocation,
 |                   bfd_put_32 (output_bfd, relocation,
 | 
      
        | Line 3061... | Line 3543... | 
      
        |                      suffices to change the second byte from 0x8d to
 |                      suffices to change the second byte from 0x8d to
 | 
      
        |                      0x8b.  */
 |                      0x8b.  */
 | 
      
        |                   bfd_put_8 (output_bfd, 0x8b, contents + roff - 2);
 |                   bfd_put_8 (output_bfd, 0x8b, contents + roff - 2);
 | 
      
        |  
 |  
 | 
      
        |                   bfd_put_32 (output_bfd,
 |                   bfd_put_32 (output_bfd,
 | 
      
        |                               htab->sgot->output_section->vma
 |                               htab->elf.sgot->output_section->vma
 | 
      
        |                               + htab->sgot->output_offset + off
 |                               + htab->elf.sgot->output_offset + off
 | 
      
        |                               - rel->r_offset
 |                               - rel->r_offset
 | 
      
        |                               - input_section->output_section->vma
 |                               - input_section->output_section->vma
 | 
      
        |                               - input_section->output_offset
 |                               - input_section->output_offset
 | 
      
        |                               - 4,
 |                               - 4,
 | 
      
        |                               contents + roff);
 |                               contents + roff);
 | 
      
        | Line 3097... | Line 3579... | 
      
        |         case R_X86_64_TLSLD:
 |         case R_X86_64_TLSLD:
 | 
      
        |           if (! elf64_x86_64_tls_transition (info, input_bfd,
 |           if (! elf64_x86_64_tls_transition (info, input_bfd,
 | 
      
        |                                              input_section, contents,
 |                                              input_section, contents,
 | 
      
        |                                              symtab_hdr, sym_hashes,
 |                                              symtab_hdr, sym_hashes,
 | 
      
        |                                              &r_type, GOT_UNKNOWN,
 |                                              &r_type, GOT_UNKNOWN,
 | 
      
        |                                              rel, relend, h))
 |                                              rel, relend, h, r_symndx))
 | 
      
        |             return FALSE;
 |             return FALSE;
 | 
      
        |  
 |  
 | 
      
        |           if (r_type != R_X86_64_TLSLD)
 |           if (r_type != R_X86_64_TLSLD)
 | 
      
        |             {
 |             {
 | 
      
        |               /* LD->LE transition:
 |               /* LD->LE transition:
 | 
      
        | Line 3115... | Line 3597... | 
      
        |               /* Skip R_X86_64_PC32/R_X86_64_PLT32.  */
 |               /* Skip R_X86_64_PC32/R_X86_64_PLT32.  */
 | 
      
        |               rel++;
 |               rel++;
 | 
      
        |               continue;
 |               continue;
 | 
      
        |             }
 |             }
 | 
      
        |  
 |  
 | 
      
        |           if (htab->sgot == NULL)
 |           if (htab->elf.sgot == NULL)
 | 
      
        |             abort ();
 |             abort ();
 | 
      
        |  
 |  
 | 
      
        |           off = htab->tls_ld_got.offset;
 |           off = htab->tls_ld_got.offset;
 | 
      
        |           if (off & 1)
 |           if (off & 1)
 | 
      
        |             off &= ~1;
 |             off &= ~1;
 | 
      
        |           else
 |           else
 | 
      
        |             {
 |             {
 | 
      
        |               Elf_Internal_Rela outrel;
 |               Elf_Internal_Rela outrel;
 | 
      
        |               bfd_byte *loc;
 |               bfd_byte *loc;
 | 
      
        |  
 |  
 | 
      
        |               if (htab->srelgot == NULL)
 |               if (htab->elf.srelgot == NULL)
 | 
      
        |                 abort ();
 |                 abort ();
 | 
      
        |  
 |  
 | 
      
        |               outrel.r_offset = (htab->sgot->output_section->vma
 |               outrel.r_offset = (htab->elf.sgot->output_section->vma
 | 
      
        |                                  + htab->sgot->output_offset + off);
 |                                  + htab->elf.sgot->output_offset + off);
 | 
      
        |  
 |  
 | 
      
        |               bfd_put_64 (output_bfd, 0,
 |               bfd_put_64 (output_bfd, 0,
 | 
      
        |                           htab->sgot->contents + off);
 |                           htab->elf.sgot->contents + off);
 | 
      
        |               bfd_put_64 (output_bfd, 0,
 |               bfd_put_64 (output_bfd, 0,
 | 
      
        |                           htab->sgot->contents + off + GOT_ENTRY_SIZE);
 |                           htab->elf.sgot->contents + off + GOT_ENTRY_SIZE);
 | 
      
        |               outrel.r_info = ELF64_R_INFO (0, R_X86_64_DTPMOD64);
 |               outrel.r_info = ELF64_R_INFO (0, R_X86_64_DTPMOD64);
 | 
      
        |               outrel.r_addend = 0;
 |               outrel.r_addend = 0;
 | 
      
        |               loc = htab->srelgot->contents;
 |               loc = htab->elf.srelgot->contents;
 | 
      
        |               loc += htab->srelgot->reloc_count++ * sizeof (Elf64_External_Rela);
 |               loc += htab->elf.srelgot->reloc_count++ * sizeof (Elf64_External_Rela);
 | 
      
        |               bfd_elf64_swap_reloca_out (output_bfd, &outrel, loc);
 |               bfd_elf64_swap_reloca_out (output_bfd, &outrel, loc);
 | 
      
        |               htab->tls_ld_got.offset |= 1;
 |               htab->tls_ld_got.offset |= 1;
 | 
      
        |             }
 |             }
 | 
      
        |           relocation = htab->sgot->output_section->vma
 |           relocation = htab->elf.sgot->output_section->vma
 | 
      
        |                        + htab->sgot->output_offset + off;
 |                        + htab->elf.sgot->output_offset + off;
 | 
      
        |           unresolved_reloc = FALSE;
 |           unresolved_reloc = FALSE;
 | 
      
        |           break;
 |           break;
 | 
      
        |  
 |  
 | 
      
        |         case R_X86_64_DTPOFF32:
 |         case R_X86_64_DTPOFF32:
 | 
      
        |           if (info->shared || (input_section->flags & SEC_CODE) == 0)
 |           if (!info->executable|| (input_section->flags & SEC_CODE) == 0)
 | 
      
        |             relocation -= dtpoff_base (info);
 |             relocation -= elf64_x86_64_dtpoff_base (info);
 | 
      
        |           else
 |           else
 | 
      
        |             relocation = tpoff (info, relocation);
 |             relocation = elf64_x86_64_tpoff (info, relocation);
 | 
      
        |           break;
 |           break;
 | 
      
        |  
 |  
 | 
      
        |         case R_X86_64_TPOFF32:
 |         case R_X86_64_TPOFF32:
 | 
      
        |           BFD_ASSERT (! info->shared);
 |           BFD_ASSERT (info->executable);
 | 
      
        |           relocation = tpoff (info, relocation);
 |           relocation = elf64_x86_64_tpoff (info, relocation);
 | 
      
        |           break;
 |           break;
 | 
      
        |  
 |  
 | 
      
        |         default:
 |         default:
 | 
      
        |           break;
 |           break;
 | 
      
        |         }
 |         }
 | 
      
        | Line 3178... | Line 3660... | 
      
        |            input_section,
 |            input_section,
 | 
      
        |            (long) rel->r_offset,
 |            (long) rel->r_offset,
 | 
      
        |            howto->name,
 |            howto->name,
 | 
      
        |            h->root.root.string);
 |            h->root.root.string);
 | 
      
        |  
 |  
 | 
      
        |   | do_relocation:
 | 
      
        |       r = _bfd_final_link_relocate (howto, input_bfd, input_section,
 |       r = _bfd_final_link_relocate (howto, input_bfd, input_section,
 | 
      
        |                                     contents, rel->r_offset,
 |                                     contents, rel->r_offset,
 | 
      
        |                                     relocation, rel->r_addend);
 |                                     relocation, rel->r_addend);
 | 
      
        |  
 |  
 | 
      
        |       if (r != bfd_reloc_ok)
 |       if (r != bfd_reloc_ok)
 | 
      
        | Line 3240... | Line 3723... | 
      
        |     {
 |     {
 | 
      
        |       bfd_vma plt_index;
 |       bfd_vma plt_index;
 | 
      
        |       bfd_vma got_offset;
 |       bfd_vma got_offset;
 | 
      
        |       Elf_Internal_Rela rela;
 |       Elf_Internal_Rela rela;
 | 
      
        |       bfd_byte *loc;
 |       bfd_byte *loc;
 | 
      
        |   |       asection *plt, *gotplt, *relplt;
 | 
      
        |   |  
 | 
      
        |   |       /* When building a static executable, use .iplt, .igot.plt and
 | 
      
        |   |          .rela.iplt sections for STT_GNU_IFUNC symbols.  */
 | 
      
        |   |       if (htab->elf.splt != NULL)
 | 
      
        |   |         {
 | 
      
        |   |           plt = htab->elf.splt;
 | 
      
        |   |           gotplt = htab->elf.sgotplt;
 | 
      
        |   |           relplt = htab->elf.srelplt;
 | 
      
        |   |         }
 | 
      
        |   |       else
 | 
      
        |   |         {
 | 
      
        |   |           plt = htab->elf.iplt;
 | 
      
        |   |           gotplt = htab->elf.igotplt;
 | 
      
        |   |           relplt = htab->elf.irelplt;
 | 
      
        |   |         }
 | 
      
        |  
 |  
 | 
      
        |       /* This symbol has an entry in the procedure linkage table.  Set
 |       /* This symbol has an entry in the procedure linkage table.  Set
 | 
      
        |          it up.  */
 |          it up.  */
 | 
      
        |       if (h->dynindx == -1
 |       if ((h->dynindx == -1
 | 
      
        |           || htab->splt == NULL
 |            && !((h->forced_local || info->executable)
 | 
      
        |           || htab->sgotplt == NULL
 |                 && h->def_regular
 | 
      
        |           || htab->srelplt == NULL)
 |                 && h->type == STT_GNU_IFUNC))
 | 
      
        |   |           || plt == NULL
 | 
      
        |   |           || gotplt == NULL
 | 
      
        |   |           || relplt == NULL)
 | 
      
        |         abort ();
 |         abort ();
 | 
      
        |  
 |  
 | 
      
        |       /* Get the index in the procedure linkage table which
 |       /* Get the index in the procedure linkage table which
 | 
      
        |          corresponds to this symbol.  This is the index of this symbol
 |          corresponds to this symbol.  This is the index of this symbol
 | 
      
        |          in all the symbols for which we are making plt entries.  The
 |          in all the symbols for which we are making plt entries.  The
 | 
      
        |          first entry in the procedure linkage table is reserved.  */
 |          first entry in the procedure linkage table is reserved.
 | 
      
        |       plt_index = h->plt.offset / PLT_ENTRY_SIZE - 1;
 |   | 
      
        |  
 |  
 | 
      
        |       /* Get the offset into the .got table of the entry that
 |          Get the offset into the .got table of the entry that
 | 
      
        |          corresponds to this function.  Each .got entry is GOT_ENTRY_SIZE
 |          corresponds to this function.  Each .got entry is GOT_ENTRY_SIZE
 | 
      
        |          bytes. The first three are reserved for the dynamic linker.  */
 |          bytes. The first three are reserved for the dynamic linker.
 | 
      
        |   |  
 | 
      
        |   |          For static executables, we don't reserve anything.  */
 | 
      
        |   |  
 | 
      
        |   |       if (plt == htab->elf.splt)
 | 
      
        |   |         {
 | 
      
        |   |           plt_index = h->plt.offset / PLT_ENTRY_SIZE - 1;
 | 
      
        |       got_offset = (plt_index + 3) * GOT_ENTRY_SIZE;
 |       got_offset = (plt_index + 3) * GOT_ENTRY_SIZE;
 | 
      
        |   |         }
 | 
      
        |   |       else
 | 
      
        |   |         {
 | 
      
        |   |           plt_index = h->plt.offset / PLT_ENTRY_SIZE;
 | 
      
        |   |           got_offset = plt_index * GOT_ENTRY_SIZE;
 | 
      
        |   |         }
 | 
      
        |  
 |  
 | 
      
        |       /* Fill in the entry in the procedure linkage table.  */
 |       /* Fill in the entry in the procedure linkage table.  */
 | 
      
        |       memcpy (htab->splt->contents + h->plt.offset, elf64_x86_64_plt_entry,
 |       memcpy (plt->contents + h->plt.offset, elf64_x86_64_plt_entry,
 | 
      
        |               PLT_ENTRY_SIZE);
 |               PLT_ENTRY_SIZE);
 | 
      
        |  
 |  
 | 
      
        |       /* Insert the relocation positions of the plt section.  The magic
 |       /* Insert the relocation positions of the plt section.  The magic
 | 
      
        |          numbers at the end of the statements are the positions of the
 |          numbers at the end of the statements are the positions of the
 | 
      
        |          relocations in the plt section.  */
 |          relocations in the plt section.  */
 | 
      
        |       /* Put offset for jmp *name@GOTPCREL(%rip), since the
 |       /* Put offset for jmp *name@GOTPCREL(%rip), since the
 | 
      
        |          instruction uses 6 bytes, subtract this value.  */
 |          instruction uses 6 bytes, subtract this value.  */
 | 
      
        |       bfd_put_32 (output_bfd,
 |       bfd_put_32 (output_bfd,
 | 
      
        |                       (htab->sgotplt->output_section->vma
 |                       (gotplt->output_section->vma
 | 
      
        |                        + htab->sgotplt->output_offset
 |                        + gotplt->output_offset
 | 
      
        |                        + got_offset
 |                        + got_offset
 | 
      
        |                        - htab->splt->output_section->vma
 |                        - plt->output_section->vma
 | 
      
        |                        - htab->splt->output_offset
 |                        - plt->output_offset
 | 
      
        |                        - h->plt.offset
 |                        - h->plt.offset
 | 
      
        |                        - 6),
 |                        - 6),
 | 
      
        |                   htab->splt->contents + h->plt.offset + 2);
 |                   plt->contents + h->plt.offset + 2);
 | 
      
        |   |  
 | 
      
        |   |       /* Don't fill PLT entry for static executables.  */
 | 
      
        |   |       if (plt == htab->elf.splt)
 | 
      
        |   |         {
 | 
      
        |       /* Put relocation index.  */
 |       /* Put relocation index.  */
 | 
      
        |       bfd_put_32 (output_bfd, plt_index,
 |       bfd_put_32 (output_bfd, plt_index,
 | 
      
        |                   htab->splt->contents + h->plt.offset + 7);
 |                       plt->contents + h->plt.offset + 7);
 | 
      
        |       /* Put offset for jmp .PLT0.  */
 |       /* Put offset for jmp .PLT0.  */
 | 
      
        |       bfd_put_32 (output_bfd, - (h->plt.offset + PLT_ENTRY_SIZE),
 |       bfd_put_32 (output_bfd, - (h->plt.offset + PLT_ENTRY_SIZE),
 | 
      
        |                   htab->splt->contents + h->plt.offset + 12);
 |                       plt->contents + h->plt.offset + 12);
 | 
      
        |   |         }
 | 
      
        |  
 |  
 | 
      
        |       /* Fill in the entry in the global offset table, initially this
 |       /* Fill in the entry in the global offset table, initially this
 | 
      
        |          points to the pushq instruction in the PLT which is at offset 6.  */
 |          points to the pushq instruction in the PLT which is at offset 6.  */
 | 
      
        |       bfd_put_64 (output_bfd, (htab->splt->output_section->vma
 |       bfd_put_64 (output_bfd, (plt->output_section->vma
 | 
      
        |                                + htab->splt->output_offset
 |                                + plt->output_offset
 | 
      
        |                                + h->plt.offset + 6),
 |                                + h->plt.offset + 6),
 | 
      
        |                   htab->sgotplt->contents + got_offset);
 |                   gotplt->contents + got_offset);
 | 
      
        |  
 |  
 | 
      
        |       /* Fill in the entry in the .rela.plt section.  */
 |       /* Fill in the entry in the .rela.plt section.  */
 | 
      
        |       rela.r_offset = (htab->sgotplt->output_section->vma
 |       rela.r_offset = (gotplt->output_section->vma
 | 
      
        |                        + htab->sgotplt->output_offset
 |                        + gotplt->output_offset
 | 
      
        |                        + got_offset);
 |                        + got_offset);
 | 
      
        |   |       if (h->dynindx == -1
 | 
      
        |   |           || ((info->executable
 | 
      
        |   |                || ELF_ST_VISIBILITY (h->other) != STV_DEFAULT)
 | 
      
        |   |               && h->def_regular
 | 
      
        |   |               && h->type == STT_GNU_IFUNC))
 | 
      
        |   |         {
 | 
      
        |   |           /* If an STT_GNU_IFUNC symbol is locally defined, generate
 | 
      
        |   |              R_X86_64_IRELATIVE instead of R_X86_64_JUMP_SLOT.  */
 | 
      
        |   |           rela.r_info = ELF64_R_INFO (0, R_X86_64_IRELATIVE);
 | 
      
        |   |           rela.r_addend = (h->root.u.def.value
 | 
      
        |   |                            + h->root.u.def.section->output_section->vma
 | 
      
        |   |                            + h->root.u.def.section->output_offset);
 | 
      
        |   |         }
 | 
      
        |   |       else
 | 
      
        |   |         {
 | 
      
        |       rela.r_info = ELF64_R_INFO (h->dynindx, R_X86_64_JUMP_SLOT);
 |       rela.r_info = ELF64_R_INFO (h->dynindx, R_X86_64_JUMP_SLOT);
 | 
      
        |       rela.r_addend = 0;
 |       rela.r_addend = 0;
 | 
      
        |       loc = htab->srelplt->contents + plt_index * sizeof (Elf64_External_Rela);
 |         }
 | 
      
        |   |       loc = relplt->contents + plt_index * sizeof (Elf64_External_Rela);
 | 
      
        |       bfd_elf64_swap_reloca_out (output_bfd, &rela, loc);
 |       bfd_elf64_swap_reloca_out (output_bfd, &rela, loc);
 | 
      
        |  
 |  
 | 
      
        |       if (!h->def_regular)
 |       if (!h->def_regular)
 | 
      
        |         {
 |         {
 | 
      
        |           /* Mark the symbol as undefined, rather than as defined in
 |           /* Mark the symbol as undefined, rather than as defined in
 | 
      
        | Line 3326... | Line 3860... | 
      
        |       Elf_Internal_Rela rela;
 |       Elf_Internal_Rela rela;
 | 
      
        |       bfd_byte *loc;
 |       bfd_byte *loc;
 | 
      
        |  
 |  
 | 
      
        |       /* This symbol has an entry in the global offset table.  Set it
 |       /* This symbol has an entry in the global offset table.  Set it
 | 
      
        |          up.  */
 |          up.  */
 | 
      
        |       if (htab->sgot == NULL || htab->srelgot == NULL)
 |       if (htab->elf.sgot == NULL || htab->elf.srelgot == NULL)
 | 
      
        |         abort ();
 |         abort ();
 | 
      
        |  
 |  
 | 
      
        |       rela.r_offset = (htab->sgot->output_section->vma
 |       rela.r_offset = (htab->elf.sgot->output_section->vma
 | 
      
        |                        + htab->sgot->output_offset
 |                        + htab->elf.sgot->output_offset
 | 
      
        |                        + (h->got.offset &~ (bfd_vma) 1));
 |                        + (h->got.offset &~ (bfd_vma) 1));
 | 
      
        |  
 |  
 | 
      
        |       /* If this is a static link, or it is a -Bsymbolic link and the
 |       /* If this is a static link, or it is a -Bsymbolic link and the
 | 
      
        |          symbol is defined locally or was forced to be local because
 |          symbol is defined locally or was forced to be local because
 | 
      
        |          of a version file, we just want to emit a RELATIVE reloc.
 |          of a version file, we just want to emit a RELATIVE reloc.
 | 
      
        |          The entry in the global offset table will already have been
 |          The entry in the global offset table will already have been
 | 
      
        |          initialized in the relocate_section function.  */
 |          initialized in the relocate_section function.  */
 | 
      
        |       if (info->shared
 |       if (h->def_regular
 | 
      
        |   |           && h->type == STT_GNU_IFUNC)
 | 
      
        |   |         {
 | 
      
        |   |           if (info->shared)
 | 
      
        |   |             {
 | 
      
        |   |               /* Generate R_X86_64_GLOB_DAT.  */
 | 
      
        |   |               goto do_glob_dat;
 | 
      
        |   |             }
 | 
      
        |   |           else
 | 
      
        |   |             {
 | 
      
        |   |               asection *plt;
 | 
      
        |   |  
 | 
      
        |   |               if (!h->pointer_equality_needed)
 | 
      
        |   |                 abort ();
 | 
      
        |   |  
 | 
      
        |   |               /* For non-shared object, we can't use .got.plt, which
 | 
      
        |   |                  contains the real function addres if we need pointer
 | 
      
        |   |                  equality.  We load the GOT entry with the PLT entry.  */
 | 
      
        |   |               plt = htab->elf.splt ? htab->elf.splt : htab->elf.iplt;
 | 
      
        |   |               bfd_put_64 (output_bfd, (plt->output_section->vma
 | 
      
        |   |                                        + plt->output_offset
 | 
      
        |   |                                        + h->plt.offset),
 | 
      
        |   |                           htab->elf.sgot->contents + h->got.offset);
 | 
      
        |   |               return TRUE;
 | 
      
        |   |             }
 | 
      
        |   |         }
 | 
      
        |   |       else if (info->shared
 | 
      
        |           && SYMBOL_REFERENCES_LOCAL (info, h))
 |           && SYMBOL_REFERENCES_LOCAL (info, h))
 | 
      
        |         {
 |         {
 | 
      
        |   |           if (!h->def_regular)
 | 
      
        |   |             return FALSE;
 | 
      
        |           BFD_ASSERT((h->got.offset & 1) != 0);
 |           BFD_ASSERT((h->got.offset & 1) != 0);
 | 
      
        |           rela.r_info = ELF64_R_INFO (0, R_X86_64_RELATIVE);
 |           rela.r_info = ELF64_R_INFO (0, R_X86_64_RELATIVE);
 | 
      
        |           rela.r_addend = (h->root.u.def.value
 |           rela.r_addend = (h->root.u.def.value
 | 
      
        |                            + h->root.u.def.section->output_section->vma
 |                            + h->root.u.def.section->output_section->vma
 | 
      
        |                            + h->root.u.def.section->output_offset);
 |                            + h->root.u.def.section->output_offset);
 | 
      
        |         }
 |         }
 | 
      
        |       else
 |       else
 | 
      
        |         {
 |         {
 | 
      
        |           BFD_ASSERT((h->got.offset & 1) == 0);
 |           BFD_ASSERT((h->got.offset & 1) == 0);
 | 
      
        |   | do_glob_dat:
 | 
      
        |           bfd_put_64 (output_bfd, (bfd_vma) 0,
 |           bfd_put_64 (output_bfd, (bfd_vma) 0,
 | 
      
        |                       htab->sgot->contents + h->got.offset);
 |                       htab->elf.sgot->contents + h->got.offset);
 | 
      
        |           rela.r_info = ELF64_R_INFO (h->dynindx, R_X86_64_GLOB_DAT);
 |           rela.r_info = ELF64_R_INFO (h->dynindx, R_X86_64_GLOB_DAT);
 | 
      
        |           rela.r_addend = 0;
 |           rela.r_addend = 0;
 | 
      
        |         }
 |         }
 | 
      
        |  
 |  
 | 
      
        |       loc = htab->srelgot->contents;
 |       loc = htab->elf.srelgot->contents;
 | 
      
        |       loc += htab->srelgot->reloc_count++ * sizeof (Elf64_External_Rela);
 |       loc += htab->elf.srelgot->reloc_count++ * sizeof (Elf64_External_Rela);
 | 
      
        |       bfd_elf64_swap_reloca_out (output_bfd, &rela, loc);
 |       bfd_elf64_swap_reloca_out (output_bfd, &rela, loc);
 | 
      
        |     }
 |     }
 | 
      
        |  
 |  
 | 
      
        |   if (h->needs_copy)
 |   if (h->needs_copy)
 | 
      
        |     {
 |     {
 | 
      
        | Line 3384... | Line 3947... | 
      
        |       loc = htab->srelbss->contents;
 |       loc = htab->srelbss->contents;
 | 
      
        |       loc += htab->srelbss->reloc_count++ * sizeof (Elf64_External_Rela);
 |       loc += htab->srelbss->reloc_count++ * sizeof (Elf64_External_Rela);
 | 
      
        |       bfd_elf64_swap_reloca_out (output_bfd, &rela, loc);
 |       bfd_elf64_swap_reloca_out (output_bfd, &rela, loc);
 | 
      
        |     }
 |     }
 | 
      
        |  
 |  
 | 
      
        |   /* Mark _DYNAMIC and _GLOBAL_OFFSET_TABLE_ as absolute.  */
 |   /* Mark _DYNAMIC and _GLOBAL_OFFSET_TABLE_ as absolute.  SYM may
 | 
      
        |   if (strcmp (h->root.root.string, "_DYNAMIC") == 0
 |      be NULL for local symbols.  */
 | 
      
        |       || h == htab->elf.hgot)
 |   if (sym != NULL
 | 
      
        |   |       && (strcmp (h->root.root.string, "_DYNAMIC") == 0
 | 
      
        |   |           || h == htab->elf.hgot))
 | 
      
        |     sym->st_shndx = SHN_ABS;
 |     sym->st_shndx = SHN_ABS;
 | 
      
        |  
 |  
 | 
      
        |   return TRUE;
 |   return TRUE;
 | 
      
        | }
 | }
 | 
      
        |  
 |  
 | 
      
        |   | /* Finish up local dynamic symbol handling.  We set the contents of
 | 
      
        |   |    various dynamic sections here.  */
 | 
      
        |   |  
 | 
      
        |   | static bfd_boolean
 | 
      
        |   | elf64_x86_64_finish_local_dynamic_symbol (void **slot, void *inf)
 | 
      
        |   | {
 | 
      
        |   |   struct elf_link_hash_entry *h
 | 
      
        |   |     = (struct elf_link_hash_entry *) *slot;
 | 
      
        |   |   struct bfd_link_info *info
 | 
      
        |   |     = (struct bfd_link_info *) inf;
 | 
      
        |   |  
 | 
      
        |   |   return elf64_x86_64_finish_dynamic_symbol (info->output_bfd,
 | 
      
        |   |                                              info, h, NULL);
 | 
      
        |   | }
 | 
      
        |   |  
 | 
      
        | /* Used to decide how to sort relocs in an optimal manner for the
 | /* Used to decide how to sort relocs in an optimal manner for the
 | 
      
        |    dynamic linker, before writing them out.  */
 |    dynamic linker, before writing them out.  */
 | 
      
        |  
 |  
 | 
      
        | static enum elf_reloc_type_class
 | static enum elf_reloc_type_class
 | 
      
        | elf64_x86_64_reloc_type_class (const Elf_Internal_Rela *rela)
 | elf64_x86_64_reloc_type_class (const Elf_Internal_Rela *rela)
 | 
      
        | Line 3428... | Line 4008... | 
      
        |  
 |  
 | 
      
        |   if (htab->elf.dynamic_sections_created)
 |   if (htab->elf.dynamic_sections_created)
 | 
      
        |     {
 |     {
 | 
      
        |       Elf64_External_Dyn *dyncon, *dynconend;
 |       Elf64_External_Dyn *dyncon, *dynconend;
 | 
      
        |  
 |  
 | 
      
        |       if (sdyn == NULL || htab->sgot == NULL)
 |       if (sdyn == NULL || htab->elf.sgot == NULL)
 | 
      
        |         abort ();
 |         abort ();
 | 
      
        |  
 |  
 | 
      
        |       dyncon = (Elf64_External_Dyn *) sdyn->contents;
 |       dyncon = (Elf64_External_Dyn *) sdyn->contents;
 | 
      
        |       dynconend = (Elf64_External_Dyn *) (sdyn->contents + sdyn->size);
 |       dynconend = (Elf64_External_Dyn *) (sdyn->contents + sdyn->size);
 | 
      
        |       for (; dyncon < dynconend; dyncon++)
 |       for (; dyncon < dynconend; dyncon++)
 | 
      
        | Line 3446... | Line 4026... | 
      
        |             {
 |             {
 | 
      
        |             default:
 |             default:
 | 
      
        |               continue;
 |               continue;
 | 
      
        |  
 |  
 | 
      
        |             case DT_PLTGOT:
 |             case DT_PLTGOT:
 | 
      
        |               s = htab->sgotplt;
 |               s = htab->elf.sgotplt;
 | 
      
        |               dyn.d_un.d_ptr = s->output_section->vma + s->output_offset;
 |               dyn.d_un.d_ptr = s->output_section->vma + s->output_offset;
 | 
      
        |               break;
 |               break;
 | 
      
        |  
 |  
 | 
      
        |             case DT_JMPREL:
 |             case DT_JMPREL:
 | 
      
        |               dyn.d_un.d_ptr = htab->srelplt->output_section->vma;
 |               dyn.d_un.d_ptr = htab->elf.srelplt->output_section->vma;
 | 
      
        |               break;
 |               break;
 | 
      
        |  
 |  
 | 
      
        |             case DT_PLTRELSZ:
 |             case DT_PLTRELSZ:
 | 
      
        |               s = htab->srelplt->output_section;
 |               s = htab->elf.srelplt->output_section;
 | 
      
        |               dyn.d_un.d_val = s->size;
 |               dyn.d_un.d_val = s->size;
 | 
      
        |               break;
 |               break;
 | 
      
        |  
 |  
 | 
      
        |             case DT_RELASZ:
 |             case DT_RELASZ:
 | 
      
        |               /* The procedure linkage table relocs (DT_JMPREL) should
 |               /* The procedure linkage table relocs (DT_JMPREL) should
 | 
      
        | Line 3467... | Line 4047... | 
      
        |                  Therefore, we override the DT_RELASZ entry here to
 |                  Therefore, we override the DT_RELASZ entry here to
 | 
      
        |                  make it not include the JMPREL relocs.  Since the
 |                  make it not include the JMPREL relocs.  Since the
 | 
      
        |                  linker script arranges for .rela.plt to follow all
 |                  linker script arranges for .rela.plt to follow all
 | 
      
        |                  other relocation sections, we don't have to worry
 |                  other relocation sections, we don't have to worry
 | 
      
        |                  about changing the DT_RELA entry.  */
 |                  about changing the DT_RELA entry.  */
 | 
      
        |               if (htab->srelplt != NULL)
 |               if (htab->elf.srelplt != NULL)
 | 
      
        |                 {
 |                 {
 | 
      
        |                   s = htab->srelplt->output_section;
 |                   s = htab->elf.srelplt->output_section;
 | 
      
        |                   dyn.d_un.d_val -= s->size;
 |                   dyn.d_un.d_val -= s->size;
 | 
      
        |                 }
 |                 }
 | 
      
        |               break;
 |               break;
 | 
      
        |  
 |  
 | 
      
        |             case DT_TLSDESC_PLT:
 |             case DT_TLSDESC_PLT:
 | 
      
        |               s = htab->splt;
 |               s = htab->elf.splt;
 | 
      
        |               dyn.d_un.d_ptr = s->output_section->vma + s->output_offset
 |               dyn.d_un.d_ptr = s->output_section->vma + s->output_offset
 | 
      
        |                 + htab->tlsdesc_plt;
 |                 + htab->tlsdesc_plt;
 | 
      
        |               break;
 |               break;
 | 
      
        |  
 |  
 | 
      
        |             case DT_TLSDESC_GOT:
 |             case DT_TLSDESC_GOT:
 | 
      
        |               s = htab->sgot;
 |               s = htab->elf.sgot;
 | 
      
        |               dyn.d_un.d_ptr = s->output_section->vma + s->output_offset
 |               dyn.d_un.d_ptr = s->output_section->vma + s->output_offset
 | 
      
        |                 + htab->tlsdesc_got;
 |                 + htab->tlsdesc_got;
 | 
      
        |               break;
 |               break;
 | 
      
        |             }
 |             }
 | 
      
        |  
 |  
 | 
      
        |           bfd_elf64_swap_dyn_out (output_bfd, &dyn, dyncon);
 |           bfd_elf64_swap_dyn_out (output_bfd, &dyn, dyncon);
 | 
      
        |         }
 |         }
 | 
      
        |  
 |  
 | 
      
        |       /* Fill in the special first entry in the procedure linkage table.  */
 |       /* Fill in the special first entry in the procedure linkage table.  */
 | 
      
        |       if (htab->splt && htab->splt->size > 0)
 |       if (htab->elf.splt && htab->elf.splt->size > 0)
 | 
      
        |         {
 |         {
 | 
      
        |           /* Fill in the first entry in the procedure linkage table.  */
 |           /* Fill in the first entry in the procedure linkage table.  */
 | 
      
        |           memcpy (htab->splt->contents, elf64_x86_64_plt0_entry,
 |           memcpy (htab->elf.splt->contents, elf64_x86_64_plt0_entry,
 | 
      
        |                   PLT_ENTRY_SIZE);
 |                   PLT_ENTRY_SIZE);
 | 
      
        |           /* Add offset for pushq GOT+8(%rip), since the instruction
 |           /* Add offset for pushq GOT+8(%rip), since the instruction
 | 
      
        |              uses 6 bytes subtract this value.  */
 |              uses 6 bytes subtract this value.  */
 | 
      
        |           bfd_put_32 (output_bfd,
 |           bfd_put_32 (output_bfd,
 | 
      
        |                       (htab->sgotplt->output_section->vma
 |                       (htab->elf.sgotplt->output_section->vma
 | 
      
        |                        + htab->sgotplt->output_offset
 |                        + htab->elf.sgotplt->output_offset
 | 
      
        |                        + 8
 |                        + 8
 | 
      
        |                        - htab->splt->output_section->vma
 |                        - htab->elf.splt->output_section->vma
 | 
      
        |                        - htab->splt->output_offset
 |                        - htab->elf.splt->output_offset
 | 
      
        |                        - 6),
 |                        - 6),
 | 
      
        |                       htab->splt->contents + 2);
 |                       htab->elf.splt->contents + 2);
 | 
      
        |           /* Add offset for jmp *GOT+16(%rip). The 12 is the offset to
 |           /* Add offset for jmp *GOT+16(%rip). The 12 is the offset to
 | 
      
        |              the end of the instruction.  */
 |              the end of the instruction.  */
 | 
      
        |           bfd_put_32 (output_bfd,
 |           bfd_put_32 (output_bfd,
 | 
      
        |                       (htab->sgotplt->output_section->vma
 |                       (htab->elf.sgotplt->output_section->vma
 | 
      
        |                        + htab->sgotplt->output_offset
 |                        + htab->elf.sgotplt->output_offset
 | 
      
        |                        + 16
 |                        + 16
 | 
      
        |                        - htab->splt->output_section->vma
 |                        - htab->elf.splt->output_section->vma
 | 
      
        |                        - htab->splt->output_offset
 |                        - htab->elf.splt->output_offset
 | 
      
        |                        - 12),
 |                        - 12),
 | 
      
        |                       htab->splt->contents + 8);
 |                       htab->elf.splt->contents + 8);
 | 
      
        |  
 |  
 | 
      
        |           elf_section_data (htab->splt->output_section)->this_hdr.sh_entsize =
 |           elf_section_data (htab->elf.splt->output_section)->this_hdr.sh_entsize =
 | 
      
        |             PLT_ENTRY_SIZE;
 |             PLT_ENTRY_SIZE;
 | 
      
        |  
 |  
 | 
      
        |           if (htab->tlsdesc_plt)
 |           if (htab->tlsdesc_plt)
 | 
      
        |             {
 |             {
 | 
      
        |               bfd_put_64 (output_bfd, (bfd_vma) 0,
 |               bfd_put_64 (output_bfd, (bfd_vma) 0,
 | 
      
        |                           htab->sgot->contents + htab->tlsdesc_got);
 |                           htab->elf.sgot->contents + htab->tlsdesc_got);
 | 
      
        |  
 |  
 | 
      
        |               memcpy (htab->splt->contents + htab->tlsdesc_plt,
 |               memcpy (htab->elf.splt->contents + htab->tlsdesc_plt,
 | 
      
        |                       elf64_x86_64_plt0_entry,
 |                       elf64_x86_64_plt0_entry,
 | 
      
        |                       PLT_ENTRY_SIZE);
 |                       PLT_ENTRY_SIZE);
 | 
      
        |  
 |  
 | 
      
        |               /* Add offset for pushq GOT+8(%rip), since the
 |               /* Add offset for pushq GOT+8(%rip), since the
 | 
      
        |                  instruction uses 6 bytes subtract this value.  */
 |                  instruction uses 6 bytes subtract this value.  */
 | 
      
        |               bfd_put_32 (output_bfd,
 |               bfd_put_32 (output_bfd,
 | 
      
        |                           (htab->sgotplt->output_section->vma
 |                           (htab->elf.sgotplt->output_section->vma
 | 
      
        |                            + htab->sgotplt->output_offset
 |                            + htab->elf.sgotplt->output_offset
 | 
      
        |                            + 8
 |                            + 8
 | 
      
        |                            - htab->splt->output_section->vma
 |                            - htab->elf.splt->output_section->vma
 | 
      
        |                            - htab->splt->output_offset
 |                            - htab->elf.splt->output_offset
 | 
      
        |                            - htab->tlsdesc_plt
 |                            - htab->tlsdesc_plt
 | 
      
        |                            - 6),
 |                            - 6),
 | 
      
        |                           htab->splt->contents + htab->tlsdesc_plt + 2);
 |                           htab->elf.splt->contents + htab->tlsdesc_plt + 2);
 | 
      
        |               /* Add offset for jmp *GOT+TDG(%rip), where TGD stands for
 |               /* Add offset for jmp *GOT+TDG(%rip), where TGD stands for
 | 
      
        |                  htab->tlsdesc_got. The 12 is the offset to the end of
 |                  htab->tlsdesc_got. The 12 is the offset to the end of
 | 
      
        |                  the instruction.  */
 |                  the instruction.  */
 | 
      
        |               bfd_put_32 (output_bfd,
 |               bfd_put_32 (output_bfd,
 | 
      
        |                           (htab->sgot->output_section->vma
 |                           (htab->elf.sgot->output_section->vma
 | 
      
        |                            + htab->sgot->output_offset
 |                            + htab->elf.sgot->output_offset
 | 
      
        |                            + htab->tlsdesc_got
 |                            + htab->tlsdesc_got
 | 
      
        |                            - htab->splt->output_section->vma
 |                            - htab->elf.splt->output_section->vma
 | 
      
        |                            - htab->splt->output_offset
 |                            - htab->elf.splt->output_offset
 | 
      
        |                            - htab->tlsdesc_plt
 |                            - htab->tlsdesc_plt
 | 
      
        |                            - 12),
 |                            - 12),
 | 
      
        |                           htab->splt->contents + htab->tlsdesc_plt + 8);
 |                           htab->elf.splt->contents + htab->tlsdesc_plt + 8);
 | 
      
        |             }
 |             }
 | 
      
        |         }
 |         }
 | 
      
        |     }
 |     }
 | 
      
        |  
 |  
 | 
      
        |   if (htab->sgotplt)
 |   if (htab->elf.sgotplt)
 | 
      
        |     {
 |     {
 | 
      
        |       /* Fill in the first three entries in the global offset table.  */
 |       /* Fill in the first three entries in the global offset table.  */
 | 
      
        |       if (htab->sgotplt->size > 0)
 |       if (htab->elf.sgotplt->size > 0)
 | 
      
        |         {
 |         {
 | 
      
        |           /* Set the first entry in the global offset table to the address of
 |           /* Set the first entry in the global offset table to the address of
 | 
      
        |              the dynamic section.  */
 |              the dynamic section.  */
 | 
      
        |           if (sdyn == NULL)
 |           if (sdyn == NULL)
 | 
      
        |             bfd_put_64 (output_bfd, (bfd_vma) 0, htab->sgotplt->contents);
 |             bfd_put_64 (output_bfd, (bfd_vma) 0, htab->elf.sgotplt->contents);
 | 
      
        |           else
 |           else
 | 
      
        |             bfd_put_64 (output_bfd,
 |             bfd_put_64 (output_bfd,
 | 
      
        |                         sdyn->output_section->vma + sdyn->output_offset,
 |                         sdyn->output_section->vma + sdyn->output_offset,
 | 
      
        |                         htab->sgotplt->contents);
 |                         htab->elf.sgotplt->contents);
 | 
      
        |           /* Write GOT[1] and GOT[2], needed for the dynamic linker.  */
 |           /* Write GOT[1] and GOT[2], needed for the dynamic linker.  */
 | 
      
        |           bfd_put_64 (output_bfd, (bfd_vma) 0, htab->sgotplt->contents + GOT_ENTRY_SIZE);
 |           bfd_put_64 (output_bfd, (bfd_vma) 0, htab->elf.sgotplt->contents + GOT_ENTRY_SIZE);
 | 
      
        |           bfd_put_64 (output_bfd, (bfd_vma) 0, htab->sgotplt->contents + GOT_ENTRY_SIZE*2);
 |           bfd_put_64 (output_bfd, (bfd_vma) 0, htab->elf.sgotplt->contents + GOT_ENTRY_SIZE*2);
 | 
      
        |         }
 |         }
 | 
      
        |  
 |  
 | 
      
        |       elf_section_data (htab->sgotplt->output_section)->this_hdr.sh_entsize =
 |       elf_section_data (htab->elf.sgotplt->output_section)->this_hdr.sh_entsize =
 | 
      
        |         GOT_ENTRY_SIZE;
 |         GOT_ENTRY_SIZE;
 | 
      
        |     }
 |     }
 | 
      
        |  
 |  
 | 
      
        |   if (htab->sgot && htab->sgot->size > 0)
 |   if (htab->elf.sgot && htab->elf.sgot->size > 0)
 | 
      
        |     elf_section_data (htab->sgot->output_section)->this_hdr.sh_entsize
 |     elf_section_data (htab->elf.sgot->output_section)->this_hdr.sh_entsize
 | 
      
        |       = GOT_ENTRY_SIZE;
 |       = GOT_ENTRY_SIZE;
 | 
      
        |  
 |  
 | 
      
        |   |   /* Fill PLT and GOT entries for local STT_GNU_IFUNC symbols.  */
 | 
      
        |   |   htab_traverse (htab->loc_hash_table,
 | 
      
        |   |                  elf64_x86_64_finish_local_dynamic_symbol,
 | 
      
        |   |                  info);
 | 
      
        |   |  
 | 
      
        |   return TRUE;
 |   return TRUE;
 | 
      
        | }
 | }
 | 
      
        |  
 |  
 | 
      
        | /* Return address for Ith PLT stub in section PLT, for relocation REL
 | /* Return address for Ith PLT stub in section PLT, for relocation REL
 | 
      
        |    or (bfd_vma) -1 if it should not be included.  */
 |    or (bfd_vma) -1 if it should not be included.  */
 | 
      
        | Line 3619... | Line 4204... | 
      
        |    file.  We use it to put SHN_X86_64_LCOMMON items in .lbss, instead
 |    file.  We use it to put SHN_X86_64_LCOMMON items in .lbss, instead
 | 
      
        |    of .bss.  */
 |    of .bss.  */
 | 
      
        |  
 |  
 | 
      
        | static bfd_boolean
 | static bfd_boolean
 | 
      
        | elf64_x86_64_add_symbol_hook (bfd *abfd,
 | elf64_x86_64_add_symbol_hook (bfd *abfd,
 | 
      
        |                               struct bfd_link_info *info ATTRIBUTE_UNUSED,
 |                               struct bfd_link_info *info,
 | 
      
        |                               Elf_Internal_Sym *sym,
 |                               Elf_Internal_Sym *sym,
 | 
      
        |                               const char **namep ATTRIBUTE_UNUSED,
 |                               const char **namep ATTRIBUTE_UNUSED,
 | 
      
        |                               flagword *flagsp ATTRIBUTE_UNUSED,
 |                               flagword *flagsp ATTRIBUTE_UNUSED,
 | 
      
        |                               asection **secp, bfd_vma *valp)
 |                               asection **secp,
 | 
      
        |   |                               bfd_vma *valp)
 | 
      
        | {
 | {
 | 
      
        |   asection *lcomm;
 |   asection *lcomm;
 | 
      
        |  
 |  
 | 
      
        |   switch (sym->st_shndx)
 |   switch (sym->st_shndx)
 | 
      
        |     {
 |     {
 | 
      
        | Line 3646... | Line 4232... | 
      
        |         }
 |         }
 | 
      
        |       *secp = lcomm;
 |       *secp = lcomm;
 | 
      
        |       *valp = sym->st_size;
 |       *valp = sym->st_size;
 | 
      
        |       break;
 |       break;
 | 
      
        |     }
 |     }
 | 
      
        |   |  
 | 
      
        |   |   if (ELF_ST_TYPE (sym->st_info) == STT_GNU_IFUNC)
 | 
      
        |   |     elf_tdata (info->output_bfd)->has_ifunc_symbols = TRUE;
 | 
      
        |   |  
 | 
      
        |   return TRUE;
 |   return TRUE;
 | 
      
        | }
 | }
 | 
      
        |  
 |  
 | 
      
        |  
 |  
 | 
      
        | /* Given a BFD section, try to locate the corresponding ELF section
 | /* Given a BFD section, try to locate the corresponding ELF section
 | 
      
        | Line 3825... | Line 4415... | 
      
        |  
 |  
 | 
      
        | #define elf_info_to_howto                   elf64_x86_64_info_to_howto
 | #define elf_info_to_howto                   elf64_x86_64_info_to_howto
 | 
      
        |  
 |  
 | 
      
        | #define bfd_elf64_bfd_link_hash_table_create \
 | #define bfd_elf64_bfd_link_hash_table_create \
 | 
      
        |   elf64_x86_64_link_hash_table_create
 |   elf64_x86_64_link_hash_table_create
 | 
      
        |   | #define bfd_elf64_bfd_link_hash_table_free \
 | 
      
        |   |   elf64_x86_64_link_hash_table_free
 | 
      
        | #define bfd_elf64_bfd_reloc_type_lookup     elf64_x86_64_reloc_type_lookup
 | #define bfd_elf64_bfd_reloc_type_lookup     elf64_x86_64_reloc_type_lookup
 | 
      
        | #define bfd_elf64_bfd_reloc_name_lookup \
 | #define bfd_elf64_bfd_reloc_name_lookup \
 | 
      
        |   elf64_x86_64_reloc_name_lookup
 |   elf64_x86_64_reloc_name_lookup
 | 
      
        |  
 |  
 | 
      
        | #define elf_backend_adjust_dynamic_symbol   elf64_x86_64_adjust_dynamic_symbol
 | #define elf_backend_adjust_dynamic_symbol   elf64_x86_64_adjust_dynamic_symbol
 | 
      
        | Line 3873... | Line 4465... | 
      
        | #define elf_backend_additional_program_headers \
 | #define elf_backend_additional_program_headers \
 | 
      
        |   elf64_x86_64_additional_program_headers
 |   elf64_x86_64_additional_program_headers
 | 
      
        | #define elf_backend_hash_symbol \
 | #define elf_backend_hash_symbol \
 | 
      
        |   elf64_x86_64_hash_symbol
 |   elf64_x86_64_hash_symbol
 | 
      
        |  
 |  
 | 
      
        |   | #undef  elf_backend_post_process_headers
 | 
      
        |   | #define elf_backend_post_process_headers  _bfd_elf_set_osabi
 | 
      
        |   |  
 | 
      
        | #include "elf64-target.h"
 | #include "elf64-target.h"
 | 
      
        |  
 |  
 | 
      
        | /* FreeBSD support.  */
 | /* FreeBSD support.  */
 | 
      
        |  
 |  
 | 
      
        | #undef  TARGET_LITTLE_SYM
 | #undef  TARGET_LITTLE_SYM
 | 
      
        | Line 3885... | Line 4480... | 
      
        | #define TARGET_LITTLE_NAME                  "elf64-x86-64-freebsd"
 | #define TARGET_LITTLE_NAME                  "elf64-x86-64-freebsd"
 | 
      
        |  
 |  
 | 
      
        | #undef  ELF_OSABI
 | #undef  ELF_OSABI
 | 
      
        | #define ELF_OSABI                           ELFOSABI_FREEBSD
 | #define ELF_OSABI                           ELFOSABI_FREEBSD
 | 
      
        |  
 |  
 | 
      
        |   | #undef  elf64_bed
 | 
      
        |   | #define elf64_bed elf64_x86_64_fbsd_bed
 | 
      
        |   |  
 | 
      
        |   | #include "elf64-target.h"
 | 
      
        |   |  
 | 
      
        |   | /* Intel L1OM support.  */
 | 
      
        |   |  
 | 
      
        |   | static bfd_boolean
 | 
      
        |   | elf64_l1om_elf_object_p (bfd *abfd)
 | 
      
        |   | {
 | 
      
        |   |   /* Set the right machine number for an L1OM elf64 file.  */
 | 
      
        |   |   bfd_default_set_arch_mach (abfd, bfd_arch_l1om, bfd_mach_l1om);
 | 
      
        |   |   return TRUE;
 | 
      
        |   | }
 | 
      
        |   |  
 | 
      
        |   | #undef  TARGET_LITTLE_SYM
 | 
      
        |   | #define TARGET_LITTLE_SYM                   bfd_elf64_l1om_vec
 | 
      
        |   | #undef  TARGET_LITTLE_NAME
 | 
      
        |   | #define TARGET_LITTLE_NAME                  "elf64-l1om"
 | 
      
        |   | #undef ELF_ARCH
 | 
      
        |   | #define ELF_ARCH                            bfd_arch_l1om
 | 
      
        |   |  
 | 
      
        |   | #undef  ELF_MACHINE_CODE
 | 
      
        |   | #define ELF_MACHINE_CODE                    EM_L1OM
 | 
      
        |   |  
 | 
      
        |   | #undef  ELF_OSABI
 | 
      
        |   |  
 | 
      
        |   | #undef  elf64_bed
 | 
      
        |   | #define elf64_bed elf64_l1om_bed
 | 
      
        |   |  
 | 
      
        |   | #undef elf_backend_object_p
 | 
      
        |   | #define elf_backend_object_p                elf64_l1om_elf_object_p
 | 
      
        |   |  
 | 
      
        | #undef  elf_backend_post_process_headers
 | #undef  elf_backend_post_process_headers
 | 
      
        | #define elf_backend_post_process_headers  _bfd_elf_set_osabi
 |  
 | 
      
        |   | #include "elf64-target.h"
 | 
      
        |   |  
 | 
      
        |   | /* FreeBSD L1OM support.  */
 | 
      
        |   |  
 | 
      
        |   | #undef  TARGET_LITTLE_SYM
 | 
      
        |   | #define TARGET_LITTLE_SYM                   bfd_elf64_l1om_freebsd_vec
 | 
      
        |   | #undef  TARGET_LITTLE_NAME
 | 
      
        |   | #define TARGET_LITTLE_NAME                  "elf64-l1om-freebsd"
 | 
      
        |   |  
 | 
      
        |   | #undef  ELF_OSABI
 | 
      
        |   | #define ELF_OSABI                           ELFOSABI_FREEBSD
 | 
      
        |  
 |  
 | 
      
        | #undef  elf64_bed
 | #undef  elf64_bed
 | 
      
        | #define elf64_bed elf64_x86_64_fbsd_bed
 | #define elf64_bed elf64_l1om_fbsd_bed
 | 
      
        |   |  
 | 
      
        |   | #undef  elf_backend_post_process_headers
 | 
      
        |   | #define elf_backend_post_process_headers  _bfd_elf_set_osabi
 | 
      
        |  
 |  
 | 
      
        | #include "elf64-target.h"
 | #include "elf64-target.h"
 | 
      
        |  
 |  
 | 
      
        |  No newline at end of file
 |  No newline at end of file
 |