Home | History | Annotate | Line # | Download | only in bfd
elfxx-x86.c revision 1.1.1.1.2.2
      1  1.1.1.1.2.2  pgoyette /* x86 specific support for ELF
      2  1.1.1.1.2.2  pgoyette    Copyright (C) 2017-2018 Free Software Foundation, Inc.
      3  1.1.1.1.2.2  pgoyette 
      4  1.1.1.1.2.2  pgoyette    This file is part of BFD, the Binary File Descriptor library.
      5  1.1.1.1.2.2  pgoyette 
      6  1.1.1.1.2.2  pgoyette    This program is free software; you can redistribute it and/or modify
      7  1.1.1.1.2.2  pgoyette    it under the terms of the GNU General Public License as published by
      8  1.1.1.1.2.2  pgoyette    the Free Software Foundation; either version 3 of the License, or
      9  1.1.1.1.2.2  pgoyette    (at your option) any later version.
     10  1.1.1.1.2.2  pgoyette 
     11  1.1.1.1.2.2  pgoyette    This program is distributed in the hope that it will be useful,
     12  1.1.1.1.2.2  pgoyette    but WITHOUT ANY WARRANTY; without even the implied warranty of
     13  1.1.1.1.2.2  pgoyette    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     14  1.1.1.1.2.2  pgoyette    GNU General Public License for more details.
     15  1.1.1.1.2.2  pgoyette 
     16  1.1.1.1.2.2  pgoyette    You should have received a copy of the GNU General Public License
     17  1.1.1.1.2.2  pgoyette    along with this program; if not, write to the Free Software
     18  1.1.1.1.2.2  pgoyette    Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
     19  1.1.1.1.2.2  pgoyette    MA 02110-1301, USA.  */
     20  1.1.1.1.2.2  pgoyette 
     21  1.1.1.1.2.2  pgoyette #include "elfxx-x86.h"
     22  1.1.1.1.2.2  pgoyette #include "elf-vxworks.h"
     23  1.1.1.1.2.2  pgoyette #include "objalloc.h"
     24  1.1.1.1.2.2  pgoyette #include "elf/i386.h"
     25  1.1.1.1.2.2  pgoyette #include "elf/x86-64.h"
     26  1.1.1.1.2.2  pgoyette 
     27  1.1.1.1.2.2  pgoyette /* The name of the dynamic interpreter.  This is put in the .interp
     28  1.1.1.1.2.2  pgoyette    section.  */
     29  1.1.1.1.2.2  pgoyette 
     30  1.1.1.1.2.2  pgoyette #define ELF32_DYNAMIC_INTERPRETER "/usr/lib/libc.so.1"
     31  1.1.1.1.2.2  pgoyette #define ELF64_DYNAMIC_INTERPRETER "/lib/ld64.so.1"
     32  1.1.1.1.2.2  pgoyette #define ELFX32_DYNAMIC_INTERPRETER "/lib/ldx32.so.1"
     33  1.1.1.1.2.2  pgoyette 
     34  1.1.1.1.2.2  pgoyette bfd_boolean
     35  1.1.1.1.2.2  pgoyette _bfd_x86_elf_mkobject (bfd *abfd)
     36  1.1.1.1.2.2  pgoyette {
     37  1.1.1.1.2.2  pgoyette   return bfd_elf_allocate_object (abfd,
     38  1.1.1.1.2.2  pgoyette 				  sizeof (struct elf_x86_obj_tdata),
     39  1.1.1.1.2.2  pgoyette 				  get_elf_backend_data (abfd)->target_id);
     40  1.1.1.1.2.2  pgoyette }
     41  1.1.1.1.2.2  pgoyette 
     42  1.1.1.1.2.2  pgoyette /* _TLS_MODULE_BASE_ needs to be treated especially when linking
     43  1.1.1.1.2.2  pgoyette    executables.  Rather than setting it to the beginning of the TLS
     44  1.1.1.1.2.2  pgoyette    section, we have to set it to the end.    This function may be called
     45  1.1.1.1.2.2  pgoyette    multiple times, it is idempotent.  */
     46  1.1.1.1.2.2  pgoyette 
     47  1.1.1.1.2.2  pgoyette void
     48  1.1.1.1.2.2  pgoyette _bfd_x86_elf_set_tls_module_base (struct bfd_link_info *info)
     49  1.1.1.1.2.2  pgoyette {
     50  1.1.1.1.2.2  pgoyette   struct elf_x86_link_hash_table *htab;
     51  1.1.1.1.2.2  pgoyette   struct bfd_link_hash_entry *base;
     52  1.1.1.1.2.2  pgoyette   const struct elf_backend_data *bed;
     53  1.1.1.1.2.2  pgoyette 
     54  1.1.1.1.2.2  pgoyette   if (!bfd_link_executable (info))
     55  1.1.1.1.2.2  pgoyette     return;
     56  1.1.1.1.2.2  pgoyette 
     57  1.1.1.1.2.2  pgoyette   bed = get_elf_backend_data (info->output_bfd);
     58  1.1.1.1.2.2  pgoyette   htab = elf_x86_hash_table (info, bed->target_id);
     59  1.1.1.1.2.2  pgoyette   if (htab == NULL)
     60  1.1.1.1.2.2  pgoyette     return;
     61  1.1.1.1.2.2  pgoyette 
     62  1.1.1.1.2.2  pgoyette   base = htab->tls_module_base;
     63  1.1.1.1.2.2  pgoyette   if (base == NULL)
     64  1.1.1.1.2.2  pgoyette     return;
     65  1.1.1.1.2.2  pgoyette 
     66  1.1.1.1.2.2  pgoyette   base->u.def.value = htab->elf.tls_size;
     67  1.1.1.1.2.2  pgoyette }
     68  1.1.1.1.2.2  pgoyette 
     69  1.1.1.1.2.2  pgoyette /* Return the base VMA address which should be subtracted from real addresses
     70  1.1.1.1.2.2  pgoyette    when resolving @dtpoff relocation.
     71  1.1.1.1.2.2  pgoyette    This is PT_TLS segment p_vaddr.  */
     72  1.1.1.1.2.2  pgoyette 
     73  1.1.1.1.2.2  pgoyette bfd_vma
     74  1.1.1.1.2.2  pgoyette _bfd_x86_elf_dtpoff_base (struct bfd_link_info *info)
     75  1.1.1.1.2.2  pgoyette {
     76  1.1.1.1.2.2  pgoyette   /* If tls_sec is NULL, we should have signalled an error already.  */
     77  1.1.1.1.2.2  pgoyette   if (elf_hash_table (info)->tls_sec == NULL)
     78  1.1.1.1.2.2  pgoyette     return 0;
     79  1.1.1.1.2.2  pgoyette   return elf_hash_table (info)->tls_sec->vma;
     80  1.1.1.1.2.2  pgoyette }
     81  1.1.1.1.2.2  pgoyette 
     82  1.1.1.1.2.2  pgoyette /* Allocate space in .plt, .got and associated reloc sections for
     83  1.1.1.1.2.2  pgoyette    dynamic relocs.  */
     84  1.1.1.1.2.2  pgoyette 
     85  1.1.1.1.2.2  pgoyette static bfd_boolean
     86  1.1.1.1.2.2  pgoyette elf_x86_allocate_dynrelocs (struct elf_link_hash_entry *h, void *inf)
     87  1.1.1.1.2.2  pgoyette {
     88  1.1.1.1.2.2  pgoyette   struct bfd_link_info *info;
     89  1.1.1.1.2.2  pgoyette   struct elf_x86_link_hash_table *htab;
     90  1.1.1.1.2.2  pgoyette   struct elf_x86_link_hash_entry *eh;
     91  1.1.1.1.2.2  pgoyette   struct elf_dyn_relocs *p;
     92  1.1.1.1.2.2  pgoyette   unsigned int plt_entry_size;
     93  1.1.1.1.2.2  pgoyette   bfd_boolean resolved_to_zero;
     94  1.1.1.1.2.2  pgoyette   const struct elf_backend_data *bed;
     95  1.1.1.1.2.2  pgoyette 
     96  1.1.1.1.2.2  pgoyette   if (h->root.type == bfd_link_hash_indirect)
     97  1.1.1.1.2.2  pgoyette     return TRUE;
     98  1.1.1.1.2.2  pgoyette 
     99  1.1.1.1.2.2  pgoyette   eh = (struct elf_x86_link_hash_entry *) h;
    100  1.1.1.1.2.2  pgoyette 
    101  1.1.1.1.2.2  pgoyette   info = (struct bfd_link_info *) inf;
    102  1.1.1.1.2.2  pgoyette   bed = get_elf_backend_data (info->output_bfd);
    103  1.1.1.1.2.2  pgoyette   htab = elf_x86_hash_table (info, bed->target_id);
    104  1.1.1.1.2.2  pgoyette   if (htab == NULL)
    105  1.1.1.1.2.2  pgoyette     return FALSE;
    106  1.1.1.1.2.2  pgoyette 
    107  1.1.1.1.2.2  pgoyette   plt_entry_size = htab->plt.plt_entry_size;
    108  1.1.1.1.2.2  pgoyette 
    109  1.1.1.1.2.2  pgoyette   resolved_to_zero = UNDEFINED_WEAK_RESOLVED_TO_ZERO (info, eh);
    110  1.1.1.1.2.2  pgoyette 
    111  1.1.1.1.2.2  pgoyette   /* We can't use the GOT PLT if pointer equality is needed since
    112  1.1.1.1.2.2  pgoyette      finish_dynamic_symbol won't clear symbol value and the dynamic
    113  1.1.1.1.2.2  pgoyette      linker won't update the GOT slot.  We will get into an infinite
    114  1.1.1.1.2.2  pgoyette      loop at run-time.  */
    115  1.1.1.1.2.2  pgoyette   if (htab->plt_got != NULL
    116  1.1.1.1.2.2  pgoyette       && h->type != STT_GNU_IFUNC
    117  1.1.1.1.2.2  pgoyette       && !h->pointer_equality_needed
    118  1.1.1.1.2.2  pgoyette       && h->plt.refcount > 0
    119  1.1.1.1.2.2  pgoyette       && h->got.refcount > 0)
    120  1.1.1.1.2.2  pgoyette     {
    121  1.1.1.1.2.2  pgoyette       /* Don't use the regular PLT if there are both GOT and GOTPLT
    122  1.1.1.1.2.2  pgoyette 	 reloctions.  */
    123  1.1.1.1.2.2  pgoyette       h->plt.offset = (bfd_vma) -1;
    124  1.1.1.1.2.2  pgoyette 
    125  1.1.1.1.2.2  pgoyette       /* Use the GOT PLT.  */
    126  1.1.1.1.2.2  pgoyette       eh->plt_got.refcount = 1;
    127  1.1.1.1.2.2  pgoyette     }
    128  1.1.1.1.2.2  pgoyette 
    129  1.1.1.1.2.2  pgoyette   /* Since STT_GNU_IFUNC symbol must go through PLT, we handle it
    130  1.1.1.1.2.2  pgoyette      here if it is defined and referenced in a non-shared object.  */
    131  1.1.1.1.2.2  pgoyette   if (h->type == STT_GNU_IFUNC
    132  1.1.1.1.2.2  pgoyette       && h->def_regular)
    133  1.1.1.1.2.2  pgoyette     {
    134  1.1.1.1.2.2  pgoyette       if (_bfd_elf_allocate_ifunc_dyn_relocs (info, h, &eh->dyn_relocs,
    135  1.1.1.1.2.2  pgoyette 					      &htab->readonly_dynrelocs_against_ifunc,
    136  1.1.1.1.2.2  pgoyette 					      plt_entry_size,
    137  1.1.1.1.2.2  pgoyette 					      (htab->plt.has_plt0
    138  1.1.1.1.2.2  pgoyette 					       * plt_entry_size),
    139  1.1.1.1.2.2  pgoyette 					       htab->got_entry_size,
    140  1.1.1.1.2.2  pgoyette 					       TRUE))
    141  1.1.1.1.2.2  pgoyette 	{
    142  1.1.1.1.2.2  pgoyette 	  asection *s = htab->plt_second;
    143  1.1.1.1.2.2  pgoyette 	  if (h->plt.offset != (bfd_vma) -1 && s != NULL)
    144  1.1.1.1.2.2  pgoyette 	    {
    145  1.1.1.1.2.2  pgoyette 	      /* Use the second PLT section if it is created.  */
    146  1.1.1.1.2.2  pgoyette 	      eh->plt_second.offset = s->size;
    147  1.1.1.1.2.2  pgoyette 
    148  1.1.1.1.2.2  pgoyette 	      /* Make room for this entry in the second PLT section.  */
    149  1.1.1.1.2.2  pgoyette 	      s->size += htab->non_lazy_plt->plt_entry_size;
    150  1.1.1.1.2.2  pgoyette 	    }
    151  1.1.1.1.2.2  pgoyette 
    152  1.1.1.1.2.2  pgoyette 	  return TRUE;
    153  1.1.1.1.2.2  pgoyette 	}
    154  1.1.1.1.2.2  pgoyette       else
    155  1.1.1.1.2.2  pgoyette 	return FALSE;
    156  1.1.1.1.2.2  pgoyette     }
    157  1.1.1.1.2.2  pgoyette   /* Don't create the PLT entry if there are only function pointer
    158  1.1.1.1.2.2  pgoyette      relocations which can be resolved at run-time.  */
    159  1.1.1.1.2.2  pgoyette   else if (htab->elf.dynamic_sections_created
    160  1.1.1.1.2.2  pgoyette 	   && (h->plt.refcount > 0
    161  1.1.1.1.2.2  pgoyette 	       || eh->plt_got.refcount > 0))
    162  1.1.1.1.2.2  pgoyette     {
    163  1.1.1.1.2.2  pgoyette       bfd_boolean use_plt_got = eh->plt_got.refcount > 0;
    164  1.1.1.1.2.2  pgoyette 
    165  1.1.1.1.2.2  pgoyette       /* Make sure this symbol is output as a dynamic symbol.
    166  1.1.1.1.2.2  pgoyette 	 Undefined weak syms won't yet be marked as dynamic.  */
    167  1.1.1.1.2.2  pgoyette       if (h->dynindx == -1
    168  1.1.1.1.2.2  pgoyette 	  && !h->forced_local
    169  1.1.1.1.2.2  pgoyette 	  && !resolved_to_zero
    170  1.1.1.1.2.2  pgoyette 	  && h->root.type == bfd_link_hash_undefweak)
    171  1.1.1.1.2.2  pgoyette 	{
    172  1.1.1.1.2.2  pgoyette 	  if (! bfd_elf_link_record_dynamic_symbol (info, h))
    173  1.1.1.1.2.2  pgoyette 	    return FALSE;
    174  1.1.1.1.2.2  pgoyette 	}
    175  1.1.1.1.2.2  pgoyette 
    176  1.1.1.1.2.2  pgoyette       if (bfd_link_pic (info)
    177  1.1.1.1.2.2  pgoyette 	  || WILL_CALL_FINISH_DYNAMIC_SYMBOL (1, 0, h))
    178  1.1.1.1.2.2  pgoyette 	{
    179  1.1.1.1.2.2  pgoyette 	  asection *s = htab->elf.splt;
    180  1.1.1.1.2.2  pgoyette 	  asection *second_s = htab->plt_second;
    181  1.1.1.1.2.2  pgoyette 	  asection *got_s = htab->plt_got;
    182  1.1.1.1.2.2  pgoyette 
    183  1.1.1.1.2.2  pgoyette 	  /* If this is the first .plt entry, make room for the special
    184  1.1.1.1.2.2  pgoyette 	     first entry.  The .plt section is used by prelink to undo
    185  1.1.1.1.2.2  pgoyette 	     prelinking for dynamic relocations.  */
    186  1.1.1.1.2.2  pgoyette 	  if (s->size == 0)
    187  1.1.1.1.2.2  pgoyette 	    s->size = htab->plt.has_plt0 * plt_entry_size;
    188  1.1.1.1.2.2  pgoyette 
    189  1.1.1.1.2.2  pgoyette 	  if (use_plt_got)
    190  1.1.1.1.2.2  pgoyette 	    eh->plt_got.offset = got_s->size;
    191  1.1.1.1.2.2  pgoyette 	  else
    192  1.1.1.1.2.2  pgoyette 	    {
    193  1.1.1.1.2.2  pgoyette 	      h->plt.offset = s->size;
    194  1.1.1.1.2.2  pgoyette 	      if (second_s)
    195  1.1.1.1.2.2  pgoyette 		eh->plt_second.offset = second_s->size;
    196  1.1.1.1.2.2  pgoyette 	    }
    197  1.1.1.1.2.2  pgoyette 
    198  1.1.1.1.2.2  pgoyette 	  /* If this symbol is not defined in a regular file, and we are
    199  1.1.1.1.2.2  pgoyette 	     not generating a shared library, then set the symbol to this
    200  1.1.1.1.2.2  pgoyette 	     location in the .plt.  This is required to make function
    201  1.1.1.1.2.2  pgoyette 	     pointers compare as equal between the normal executable and
    202  1.1.1.1.2.2  pgoyette 	     the shared library.  */
    203  1.1.1.1.2.2  pgoyette 	  if (! bfd_link_pic (info)
    204  1.1.1.1.2.2  pgoyette 	      && !h->def_regular)
    205  1.1.1.1.2.2  pgoyette 	    {
    206  1.1.1.1.2.2  pgoyette 	      if (use_plt_got)
    207  1.1.1.1.2.2  pgoyette 		{
    208  1.1.1.1.2.2  pgoyette 		  /* We need to make a call to the entry of the GOT PLT
    209  1.1.1.1.2.2  pgoyette 		     instead of regular PLT entry.  */
    210  1.1.1.1.2.2  pgoyette 		  h->root.u.def.section = got_s;
    211  1.1.1.1.2.2  pgoyette 		  h->root.u.def.value = eh->plt_got.offset;
    212  1.1.1.1.2.2  pgoyette 		}
    213  1.1.1.1.2.2  pgoyette 	      else
    214  1.1.1.1.2.2  pgoyette 		{
    215  1.1.1.1.2.2  pgoyette 		  if (second_s)
    216  1.1.1.1.2.2  pgoyette 		    {
    217  1.1.1.1.2.2  pgoyette 		      /* We need to make a call to the entry of the
    218  1.1.1.1.2.2  pgoyette 			 second PLT instead of regular PLT entry.  */
    219  1.1.1.1.2.2  pgoyette 		      h->root.u.def.section = second_s;
    220  1.1.1.1.2.2  pgoyette 		      h->root.u.def.value = eh->plt_second.offset;
    221  1.1.1.1.2.2  pgoyette 		    }
    222  1.1.1.1.2.2  pgoyette 		  else
    223  1.1.1.1.2.2  pgoyette 		    {
    224  1.1.1.1.2.2  pgoyette 		      h->root.u.def.section = s;
    225  1.1.1.1.2.2  pgoyette 		      h->root.u.def.value = h->plt.offset;
    226  1.1.1.1.2.2  pgoyette 		    }
    227  1.1.1.1.2.2  pgoyette 		}
    228  1.1.1.1.2.2  pgoyette 	    }
    229  1.1.1.1.2.2  pgoyette 
    230  1.1.1.1.2.2  pgoyette 	  /* Make room for this entry.  */
    231  1.1.1.1.2.2  pgoyette 	  if (use_plt_got)
    232  1.1.1.1.2.2  pgoyette 	    got_s->size += htab->non_lazy_plt->plt_entry_size;
    233  1.1.1.1.2.2  pgoyette 	  else
    234  1.1.1.1.2.2  pgoyette 	    {
    235  1.1.1.1.2.2  pgoyette 	      s->size += plt_entry_size;
    236  1.1.1.1.2.2  pgoyette 	      if (second_s)
    237  1.1.1.1.2.2  pgoyette 		second_s->size += htab->non_lazy_plt->plt_entry_size;
    238  1.1.1.1.2.2  pgoyette 
    239  1.1.1.1.2.2  pgoyette 	      /* We also need to make an entry in the .got.plt section,
    240  1.1.1.1.2.2  pgoyette 		 which will be placed in the .got section by the linker
    241  1.1.1.1.2.2  pgoyette 		 script.  */
    242  1.1.1.1.2.2  pgoyette 	      htab->elf.sgotplt->size += htab->got_entry_size;
    243  1.1.1.1.2.2  pgoyette 
    244  1.1.1.1.2.2  pgoyette 	      /* There should be no PLT relocation against resolved
    245  1.1.1.1.2.2  pgoyette 		 undefined weak symbol in executable.  */
    246  1.1.1.1.2.2  pgoyette 	      if (!resolved_to_zero)
    247  1.1.1.1.2.2  pgoyette 		{
    248  1.1.1.1.2.2  pgoyette 		  /* We also need to make an entry in the .rel.plt
    249  1.1.1.1.2.2  pgoyette 		     section.  */
    250  1.1.1.1.2.2  pgoyette 		  htab->elf.srelplt->size += htab->sizeof_reloc;
    251  1.1.1.1.2.2  pgoyette 		  htab->elf.srelplt->reloc_count++;
    252  1.1.1.1.2.2  pgoyette 		}
    253  1.1.1.1.2.2  pgoyette 	    }
    254  1.1.1.1.2.2  pgoyette 
    255  1.1.1.1.2.2  pgoyette 	  if (htab->target_os == is_vxworks && !bfd_link_pic (info))
    256  1.1.1.1.2.2  pgoyette 	    {
    257  1.1.1.1.2.2  pgoyette 	      /* VxWorks has a second set of relocations for each PLT entry
    258  1.1.1.1.2.2  pgoyette 		 in executables.  They go in a separate relocation section,
    259  1.1.1.1.2.2  pgoyette 		 which is processed by the kernel loader.  */
    260  1.1.1.1.2.2  pgoyette 
    261  1.1.1.1.2.2  pgoyette 	      /* There are two relocations for the initial PLT entry: an
    262  1.1.1.1.2.2  pgoyette 		 R_386_32 relocation for _GLOBAL_OFFSET_TABLE_ + 4 and an
    263  1.1.1.1.2.2  pgoyette 		 R_386_32 relocation for _GLOBAL_OFFSET_TABLE_ + 8.  */
    264  1.1.1.1.2.2  pgoyette 
    265  1.1.1.1.2.2  pgoyette 	      asection *srelplt2 = htab->srelplt2;
    266  1.1.1.1.2.2  pgoyette 	      if (h->plt.offset == plt_entry_size)
    267  1.1.1.1.2.2  pgoyette 		srelplt2->size += (htab->sizeof_reloc * 2);
    268  1.1.1.1.2.2  pgoyette 
    269  1.1.1.1.2.2  pgoyette 	      /* There are two extra relocations for each subsequent PLT entry:
    270  1.1.1.1.2.2  pgoyette 		 an R_386_32 relocation for the GOT entry, and an R_386_32
    271  1.1.1.1.2.2  pgoyette 		 relocation for the PLT entry.  */
    272  1.1.1.1.2.2  pgoyette 
    273  1.1.1.1.2.2  pgoyette 	      srelplt2->size += (htab->sizeof_reloc * 2);
    274  1.1.1.1.2.2  pgoyette 	    }
    275  1.1.1.1.2.2  pgoyette 	}
    276  1.1.1.1.2.2  pgoyette       else
    277  1.1.1.1.2.2  pgoyette 	{
    278  1.1.1.1.2.2  pgoyette 	  eh->plt_got.offset = (bfd_vma) -1;
    279  1.1.1.1.2.2  pgoyette 	  h->plt.offset = (bfd_vma) -1;
    280  1.1.1.1.2.2  pgoyette 	  h->needs_plt = 0;
    281  1.1.1.1.2.2  pgoyette 	}
    282  1.1.1.1.2.2  pgoyette     }
    283  1.1.1.1.2.2  pgoyette   else
    284  1.1.1.1.2.2  pgoyette     {
    285  1.1.1.1.2.2  pgoyette       eh->plt_got.offset = (bfd_vma) -1;
    286  1.1.1.1.2.2  pgoyette       h->plt.offset = (bfd_vma) -1;
    287  1.1.1.1.2.2  pgoyette       h->needs_plt = 0;
    288  1.1.1.1.2.2  pgoyette     }
    289  1.1.1.1.2.2  pgoyette 
    290  1.1.1.1.2.2  pgoyette   eh->tlsdesc_got = (bfd_vma) -1;
    291  1.1.1.1.2.2  pgoyette 
    292  1.1.1.1.2.2  pgoyette   /* For i386, if R_386_TLS_{IE_32,IE,GOTIE} symbol is now local to the
    293  1.1.1.1.2.2  pgoyette      binary, make it a R_386_TLS_LE_32 requiring no TLS entry.  For
    294  1.1.1.1.2.2  pgoyette      x86-64, if R_X86_64_GOTTPOFF symbol is now local to the binary,
    295  1.1.1.1.2.2  pgoyette      make it a R_X86_64_TPOFF32 requiring no GOT entry.  */
    296  1.1.1.1.2.2  pgoyette   if (h->got.refcount > 0
    297  1.1.1.1.2.2  pgoyette       && bfd_link_executable (info)
    298  1.1.1.1.2.2  pgoyette       && h->dynindx == -1
    299  1.1.1.1.2.2  pgoyette       && (elf_x86_hash_entry (h)->tls_type & GOT_TLS_IE))
    300  1.1.1.1.2.2  pgoyette     h->got.offset = (bfd_vma) -1;
    301  1.1.1.1.2.2  pgoyette   else if (h->got.refcount > 0)
    302  1.1.1.1.2.2  pgoyette     {
    303  1.1.1.1.2.2  pgoyette       asection *s;
    304  1.1.1.1.2.2  pgoyette       bfd_boolean dyn;
    305  1.1.1.1.2.2  pgoyette       int tls_type = elf_x86_hash_entry (h)->tls_type;
    306  1.1.1.1.2.2  pgoyette 
    307  1.1.1.1.2.2  pgoyette       /* Make sure this symbol is output as a dynamic symbol.
    308  1.1.1.1.2.2  pgoyette 	 Undefined weak syms won't yet be marked as dynamic.  */
    309  1.1.1.1.2.2  pgoyette       if (h->dynindx == -1
    310  1.1.1.1.2.2  pgoyette 	  && !h->forced_local
    311  1.1.1.1.2.2  pgoyette 	  && !resolved_to_zero
    312  1.1.1.1.2.2  pgoyette 	  && h->root.type == bfd_link_hash_undefweak)
    313  1.1.1.1.2.2  pgoyette 	{
    314  1.1.1.1.2.2  pgoyette 	  if (! bfd_elf_link_record_dynamic_symbol (info, h))
    315  1.1.1.1.2.2  pgoyette 	    return FALSE;
    316  1.1.1.1.2.2  pgoyette 	}
    317  1.1.1.1.2.2  pgoyette 
    318  1.1.1.1.2.2  pgoyette       s = htab->elf.sgot;
    319  1.1.1.1.2.2  pgoyette       if (GOT_TLS_GDESC_P (tls_type))
    320  1.1.1.1.2.2  pgoyette 	{
    321  1.1.1.1.2.2  pgoyette 	  eh->tlsdesc_got = htab->elf.sgotplt->size
    322  1.1.1.1.2.2  pgoyette 	    - elf_x86_compute_jump_table_size (htab);
    323  1.1.1.1.2.2  pgoyette 	  htab->elf.sgotplt->size += 2 * htab->got_entry_size;
    324  1.1.1.1.2.2  pgoyette 	  h->got.offset = (bfd_vma) -2;
    325  1.1.1.1.2.2  pgoyette 	}
    326  1.1.1.1.2.2  pgoyette       if (! GOT_TLS_GDESC_P (tls_type)
    327  1.1.1.1.2.2  pgoyette 	  || GOT_TLS_GD_P (tls_type))
    328  1.1.1.1.2.2  pgoyette 	{
    329  1.1.1.1.2.2  pgoyette 	  h->got.offset = s->size;
    330  1.1.1.1.2.2  pgoyette 	  s->size += htab->got_entry_size;
    331  1.1.1.1.2.2  pgoyette 	  /* R_386_TLS_GD and R_X86_64_TLSGD need 2 consecutive GOT
    332  1.1.1.1.2.2  pgoyette 	     slots.  */
    333  1.1.1.1.2.2  pgoyette 	  if (GOT_TLS_GD_P (tls_type) || tls_type == GOT_TLS_IE_BOTH)
    334  1.1.1.1.2.2  pgoyette 	    s->size += htab->got_entry_size;
    335  1.1.1.1.2.2  pgoyette 	}
    336  1.1.1.1.2.2  pgoyette       dyn = htab->elf.dynamic_sections_created;
    337  1.1.1.1.2.2  pgoyette       /* R_386_TLS_IE_32 needs one dynamic relocation,
    338  1.1.1.1.2.2  pgoyette 	 R_386_TLS_IE resp. R_386_TLS_GOTIE needs one dynamic relocation,
    339  1.1.1.1.2.2  pgoyette 	 (but if both R_386_TLS_IE_32 and R_386_TLS_IE is present, we
    340  1.1.1.1.2.2  pgoyette 	 need two), R_386_TLS_GD and R_X86_64_TLSGD need one if local
    341  1.1.1.1.2.2  pgoyette 	 symbol and two if global.  No dynamic relocation against
    342  1.1.1.1.2.2  pgoyette 	 resolved undefined weak symbol in executable.  */
    343  1.1.1.1.2.2  pgoyette       if (tls_type == GOT_TLS_IE_BOTH)
    344  1.1.1.1.2.2  pgoyette 	htab->elf.srelgot->size += 2 * htab->sizeof_reloc;
    345  1.1.1.1.2.2  pgoyette       else if ((GOT_TLS_GD_P (tls_type) && h->dynindx == -1)
    346  1.1.1.1.2.2  pgoyette 	       || (tls_type & GOT_TLS_IE))
    347  1.1.1.1.2.2  pgoyette 	htab->elf.srelgot->size += htab->sizeof_reloc;
    348  1.1.1.1.2.2  pgoyette       else if (GOT_TLS_GD_P (tls_type))
    349  1.1.1.1.2.2  pgoyette 	htab->elf.srelgot->size += 2 * htab->sizeof_reloc;
    350  1.1.1.1.2.2  pgoyette       else if (! GOT_TLS_GDESC_P (tls_type)
    351  1.1.1.1.2.2  pgoyette 	       && ((ELF_ST_VISIBILITY (h->other) == STV_DEFAULT
    352  1.1.1.1.2.2  pgoyette 		    && !resolved_to_zero)
    353  1.1.1.1.2.2  pgoyette 		   || h->root.type != bfd_link_hash_undefweak)
    354  1.1.1.1.2.2  pgoyette 	       && (bfd_link_pic (info)
    355  1.1.1.1.2.2  pgoyette 		   || WILL_CALL_FINISH_DYNAMIC_SYMBOL (dyn, 0, h)))
    356  1.1.1.1.2.2  pgoyette 	htab->elf.srelgot->size += htab->sizeof_reloc;
    357  1.1.1.1.2.2  pgoyette       if (GOT_TLS_GDESC_P (tls_type))
    358  1.1.1.1.2.2  pgoyette 	{
    359  1.1.1.1.2.2  pgoyette 	  htab->elf.srelplt->size += htab->sizeof_reloc;
    360  1.1.1.1.2.2  pgoyette 	  if (bed->target_id == X86_64_ELF_DATA)
    361  1.1.1.1.2.2  pgoyette 	    htab->tlsdesc_plt = (bfd_vma) -1;
    362  1.1.1.1.2.2  pgoyette 	}
    363  1.1.1.1.2.2  pgoyette     }
    364  1.1.1.1.2.2  pgoyette   else
    365  1.1.1.1.2.2  pgoyette     h->got.offset = (bfd_vma) -1;
    366  1.1.1.1.2.2  pgoyette 
    367  1.1.1.1.2.2  pgoyette   if (eh->dyn_relocs == NULL)
    368  1.1.1.1.2.2  pgoyette     return TRUE;
    369  1.1.1.1.2.2  pgoyette 
    370  1.1.1.1.2.2  pgoyette   /* In the shared -Bsymbolic case, discard space allocated for
    371  1.1.1.1.2.2  pgoyette      dynamic pc-relative relocs against symbols which turn out to be
    372  1.1.1.1.2.2  pgoyette      defined in regular objects.  For the normal shared case, discard
    373  1.1.1.1.2.2  pgoyette      space for pc-relative relocs that have become local due to symbol
    374  1.1.1.1.2.2  pgoyette      visibility changes.  */
    375  1.1.1.1.2.2  pgoyette 
    376  1.1.1.1.2.2  pgoyette   if (bfd_link_pic (info))
    377  1.1.1.1.2.2  pgoyette     {
    378  1.1.1.1.2.2  pgoyette       /* Relocs that use pc_count are those that appear on a call
    379  1.1.1.1.2.2  pgoyette 	 insn, or certain REL relocs that can generated via assembly.
    380  1.1.1.1.2.2  pgoyette 	 We want calls to protected symbols to resolve directly to the
    381  1.1.1.1.2.2  pgoyette 	 function rather than going via the plt.  If people want
    382  1.1.1.1.2.2  pgoyette 	 function pointer comparisons to work as expected then they
    383  1.1.1.1.2.2  pgoyette 	 should avoid writing weird assembly.  */
    384  1.1.1.1.2.2  pgoyette       if (SYMBOL_CALLS_LOCAL (info, h))
    385  1.1.1.1.2.2  pgoyette 	{
    386  1.1.1.1.2.2  pgoyette 	  struct elf_dyn_relocs **pp;
    387  1.1.1.1.2.2  pgoyette 
    388  1.1.1.1.2.2  pgoyette 	  for (pp = &eh->dyn_relocs; (p = *pp) != NULL; )
    389  1.1.1.1.2.2  pgoyette 	    {
    390  1.1.1.1.2.2  pgoyette 	      p->count -= p->pc_count;
    391  1.1.1.1.2.2  pgoyette 	      p->pc_count = 0;
    392  1.1.1.1.2.2  pgoyette 	      if (p->count == 0)
    393  1.1.1.1.2.2  pgoyette 		*pp = p->next;
    394  1.1.1.1.2.2  pgoyette 	      else
    395  1.1.1.1.2.2  pgoyette 		pp = &p->next;
    396  1.1.1.1.2.2  pgoyette 	    }
    397  1.1.1.1.2.2  pgoyette 	}
    398  1.1.1.1.2.2  pgoyette 
    399  1.1.1.1.2.2  pgoyette       if (htab->target_os == is_vxworks)
    400  1.1.1.1.2.2  pgoyette 	{
    401  1.1.1.1.2.2  pgoyette 	  struct elf_dyn_relocs **pp;
    402  1.1.1.1.2.2  pgoyette 	  for (pp = &eh->dyn_relocs; (p = *pp) != NULL; )
    403  1.1.1.1.2.2  pgoyette 	    {
    404  1.1.1.1.2.2  pgoyette 	      if (strcmp (p->sec->output_section->name, ".tls_vars") == 0)
    405  1.1.1.1.2.2  pgoyette 		*pp = p->next;
    406  1.1.1.1.2.2  pgoyette 	      else
    407  1.1.1.1.2.2  pgoyette 		pp = &p->next;
    408  1.1.1.1.2.2  pgoyette 	    }
    409  1.1.1.1.2.2  pgoyette 	}
    410  1.1.1.1.2.2  pgoyette 
    411  1.1.1.1.2.2  pgoyette       /* Also discard relocs on undefined weak syms with non-default
    412  1.1.1.1.2.2  pgoyette 	 visibility or in PIE.  */
    413  1.1.1.1.2.2  pgoyette       if (eh->dyn_relocs != NULL)
    414  1.1.1.1.2.2  pgoyette 	{
    415  1.1.1.1.2.2  pgoyette 	  if (h->root.type == bfd_link_hash_undefweak)
    416  1.1.1.1.2.2  pgoyette 	    {
    417  1.1.1.1.2.2  pgoyette 	      /* Undefined weak symbol is never bound locally in shared
    418  1.1.1.1.2.2  pgoyette 		 library.  */
    419  1.1.1.1.2.2  pgoyette 	      if (ELF_ST_VISIBILITY (h->other) != STV_DEFAULT
    420  1.1.1.1.2.2  pgoyette 		  || resolved_to_zero)
    421  1.1.1.1.2.2  pgoyette 		{
    422  1.1.1.1.2.2  pgoyette 		  if (bed->target_id == I386_ELF_DATA
    423  1.1.1.1.2.2  pgoyette 		      && h->non_got_ref)
    424  1.1.1.1.2.2  pgoyette 		    {
    425  1.1.1.1.2.2  pgoyette 		      /* Keep dynamic non-GOT/non-PLT relocation so
    426  1.1.1.1.2.2  pgoyette 			 that we can branch to 0 without PLT.  */
    427  1.1.1.1.2.2  pgoyette 		      struct elf_dyn_relocs **pp;
    428  1.1.1.1.2.2  pgoyette 
    429  1.1.1.1.2.2  pgoyette 		      for (pp = &eh->dyn_relocs; (p = *pp) != NULL; )
    430  1.1.1.1.2.2  pgoyette 			if (p->pc_count == 0)
    431  1.1.1.1.2.2  pgoyette 			  *pp = p->next;
    432  1.1.1.1.2.2  pgoyette 			else
    433  1.1.1.1.2.2  pgoyette 			  {
    434  1.1.1.1.2.2  pgoyette 			    /* Remove non-R_386_PC32 relocation.  */
    435  1.1.1.1.2.2  pgoyette 			    p->count = p->pc_count;
    436  1.1.1.1.2.2  pgoyette 			    pp = &p->next;
    437  1.1.1.1.2.2  pgoyette 			  }
    438  1.1.1.1.2.2  pgoyette 
    439  1.1.1.1.2.2  pgoyette 		      /* Make sure undefined weak symbols are output
    440  1.1.1.1.2.2  pgoyette 			 as dynamic symbols in PIEs for dynamic non-GOT
    441  1.1.1.1.2.2  pgoyette 			 non-PLT reloations.  */
    442  1.1.1.1.2.2  pgoyette 		      if (eh->dyn_relocs != NULL
    443  1.1.1.1.2.2  pgoyette 			  && !bfd_elf_link_record_dynamic_symbol (info, h))
    444  1.1.1.1.2.2  pgoyette 			return FALSE;
    445  1.1.1.1.2.2  pgoyette 		    }
    446  1.1.1.1.2.2  pgoyette 		  else
    447  1.1.1.1.2.2  pgoyette 		    eh->dyn_relocs = NULL;
    448  1.1.1.1.2.2  pgoyette 		}
    449  1.1.1.1.2.2  pgoyette 	      else if (h->dynindx == -1
    450  1.1.1.1.2.2  pgoyette 		       && !h->forced_local
    451  1.1.1.1.2.2  pgoyette 		       && !bfd_elf_link_record_dynamic_symbol (info, h))
    452  1.1.1.1.2.2  pgoyette 		return FALSE;
    453  1.1.1.1.2.2  pgoyette 	    }
    454  1.1.1.1.2.2  pgoyette 	  else if (bfd_link_executable (info)
    455  1.1.1.1.2.2  pgoyette 		   && (h->needs_copy || eh->needs_copy)
    456  1.1.1.1.2.2  pgoyette 		   && h->def_dynamic
    457  1.1.1.1.2.2  pgoyette 		   && !h->def_regular)
    458  1.1.1.1.2.2  pgoyette 	    {
    459  1.1.1.1.2.2  pgoyette 	      /* NB: needs_copy is set only for x86-64.  For PIE,
    460  1.1.1.1.2.2  pgoyette 		 discard space for pc-relative relocs against symbols
    461  1.1.1.1.2.2  pgoyette 		 which turn out to need copy relocs.  */
    462  1.1.1.1.2.2  pgoyette 	      struct elf_dyn_relocs **pp;
    463  1.1.1.1.2.2  pgoyette 
    464  1.1.1.1.2.2  pgoyette 	      for (pp = &eh->dyn_relocs; (p = *pp) != NULL; )
    465  1.1.1.1.2.2  pgoyette 		{
    466  1.1.1.1.2.2  pgoyette 		  if (p->pc_count != 0)
    467  1.1.1.1.2.2  pgoyette 		    *pp = p->next;
    468  1.1.1.1.2.2  pgoyette 		  else
    469  1.1.1.1.2.2  pgoyette 		    pp = &p->next;
    470  1.1.1.1.2.2  pgoyette 		}
    471  1.1.1.1.2.2  pgoyette 	    }
    472  1.1.1.1.2.2  pgoyette 	}
    473  1.1.1.1.2.2  pgoyette     }
    474  1.1.1.1.2.2  pgoyette   else if (ELIMINATE_COPY_RELOCS)
    475  1.1.1.1.2.2  pgoyette     {
    476  1.1.1.1.2.2  pgoyette       /* For the non-shared case, discard space for relocs against
    477  1.1.1.1.2.2  pgoyette 	 symbols which turn out to need copy relocs or are not
    478  1.1.1.1.2.2  pgoyette 	 dynamic.  Keep dynamic relocations for run-time function
    479  1.1.1.1.2.2  pgoyette 	 pointer initialization.  */
    480  1.1.1.1.2.2  pgoyette 
    481  1.1.1.1.2.2  pgoyette       if ((!h->non_got_ref
    482  1.1.1.1.2.2  pgoyette 	   || (h->root.type == bfd_link_hash_undefweak
    483  1.1.1.1.2.2  pgoyette 	       && !resolved_to_zero))
    484  1.1.1.1.2.2  pgoyette 	  && ((h->def_dynamic
    485  1.1.1.1.2.2  pgoyette 	       && !h->def_regular)
    486  1.1.1.1.2.2  pgoyette 	      || (htab->elf.dynamic_sections_created
    487  1.1.1.1.2.2  pgoyette 		  && (h->root.type == bfd_link_hash_undefweak
    488  1.1.1.1.2.2  pgoyette 		      || h->root.type == bfd_link_hash_undefined))))
    489  1.1.1.1.2.2  pgoyette 	{
    490  1.1.1.1.2.2  pgoyette 	  /* Make sure this symbol is output as a dynamic symbol.
    491  1.1.1.1.2.2  pgoyette 	     Undefined weak syms won't yet be marked as dynamic.  */
    492  1.1.1.1.2.2  pgoyette 	  if (h->dynindx == -1
    493  1.1.1.1.2.2  pgoyette 	      && !h->forced_local
    494  1.1.1.1.2.2  pgoyette 	      && !resolved_to_zero
    495  1.1.1.1.2.2  pgoyette 	      && h->root.type == bfd_link_hash_undefweak
    496  1.1.1.1.2.2  pgoyette 	      && ! bfd_elf_link_record_dynamic_symbol (info, h))
    497  1.1.1.1.2.2  pgoyette 	    return FALSE;
    498  1.1.1.1.2.2  pgoyette 
    499  1.1.1.1.2.2  pgoyette 	  /* If that succeeded, we know we'll be keeping all the
    500  1.1.1.1.2.2  pgoyette 	     relocs.  */
    501  1.1.1.1.2.2  pgoyette 	  if (h->dynindx != -1)
    502  1.1.1.1.2.2  pgoyette 	    goto keep;
    503  1.1.1.1.2.2  pgoyette 	}
    504  1.1.1.1.2.2  pgoyette 
    505  1.1.1.1.2.2  pgoyette       eh->dyn_relocs = NULL;
    506  1.1.1.1.2.2  pgoyette 
    507  1.1.1.1.2.2  pgoyette     keep: ;
    508  1.1.1.1.2.2  pgoyette     }
    509  1.1.1.1.2.2  pgoyette 
    510  1.1.1.1.2.2  pgoyette   /* Finally, allocate space.  */
    511  1.1.1.1.2.2  pgoyette   for (p = eh->dyn_relocs; p != NULL; p = p->next)
    512  1.1.1.1.2.2  pgoyette     {
    513  1.1.1.1.2.2  pgoyette       asection *sreloc;
    514  1.1.1.1.2.2  pgoyette 
    515  1.1.1.1.2.2  pgoyette       sreloc = elf_section_data (p->sec)->sreloc;
    516  1.1.1.1.2.2  pgoyette 
    517  1.1.1.1.2.2  pgoyette       BFD_ASSERT (sreloc != NULL);
    518  1.1.1.1.2.2  pgoyette       sreloc->size += p->count * htab->sizeof_reloc;
    519  1.1.1.1.2.2  pgoyette     }
    520  1.1.1.1.2.2  pgoyette 
    521  1.1.1.1.2.2  pgoyette   return TRUE;
    522  1.1.1.1.2.2  pgoyette }
    523  1.1.1.1.2.2  pgoyette 
    524  1.1.1.1.2.2  pgoyette /* Find dynamic relocs for H that apply to read-only sections.  */
    525  1.1.1.1.2.2  pgoyette 
    526  1.1.1.1.2.2  pgoyette static asection *
    527  1.1.1.1.2.2  pgoyette readonly_dynrelocs (struct elf_link_hash_entry *h)
    528  1.1.1.1.2.2  pgoyette {
    529  1.1.1.1.2.2  pgoyette   struct elf_dyn_relocs *p;
    530  1.1.1.1.2.2  pgoyette 
    531  1.1.1.1.2.2  pgoyette   for (p = elf_x86_hash_entry (h)->dyn_relocs; p != NULL; p = p->next)
    532  1.1.1.1.2.2  pgoyette     {
    533  1.1.1.1.2.2  pgoyette       asection *s = p->sec->output_section;
    534  1.1.1.1.2.2  pgoyette 
    535  1.1.1.1.2.2  pgoyette       if (s != NULL && (s->flags & SEC_READONLY) != 0)
    536  1.1.1.1.2.2  pgoyette 	return p->sec;
    537  1.1.1.1.2.2  pgoyette     }
    538  1.1.1.1.2.2  pgoyette   return NULL;
    539  1.1.1.1.2.2  pgoyette }
    540  1.1.1.1.2.2  pgoyette 
    541  1.1.1.1.2.2  pgoyette /* Set DF_TEXTREL if we find any dynamic relocs that apply to
    542  1.1.1.1.2.2  pgoyette    read-only sections.  */
    543  1.1.1.1.2.2  pgoyette 
    544  1.1.1.1.2.2  pgoyette static bfd_boolean
    545  1.1.1.1.2.2  pgoyette maybe_set_textrel (struct elf_link_hash_entry *h, void *inf)
    546  1.1.1.1.2.2  pgoyette {
    547  1.1.1.1.2.2  pgoyette   asection *sec;
    548  1.1.1.1.2.2  pgoyette 
    549  1.1.1.1.2.2  pgoyette   if (h->root.type == bfd_link_hash_indirect)
    550  1.1.1.1.2.2  pgoyette     return TRUE;
    551  1.1.1.1.2.2  pgoyette 
    552  1.1.1.1.2.2  pgoyette   /* Skip local IFUNC symbols. */
    553  1.1.1.1.2.2  pgoyette   if (h->forced_local && h->type == STT_GNU_IFUNC)
    554  1.1.1.1.2.2  pgoyette     return TRUE;
    555  1.1.1.1.2.2  pgoyette 
    556  1.1.1.1.2.2  pgoyette   sec = readonly_dynrelocs (h);
    557  1.1.1.1.2.2  pgoyette   if (sec != NULL)
    558  1.1.1.1.2.2  pgoyette     {
    559  1.1.1.1.2.2  pgoyette       struct bfd_link_info *info = (struct bfd_link_info *) inf;
    560  1.1.1.1.2.2  pgoyette 
    561  1.1.1.1.2.2  pgoyette       info->flags |= DF_TEXTREL;
    562  1.1.1.1.2.2  pgoyette       /* xgettext:c-format */
    563  1.1.1.1.2.2  pgoyette       info->callbacks->minfo (_("%B: dynamic relocation against `%T' "
    564  1.1.1.1.2.2  pgoyette 				"in read-only section `%A'\n"),
    565  1.1.1.1.2.2  pgoyette 			      sec->owner, h->root.root.string, sec);
    566  1.1.1.1.2.2  pgoyette 
    567  1.1.1.1.2.2  pgoyette       if ((info->warn_shared_textrel && bfd_link_pic (info))
    568  1.1.1.1.2.2  pgoyette 	  || info->error_textrel)
    569  1.1.1.1.2.2  pgoyette 	/* xgettext:c-format */
    570  1.1.1.1.2.2  pgoyette 	info->callbacks->einfo (_("%P: %B: warning: relocation against `%s' "
    571  1.1.1.1.2.2  pgoyette 				  "in read-only section `%A'\n"),
    572  1.1.1.1.2.2  pgoyette 				sec->owner, h->root.root.string, sec);
    573  1.1.1.1.2.2  pgoyette 
    574  1.1.1.1.2.2  pgoyette       /* Not an error, just cut short the traversal.  */
    575  1.1.1.1.2.2  pgoyette       return FALSE;
    576  1.1.1.1.2.2  pgoyette     }
    577  1.1.1.1.2.2  pgoyette   return TRUE;
    578  1.1.1.1.2.2  pgoyette }
    579  1.1.1.1.2.2  pgoyette 
    580  1.1.1.1.2.2  pgoyette /* Allocate space in .plt, .got and associated reloc sections for
    581  1.1.1.1.2.2  pgoyette    local dynamic relocs.  */
    582  1.1.1.1.2.2  pgoyette 
    583  1.1.1.1.2.2  pgoyette static bfd_boolean
    584  1.1.1.1.2.2  pgoyette elf_x86_allocate_local_dynreloc (void **slot, void *inf)
    585  1.1.1.1.2.2  pgoyette {
    586  1.1.1.1.2.2  pgoyette   struct elf_link_hash_entry *h
    587  1.1.1.1.2.2  pgoyette     = (struct elf_link_hash_entry *) *slot;
    588  1.1.1.1.2.2  pgoyette 
    589  1.1.1.1.2.2  pgoyette   if (h->type != STT_GNU_IFUNC
    590  1.1.1.1.2.2  pgoyette       || !h->def_regular
    591  1.1.1.1.2.2  pgoyette       || !h->ref_regular
    592  1.1.1.1.2.2  pgoyette       || !h->forced_local
    593  1.1.1.1.2.2  pgoyette       || h->root.type != bfd_link_hash_defined)
    594  1.1.1.1.2.2  pgoyette     abort ();
    595  1.1.1.1.2.2  pgoyette 
    596  1.1.1.1.2.2  pgoyette   return elf_x86_allocate_dynrelocs (h, inf);
    597  1.1.1.1.2.2  pgoyette }
    598  1.1.1.1.2.2  pgoyette 
    599  1.1.1.1.2.2  pgoyette /* Find and/or create a hash entry for local symbol.  */
    600  1.1.1.1.2.2  pgoyette 
    601  1.1.1.1.2.2  pgoyette struct elf_link_hash_entry *
    602  1.1.1.1.2.2  pgoyette _bfd_elf_x86_get_local_sym_hash (struct elf_x86_link_hash_table *htab,
    603  1.1.1.1.2.2  pgoyette 				 bfd *abfd, const Elf_Internal_Rela *rel,
    604  1.1.1.1.2.2  pgoyette 				 bfd_boolean create)
    605  1.1.1.1.2.2  pgoyette {
    606  1.1.1.1.2.2  pgoyette   struct elf_x86_link_hash_entry e, *ret;
    607  1.1.1.1.2.2  pgoyette   asection *sec = abfd->sections;
    608  1.1.1.1.2.2  pgoyette   hashval_t h = ELF_LOCAL_SYMBOL_HASH (sec->id,
    609  1.1.1.1.2.2  pgoyette 				       htab->r_sym (rel->r_info));
    610  1.1.1.1.2.2  pgoyette   void **slot;
    611  1.1.1.1.2.2  pgoyette 
    612  1.1.1.1.2.2  pgoyette   e.elf.indx = sec->id;
    613  1.1.1.1.2.2  pgoyette   e.elf.dynstr_index = htab->r_sym (rel->r_info);
    614  1.1.1.1.2.2  pgoyette   slot = htab_find_slot_with_hash (htab->loc_hash_table, &e, h,
    615  1.1.1.1.2.2  pgoyette 				   create ? INSERT : NO_INSERT);
    616  1.1.1.1.2.2  pgoyette 
    617  1.1.1.1.2.2  pgoyette   if (!slot)
    618  1.1.1.1.2.2  pgoyette     return NULL;
    619  1.1.1.1.2.2  pgoyette 
    620  1.1.1.1.2.2  pgoyette   if (*slot)
    621  1.1.1.1.2.2  pgoyette     {
    622  1.1.1.1.2.2  pgoyette       ret = (struct elf_x86_link_hash_entry *) *slot;
    623  1.1.1.1.2.2  pgoyette       return &ret->elf;
    624  1.1.1.1.2.2  pgoyette     }
    625  1.1.1.1.2.2  pgoyette 
    626  1.1.1.1.2.2  pgoyette   ret = (struct elf_x86_link_hash_entry *)
    627  1.1.1.1.2.2  pgoyette 	objalloc_alloc ((struct objalloc *) htab->loc_hash_memory,
    628  1.1.1.1.2.2  pgoyette 			sizeof (struct elf_x86_link_hash_entry));
    629  1.1.1.1.2.2  pgoyette   if (ret)
    630  1.1.1.1.2.2  pgoyette     {
    631  1.1.1.1.2.2  pgoyette       memset (ret, 0, sizeof (*ret));
    632  1.1.1.1.2.2  pgoyette       ret->elf.indx = sec->id;
    633  1.1.1.1.2.2  pgoyette       ret->elf.dynstr_index = htab->r_sym (rel->r_info);
    634  1.1.1.1.2.2  pgoyette       ret->elf.dynindx = -1;
    635  1.1.1.1.2.2  pgoyette       ret->plt_got.offset = (bfd_vma) -1;
    636  1.1.1.1.2.2  pgoyette       *slot = ret;
    637  1.1.1.1.2.2  pgoyette     }
    638  1.1.1.1.2.2  pgoyette   return &ret->elf;
    639  1.1.1.1.2.2  pgoyette }
    640  1.1.1.1.2.2  pgoyette 
    641  1.1.1.1.2.2  pgoyette /* Create an entry in a x86 ELF linker hash table.  NB: THIS MUST BE IN
    642  1.1.1.1.2.2  pgoyette    SYNC WITH _bfd_elf_link_hash_newfunc.  */
    643  1.1.1.1.2.2  pgoyette 
    644  1.1.1.1.2.2  pgoyette struct bfd_hash_entry *
    645  1.1.1.1.2.2  pgoyette _bfd_x86_elf_link_hash_newfunc (struct bfd_hash_entry *entry,
    646  1.1.1.1.2.2  pgoyette 				struct bfd_hash_table *table,
    647  1.1.1.1.2.2  pgoyette 				const char *string)
    648  1.1.1.1.2.2  pgoyette {
    649  1.1.1.1.2.2  pgoyette   /* Allocate the structure if it has not already been allocated by a
    650  1.1.1.1.2.2  pgoyette      subclass.  */
    651  1.1.1.1.2.2  pgoyette   if (entry == NULL)
    652  1.1.1.1.2.2  pgoyette     {
    653  1.1.1.1.2.2  pgoyette       entry = (struct bfd_hash_entry *)
    654  1.1.1.1.2.2  pgoyette 	bfd_hash_allocate (table,
    655  1.1.1.1.2.2  pgoyette 			   sizeof (struct elf_x86_link_hash_entry));
    656  1.1.1.1.2.2  pgoyette       if (entry == NULL)
    657  1.1.1.1.2.2  pgoyette 	return entry;
    658  1.1.1.1.2.2  pgoyette     }
    659  1.1.1.1.2.2  pgoyette 
    660  1.1.1.1.2.2  pgoyette   /* Call the allocation method of the superclass.  */
    661  1.1.1.1.2.2  pgoyette   entry = _bfd_link_hash_newfunc (entry, table, string);
    662  1.1.1.1.2.2  pgoyette   if (entry != NULL)
    663  1.1.1.1.2.2  pgoyette     {
    664  1.1.1.1.2.2  pgoyette       struct elf_x86_link_hash_entry *eh
    665  1.1.1.1.2.2  pgoyette        = (struct elf_x86_link_hash_entry *) entry;
    666  1.1.1.1.2.2  pgoyette       struct elf_link_hash_table *htab
    667  1.1.1.1.2.2  pgoyette 	= (struct elf_link_hash_table *) table;
    668  1.1.1.1.2.2  pgoyette 
    669  1.1.1.1.2.2  pgoyette       memset (&eh->elf.size, 0,
    670  1.1.1.1.2.2  pgoyette 	      (sizeof (struct elf_x86_link_hash_entry)
    671  1.1.1.1.2.2  pgoyette 	       - offsetof (struct elf_link_hash_entry, size)));
    672  1.1.1.1.2.2  pgoyette       /* Set local fields.  */
    673  1.1.1.1.2.2  pgoyette       eh->elf.indx = -1;
    674  1.1.1.1.2.2  pgoyette       eh->elf.dynindx = -1;
    675  1.1.1.1.2.2  pgoyette       eh->elf.got = htab->init_got_refcount;
    676  1.1.1.1.2.2  pgoyette       eh->elf.plt = htab->init_plt_refcount;
    677  1.1.1.1.2.2  pgoyette       /* Assume that we have been called by a non-ELF symbol reader.
    678  1.1.1.1.2.2  pgoyette 	 This flag is then reset by the code which reads an ELF input
    679  1.1.1.1.2.2  pgoyette 	 file.  This ensures that a symbol created by a non-ELF symbol
    680  1.1.1.1.2.2  pgoyette 	 reader will have the flag set correctly.  */
    681  1.1.1.1.2.2  pgoyette       eh->elf.non_elf = 1;
    682  1.1.1.1.2.2  pgoyette       eh->plt_second.offset = (bfd_vma) -1;
    683  1.1.1.1.2.2  pgoyette       eh->plt_got.offset = (bfd_vma) -1;
    684  1.1.1.1.2.2  pgoyette       eh->tlsdesc_got = (bfd_vma) -1;
    685  1.1.1.1.2.2  pgoyette       eh->zero_undefweak = 1;
    686  1.1.1.1.2.2  pgoyette     }
    687  1.1.1.1.2.2  pgoyette 
    688  1.1.1.1.2.2  pgoyette   return entry;
    689  1.1.1.1.2.2  pgoyette }
    690  1.1.1.1.2.2  pgoyette 
    691  1.1.1.1.2.2  pgoyette /* Compute a hash of a local hash entry.  We use elf_link_hash_entry
    692  1.1.1.1.2.2  pgoyette   for local symbol so that we can handle local STT_GNU_IFUNC symbols
    693  1.1.1.1.2.2  pgoyette   as global symbol.  We reuse indx and dynstr_index for local symbol
    694  1.1.1.1.2.2  pgoyette   hash since they aren't used by global symbols in this backend.  */
    695  1.1.1.1.2.2  pgoyette 
    696  1.1.1.1.2.2  pgoyette hashval_t
    697  1.1.1.1.2.2  pgoyette _bfd_x86_elf_local_htab_hash (const void *ptr)
    698  1.1.1.1.2.2  pgoyette {
    699  1.1.1.1.2.2  pgoyette   struct elf_link_hash_entry *h
    700  1.1.1.1.2.2  pgoyette     = (struct elf_link_hash_entry *) ptr;
    701  1.1.1.1.2.2  pgoyette   return ELF_LOCAL_SYMBOL_HASH (h->indx, h->dynstr_index);
    702  1.1.1.1.2.2  pgoyette }
    703  1.1.1.1.2.2  pgoyette 
    704  1.1.1.1.2.2  pgoyette /* Compare local hash entries.  */
    705  1.1.1.1.2.2  pgoyette 
    706  1.1.1.1.2.2  pgoyette int
    707  1.1.1.1.2.2  pgoyette _bfd_x86_elf_local_htab_eq (const void *ptr1, const void *ptr2)
    708  1.1.1.1.2.2  pgoyette {
    709  1.1.1.1.2.2  pgoyette   struct elf_link_hash_entry *h1
    710  1.1.1.1.2.2  pgoyette      = (struct elf_link_hash_entry *) ptr1;
    711  1.1.1.1.2.2  pgoyette   struct elf_link_hash_entry *h2
    712  1.1.1.1.2.2  pgoyette     = (struct elf_link_hash_entry *) ptr2;
    713  1.1.1.1.2.2  pgoyette 
    714  1.1.1.1.2.2  pgoyette   return h1->indx == h2->indx && h1->dynstr_index == h2->dynstr_index;
    715  1.1.1.1.2.2  pgoyette }
    716  1.1.1.1.2.2  pgoyette 
    717  1.1.1.1.2.2  pgoyette /* Destroy an x86 ELF linker hash table.  */
    718  1.1.1.1.2.2  pgoyette 
    719  1.1.1.1.2.2  pgoyette static void
    720  1.1.1.1.2.2  pgoyette elf_x86_link_hash_table_free (bfd *obfd)
    721  1.1.1.1.2.2  pgoyette {
    722  1.1.1.1.2.2  pgoyette   struct elf_x86_link_hash_table *htab
    723  1.1.1.1.2.2  pgoyette     = (struct elf_x86_link_hash_table *) obfd->link.hash;
    724  1.1.1.1.2.2  pgoyette 
    725  1.1.1.1.2.2  pgoyette   if (htab->loc_hash_table)
    726  1.1.1.1.2.2  pgoyette     htab_delete (htab->loc_hash_table);
    727  1.1.1.1.2.2  pgoyette   if (htab->loc_hash_memory)
    728  1.1.1.1.2.2  pgoyette     objalloc_free ((struct objalloc *) htab->loc_hash_memory);
    729  1.1.1.1.2.2  pgoyette   _bfd_elf_link_hash_table_free (obfd);
    730  1.1.1.1.2.2  pgoyette }
    731  1.1.1.1.2.2  pgoyette 
    732  1.1.1.1.2.2  pgoyette static bfd_boolean
    733  1.1.1.1.2.2  pgoyette elf_i386_is_reloc_section (const char *secname)
    734  1.1.1.1.2.2  pgoyette {
    735  1.1.1.1.2.2  pgoyette   return CONST_STRNEQ (secname, ".rel");
    736  1.1.1.1.2.2  pgoyette }
    737  1.1.1.1.2.2  pgoyette 
    738  1.1.1.1.2.2  pgoyette static bfd_boolean
    739  1.1.1.1.2.2  pgoyette elf_x86_64_is_reloc_section (const char *secname)
    740  1.1.1.1.2.2  pgoyette {
    741  1.1.1.1.2.2  pgoyette   return CONST_STRNEQ (secname, ".rela");
    742  1.1.1.1.2.2  pgoyette }
    743  1.1.1.1.2.2  pgoyette 
    744  1.1.1.1.2.2  pgoyette /* Create an x86 ELF linker hash table.  */
    745  1.1.1.1.2.2  pgoyette 
    746  1.1.1.1.2.2  pgoyette struct bfd_link_hash_table *
    747  1.1.1.1.2.2  pgoyette _bfd_x86_elf_link_hash_table_create (bfd *abfd)
    748  1.1.1.1.2.2  pgoyette {
    749  1.1.1.1.2.2  pgoyette   struct elf_x86_link_hash_table *ret;
    750  1.1.1.1.2.2  pgoyette   const struct elf_backend_data *bed;
    751  1.1.1.1.2.2  pgoyette   bfd_size_type amt = sizeof (struct elf_x86_link_hash_table);
    752  1.1.1.1.2.2  pgoyette 
    753  1.1.1.1.2.2  pgoyette   ret = (struct elf_x86_link_hash_table *) bfd_zmalloc (amt);
    754  1.1.1.1.2.2  pgoyette   if (ret == NULL)
    755  1.1.1.1.2.2  pgoyette     return NULL;
    756  1.1.1.1.2.2  pgoyette 
    757  1.1.1.1.2.2  pgoyette   bed = get_elf_backend_data (abfd);
    758  1.1.1.1.2.2  pgoyette   if (!_bfd_elf_link_hash_table_init (&ret->elf, abfd,
    759  1.1.1.1.2.2  pgoyette 				      _bfd_x86_elf_link_hash_newfunc,
    760  1.1.1.1.2.2  pgoyette 				      sizeof (struct elf_x86_link_hash_entry),
    761  1.1.1.1.2.2  pgoyette 				      bed->target_id))
    762  1.1.1.1.2.2  pgoyette     {
    763  1.1.1.1.2.2  pgoyette       free (ret);
    764  1.1.1.1.2.2  pgoyette       return NULL;
    765  1.1.1.1.2.2  pgoyette     }
    766  1.1.1.1.2.2  pgoyette 
    767  1.1.1.1.2.2  pgoyette   if (bed->target_id == X86_64_ELF_DATA)
    768  1.1.1.1.2.2  pgoyette     {
    769  1.1.1.1.2.2  pgoyette       ret->is_reloc_section = elf_x86_64_is_reloc_section;
    770  1.1.1.1.2.2  pgoyette       ret->dt_reloc = DT_RELA;
    771  1.1.1.1.2.2  pgoyette       ret->dt_reloc_sz = DT_RELASZ;
    772  1.1.1.1.2.2  pgoyette       ret->dt_reloc_ent = DT_RELAENT;
    773  1.1.1.1.2.2  pgoyette       ret->got_entry_size = 8;
    774  1.1.1.1.2.2  pgoyette       ret->tls_get_addr = "__tls_get_addr";
    775  1.1.1.1.2.2  pgoyette     }
    776  1.1.1.1.2.2  pgoyette   if (ABI_64_P (abfd))
    777  1.1.1.1.2.2  pgoyette     {
    778  1.1.1.1.2.2  pgoyette       ret->sizeof_reloc = sizeof (Elf64_External_Rela);
    779  1.1.1.1.2.2  pgoyette       ret->pointer_r_type = R_X86_64_64;
    780  1.1.1.1.2.2  pgoyette       ret->dynamic_interpreter = ELF64_DYNAMIC_INTERPRETER;
    781  1.1.1.1.2.2  pgoyette       ret->dynamic_interpreter_size = sizeof ELF64_DYNAMIC_INTERPRETER;
    782  1.1.1.1.2.2  pgoyette     }
    783  1.1.1.1.2.2  pgoyette   else
    784  1.1.1.1.2.2  pgoyette     {
    785  1.1.1.1.2.2  pgoyette       if (bed->target_id == X86_64_ELF_DATA)
    786  1.1.1.1.2.2  pgoyette 	{
    787  1.1.1.1.2.2  pgoyette 	  ret->sizeof_reloc = sizeof (Elf32_External_Rela);
    788  1.1.1.1.2.2  pgoyette 	  ret->pointer_r_type = R_X86_64_32;
    789  1.1.1.1.2.2  pgoyette 	  ret->dynamic_interpreter = ELFX32_DYNAMIC_INTERPRETER;
    790  1.1.1.1.2.2  pgoyette 	  ret->dynamic_interpreter_size
    791  1.1.1.1.2.2  pgoyette 	    = sizeof ELFX32_DYNAMIC_INTERPRETER;
    792  1.1.1.1.2.2  pgoyette 	}
    793  1.1.1.1.2.2  pgoyette       else
    794  1.1.1.1.2.2  pgoyette 	{
    795  1.1.1.1.2.2  pgoyette 	  ret->is_reloc_section = elf_i386_is_reloc_section;
    796  1.1.1.1.2.2  pgoyette 	  ret->dt_reloc = DT_REL;
    797  1.1.1.1.2.2  pgoyette 	  ret->dt_reloc_sz = DT_RELSZ;
    798  1.1.1.1.2.2  pgoyette 	  ret->dt_reloc_ent = DT_RELENT;
    799  1.1.1.1.2.2  pgoyette 	  ret->sizeof_reloc = sizeof (Elf32_External_Rel);
    800  1.1.1.1.2.2  pgoyette 	  ret->got_entry_size = 4;
    801  1.1.1.1.2.2  pgoyette 	  ret->pointer_r_type = R_386_32;
    802  1.1.1.1.2.2  pgoyette 	  ret->dynamic_interpreter = ELF32_DYNAMIC_INTERPRETER;
    803  1.1.1.1.2.2  pgoyette 	  ret->dynamic_interpreter_size
    804  1.1.1.1.2.2  pgoyette 	    = sizeof ELF32_DYNAMIC_INTERPRETER;
    805  1.1.1.1.2.2  pgoyette 	  ret->tls_get_addr = "___tls_get_addr";
    806  1.1.1.1.2.2  pgoyette 	}
    807  1.1.1.1.2.2  pgoyette     }
    808  1.1.1.1.2.2  pgoyette   ret->target_id = bed->target_id;
    809  1.1.1.1.2.2  pgoyette   ret->target_os = get_elf_x86_backend_data (abfd)->target_os;
    810  1.1.1.1.2.2  pgoyette 
    811  1.1.1.1.2.2  pgoyette   ret->loc_hash_table = htab_try_create (1024,
    812  1.1.1.1.2.2  pgoyette 					 _bfd_x86_elf_local_htab_hash,
    813  1.1.1.1.2.2  pgoyette 					 _bfd_x86_elf_local_htab_eq,
    814  1.1.1.1.2.2  pgoyette 					 NULL);
    815  1.1.1.1.2.2  pgoyette   ret->loc_hash_memory = objalloc_create ();
    816  1.1.1.1.2.2  pgoyette   if (!ret->loc_hash_table || !ret->loc_hash_memory)
    817  1.1.1.1.2.2  pgoyette     {
    818  1.1.1.1.2.2  pgoyette       elf_x86_link_hash_table_free (abfd);
    819  1.1.1.1.2.2  pgoyette       return NULL;
    820  1.1.1.1.2.2  pgoyette     }
    821  1.1.1.1.2.2  pgoyette   ret->elf.root.hash_table_free = elf_x86_link_hash_table_free;
    822  1.1.1.1.2.2  pgoyette 
    823  1.1.1.1.2.2  pgoyette   return &ret->elf.root;
    824  1.1.1.1.2.2  pgoyette }
    825  1.1.1.1.2.2  pgoyette 
    826  1.1.1.1.2.2  pgoyette /* Sort relocs into address order.  */
    827  1.1.1.1.2.2  pgoyette 
    828  1.1.1.1.2.2  pgoyette int
    829  1.1.1.1.2.2  pgoyette _bfd_x86_elf_compare_relocs (const void *ap, const void *bp)
    830  1.1.1.1.2.2  pgoyette {
    831  1.1.1.1.2.2  pgoyette   const arelent *a = * (const arelent **) ap;
    832  1.1.1.1.2.2  pgoyette   const arelent *b = * (const arelent **) bp;
    833  1.1.1.1.2.2  pgoyette 
    834  1.1.1.1.2.2  pgoyette   if (a->address > b->address)
    835  1.1.1.1.2.2  pgoyette     return 1;
    836  1.1.1.1.2.2  pgoyette   else if (a->address < b->address)
    837  1.1.1.1.2.2  pgoyette     return -1;
    838  1.1.1.1.2.2  pgoyette   else
    839  1.1.1.1.2.2  pgoyette     return 0;
    840  1.1.1.1.2.2  pgoyette }
    841  1.1.1.1.2.2  pgoyette 
    842  1.1.1.1.2.2  pgoyette bfd_boolean
    843  1.1.1.1.2.2  pgoyette _bfd_x86_elf_link_check_relocs (bfd *abfd, struct bfd_link_info *info)
    844  1.1.1.1.2.2  pgoyette {
    845  1.1.1.1.2.2  pgoyette   if (!bfd_link_relocatable (info))
    846  1.1.1.1.2.2  pgoyette     {
    847  1.1.1.1.2.2  pgoyette       /* Check for __tls_get_addr reference.  */
    848  1.1.1.1.2.2  pgoyette       struct elf_x86_link_hash_table *htab;
    849  1.1.1.1.2.2  pgoyette       const struct elf_backend_data *bed = get_elf_backend_data (abfd);
    850  1.1.1.1.2.2  pgoyette       htab = elf_x86_hash_table (info, bed->target_id);
    851  1.1.1.1.2.2  pgoyette       if (htab)
    852  1.1.1.1.2.2  pgoyette 	{
    853  1.1.1.1.2.2  pgoyette 	  struct elf_link_hash_entry *h;
    854  1.1.1.1.2.2  pgoyette 
    855  1.1.1.1.2.2  pgoyette 	  h = elf_link_hash_lookup (elf_hash_table (info),
    856  1.1.1.1.2.2  pgoyette 				    htab->tls_get_addr,
    857  1.1.1.1.2.2  pgoyette 				    FALSE, FALSE, FALSE);
    858  1.1.1.1.2.2  pgoyette 	  if (h != NULL)
    859  1.1.1.1.2.2  pgoyette 	    {
    860  1.1.1.1.2.2  pgoyette 	      elf_x86_hash_entry (h)->tls_get_addr = 1;
    861  1.1.1.1.2.2  pgoyette 
    862  1.1.1.1.2.2  pgoyette 	      /* Check the versioned __tls_get_addr symbol.  */
    863  1.1.1.1.2.2  pgoyette 	      while (h->root.type == bfd_link_hash_indirect)
    864  1.1.1.1.2.2  pgoyette 		{
    865  1.1.1.1.2.2  pgoyette 		  h = (struct elf_link_hash_entry *) h->root.u.i.link;
    866  1.1.1.1.2.2  pgoyette 		  elf_x86_hash_entry (h)->tls_get_addr = 1;
    867  1.1.1.1.2.2  pgoyette 		}
    868  1.1.1.1.2.2  pgoyette 	    }
    869  1.1.1.1.2.2  pgoyette 
    870  1.1.1.1.2.2  pgoyette 	  /* "__ehdr_start" will be defined by linker as a hidden symbol
    871  1.1.1.1.2.2  pgoyette 	     later if it is referenced and not defined.  */
    872  1.1.1.1.2.2  pgoyette 	  h = elf_link_hash_lookup (elf_hash_table (info),
    873  1.1.1.1.2.2  pgoyette 				    "__ehdr_start",
    874  1.1.1.1.2.2  pgoyette 				    FALSE, FALSE, FALSE);
    875  1.1.1.1.2.2  pgoyette 	  if (h != NULL
    876  1.1.1.1.2.2  pgoyette 	      && (h->root.type == bfd_link_hash_new
    877  1.1.1.1.2.2  pgoyette 		  || h->root.type == bfd_link_hash_undefined
    878  1.1.1.1.2.2  pgoyette 		  || h->root.type == bfd_link_hash_undefweak
    879  1.1.1.1.2.2  pgoyette 		  || h->root.type == bfd_link_hash_common))
    880  1.1.1.1.2.2  pgoyette 	    {
    881  1.1.1.1.2.2  pgoyette 	      elf_x86_hash_entry (h)->local_ref = 2;
    882  1.1.1.1.2.2  pgoyette 	      elf_x86_hash_entry (h)->linker_def = 1;
    883  1.1.1.1.2.2  pgoyette 	    }
    884  1.1.1.1.2.2  pgoyette 	}
    885  1.1.1.1.2.2  pgoyette     }
    886  1.1.1.1.2.2  pgoyette 
    887  1.1.1.1.2.2  pgoyette   /* Invoke the regular ELF backend linker to do all the work.  */
    888  1.1.1.1.2.2  pgoyette   return _bfd_elf_link_check_relocs (abfd, info);
    889  1.1.1.1.2.2  pgoyette }
    890  1.1.1.1.2.2  pgoyette 
    891  1.1.1.1.2.2  pgoyette /* Set the sizes of the dynamic sections.  */
    892  1.1.1.1.2.2  pgoyette 
    893  1.1.1.1.2.2  pgoyette bfd_boolean
    894  1.1.1.1.2.2  pgoyette _bfd_x86_elf_size_dynamic_sections (bfd *output_bfd,
    895  1.1.1.1.2.2  pgoyette 				    struct bfd_link_info *info)
    896  1.1.1.1.2.2  pgoyette {
    897  1.1.1.1.2.2  pgoyette   struct elf_x86_link_hash_table *htab;
    898  1.1.1.1.2.2  pgoyette   bfd *dynobj;
    899  1.1.1.1.2.2  pgoyette   asection *s;
    900  1.1.1.1.2.2  pgoyette   bfd_boolean relocs;
    901  1.1.1.1.2.2  pgoyette   bfd *ibfd;
    902  1.1.1.1.2.2  pgoyette   const struct elf_backend_data *bed
    903  1.1.1.1.2.2  pgoyette     = get_elf_backend_data (output_bfd);
    904  1.1.1.1.2.2  pgoyette 
    905  1.1.1.1.2.2  pgoyette   htab = elf_x86_hash_table (info, bed->target_id);
    906  1.1.1.1.2.2  pgoyette   if (htab == NULL)
    907  1.1.1.1.2.2  pgoyette     return FALSE;
    908  1.1.1.1.2.2  pgoyette   dynobj = htab->elf.dynobj;
    909  1.1.1.1.2.2  pgoyette   if (dynobj == NULL)
    910  1.1.1.1.2.2  pgoyette     abort ();
    911  1.1.1.1.2.2  pgoyette 
    912  1.1.1.1.2.2  pgoyette   /* Set up .got offsets for local syms, and space for local dynamic
    913  1.1.1.1.2.2  pgoyette      relocs.  */
    914  1.1.1.1.2.2  pgoyette   for (ibfd = info->input_bfds; ibfd != NULL; ibfd = ibfd->link.next)
    915  1.1.1.1.2.2  pgoyette     {
    916  1.1.1.1.2.2  pgoyette       bfd_signed_vma *local_got;
    917  1.1.1.1.2.2  pgoyette       bfd_signed_vma *end_local_got;
    918  1.1.1.1.2.2  pgoyette       char *local_tls_type;
    919  1.1.1.1.2.2  pgoyette       bfd_vma *local_tlsdesc_gotent;
    920  1.1.1.1.2.2  pgoyette       bfd_size_type locsymcount;
    921  1.1.1.1.2.2  pgoyette       Elf_Internal_Shdr *symtab_hdr;
    922  1.1.1.1.2.2  pgoyette       asection *srel;
    923  1.1.1.1.2.2  pgoyette 
    924  1.1.1.1.2.2  pgoyette       if (! is_x86_elf (ibfd, htab))
    925  1.1.1.1.2.2  pgoyette 	continue;
    926  1.1.1.1.2.2  pgoyette 
    927  1.1.1.1.2.2  pgoyette       for (s = ibfd->sections; s != NULL; s = s->next)
    928  1.1.1.1.2.2  pgoyette 	{
    929  1.1.1.1.2.2  pgoyette 	  struct elf_dyn_relocs *p;
    930  1.1.1.1.2.2  pgoyette 
    931  1.1.1.1.2.2  pgoyette 	  for (p = ((struct elf_dyn_relocs *)
    932  1.1.1.1.2.2  pgoyette 		     elf_section_data (s)->local_dynrel);
    933  1.1.1.1.2.2  pgoyette 	       p != NULL;
    934  1.1.1.1.2.2  pgoyette 	       p = p->next)
    935  1.1.1.1.2.2  pgoyette 	    {
    936  1.1.1.1.2.2  pgoyette 	      if (!bfd_is_abs_section (p->sec)
    937  1.1.1.1.2.2  pgoyette 		  && bfd_is_abs_section (p->sec->output_section))
    938  1.1.1.1.2.2  pgoyette 		{
    939  1.1.1.1.2.2  pgoyette 		  /* Input section has been discarded, either because
    940  1.1.1.1.2.2  pgoyette 		     it is a copy of a linkonce section or due to
    941  1.1.1.1.2.2  pgoyette 		     linker script /DISCARD/, so we'll be discarding
    942  1.1.1.1.2.2  pgoyette 		     the relocs too.  */
    943  1.1.1.1.2.2  pgoyette 		}
    944  1.1.1.1.2.2  pgoyette 	      else if (htab->target_os == is_vxworks
    945  1.1.1.1.2.2  pgoyette 		       && strcmp (p->sec->output_section->name,
    946  1.1.1.1.2.2  pgoyette 				  ".tls_vars") == 0)
    947  1.1.1.1.2.2  pgoyette 		{
    948  1.1.1.1.2.2  pgoyette 		  /* Relocations in vxworks .tls_vars sections are
    949  1.1.1.1.2.2  pgoyette 		     handled specially by the loader.  */
    950  1.1.1.1.2.2  pgoyette 		}
    951  1.1.1.1.2.2  pgoyette 	      else if (p->count != 0)
    952  1.1.1.1.2.2  pgoyette 		{
    953  1.1.1.1.2.2  pgoyette 		  srel = elf_section_data (p->sec)->sreloc;
    954  1.1.1.1.2.2  pgoyette 		  srel->size += p->count * htab->sizeof_reloc;
    955  1.1.1.1.2.2  pgoyette 		  if ((p->sec->output_section->flags & SEC_READONLY) != 0
    956  1.1.1.1.2.2  pgoyette 		      && (info->flags & DF_TEXTREL) == 0)
    957  1.1.1.1.2.2  pgoyette 		    {
    958  1.1.1.1.2.2  pgoyette 		      info->flags |= DF_TEXTREL;
    959  1.1.1.1.2.2  pgoyette 		      if ((info->warn_shared_textrel && bfd_link_pic (info))
    960  1.1.1.1.2.2  pgoyette 			  || info->error_textrel)
    961  1.1.1.1.2.2  pgoyette 			/* xgettext:c-format */
    962  1.1.1.1.2.2  pgoyette 			info->callbacks->einfo
    963  1.1.1.1.2.2  pgoyette 			  (_("%P: %B: warning: relocation "
    964  1.1.1.1.2.2  pgoyette 			     "in read-only section `%A'\n"),
    965  1.1.1.1.2.2  pgoyette 			   p->sec->owner, p->sec);
    966  1.1.1.1.2.2  pgoyette 		    }
    967  1.1.1.1.2.2  pgoyette 		}
    968  1.1.1.1.2.2  pgoyette 	    }
    969  1.1.1.1.2.2  pgoyette 	}
    970  1.1.1.1.2.2  pgoyette 
    971  1.1.1.1.2.2  pgoyette       local_got = elf_local_got_refcounts (ibfd);
    972  1.1.1.1.2.2  pgoyette       if (!local_got)
    973  1.1.1.1.2.2  pgoyette 	continue;
    974  1.1.1.1.2.2  pgoyette 
    975  1.1.1.1.2.2  pgoyette       symtab_hdr = &elf_symtab_hdr (ibfd);
    976  1.1.1.1.2.2  pgoyette       locsymcount = symtab_hdr->sh_info;
    977  1.1.1.1.2.2  pgoyette       end_local_got = local_got + locsymcount;
    978  1.1.1.1.2.2  pgoyette       local_tls_type = elf_x86_local_got_tls_type (ibfd);
    979  1.1.1.1.2.2  pgoyette       local_tlsdesc_gotent = elf_x86_local_tlsdesc_gotent (ibfd);
    980  1.1.1.1.2.2  pgoyette       s = htab->elf.sgot;
    981  1.1.1.1.2.2  pgoyette       srel = htab->elf.srelgot;
    982  1.1.1.1.2.2  pgoyette       for (; local_got < end_local_got;
    983  1.1.1.1.2.2  pgoyette 	   ++local_got, ++local_tls_type, ++local_tlsdesc_gotent)
    984  1.1.1.1.2.2  pgoyette 	{
    985  1.1.1.1.2.2  pgoyette 	  *local_tlsdesc_gotent = (bfd_vma) -1;
    986  1.1.1.1.2.2  pgoyette 	  if (*local_got > 0)
    987  1.1.1.1.2.2  pgoyette 	    {
    988  1.1.1.1.2.2  pgoyette 	      if (GOT_TLS_GDESC_P (*local_tls_type))
    989  1.1.1.1.2.2  pgoyette 		{
    990  1.1.1.1.2.2  pgoyette 		  *local_tlsdesc_gotent = htab->elf.sgotplt->size
    991  1.1.1.1.2.2  pgoyette 		    - elf_x86_compute_jump_table_size (htab);
    992  1.1.1.1.2.2  pgoyette 		  htab->elf.sgotplt->size += 2 * htab->got_entry_size;
    993  1.1.1.1.2.2  pgoyette 		  *local_got = (bfd_vma) -2;
    994  1.1.1.1.2.2  pgoyette 		}
    995  1.1.1.1.2.2  pgoyette 	      if (! GOT_TLS_GDESC_P (*local_tls_type)
    996  1.1.1.1.2.2  pgoyette 		  || GOT_TLS_GD_P (*local_tls_type))
    997  1.1.1.1.2.2  pgoyette 		{
    998  1.1.1.1.2.2  pgoyette 		  *local_got = s->size;
    999  1.1.1.1.2.2  pgoyette 		  s->size += htab->got_entry_size;
   1000  1.1.1.1.2.2  pgoyette 		  if (GOT_TLS_GD_P (*local_tls_type)
   1001  1.1.1.1.2.2  pgoyette 		      || *local_tls_type == GOT_TLS_IE_BOTH)
   1002  1.1.1.1.2.2  pgoyette 		    s->size += htab->got_entry_size;
   1003  1.1.1.1.2.2  pgoyette 		}
   1004  1.1.1.1.2.2  pgoyette 	      if (bfd_link_pic (info)
   1005  1.1.1.1.2.2  pgoyette 		  || GOT_TLS_GD_ANY_P (*local_tls_type)
   1006  1.1.1.1.2.2  pgoyette 		  || (*local_tls_type & GOT_TLS_IE))
   1007  1.1.1.1.2.2  pgoyette 		{
   1008  1.1.1.1.2.2  pgoyette 		  if (*local_tls_type == GOT_TLS_IE_BOTH)
   1009  1.1.1.1.2.2  pgoyette 		    srel->size += 2 * htab->sizeof_reloc;
   1010  1.1.1.1.2.2  pgoyette 		  else if (GOT_TLS_GD_P (*local_tls_type)
   1011  1.1.1.1.2.2  pgoyette 			   || ! GOT_TLS_GDESC_P (*local_tls_type))
   1012  1.1.1.1.2.2  pgoyette 		    srel->size += htab->sizeof_reloc;
   1013  1.1.1.1.2.2  pgoyette 		  if (GOT_TLS_GDESC_P (*local_tls_type))
   1014  1.1.1.1.2.2  pgoyette 		    {
   1015  1.1.1.1.2.2  pgoyette 		      htab->elf.srelplt->size += htab->sizeof_reloc;
   1016  1.1.1.1.2.2  pgoyette 		      if (bed->target_id == X86_64_ELF_DATA)
   1017  1.1.1.1.2.2  pgoyette 			htab->tlsdesc_plt = (bfd_vma) -1;
   1018  1.1.1.1.2.2  pgoyette 		    }
   1019  1.1.1.1.2.2  pgoyette 		}
   1020  1.1.1.1.2.2  pgoyette 	    }
   1021  1.1.1.1.2.2  pgoyette 	  else
   1022  1.1.1.1.2.2  pgoyette 	    *local_got = (bfd_vma) -1;
   1023  1.1.1.1.2.2  pgoyette 	}
   1024  1.1.1.1.2.2  pgoyette     }
   1025  1.1.1.1.2.2  pgoyette 
   1026  1.1.1.1.2.2  pgoyette   if (htab->tls_ld_or_ldm_got.refcount > 0)
   1027  1.1.1.1.2.2  pgoyette     {
   1028  1.1.1.1.2.2  pgoyette       /* Allocate 2 got entries and 1 dynamic reloc for R_386_TLS_LDM
   1029  1.1.1.1.2.2  pgoyette 	 or R_X86_64_TLSLD relocs.  */
   1030  1.1.1.1.2.2  pgoyette       htab->tls_ld_or_ldm_got.offset = htab->elf.sgot->size;
   1031  1.1.1.1.2.2  pgoyette       htab->elf.sgot->size += 2 * htab->got_entry_size;
   1032  1.1.1.1.2.2  pgoyette       htab->elf.srelgot->size += htab->sizeof_reloc;
   1033  1.1.1.1.2.2  pgoyette     }
   1034  1.1.1.1.2.2  pgoyette   else
   1035  1.1.1.1.2.2  pgoyette     htab->tls_ld_or_ldm_got.offset = -1;
   1036  1.1.1.1.2.2  pgoyette 
   1037  1.1.1.1.2.2  pgoyette   /* Allocate global sym .plt and .got entries, and space for global
   1038  1.1.1.1.2.2  pgoyette      sym dynamic relocs.  */
   1039  1.1.1.1.2.2  pgoyette   elf_link_hash_traverse (&htab->elf, elf_x86_allocate_dynrelocs,
   1040  1.1.1.1.2.2  pgoyette 			  info);
   1041  1.1.1.1.2.2  pgoyette 
   1042  1.1.1.1.2.2  pgoyette   /* Allocate .plt and .got entries, and space for local symbols.  */
   1043  1.1.1.1.2.2  pgoyette   htab_traverse (htab->loc_hash_table, elf_x86_allocate_local_dynreloc,
   1044  1.1.1.1.2.2  pgoyette 		 info);
   1045  1.1.1.1.2.2  pgoyette 
   1046  1.1.1.1.2.2  pgoyette   /* For every jump slot reserved in the sgotplt, reloc_count is
   1047  1.1.1.1.2.2  pgoyette      incremented.  However, when we reserve space for TLS descriptors,
   1048  1.1.1.1.2.2  pgoyette      it's not incremented, so in order to compute the space reserved
   1049  1.1.1.1.2.2  pgoyette      for them, it suffices to multiply the reloc count by the jump
   1050  1.1.1.1.2.2  pgoyette      slot size.
   1051  1.1.1.1.2.2  pgoyette 
   1052  1.1.1.1.2.2  pgoyette      PR ld/13302: We start next_irelative_index at the end of .rela.plt
   1053  1.1.1.1.2.2  pgoyette      so that R_{386,X86_64}_IRELATIVE entries come last.  */
   1054  1.1.1.1.2.2  pgoyette   if (htab->elf.srelplt)
   1055  1.1.1.1.2.2  pgoyette     {
   1056  1.1.1.1.2.2  pgoyette       htab->next_tls_desc_index = htab->elf.srelplt->reloc_count;
   1057  1.1.1.1.2.2  pgoyette       htab->sgotplt_jump_table_size
   1058  1.1.1.1.2.2  pgoyette 	= elf_x86_compute_jump_table_size (htab);
   1059  1.1.1.1.2.2  pgoyette       htab->next_irelative_index = htab->elf.srelplt->reloc_count - 1;
   1060  1.1.1.1.2.2  pgoyette     }
   1061  1.1.1.1.2.2  pgoyette   else if (htab->elf.irelplt)
   1062  1.1.1.1.2.2  pgoyette     htab->next_irelative_index = htab->elf.irelplt->reloc_count - 1;
   1063  1.1.1.1.2.2  pgoyette 
   1064  1.1.1.1.2.2  pgoyette   if (htab->tlsdesc_plt)
   1065  1.1.1.1.2.2  pgoyette     {
   1066  1.1.1.1.2.2  pgoyette       /* NB: tlsdesc_plt is set only for x86-64.  If we're not using
   1067  1.1.1.1.2.2  pgoyette 	 lazy TLS relocations, don't generate the PLT and GOT entries
   1068  1.1.1.1.2.2  pgoyette 	 they require.  */
   1069  1.1.1.1.2.2  pgoyette       if ((info->flags & DF_BIND_NOW))
   1070  1.1.1.1.2.2  pgoyette 	htab->tlsdesc_plt = 0;
   1071  1.1.1.1.2.2  pgoyette       else
   1072  1.1.1.1.2.2  pgoyette 	{
   1073  1.1.1.1.2.2  pgoyette 	  htab->tlsdesc_got = htab->elf.sgot->size;
   1074  1.1.1.1.2.2  pgoyette 	  htab->elf.sgot->size += htab->got_entry_size;
   1075  1.1.1.1.2.2  pgoyette 	  /* Reserve room for the initial entry.
   1076  1.1.1.1.2.2  pgoyette 	     FIXME: we could probably do away with it in this case.  */
   1077  1.1.1.1.2.2  pgoyette 	  if (htab->elf.splt->size == 0)
   1078  1.1.1.1.2.2  pgoyette 	    htab->elf.splt->size = htab->plt.plt_entry_size;
   1079  1.1.1.1.2.2  pgoyette 	  htab->tlsdesc_plt = htab->elf.splt->size;
   1080  1.1.1.1.2.2  pgoyette 	  htab->elf.splt->size += htab->plt.plt_entry_size;
   1081  1.1.1.1.2.2  pgoyette 	}
   1082  1.1.1.1.2.2  pgoyette     }
   1083  1.1.1.1.2.2  pgoyette 
   1084  1.1.1.1.2.2  pgoyette   if (htab->elf.sgotplt)
   1085  1.1.1.1.2.2  pgoyette     {
   1086  1.1.1.1.2.2  pgoyette       /* Don't allocate .got.plt section if there are no GOT nor PLT
   1087  1.1.1.1.2.2  pgoyette 	 entries and there is no reference to _GLOBAL_OFFSET_TABLE_.  */
   1088  1.1.1.1.2.2  pgoyette       if ((htab->elf.hgot == NULL
   1089  1.1.1.1.2.2  pgoyette 	   || !htab->elf.hgot->ref_regular_nonweak)
   1090  1.1.1.1.2.2  pgoyette 	  && (htab->elf.sgotplt->size == bed->got_header_size)
   1091  1.1.1.1.2.2  pgoyette 	  && (htab->elf.splt == NULL
   1092  1.1.1.1.2.2  pgoyette 	      || htab->elf.splt->size == 0)
   1093  1.1.1.1.2.2  pgoyette 	  && (htab->elf.sgot == NULL
   1094  1.1.1.1.2.2  pgoyette 	      || htab->elf.sgot->size == 0)
   1095  1.1.1.1.2.2  pgoyette 	  && (htab->elf.iplt == NULL
   1096  1.1.1.1.2.2  pgoyette 	      || htab->elf.iplt->size == 0)
   1097  1.1.1.1.2.2  pgoyette 	  && (htab->elf.igotplt == NULL
   1098  1.1.1.1.2.2  pgoyette 	      || htab->elf.igotplt->size == 0))
   1099  1.1.1.1.2.2  pgoyette 	htab->elf.sgotplt->size = 0;
   1100  1.1.1.1.2.2  pgoyette     }
   1101  1.1.1.1.2.2  pgoyette 
   1102  1.1.1.1.2.2  pgoyette   if (_bfd_elf_eh_frame_present (info))
   1103  1.1.1.1.2.2  pgoyette     {
   1104  1.1.1.1.2.2  pgoyette       if (htab->plt_eh_frame != NULL
   1105  1.1.1.1.2.2  pgoyette 	  && htab->elf.splt != NULL
   1106  1.1.1.1.2.2  pgoyette 	  && htab->elf.splt->size != 0
   1107  1.1.1.1.2.2  pgoyette 	  && !bfd_is_abs_section (htab->elf.splt->output_section))
   1108  1.1.1.1.2.2  pgoyette 	htab->plt_eh_frame->size = htab->plt.eh_frame_plt_size;
   1109  1.1.1.1.2.2  pgoyette 
   1110  1.1.1.1.2.2  pgoyette       if (htab->plt_got_eh_frame != NULL
   1111  1.1.1.1.2.2  pgoyette 	  && htab->plt_got != NULL
   1112  1.1.1.1.2.2  pgoyette 	  && htab->plt_got->size != 0
   1113  1.1.1.1.2.2  pgoyette 	  && !bfd_is_abs_section (htab->plt_got->output_section))
   1114  1.1.1.1.2.2  pgoyette 	htab->plt_got_eh_frame->size
   1115  1.1.1.1.2.2  pgoyette 	  = htab->non_lazy_plt->eh_frame_plt_size;
   1116  1.1.1.1.2.2  pgoyette 
   1117  1.1.1.1.2.2  pgoyette       /* Unwind info for the second PLT and .plt.got sections are
   1118  1.1.1.1.2.2  pgoyette 	 identical.  */
   1119  1.1.1.1.2.2  pgoyette       if (htab->plt_second_eh_frame != NULL
   1120  1.1.1.1.2.2  pgoyette 	  && htab->plt_second != NULL
   1121  1.1.1.1.2.2  pgoyette 	  && htab->plt_second->size != 0
   1122  1.1.1.1.2.2  pgoyette 	  && !bfd_is_abs_section (htab->plt_second->output_section))
   1123  1.1.1.1.2.2  pgoyette 	htab->plt_second_eh_frame->size
   1124  1.1.1.1.2.2  pgoyette 	  = htab->non_lazy_plt->eh_frame_plt_size;
   1125  1.1.1.1.2.2  pgoyette     }
   1126  1.1.1.1.2.2  pgoyette 
   1127  1.1.1.1.2.2  pgoyette   /* We now have determined the sizes of the various dynamic sections.
   1128  1.1.1.1.2.2  pgoyette      Allocate memory for them.  */
   1129  1.1.1.1.2.2  pgoyette   relocs = FALSE;
   1130  1.1.1.1.2.2  pgoyette   for (s = dynobj->sections; s != NULL; s = s->next)
   1131  1.1.1.1.2.2  pgoyette     {
   1132  1.1.1.1.2.2  pgoyette       bfd_boolean strip_section = TRUE;
   1133  1.1.1.1.2.2  pgoyette 
   1134  1.1.1.1.2.2  pgoyette       if ((s->flags & SEC_LINKER_CREATED) == 0)
   1135  1.1.1.1.2.2  pgoyette 	continue;
   1136  1.1.1.1.2.2  pgoyette 
   1137  1.1.1.1.2.2  pgoyette       if (s == htab->elf.splt
   1138  1.1.1.1.2.2  pgoyette 	  || s == htab->elf.sgot)
   1139  1.1.1.1.2.2  pgoyette 	{
   1140  1.1.1.1.2.2  pgoyette 	  /* Strip this section if we don't need it; see the
   1141  1.1.1.1.2.2  pgoyette 	     comment below.  */
   1142  1.1.1.1.2.2  pgoyette 	  /* We'd like to strip these sections if they aren't needed, but if
   1143  1.1.1.1.2.2  pgoyette 	     we've exported dynamic symbols from them we must leave them.
   1144  1.1.1.1.2.2  pgoyette 	     It's too late to tell BFD to get rid of the symbols.  */
   1145  1.1.1.1.2.2  pgoyette 
   1146  1.1.1.1.2.2  pgoyette 	  if (htab->elf.hplt != NULL)
   1147  1.1.1.1.2.2  pgoyette 	    strip_section = FALSE;
   1148  1.1.1.1.2.2  pgoyette 	}
   1149  1.1.1.1.2.2  pgoyette       else if (s == htab->elf.sgotplt
   1150  1.1.1.1.2.2  pgoyette 	       || s == htab->elf.iplt
   1151  1.1.1.1.2.2  pgoyette 	       || s == htab->elf.igotplt
   1152  1.1.1.1.2.2  pgoyette 	       || s == htab->plt_second
   1153  1.1.1.1.2.2  pgoyette 	       || s == htab->plt_got
   1154  1.1.1.1.2.2  pgoyette 	       || s == htab->plt_eh_frame
   1155  1.1.1.1.2.2  pgoyette 	       || s == htab->plt_got_eh_frame
   1156  1.1.1.1.2.2  pgoyette 	       || s == htab->plt_second_eh_frame
   1157  1.1.1.1.2.2  pgoyette 	       || s == htab->elf.sdynbss
   1158  1.1.1.1.2.2  pgoyette 	       || s == htab->elf.sdynrelro)
   1159  1.1.1.1.2.2  pgoyette 	{
   1160  1.1.1.1.2.2  pgoyette 	  /* Strip these too.  */
   1161  1.1.1.1.2.2  pgoyette 	}
   1162  1.1.1.1.2.2  pgoyette       else if (htab->is_reloc_section (bfd_get_section_name (dynobj, s)))
   1163  1.1.1.1.2.2  pgoyette 	{
   1164  1.1.1.1.2.2  pgoyette 	  if (s->size != 0
   1165  1.1.1.1.2.2  pgoyette 	      && s != htab->elf.srelplt
   1166  1.1.1.1.2.2  pgoyette 	      && s != htab->srelplt2)
   1167  1.1.1.1.2.2  pgoyette 	    relocs = TRUE;
   1168  1.1.1.1.2.2  pgoyette 
   1169  1.1.1.1.2.2  pgoyette 	  /* We use the reloc_count field as a counter if we need
   1170  1.1.1.1.2.2  pgoyette 	     to copy relocs into the output file.  */
   1171  1.1.1.1.2.2  pgoyette 	  if (s != htab->elf.srelplt)
   1172  1.1.1.1.2.2  pgoyette 	    s->reloc_count = 0;
   1173  1.1.1.1.2.2  pgoyette 	}
   1174  1.1.1.1.2.2  pgoyette       else
   1175  1.1.1.1.2.2  pgoyette 	{
   1176  1.1.1.1.2.2  pgoyette 	  /* It's not one of our sections, so don't allocate space.  */
   1177  1.1.1.1.2.2  pgoyette 	  continue;
   1178  1.1.1.1.2.2  pgoyette 	}
   1179  1.1.1.1.2.2  pgoyette 
   1180  1.1.1.1.2.2  pgoyette       if (s->size == 0)
   1181  1.1.1.1.2.2  pgoyette 	{
   1182  1.1.1.1.2.2  pgoyette 	  /* If we don't need this section, strip it from the
   1183  1.1.1.1.2.2  pgoyette 	     output file.  This is mostly to handle .rel.bss and
   1184  1.1.1.1.2.2  pgoyette 	     .rel.plt.  We must create both sections in
   1185  1.1.1.1.2.2  pgoyette 	     create_dynamic_sections, because they must be created
   1186  1.1.1.1.2.2  pgoyette 	     before the linker maps input sections to output
   1187  1.1.1.1.2.2  pgoyette 	     sections.  The linker does that before
   1188  1.1.1.1.2.2  pgoyette 	     adjust_dynamic_symbol is called, and it is that
   1189  1.1.1.1.2.2  pgoyette 	     function which decides whether anything needs to go
   1190  1.1.1.1.2.2  pgoyette 	     into these sections.  */
   1191  1.1.1.1.2.2  pgoyette 	  if (strip_section)
   1192  1.1.1.1.2.2  pgoyette 	    s->flags |= SEC_EXCLUDE;
   1193  1.1.1.1.2.2  pgoyette 	  continue;
   1194  1.1.1.1.2.2  pgoyette 	}
   1195  1.1.1.1.2.2  pgoyette 
   1196  1.1.1.1.2.2  pgoyette       if ((s->flags & SEC_HAS_CONTENTS) == 0)
   1197  1.1.1.1.2.2  pgoyette 	continue;
   1198  1.1.1.1.2.2  pgoyette 
   1199  1.1.1.1.2.2  pgoyette       /* Allocate memory for the section contents.  We use bfd_zalloc
   1200  1.1.1.1.2.2  pgoyette 	 here in case unused entries are not reclaimed before the
   1201  1.1.1.1.2.2  pgoyette 	 section's contents are written out.  This should not happen,
   1202  1.1.1.1.2.2  pgoyette 	 but this way if it does, we get a R_386_NONE or R_X86_64_NONE
   1203  1.1.1.1.2.2  pgoyette 	 reloc instead of garbage.  */
   1204  1.1.1.1.2.2  pgoyette       s->contents = (unsigned char *) bfd_zalloc (dynobj, s->size);
   1205  1.1.1.1.2.2  pgoyette       if (s->contents == NULL)
   1206  1.1.1.1.2.2  pgoyette 	return FALSE;
   1207  1.1.1.1.2.2  pgoyette     }
   1208  1.1.1.1.2.2  pgoyette 
   1209  1.1.1.1.2.2  pgoyette   if (htab->plt_eh_frame != NULL
   1210  1.1.1.1.2.2  pgoyette       && htab->plt_eh_frame->contents != NULL)
   1211  1.1.1.1.2.2  pgoyette     {
   1212  1.1.1.1.2.2  pgoyette       memcpy (htab->plt_eh_frame->contents,
   1213  1.1.1.1.2.2  pgoyette 	      htab->plt.eh_frame_plt,
   1214  1.1.1.1.2.2  pgoyette 	      htab->plt_eh_frame->size);
   1215  1.1.1.1.2.2  pgoyette       bfd_put_32 (dynobj, htab->elf.splt->size,
   1216  1.1.1.1.2.2  pgoyette 		  htab->plt_eh_frame->contents + PLT_FDE_LEN_OFFSET);
   1217  1.1.1.1.2.2  pgoyette     }
   1218  1.1.1.1.2.2  pgoyette 
   1219  1.1.1.1.2.2  pgoyette   if (htab->plt_got_eh_frame != NULL
   1220  1.1.1.1.2.2  pgoyette       && htab->plt_got_eh_frame->contents != NULL)
   1221  1.1.1.1.2.2  pgoyette     {
   1222  1.1.1.1.2.2  pgoyette       memcpy (htab->plt_got_eh_frame->contents,
   1223  1.1.1.1.2.2  pgoyette 	      htab->non_lazy_plt->eh_frame_plt,
   1224  1.1.1.1.2.2  pgoyette 	      htab->plt_got_eh_frame->size);
   1225  1.1.1.1.2.2  pgoyette       bfd_put_32 (dynobj, htab->plt_got->size,
   1226  1.1.1.1.2.2  pgoyette 		  (htab->plt_got_eh_frame->contents
   1227  1.1.1.1.2.2  pgoyette 		   + PLT_FDE_LEN_OFFSET));
   1228  1.1.1.1.2.2  pgoyette     }
   1229  1.1.1.1.2.2  pgoyette 
   1230  1.1.1.1.2.2  pgoyette   if (htab->plt_second_eh_frame != NULL
   1231  1.1.1.1.2.2  pgoyette       && htab->plt_second_eh_frame->contents != NULL)
   1232  1.1.1.1.2.2  pgoyette     {
   1233  1.1.1.1.2.2  pgoyette       memcpy (htab->plt_second_eh_frame->contents,
   1234  1.1.1.1.2.2  pgoyette 	      htab->non_lazy_plt->eh_frame_plt,
   1235  1.1.1.1.2.2  pgoyette 	      htab->plt_second_eh_frame->size);
   1236  1.1.1.1.2.2  pgoyette       bfd_put_32 (dynobj, htab->plt_second->size,
   1237  1.1.1.1.2.2  pgoyette 		  (htab->plt_second_eh_frame->contents
   1238  1.1.1.1.2.2  pgoyette 		   + PLT_FDE_LEN_OFFSET));
   1239  1.1.1.1.2.2  pgoyette     }
   1240  1.1.1.1.2.2  pgoyette 
   1241  1.1.1.1.2.2  pgoyette   if (htab->elf.dynamic_sections_created)
   1242  1.1.1.1.2.2  pgoyette     {
   1243  1.1.1.1.2.2  pgoyette       /* Add some entries to the .dynamic section.  We fill in the
   1244  1.1.1.1.2.2  pgoyette 	 values later, in elf_{i386,x86_64}_finish_dynamic_sections,
   1245  1.1.1.1.2.2  pgoyette 	 but we must add the entries now so that we get the correct
   1246  1.1.1.1.2.2  pgoyette 	 size for the .dynamic section.  The DT_DEBUG entry is filled
   1247  1.1.1.1.2.2  pgoyette 	 in by the dynamic linker and used by the debugger.  */
   1248  1.1.1.1.2.2  pgoyette #define add_dynamic_entry(TAG, VAL) \
   1249  1.1.1.1.2.2  pgoyette   _bfd_elf_add_dynamic_entry (info, TAG, VAL)
   1250  1.1.1.1.2.2  pgoyette 
   1251  1.1.1.1.2.2  pgoyette       if (bfd_link_executable (info))
   1252  1.1.1.1.2.2  pgoyette 	{
   1253  1.1.1.1.2.2  pgoyette 	  if (!add_dynamic_entry (DT_DEBUG, 0))
   1254  1.1.1.1.2.2  pgoyette 	    return FALSE;
   1255  1.1.1.1.2.2  pgoyette 	}
   1256  1.1.1.1.2.2  pgoyette 
   1257  1.1.1.1.2.2  pgoyette       if (htab->elf.splt->size != 0)
   1258  1.1.1.1.2.2  pgoyette 	{
   1259  1.1.1.1.2.2  pgoyette 	  /* DT_PLTGOT is used by prelink even if there is no PLT
   1260  1.1.1.1.2.2  pgoyette 	     relocation.  */
   1261  1.1.1.1.2.2  pgoyette 	  if (!add_dynamic_entry (DT_PLTGOT, 0))
   1262  1.1.1.1.2.2  pgoyette 	    return FALSE;
   1263  1.1.1.1.2.2  pgoyette 	}
   1264  1.1.1.1.2.2  pgoyette 
   1265  1.1.1.1.2.2  pgoyette       if (htab->elf.srelplt->size != 0)
   1266  1.1.1.1.2.2  pgoyette 	{
   1267  1.1.1.1.2.2  pgoyette 	  if (!add_dynamic_entry (DT_PLTRELSZ, 0)
   1268  1.1.1.1.2.2  pgoyette 	      || !add_dynamic_entry (DT_PLTREL, htab->dt_reloc)
   1269  1.1.1.1.2.2  pgoyette 	      || !add_dynamic_entry (DT_JMPREL, 0))
   1270  1.1.1.1.2.2  pgoyette 	    return FALSE;
   1271  1.1.1.1.2.2  pgoyette 	}
   1272  1.1.1.1.2.2  pgoyette 
   1273  1.1.1.1.2.2  pgoyette       if (htab->tlsdesc_plt
   1274  1.1.1.1.2.2  pgoyette 	  && (!add_dynamic_entry (DT_TLSDESC_PLT, 0)
   1275  1.1.1.1.2.2  pgoyette 	      || !add_dynamic_entry (DT_TLSDESC_GOT, 0)))
   1276  1.1.1.1.2.2  pgoyette 	return FALSE;
   1277  1.1.1.1.2.2  pgoyette 
   1278  1.1.1.1.2.2  pgoyette       if (relocs)
   1279  1.1.1.1.2.2  pgoyette 	{
   1280  1.1.1.1.2.2  pgoyette 	  if (!add_dynamic_entry (htab->dt_reloc, 0)
   1281  1.1.1.1.2.2  pgoyette 	      || !add_dynamic_entry (htab->dt_reloc_sz, 0)
   1282  1.1.1.1.2.2  pgoyette 	      || !add_dynamic_entry (htab->dt_reloc_ent,
   1283  1.1.1.1.2.2  pgoyette 				     htab->sizeof_reloc))
   1284  1.1.1.1.2.2  pgoyette 	    return FALSE;
   1285  1.1.1.1.2.2  pgoyette 
   1286  1.1.1.1.2.2  pgoyette 	  /* If any dynamic relocs apply to a read-only section,
   1287  1.1.1.1.2.2  pgoyette 	     then we need a DT_TEXTREL entry.  */
   1288  1.1.1.1.2.2  pgoyette 	  if ((info->flags & DF_TEXTREL) == 0)
   1289  1.1.1.1.2.2  pgoyette 	    elf_link_hash_traverse (&htab->elf, maybe_set_textrel, info);
   1290  1.1.1.1.2.2  pgoyette 
   1291  1.1.1.1.2.2  pgoyette 	  if ((info->flags & DF_TEXTREL) != 0)
   1292  1.1.1.1.2.2  pgoyette 	    {
   1293  1.1.1.1.2.2  pgoyette 	      if (htab->readonly_dynrelocs_against_ifunc)
   1294  1.1.1.1.2.2  pgoyette 		{
   1295  1.1.1.1.2.2  pgoyette 		  info->callbacks->einfo
   1296  1.1.1.1.2.2  pgoyette 		    (_("%P%X: read-only segment has dynamic IFUNC relocations;"
   1297  1.1.1.1.2.2  pgoyette 		       " recompile with -fPIC\n"));
   1298  1.1.1.1.2.2  pgoyette 		  bfd_set_error (bfd_error_bad_value);
   1299  1.1.1.1.2.2  pgoyette 		  return FALSE;
   1300  1.1.1.1.2.2  pgoyette 		}
   1301  1.1.1.1.2.2  pgoyette 
   1302  1.1.1.1.2.2  pgoyette 	      if (!add_dynamic_entry (DT_TEXTREL, 0))
   1303  1.1.1.1.2.2  pgoyette 		return FALSE;
   1304  1.1.1.1.2.2  pgoyette 	    }
   1305  1.1.1.1.2.2  pgoyette 	}
   1306  1.1.1.1.2.2  pgoyette       if (htab->target_os == is_vxworks
   1307  1.1.1.1.2.2  pgoyette 	  && !elf_vxworks_add_dynamic_entries (output_bfd, info))
   1308  1.1.1.1.2.2  pgoyette 	return FALSE;
   1309  1.1.1.1.2.2  pgoyette     }
   1310  1.1.1.1.2.2  pgoyette #undef add_dynamic_entry
   1311  1.1.1.1.2.2  pgoyette 
   1312  1.1.1.1.2.2  pgoyette   return TRUE;
   1313  1.1.1.1.2.2  pgoyette }
   1314  1.1.1.1.2.2  pgoyette 
   1315  1.1.1.1.2.2  pgoyette /* Finish up the x86 dynamic sections.  */
   1316  1.1.1.1.2.2  pgoyette 
   1317  1.1.1.1.2.2  pgoyette struct elf_x86_link_hash_table *
   1318  1.1.1.1.2.2  pgoyette _bfd_x86_elf_finish_dynamic_sections (bfd *output_bfd,
   1319  1.1.1.1.2.2  pgoyette 				      struct bfd_link_info *info)
   1320  1.1.1.1.2.2  pgoyette {
   1321  1.1.1.1.2.2  pgoyette   struct elf_x86_link_hash_table *htab;
   1322  1.1.1.1.2.2  pgoyette   const struct elf_backend_data *bed;
   1323  1.1.1.1.2.2  pgoyette   bfd *dynobj;
   1324  1.1.1.1.2.2  pgoyette   asection *sdyn;
   1325  1.1.1.1.2.2  pgoyette   bfd_byte *dyncon, *dynconend;
   1326  1.1.1.1.2.2  pgoyette   bfd_size_type sizeof_dyn;
   1327  1.1.1.1.2.2  pgoyette 
   1328  1.1.1.1.2.2  pgoyette   bed = get_elf_backend_data (output_bfd);
   1329  1.1.1.1.2.2  pgoyette   htab = elf_x86_hash_table (info, bed->target_id);
   1330  1.1.1.1.2.2  pgoyette   if (htab == NULL)
   1331  1.1.1.1.2.2  pgoyette     return htab;
   1332  1.1.1.1.2.2  pgoyette 
   1333  1.1.1.1.2.2  pgoyette   dynobj = htab->elf.dynobj;
   1334  1.1.1.1.2.2  pgoyette   sdyn = bfd_get_linker_section (dynobj, ".dynamic");
   1335  1.1.1.1.2.2  pgoyette 
   1336  1.1.1.1.2.2  pgoyette   /* GOT is always created in setup_gnu_properties.  But it may not be
   1337  1.1.1.1.2.2  pgoyette      needed.  .got.plt section may be needed for static IFUNC.  */
   1338  1.1.1.1.2.2  pgoyette   if (htab->elf.sgotplt && htab->elf.sgotplt->size > 0)
   1339  1.1.1.1.2.2  pgoyette     {
   1340  1.1.1.1.2.2  pgoyette       bfd_vma dynamic_addr;
   1341  1.1.1.1.2.2  pgoyette 
   1342  1.1.1.1.2.2  pgoyette       if (bfd_is_abs_section (htab->elf.sgotplt->output_section))
   1343  1.1.1.1.2.2  pgoyette 	{
   1344  1.1.1.1.2.2  pgoyette 	  _bfd_error_handler
   1345  1.1.1.1.2.2  pgoyette 	    (_("discarded output section: `%A'"), htab->elf.sgotplt);
   1346  1.1.1.1.2.2  pgoyette 	  return NULL;
   1347  1.1.1.1.2.2  pgoyette 	}
   1348  1.1.1.1.2.2  pgoyette 
   1349  1.1.1.1.2.2  pgoyette       elf_section_data (htab->elf.sgotplt->output_section)->this_hdr.sh_entsize
   1350  1.1.1.1.2.2  pgoyette 	= htab->got_entry_size;
   1351  1.1.1.1.2.2  pgoyette 
   1352  1.1.1.1.2.2  pgoyette       dynamic_addr = (sdyn == NULL
   1353  1.1.1.1.2.2  pgoyette 		      ? (bfd_vma) 0
   1354  1.1.1.1.2.2  pgoyette 		      : sdyn->output_section->vma + sdyn->output_offset);
   1355  1.1.1.1.2.2  pgoyette 
   1356  1.1.1.1.2.2  pgoyette       /* Set the first entry in the global offset table to the address
   1357  1.1.1.1.2.2  pgoyette 	 of the dynamic section.  Write GOT[1] and GOT[2], needed for
   1358  1.1.1.1.2.2  pgoyette 	 the dynamic linker.  */
   1359  1.1.1.1.2.2  pgoyette       if (htab->got_entry_size == 8)
   1360  1.1.1.1.2.2  pgoyette 	{
   1361  1.1.1.1.2.2  pgoyette 	  bfd_put_64 (output_bfd, dynamic_addr,
   1362  1.1.1.1.2.2  pgoyette 		      htab->elf.sgotplt->contents);
   1363  1.1.1.1.2.2  pgoyette 	  bfd_put_64 (output_bfd, (bfd_vma) 0,
   1364  1.1.1.1.2.2  pgoyette 		      htab->elf.sgotplt->contents + 8);
   1365  1.1.1.1.2.2  pgoyette 	  bfd_put_64 (output_bfd, (bfd_vma) 0,
   1366  1.1.1.1.2.2  pgoyette 		      htab->elf.sgotplt->contents + 8*2);
   1367  1.1.1.1.2.2  pgoyette 	}
   1368  1.1.1.1.2.2  pgoyette       else
   1369  1.1.1.1.2.2  pgoyette 	{
   1370  1.1.1.1.2.2  pgoyette 	  bfd_put_32 (output_bfd, dynamic_addr,
   1371  1.1.1.1.2.2  pgoyette 		      htab->elf.sgotplt->contents);
   1372  1.1.1.1.2.2  pgoyette 	  bfd_put_32 (output_bfd, 0,
   1373  1.1.1.1.2.2  pgoyette 		      htab->elf.sgotplt->contents + 4);
   1374  1.1.1.1.2.2  pgoyette 	  bfd_put_32 (output_bfd, 0,
   1375  1.1.1.1.2.2  pgoyette 		      htab->elf.sgotplt->contents + 4*2);
   1376  1.1.1.1.2.2  pgoyette 	}
   1377  1.1.1.1.2.2  pgoyette     }
   1378  1.1.1.1.2.2  pgoyette 
   1379  1.1.1.1.2.2  pgoyette   if (!htab->elf.dynamic_sections_created)
   1380  1.1.1.1.2.2  pgoyette     return htab;
   1381  1.1.1.1.2.2  pgoyette 
   1382  1.1.1.1.2.2  pgoyette   if (sdyn == NULL || htab->elf.sgot == NULL)
   1383  1.1.1.1.2.2  pgoyette     abort ();
   1384  1.1.1.1.2.2  pgoyette 
   1385  1.1.1.1.2.2  pgoyette   sizeof_dyn = bed->s->sizeof_dyn;
   1386  1.1.1.1.2.2  pgoyette   dyncon = sdyn->contents;
   1387  1.1.1.1.2.2  pgoyette   dynconend = sdyn->contents + sdyn->size;
   1388  1.1.1.1.2.2  pgoyette   for (; dyncon < dynconend; dyncon += sizeof_dyn)
   1389  1.1.1.1.2.2  pgoyette     {
   1390  1.1.1.1.2.2  pgoyette       Elf_Internal_Dyn dyn;
   1391  1.1.1.1.2.2  pgoyette       asection *s;
   1392  1.1.1.1.2.2  pgoyette 
   1393  1.1.1.1.2.2  pgoyette       (*bed->s->swap_dyn_in) (dynobj, dyncon, &dyn);
   1394  1.1.1.1.2.2  pgoyette 
   1395  1.1.1.1.2.2  pgoyette       switch (dyn.d_tag)
   1396  1.1.1.1.2.2  pgoyette 	{
   1397  1.1.1.1.2.2  pgoyette 	default:
   1398  1.1.1.1.2.2  pgoyette 	  if (htab->target_os == is_vxworks
   1399  1.1.1.1.2.2  pgoyette 	      && elf_vxworks_finish_dynamic_entry (output_bfd, &dyn))
   1400  1.1.1.1.2.2  pgoyette 	    break;
   1401  1.1.1.1.2.2  pgoyette 	  continue;
   1402  1.1.1.1.2.2  pgoyette 
   1403  1.1.1.1.2.2  pgoyette 	case DT_PLTGOT:
   1404  1.1.1.1.2.2  pgoyette 	  s = htab->elf.sgotplt;
   1405  1.1.1.1.2.2  pgoyette 	  dyn.d_un.d_ptr = s->output_section->vma + s->output_offset;
   1406  1.1.1.1.2.2  pgoyette 	  break;
   1407  1.1.1.1.2.2  pgoyette 
   1408  1.1.1.1.2.2  pgoyette 	case DT_JMPREL:
   1409  1.1.1.1.2.2  pgoyette 	  dyn.d_un.d_ptr = htab->elf.srelplt->output_section->vma;
   1410  1.1.1.1.2.2  pgoyette 	  break;
   1411  1.1.1.1.2.2  pgoyette 
   1412  1.1.1.1.2.2  pgoyette 	case DT_PLTRELSZ:
   1413  1.1.1.1.2.2  pgoyette 	  s = htab->elf.srelplt->output_section;
   1414  1.1.1.1.2.2  pgoyette 	  dyn.d_un.d_val = s->size;
   1415  1.1.1.1.2.2  pgoyette 	  break;
   1416  1.1.1.1.2.2  pgoyette 
   1417  1.1.1.1.2.2  pgoyette 	case DT_TLSDESC_PLT:
   1418  1.1.1.1.2.2  pgoyette 	  s = htab->elf.splt;
   1419  1.1.1.1.2.2  pgoyette 	  dyn.d_un.d_ptr = s->output_section->vma + s->output_offset
   1420  1.1.1.1.2.2  pgoyette 	    + htab->tlsdesc_plt;
   1421  1.1.1.1.2.2  pgoyette 	  break;
   1422  1.1.1.1.2.2  pgoyette 
   1423  1.1.1.1.2.2  pgoyette 	case DT_TLSDESC_GOT:
   1424  1.1.1.1.2.2  pgoyette 	  s = htab->elf.sgot;
   1425  1.1.1.1.2.2  pgoyette 	  dyn.d_un.d_ptr = s->output_section->vma + s->output_offset
   1426  1.1.1.1.2.2  pgoyette 	    + htab->tlsdesc_got;
   1427  1.1.1.1.2.2  pgoyette 	  break;
   1428  1.1.1.1.2.2  pgoyette 	}
   1429  1.1.1.1.2.2  pgoyette 
   1430  1.1.1.1.2.2  pgoyette       (*bed->s->swap_dyn_out) (output_bfd, &dyn, dyncon);
   1431  1.1.1.1.2.2  pgoyette     }
   1432  1.1.1.1.2.2  pgoyette 
   1433  1.1.1.1.2.2  pgoyette   if (htab->plt_got != NULL && htab->plt_got->size > 0)
   1434  1.1.1.1.2.2  pgoyette     elf_section_data (htab->plt_got->output_section)
   1435  1.1.1.1.2.2  pgoyette       ->this_hdr.sh_entsize = htab->non_lazy_plt->plt_entry_size;
   1436  1.1.1.1.2.2  pgoyette 
   1437  1.1.1.1.2.2  pgoyette   if (htab->plt_second != NULL && htab->plt_second->size > 0)
   1438  1.1.1.1.2.2  pgoyette     elf_section_data (htab->plt_second->output_section)
   1439  1.1.1.1.2.2  pgoyette       ->this_hdr.sh_entsize = htab->non_lazy_plt->plt_entry_size;
   1440  1.1.1.1.2.2  pgoyette 
   1441  1.1.1.1.2.2  pgoyette   /* Adjust .eh_frame for .plt section.  */
   1442  1.1.1.1.2.2  pgoyette   if (htab->plt_eh_frame != NULL
   1443  1.1.1.1.2.2  pgoyette       && htab->plt_eh_frame->contents != NULL)
   1444  1.1.1.1.2.2  pgoyette     {
   1445  1.1.1.1.2.2  pgoyette       if (htab->elf.splt != NULL
   1446  1.1.1.1.2.2  pgoyette 	  && htab->elf.splt->size != 0
   1447  1.1.1.1.2.2  pgoyette 	  && (htab->elf.splt->flags & SEC_EXCLUDE) == 0
   1448  1.1.1.1.2.2  pgoyette 	  && htab->elf.splt->output_section != NULL
   1449  1.1.1.1.2.2  pgoyette 	  && htab->plt_eh_frame->output_section != NULL)
   1450  1.1.1.1.2.2  pgoyette 	{
   1451  1.1.1.1.2.2  pgoyette 	  bfd_vma plt_start = htab->elf.splt->output_section->vma;
   1452  1.1.1.1.2.2  pgoyette 	  bfd_vma eh_frame_start = htab->plt_eh_frame->output_section->vma
   1453  1.1.1.1.2.2  pgoyette 				   + htab->plt_eh_frame->output_offset
   1454  1.1.1.1.2.2  pgoyette 				   + PLT_FDE_START_OFFSET;
   1455  1.1.1.1.2.2  pgoyette 	  bfd_put_signed_32 (dynobj, plt_start - eh_frame_start,
   1456  1.1.1.1.2.2  pgoyette 			     htab->plt_eh_frame->contents
   1457  1.1.1.1.2.2  pgoyette 			     + PLT_FDE_START_OFFSET);
   1458  1.1.1.1.2.2  pgoyette 	}
   1459  1.1.1.1.2.2  pgoyette 
   1460  1.1.1.1.2.2  pgoyette       if (htab->plt_eh_frame->sec_info_type == SEC_INFO_TYPE_EH_FRAME)
   1461  1.1.1.1.2.2  pgoyette 	{
   1462  1.1.1.1.2.2  pgoyette 	  if (! _bfd_elf_write_section_eh_frame (output_bfd, info,
   1463  1.1.1.1.2.2  pgoyette 						 htab->plt_eh_frame,
   1464  1.1.1.1.2.2  pgoyette 						 htab->plt_eh_frame->contents))
   1465  1.1.1.1.2.2  pgoyette 	    return NULL;
   1466  1.1.1.1.2.2  pgoyette 	}
   1467  1.1.1.1.2.2  pgoyette     }
   1468  1.1.1.1.2.2  pgoyette 
   1469  1.1.1.1.2.2  pgoyette   /* Adjust .eh_frame for .plt.got section.  */
   1470  1.1.1.1.2.2  pgoyette   if (htab->plt_got_eh_frame != NULL
   1471  1.1.1.1.2.2  pgoyette       && htab->plt_got_eh_frame->contents != NULL)
   1472  1.1.1.1.2.2  pgoyette     {
   1473  1.1.1.1.2.2  pgoyette       if (htab->plt_got != NULL
   1474  1.1.1.1.2.2  pgoyette 	  && htab->plt_got->size != 0
   1475  1.1.1.1.2.2  pgoyette 	  && (htab->plt_got->flags & SEC_EXCLUDE) == 0
   1476  1.1.1.1.2.2  pgoyette 	  && htab->plt_got->output_section != NULL
   1477  1.1.1.1.2.2  pgoyette 	  && htab->plt_got_eh_frame->output_section != NULL)
   1478  1.1.1.1.2.2  pgoyette 	{
   1479  1.1.1.1.2.2  pgoyette 	  bfd_vma plt_start = htab->plt_got->output_section->vma;
   1480  1.1.1.1.2.2  pgoyette 	  bfd_vma eh_frame_start = htab->plt_got_eh_frame->output_section->vma
   1481  1.1.1.1.2.2  pgoyette 				   + htab->plt_got_eh_frame->output_offset
   1482  1.1.1.1.2.2  pgoyette 				   + PLT_FDE_START_OFFSET;
   1483  1.1.1.1.2.2  pgoyette 	  bfd_put_signed_32 (dynobj, plt_start - eh_frame_start,
   1484  1.1.1.1.2.2  pgoyette 			     htab->plt_got_eh_frame->contents
   1485  1.1.1.1.2.2  pgoyette 			     + PLT_FDE_START_OFFSET);
   1486  1.1.1.1.2.2  pgoyette 	}
   1487  1.1.1.1.2.2  pgoyette       if (htab->plt_got_eh_frame->sec_info_type == SEC_INFO_TYPE_EH_FRAME)
   1488  1.1.1.1.2.2  pgoyette 	{
   1489  1.1.1.1.2.2  pgoyette 	  if (! _bfd_elf_write_section_eh_frame (output_bfd, info,
   1490  1.1.1.1.2.2  pgoyette 						 htab->plt_got_eh_frame,
   1491  1.1.1.1.2.2  pgoyette 						 htab->plt_got_eh_frame->contents))
   1492  1.1.1.1.2.2  pgoyette 	    return NULL;
   1493  1.1.1.1.2.2  pgoyette 	}
   1494  1.1.1.1.2.2  pgoyette     }
   1495  1.1.1.1.2.2  pgoyette 
   1496  1.1.1.1.2.2  pgoyette   /* Adjust .eh_frame for the second PLT section.  */
   1497  1.1.1.1.2.2  pgoyette   if (htab->plt_second_eh_frame != NULL
   1498  1.1.1.1.2.2  pgoyette       && htab->plt_second_eh_frame->contents != NULL)
   1499  1.1.1.1.2.2  pgoyette     {
   1500  1.1.1.1.2.2  pgoyette       if (htab->plt_second != NULL
   1501  1.1.1.1.2.2  pgoyette 	  && htab->plt_second->size != 0
   1502  1.1.1.1.2.2  pgoyette 	  && (htab->plt_second->flags & SEC_EXCLUDE) == 0
   1503  1.1.1.1.2.2  pgoyette 	  && htab->plt_second->output_section != NULL
   1504  1.1.1.1.2.2  pgoyette 	  && htab->plt_second_eh_frame->output_section != NULL)
   1505  1.1.1.1.2.2  pgoyette 	{
   1506  1.1.1.1.2.2  pgoyette 	  bfd_vma plt_start = htab->plt_second->output_section->vma;
   1507  1.1.1.1.2.2  pgoyette 	  bfd_vma eh_frame_start
   1508  1.1.1.1.2.2  pgoyette 	    = (htab->plt_second_eh_frame->output_section->vma
   1509  1.1.1.1.2.2  pgoyette 	       + htab->plt_second_eh_frame->output_offset
   1510  1.1.1.1.2.2  pgoyette 	       + PLT_FDE_START_OFFSET);
   1511  1.1.1.1.2.2  pgoyette 	  bfd_put_signed_32 (dynobj, plt_start - eh_frame_start,
   1512  1.1.1.1.2.2  pgoyette 			     htab->plt_second_eh_frame->contents
   1513  1.1.1.1.2.2  pgoyette 			     + PLT_FDE_START_OFFSET);
   1514  1.1.1.1.2.2  pgoyette 	}
   1515  1.1.1.1.2.2  pgoyette       if (htab->plt_second_eh_frame->sec_info_type
   1516  1.1.1.1.2.2  pgoyette 	  == SEC_INFO_TYPE_EH_FRAME)
   1517  1.1.1.1.2.2  pgoyette 	{
   1518  1.1.1.1.2.2  pgoyette 	  if (! _bfd_elf_write_section_eh_frame (output_bfd, info,
   1519  1.1.1.1.2.2  pgoyette 						 htab->plt_second_eh_frame,
   1520  1.1.1.1.2.2  pgoyette 						 htab->plt_second_eh_frame->contents))
   1521  1.1.1.1.2.2  pgoyette 	    return NULL;
   1522  1.1.1.1.2.2  pgoyette 	}
   1523  1.1.1.1.2.2  pgoyette     }
   1524  1.1.1.1.2.2  pgoyette 
   1525  1.1.1.1.2.2  pgoyette   if (htab->elf.sgot && htab->elf.sgot->size > 0)
   1526  1.1.1.1.2.2  pgoyette     elf_section_data (htab->elf.sgot->output_section)->this_hdr.sh_entsize
   1527  1.1.1.1.2.2  pgoyette       = htab->got_entry_size;
   1528  1.1.1.1.2.2  pgoyette 
   1529  1.1.1.1.2.2  pgoyette   return htab;
   1530  1.1.1.1.2.2  pgoyette }
   1531  1.1.1.1.2.2  pgoyette 
   1532  1.1.1.1.2.2  pgoyette 
   1533  1.1.1.1.2.2  pgoyette bfd_boolean
   1534  1.1.1.1.2.2  pgoyette _bfd_x86_elf_always_size_sections (bfd *output_bfd,
   1535  1.1.1.1.2.2  pgoyette 				   struct bfd_link_info *info)
   1536  1.1.1.1.2.2  pgoyette {
   1537  1.1.1.1.2.2  pgoyette   asection *tls_sec = elf_hash_table (info)->tls_sec;
   1538  1.1.1.1.2.2  pgoyette 
   1539  1.1.1.1.2.2  pgoyette   if (tls_sec)
   1540  1.1.1.1.2.2  pgoyette     {
   1541  1.1.1.1.2.2  pgoyette       struct elf_link_hash_entry *tlsbase;
   1542  1.1.1.1.2.2  pgoyette 
   1543  1.1.1.1.2.2  pgoyette       tlsbase = elf_link_hash_lookup (elf_hash_table (info),
   1544  1.1.1.1.2.2  pgoyette 				      "_TLS_MODULE_BASE_",
   1545  1.1.1.1.2.2  pgoyette 				      FALSE, FALSE, FALSE);
   1546  1.1.1.1.2.2  pgoyette 
   1547  1.1.1.1.2.2  pgoyette       if (tlsbase && tlsbase->type == STT_TLS)
   1548  1.1.1.1.2.2  pgoyette 	{
   1549  1.1.1.1.2.2  pgoyette 	  struct elf_x86_link_hash_table *htab;
   1550  1.1.1.1.2.2  pgoyette 	  struct bfd_link_hash_entry *bh = NULL;
   1551  1.1.1.1.2.2  pgoyette 	  const struct elf_backend_data *bed
   1552  1.1.1.1.2.2  pgoyette 	    = get_elf_backend_data (output_bfd);
   1553  1.1.1.1.2.2  pgoyette 
   1554  1.1.1.1.2.2  pgoyette 	  htab = elf_x86_hash_table (info, bed->target_id);
   1555  1.1.1.1.2.2  pgoyette 	  if (htab == NULL)
   1556  1.1.1.1.2.2  pgoyette 	    return FALSE;
   1557  1.1.1.1.2.2  pgoyette 
   1558  1.1.1.1.2.2  pgoyette 	  if (!(_bfd_generic_link_add_one_symbol
   1559  1.1.1.1.2.2  pgoyette 		(info, output_bfd, "_TLS_MODULE_BASE_", BSF_LOCAL,
   1560  1.1.1.1.2.2  pgoyette 		 tls_sec, 0, NULL, FALSE,
   1561  1.1.1.1.2.2  pgoyette 		 bed->collect, &bh)))
   1562  1.1.1.1.2.2  pgoyette 	    return FALSE;
   1563  1.1.1.1.2.2  pgoyette 
   1564  1.1.1.1.2.2  pgoyette 	  htab->tls_module_base = bh;
   1565  1.1.1.1.2.2  pgoyette 
   1566  1.1.1.1.2.2  pgoyette 	  tlsbase = (struct elf_link_hash_entry *)bh;
   1567  1.1.1.1.2.2  pgoyette 	  tlsbase->def_regular = 1;
   1568  1.1.1.1.2.2  pgoyette 	  tlsbase->other = STV_HIDDEN;
   1569  1.1.1.1.2.2  pgoyette 	  tlsbase->root.linker_def = 1;
   1570  1.1.1.1.2.2  pgoyette 	  (*bed->elf_backend_hide_symbol) (info, tlsbase, TRUE);
   1571  1.1.1.1.2.2  pgoyette 	}
   1572  1.1.1.1.2.2  pgoyette     }
   1573  1.1.1.1.2.2  pgoyette 
   1574  1.1.1.1.2.2  pgoyette   return TRUE;
   1575  1.1.1.1.2.2  pgoyette }
   1576  1.1.1.1.2.2  pgoyette 
   1577  1.1.1.1.2.2  pgoyette void
   1578  1.1.1.1.2.2  pgoyette _bfd_x86_elf_merge_symbol_attribute (struct elf_link_hash_entry *h,
   1579  1.1.1.1.2.2  pgoyette 				     const Elf_Internal_Sym *isym,
   1580  1.1.1.1.2.2  pgoyette 				     bfd_boolean definition,
   1581  1.1.1.1.2.2  pgoyette 				     bfd_boolean dynamic ATTRIBUTE_UNUSED)
   1582  1.1.1.1.2.2  pgoyette {
   1583  1.1.1.1.2.2  pgoyette   if (definition)
   1584  1.1.1.1.2.2  pgoyette     {
   1585  1.1.1.1.2.2  pgoyette       struct elf_x86_link_hash_entry *eh
   1586  1.1.1.1.2.2  pgoyette 	= (struct elf_x86_link_hash_entry *) h;
   1587  1.1.1.1.2.2  pgoyette       eh->def_protected = (ELF_ST_VISIBILITY (isym->st_other)
   1588  1.1.1.1.2.2  pgoyette 			   == STV_PROTECTED);
   1589  1.1.1.1.2.2  pgoyette     }
   1590  1.1.1.1.2.2  pgoyette }
   1591  1.1.1.1.2.2  pgoyette 
   1592  1.1.1.1.2.2  pgoyette /* Copy the extra info we tack onto an elf_link_hash_entry.  */
   1593  1.1.1.1.2.2  pgoyette 
   1594  1.1.1.1.2.2  pgoyette void
   1595  1.1.1.1.2.2  pgoyette _bfd_x86_elf_copy_indirect_symbol (struct bfd_link_info *info,
   1596  1.1.1.1.2.2  pgoyette 				   struct elf_link_hash_entry *dir,
   1597  1.1.1.1.2.2  pgoyette 				   struct elf_link_hash_entry *ind)
   1598  1.1.1.1.2.2  pgoyette {
   1599  1.1.1.1.2.2  pgoyette   struct elf_x86_link_hash_entry *edir, *eind;
   1600  1.1.1.1.2.2  pgoyette 
   1601  1.1.1.1.2.2  pgoyette   edir = (struct elf_x86_link_hash_entry *) dir;
   1602  1.1.1.1.2.2  pgoyette   eind = (struct elf_x86_link_hash_entry *) ind;
   1603  1.1.1.1.2.2  pgoyette 
   1604  1.1.1.1.2.2  pgoyette   if (eind->dyn_relocs != NULL)
   1605  1.1.1.1.2.2  pgoyette     {
   1606  1.1.1.1.2.2  pgoyette       if (edir->dyn_relocs != NULL)
   1607  1.1.1.1.2.2  pgoyette 	{
   1608  1.1.1.1.2.2  pgoyette 	  struct elf_dyn_relocs **pp;
   1609  1.1.1.1.2.2  pgoyette 	  struct elf_dyn_relocs *p;
   1610  1.1.1.1.2.2  pgoyette 
   1611  1.1.1.1.2.2  pgoyette 	  /* Add reloc counts against the indirect sym to the direct sym
   1612  1.1.1.1.2.2  pgoyette 	     list.  Merge any entries against the same section.  */
   1613  1.1.1.1.2.2  pgoyette 	  for (pp = &eind->dyn_relocs; (p = *pp) != NULL; )
   1614  1.1.1.1.2.2  pgoyette 	    {
   1615  1.1.1.1.2.2  pgoyette 	      struct elf_dyn_relocs *q;
   1616  1.1.1.1.2.2  pgoyette 
   1617  1.1.1.1.2.2  pgoyette 	      for (q = edir->dyn_relocs; q != NULL; q = q->next)
   1618  1.1.1.1.2.2  pgoyette 		if (q->sec == p->sec)
   1619  1.1.1.1.2.2  pgoyette 		  {
   1620  1.1.1.1.2.2  pgoyette 		    q->pc_count += p->pc_count;
   1621  1.1.1.1.2.2  pgoyette 		    q->count += p->count;
   1622  1.1.1.1.2.2  pgoyette 		    *pp = p->next;
   1623  1.1.1.1.2.2  pgoyette 		    break;
   1624  1.1.1.1.2.2  pgoyette 		  }
   1625  1.1.1.1.2.2  pgoyette 	      if (q == NULL)
   1626  1.1.1.1.2.2  pgoyette 		pp = &p->next;
   1627  1.1.1.1.2.2  pgoyette 	    }
   1628  1.1.1.1.2.2  pgoyette 	  *pp = edir->dyn_relocs;
   1629  1.1.1.1.2.2  pgoyette 	}
   1630  1.1.1.1.2.2  pgoyette 
   1631  1.1.1.1.2.2  pgoyette       edir->dyn_relocs = eind->dyn_relocs;
   1632  1.1.1.1.2.2  pgoyette       eind->dyn_relocs = NULL;
   1633  1.1.1.1.2.2  pgoyette     }
   1634  1.1.1.1.2.2  pgoyette 
   1635  1.1.1.1.2.2  pgoyette   if (ind->root.type == bfd_link_hash_indirect
   1636  1.1.1.1.2.2  pgoyette       && dir->got.refcount <= 0)
   1637  1.1.1.1.2.2  pgoyette     {
   1638  1.1.1.1.2.2  pgoyette       edir->tls_type = eind->tls_type;
   1639  1.1.1.1.2.2  pgoyette       eind->tls_type = GOT_UNKNOWN;
   1640  1.1.1.1.2.2  pgoyette     }
   1641  1.1.1.1.2.2  pgoyette 
   1642  1.1.1.1.2.2  pgoyette   /* Copy gotoff_ref so that elf_i386_adjust_dynamic_symbol will
   1643  1.1.1.1.2.2  pgoyette      generate a R_386_COPY reloc.  */
   1644  1.1.1.1.2.2  pgoyette   edir->gotoff_ref |= eind->gotoff_ref;
   1645  1.1.1.1.2.2  pgoyette 
   1646  1.1.1.1.2.2  pgoyette   edir->zero_undefweak |= eind->zero_undefweak;
   1647  1.1.1.1.2.2  pgoyette 
   1648  1.1.1.1.2.2  pgoyette   if (ELIMINATE_COPY_RELOCS
   1649  1.1.1.1.2.2  pgoyette       && ind->root.type != bfd_link_hash_indirect
   1650  1.1.1.1.2.2  pgoyette       && dir->dynamic_adjusted)
   1651  1.1.1.1.2.2  pgoyette     {
   1652  1.1.1.1.2.2  pgoyette       /* If called to transfer flags for a weakdef during processing
   1653  1.1.1.1.2.2  pgoyette 	 of elf_adjust_dynamic_symbol, don't copy non_got_ref.
   1654  1.1.1.1.2.2  pgoyette 	 We clear it ourselves for ELIMINATE_COPY_RELOCS.  */
   1655  1.1.1.1.2.2  pgoyette       if (dir->versioned != versioned_hidden)
   1656  1.1.1.1.2.2  pgoyette 	dir->ref_dynamic |= ind->ref_dynamic;
   1657  1.1.1.1.2.2  pgoyette       dir->ref_regular |= ind->ref_regular;
   1658  1.1.1.1.2.2  pgoyette       dir->ref_regular_nonweak |= ind->ref_regular_nonweak;
   1659  1.1.1.1.2.2  pgoyette       dir->needs_plt |= ind->needs_plt;
   1660  1.1.1.1.2.2  pgoyette       dir->pointer_equality_needed |= ind->pointer_equality_needed;
   1661  1.1.1.1.2.2  pgoyette     }
   1662  1.1.1.1.2.2  pgoyette   else
   1663  1.1.1.1.2.2  pgoyette     _bfd_elf_link_hash_copy_indirect (info, dir, ind);
   1664  1.1.1.1.2.2  pgoyette }
   1665  1.1.1.1.2.2  pgoyette 
   1666  1.1.1.1.2.2  pgoyette /* Remove undefined weak symbol from the dynamic symbol table if it
   1667  1.1.1.1.2.2  pgoyette    is resolved to 0.   */
   1668  1.1.1.1.2.2  pgoyette 
   1669  1.1.1.1.2.2  pgoyette bfd_boolean
   1670  1.1.1.1.2.2  pgoyette _bfd_x86_elf_fixup_symbol (struct bfd_link_info *info,
   1671  1.1.1.1.2.2  pgoyette 			   struct elf_link_hash_entry *h)
   1672  1.1.1.1.2.2  pgoyette {
   1673  1.1.1.1.2.2  pgoyette   if (h->dynindx != -1
   1674  1.1.1.1.2.2  pgoyette       && UNDEFINED_WEAK_RESOLVED_TO_ZERO (info, elf_x86_hash_entry (h)))
   1675  1.1.1.1.2.2  pgoyette     {
   1676  1.1.1.1.2.2  pgoyette       h->dynindx = -1;
   1677  1.1.1.1.2.2  pgoyette       _bfd_elf_strtab_delref (elf_hash_table (info)->dynstr,
   1678  1.1.1.1.2.2  pgoyette 			      h->dynstr_index);
   1679  1.1.1.1.2.2  pgoyette     }
   1680  1.1.1.1.2.2  pgoyette   return TRUE;
   1681  1.1.1.1.2.2  pgoyette }
   1682  1.1.1.1.2.2  pgoyette 
   1683  1.1.1.1.2.2  pgoyette /* Return TRUE if symbol should be hashed in the `.gnu.hash' section.  */
   1684  1.1.1.1.2.2  pgoyette 
   1685  1.1.1.1.2.2  pgoyette bfd_boolean
   1686  1.1.1.1.2.2  pgoyette _bfd_x86_elf_hash_symbol (struct elf_link_hash_entry *h)
   1687  1.1.1.1.2.2  pgoyette {
   1688  1.1.1.1.2.2  pgoyette   if (h->plt.offset != (bfd_vma) -1
   1689  1.1.1.1.2.2  pgoyette       && !h->def_regular
   1690  1.1.1.1.2.2  pgoyette       && !h->pointer_equality_needed)
   1691  1.1.1.1.2.2  pgoyette     return FALSE;
   1692  1.1.1.1.2.2  pgoyette 
   1693  1.1.1.1.2.2  pgoyette   return _bfd_elf_hash_symbol (h);
   1694  1.1.1.1.2.2  pgoyette }
   1695  1.1.1.1.2.2  pgoyette 
   1696  1.1.1.1.2.2  pgoyette /* Adjust a symbol defined by a dynamic object and referenced by a
   1697  1.1.1.1.2.2  pgoyette    regular object.  The current definition is in some section of the
   1698  1.1.1.1.2.2  pgoyette    dynamic object, but we're not including those sections.  We have to
   1699  1.1.1.1.2.2  pgoyette    change the definition to something the rest of the link can
   1700  1.1.1.1.2.2  pgoyette    understand.  */
   1701  1.1.1.1.2.2  pgoyette 
   1702  1.1.1.1.2.2  pgoyette bfd_boolean
   1703  1.1.1.1.2.2  pgoyette _bfd_x86_elf_adjust_dynamic_symbol (struct bfd_link_info *info,
   1704  1.1.1.1.2.2  pgoyette 				    struct elf_link_hash_entry *h)
   1705  1.1.1.1.2.2  pgoyette {
   1706  1.1.1.1.2.2  pgoyette   struct elf_x86_link_hash_table *htab;
   1707  1.1.1.1.2.2  pgoyette   asection *s, *srel;
   1708  1.1.1.1.2.2  pgoyette   struct elf_x86_link_hash_entry *eh;
   1709  1.1.1.1.2.2  pgoyette   struct elf_dyn_relocs *p;
   1710  1.1.1.1.2.2  pgoyette   const struct elf_backend_data *bed
   1711  1.1.1.1.2.2  pgoyette     = get_elf_backend_data (info->output_bfd);
   1712  1.1.1.1.2.2  pgoyette 
   1713  1.1.1.1.2.2  pgoyette   /* STT_GNU_IFUNC symbol must go through PLT. */
   1714  1.1.1.1.2.2  pgoyette   if (h->type == STT_GNU_IFUNC)
   1715  1.1.1.1.2.2  pgoyette     {
   1716  1.1.1.1.2.2  pgoyette       /* All local STT_GNU_IFUNC references must be treate as local
   1717  1.1.1.1.2.2  pgoyette 	 calls via local PLT.  */
   1718  1.1.1.1.2.2  pgoyette       if (h->ref_regular
   1719  1.1.1.1.2.2  pgoyette 	  && SYMBOL_CALLS_LOCAL (info, h))
   1720  1.1.1.1.2.2  pgoyette 	{
   1721  1.1.1.1.2.2  pgoyette 	  bfd_size_type pc_count = 0, count = 0;
   1722  1.1.1.1.2.2  pgoyette 	  struct elf_dyn_relocs **pp;
   1723  1.1.1.1.2.2  pgoyette 
   1724  1.1.1.1.2.2  pgoyette 	  eh = (struct elf_x86_link_hash_entry *) h;
   1725  1.1.1.1.2.2  pgoyette 	  for (pp = &eh->dyn_relocs; (p = *pp) != NULL; )
   1726  1.1.1.1.2.2  pgoyette 	    {
   1727  1.1.1.1.2.2  pgoyette 	      pc_count += p->pc_count;
   1728  1.1.1.1.2.2  pgoyette 	      p->count -= p->pc_count;
   1729  1.1.1.1.2.2  pgoyette 	      p->pc_count = 0;
   1730  1.1.1.1.2.2  pgoyette 	      count += p->count;
   1731  1.1.1.1.2.2  pgoyette 	      if (p->count == 0)
   1732  1.1.1.1.2.2  pgoyette 		*pp = p->next;
   1733  1.1.1.1.2.2  pgoyette 	      else
   1734  1.1.1.1.2.2  pgoyette 		pp = &p->next;
   1735  1.1.1.1.2.2  pgoyette 	    }
   1736  1.1.1.1.2.2  pgoyette 
   1737  1.1.1.1.2.2  pgoyette 	  if (pc_count || count)
   1738  1.1.1.1.2.2  pgoyette 	    {
   1739  1.1.1.1.2.2  pgoyette 	      h->non_got_ref = 1;
   1740  1.1.1.1.2.2  pgoyette 	      if (pc_count)
   1741  1.1.1.1.2.2  pgoyette 		{
   1742  1.1.1.1.2.2  pgoyette 		  /* Increment PLT reference count only for PC-relative
   1743  1.1.1.1.2.2  pgoyette 		     references.  */
   1744  1.1.1.1.2.2  pgoyette 		  h->needs_plt = 1;
   1745  1.1.1.1.2.2  pgoyette 		  if (h->plt.refcount <= 0)
   1746  1.1.1.1.2.2  pgoyette 		    h->plt.refcount = 1;
   1747  1.1.1.1.2.2  pgoyette 		  else
   1748  1.1.1.1.2.2  pgoyette 		    h->plt.refcount += 1;
   1749  1.1.1.1.2.2  pgoyette 		}
   1750  1.1.1.1.2.2  pgoyette 	    }
   1751  1.1.1.1.2.2  pgoyette 	}
   1752  1.1.1.1.2.2  pgoyette 
   1753  1.1.1.1.2.2  pgoyette       if (h->plt.refcount <= 0)
   1754  1.1.1.1.2.2  pgoyette 	{
   1755  1.1.1.1.2.2  pgoyette 	  h->plt.offset = (bfd_vma) -1;
   1756  1.1.1.1.2.2  pgoyette 	  h->needs_plt = 0;
   1757  1.1.1.1.2.2  pgoyette 	}
   1758  1.1.1.1.2.2  pgoyette       return TRUE;
   1759  1.1.1.1.2.2  pgoyette     }
   1760  1.1.1.1.2.2  pgoyette 
   1761  1.1.1.1.2.2  pgoyette   /* If this is a function, put it in the procedure linkage table.  We
   1762  1.1.1.1.2.2  pgoyette      will fill in the contents of the procedure linkage table later,
   1763  1.1.1.1.2.2  pgoyette      when we know the address of the .got section.  */
   1764  1.1.1.1.2.2  pgoyette   if (h->type == STT_FUNC
   1765  1.1.1.1.2.2  pgoyette       || h->needs_plt)
   1766  1.1.1.1.2.2  pgoyette     {
   1767  1.1.1.1.2.2  pgoyette       if (h->plt.refcount <= 0
   1768  1.1.1.1.2.2  pgoyette 	  || SYMBOL_CALLS_LOCAL (info, h)
   1769  1.1.1.1.2.2  pgoyette 	  || (ELF_ST_VISIBILITY (h->other) != STV_DEFAULT
   1770  1.1.1.1.2.2  pgoyette 	      && h->root.type == bfd_link_hash_undefweak))
   1771  1.1.1.1.2.2  pgoyette 	{
   1772  1.1.1.1.2.2  pgoyette 	  /* This case can occur if we saw a PLT32 reloc in an input
   1773  1.1.1.1.2.2  pgoyette 	     file, but the symbol was never referred to by a dynamic
   1774  1.1.1.1.2.2  pgoyette 	     object, or if all references were garbage collected.  In
   1775  1.1.1.1.2.2  pgoyette 	     such a case, we don't actually need to build a procedure
   1776  1.1.1.1.2.2  pgoyette 	     linkage table, and we can just do a PC32 reloc instead.  */
   1777  1.1.1.1.2.2  pgoyette 	  h->plt.offset = (bfd_vma) -1;
   1778  1.1.1.1.2.2  pgoyette 	  h->needs_plt = 0;
   1779  1.1.1.1.2.2  pgoyette 	}
   1780  1.1.1.1.2.2  pgoyette 
   1781  1.1.1.1.2.2  pgoyette       return TRUE;
   1782  1.1.1.1.2.2  pgoyette     }
   1783  1.1.1.1.2.2  pgoyette   else
   1784  1.1.1.1.2.2  pgoyette     /* It's possible that we incorrectly decided a .plt reloc was needed
   1785  1.1.1.1.2.2  pgoyette      * for an R_386_PC32/R_X86_64_PC32 reloc to a non-function sym in
   1786  1.1.1.1.2.2  pgoyette        check_relocs.  We can't decide accurately between function and
   1787  1.1.1.1.2.2  pgoyette        non-function syms in check-relocs;  Objects loaded later in
   1788  1.1.1.1.2.2  pgoyette        the link may change h->type.  So fix it now.  */
   1789  1.1.1.1.2.2  pgoyette     h->plt.offset = (bfd_vma) -1;
   1790  1.1.1.1.2.2  pgoyette 
   1791  1.1.1.1.2.2  pgoyette   eh = (struct elf_x86_link_hash_entry *) h;
   1792  1.1.1.1.2.2  pgoyette 
   1793  1.1.1.1.2.2  pgoyette   /* If this is a weak symbol, and there is a real definition, the
   1794  1.1.1.1.2.2  pgoyette      processor independent code will have arranged for us to see the
   1795  1.1.1.1.2.2  pgoyette      real definition first, and we can just use the same value.  */
   1796  1.1.1.1.2.2  pgoyette   if (h->is_weakalias)
   1797  1.1.1.1.2.2  pgoyette     {
   1798  1.1.1.1.2.2  pgoyette       struct elf_link_hash_entry *def = weakdef (h);
   1799  1.1.1.1.2.2  pgoyette       BFD_ASSERT (def->root.type == bfd_link_hash_defined);
   1800  1.1.1.1.2.2  pgoyette       h->root.u.def.section = def->root.u.def.section;
   1801  1.1.1.1.2.2  pgoyette       h->root.u.def.value = def->root.u.def.value;
   1802  1.1.1.1.2.2  pgoyette       if (ELIMINATE_COPY_RELOCS
   1803  1.1.1.1.2.2  pgoyette 	  || info->nocopyreloc
   1804  1.1.1.1.2.2  pgoyette 	  || SYMBOL_NO_COPYRELOC (info, eh))
   1805  1.1.1.1.2.2  pgoyette 	{
   1806  1.1.1.1.2.2  pgoyette 	  /* NB: needs_copy is always 0 for i386.  */
   1807  1.1.1.1.2.2  pgoyette 	  h->non_got_ref = def->non_got_ref;
   1808  1.1.1.1.2.2  pgoyette 	  eh->needs_copy = def->needs_copy;
   1809  1.1.1.1.2.2  pgoyette 	}
   1810  1.1.1.1.2.2  pgoyette       return TRUE;
   1811  1.1.1.1.2.2  pgoyette     }
   1812  1.1.1.1.2.2  pgoyette 
   1813  1.1.1.1.2.2  pgoyette   /* This is a reference to a symbol defined by a dynamic object which
   1814  1.1.1.1.2.2  pgoyette      is not a function.  */
   1815  1.1.1.1.2.2  pgoyette 
   1816  1.1.1.1.2.2  pgoyette   /* If we are creating a shared library, we must presume that the
   1817  1.1.1.1.2.2  pgoyette      only references to the symbol are via the global offset table.
   1818  1.1.1.1.2.2  pgoyette      For such cases we need not do anything here; the relocations will
   1819  1.1.1.1.2.2  pgoyette      be handled correctly by relocate_section.  */
   1820  1.1.1.1.2.2  pgoyette   if (!bfd_link_executable (info))
   1821  1.1.1.1.2.2  pgoyette     return TRUE;
   1822  1.1.1.1.2.2  pgoyette 
   1823  1.1.1.1.2.2  pgoyette   /* If there are no references to this symbol that do not use the
   1824  1.1.1.1.2.2  pgoyette      GOT nor R_386_GOTOFF relocation, we don't need to generate a copy
   1825  1.1.1.1.2.2  pgoyette      reloc.  NB: gotoff_ref is always 0 for x86-64.  */
   1826  1.1.1.1.2.2  pgoyette   if (!h->non_got_ref && !eh->gotoff_ref)
   1827  1.1.1.1.2.2  pgoyette     return TRUE;
   1828  1.1.1.1.2.2  pgoyette 
   1829  1.1.1.1.2.2  pgoyette   /* If -z nocopyreloc was given, we won't generate them either.  */
   1830  1.1.1.1.2.2  pgoyette   if (info->nocopyreloc || SYMBOL_NO_COPYRELOC (info, eh))
   1831  1.1.1.1.2.2  pgoyette     {
   1832  1.1.1.1.2.2  pgoyette       h->non_got_ref = 0;
   1833  1.1.1.1.2.2  pgoyette       return TRUE;
   1834  1.1.1.1.2.2  pgoyette     }
   1835  1.1.1.1.2.2  pgoyette 
   1836  1.1.1.1.2.2  pgoyette   htab = elf_x86_hash_table (info, bed->target_id);
   1837  1.1.1.1.2.2  pgoyette   if (htab == NULL)
   1838  1.1.1.1.2.2  pgoyette     return FALSE;
   1839  1.1.1.1.2.2  pgoyette 
   1840  1.1.1.1.2.2  pgoyette   /* If there aren't any dynamic relocs in read-only sections nor
   1841  1.1.1.1.2.2  pgoyette      R_386_GOTOFF relocation, then we can keep the dynamic relocs and
   1842  1.1.1.1.2.2  pgoyette      avoid the copy reloc.  This doesn't work on VxWorks, where we can
   1843  1.1.1.1.2.2  pgoyette      not have dynamic relocations (other than copy and jump slot
   1844  1.1.1.1.2.2  pgoyette      relocations) in an executable.  */
   1845  1.1.1.1.2.2  pgoyette   if (ELIMINATE_COPY_RELOCS
   1846  1.1.1.1.2.2  pgoyette       && (bed->target_id == X86_64_ELF_DATA
   1847  1.1.1.1.2.2  pgoyette 	  || (!eh->gotoff_ref
   1848  1.1.1.1.2.2  pgoyette 	      && htab->target_os != is_vxworks)))
   1849  1.1.1.1.2.2  pgoyette     {
   1850  1.1.1.1.2.2  pgoyette       /* If we don't find any dynamic relocs in read-only sections,
   1851  1.1.1.1.2.2  pgoyette 	 then we'll be keeping the dynamic relocs and avoiding the copy
   1852  1.1.1.1.2.2  pgoyette 	 reloc.  */
   1853  1.1.1.1.2.2  pgoyette       if (!readonly_dynrelocs (h))
   1854  1.1.1.1.2.2  pgoyette 	{
   1855  1.1.1.1.2.2  pgoyette 	  h->non_got_ref = 0;
   1856  1.1.1.1.2.2  pgoyette 	  return TRUE;
   1857  1.1.1.1.2.2  pgoyette 	}
   1858  1.1.1.1.2.2  pgoyette     }
   1859  1.1.1.1.2.2  pgoyette 
   1860  1.1.1.1.2.2  pgoyette   /* We must allocate the symbol in our .dynbss section, which will
   1861  1.1.1.1.2.2  pgoyette      become part of the .bss section of the executable.  There will be
   1862  1.1.1.1.2.2  pgoyette      an entry for this symbol in the .dynsym section.  The dynamic
   1863  1.1.1.1.2.2  pgoyette      object will contain position independent code, so all references
   1864  1.1.1.1.2.2  pgoyette      from the dynamic object to this symbol will go through the global
   1865  1.1.1.1.2.2  pgoyette      offset table.  The dynamic linker will use the .dynsym entry to
   1866  1.1.1.1.2.2  pgoyette      determine the address it must put in the global offset table, so
   1867  1.1.1.1.2.2  pgoyette      both the dynamic object and the regular object will refer to the
   1868  1.1.1.1.2.2  pgoyette      same memory location for the variable.  */
   1869  1.1.1.1.2.2  pgoyette 
   1870  1.1.1.1.2.2  pgoyette   /* We must generate a R_386_COPY/R_X86_64_COPY reloc to tell the
   1871  1.1.1.1.2.2  pgoyette      dynamic linker to copy the initial value out of the dynamic object
   1872  1.1.1.1.2.2  pgoyette      and into the runtime process image.  */
   1873  1.1.1.1.2.2  pgoyette   if ((h->root.u.def.section->flags & SEC_READONLY) != 0)
   1874  1.1.1.1.2.2  pgoyette     {
   1875  1.1.1.1.2.2  pgoyette       s = htab->elf.sdynrelro;
   1876  1.1.1.1.2.2  pgoyette       srel = htab->elf.sreldynrelro;
   1877  1.1.1.1.2.2  pgoyette     }
   1878  1.1.1.1.2.2  pgoyette   else
   1879  1.1.1.1.2.2  pgoyette     {
   1880  1.1.1.1.2.2  pgoyette       s = htab->elf.sdynbss;
   1881  1.1.1.1.2.2  pgoyette       srel = htab->elf.srelbss;
   1882  1.1.1.1.2.2  pgoyette     }
   1883  1.1.1.1.2.2  pgoyette   if ((h->root.u.def.section->flags & SEC_ALLOC) != 0 && h->size != 0)
   1884  1.1.1.1.2.2  pgoyette     {
   1885  1.1.1.1.2.2  pgoyette       srel->size += htab->sizeof_reloc;
   1886  1.1.1.1.2.2  pgoyette       h->needs_copy = 1;
   1887  1.1.1.1.2.2  pgoyette     }
   1888  1.1.1.1.2.2  pgoyette 
   1889  1.1.1.1.2.2  pgoyette   return _bfd_elf_adjust_dynamic_copy (info, h, s);
   1890  1.1.1.1.2.2  pgoyette }
   1891  1.1.1.1.2.2  pgoyette 
   1892  1.1.1.1.2.2  pgoyette void
   1893  1.1.1.1.2.2  pgoyette _bfd_x86_elf_hide_symbol (struct bfd_link_info *info,
   1894  1.1.1.1.2.2  pgoyette 			  struct elf_link_hash_entry *h,
   1895  1.1.1.1.2.2  pgoyette 			  bfd_boolean force_local)
   1896  1.1.1.1.2.2  pgoyette {
   1897  1.1.1.1.2.2  pgoyette   if (h->root.type == bfd_link_hash_undefweak
   1898  1.1.1.1.2.2  pgoyette       && info->nointerp
   1899  1.1.1.1.2.2  pgoyette       && bfd_link_pie (info))
   1900  1.1.1.1.2.2  pgoyette     {
   1901  1.1.1.1.2.2  pgoyette       /* When there is no dynamic interpreter in PIE, make the undefined
   1902  1.1.1.1.2.2  pgoyette 	 weak symbol dynamic so that PC relative branch to the undefined
   1903  1.1.1.1.2.2  pgoyette 	 weak symbol will land to address 0.  */
   1904  1.1.1.1.2.2  pgoyette       struct elf_x86_link_hash_entry *eh = elf_x86_hash_entry (h);
   1905  1.1.1.1.2.2  pgoyette       if (h->plt.refcount > 0
   1906  1.1.1.1.2.2  pgoyette 	  || eh->plt_got.refcount > 0)
   1907  1.1.1.1.2.2  pgoyette 	return;
   1908  1.1.1.1.2.2  pgoyette     }
   1909  1.1.1.1.2.2  pgoyette 
   1910  1.1.1.1.2.2  pgoyette   _bfd_elf_link_hash_hide_symbol (info, h, force_local);
   1911  1.1.1.1.2.2  pgoyette }
   1912  1.1.1.1.2.2  pgoyette 
   1913  1.1.1.1.2.2  pgoyette /* Return TRUE if a symbol is referenced locally.  It is similar to
   1914  1.1.1.1.2.2  pgoyette    SYMBOL_REFERENCES_LOCAL, but it also checks version script.  It
   1915  1.1.1.1.2.2  pgoyette    works in check_relocs.  */
   1916  1.1.1.1.2.2  pgoyette 
   1917  1.1.1.1.2.2  pgoyette bfd_boolean
   1918  1.1.1.1.2.2  pgoyette _bfd_x86_elf_link_symbol_references_local (struct bfd_link_info *info,
   1919  1.1.1.1.2.2  pgoyette 					   struct elf_link_hash_entry *h)
   1920  1.1.1.1.2.2  pgoyette {
   1921  1.1.1.1.2.2  pgoyette   struct elf_x86_link_hash_entry *eh = elf_x86_hash_entry (h);
   1922  1.1.1.1.2.2  pgoyette   struct elf_x86_link_hash_table *htab
   1923  1.1.1.1.2.2  pgoyette     = (struct elf_x86_link_hash_table *) info->hash;
   1924  1.1.1.1.2.2  pgoyette 
   1925  1.1.1.1.2.2  pgoyette   if (eh->local_ref > 1)
   1926  1.1.1.1.2.2  pgoyette     return TRUE;
   1927  1.1.1.1.2.2  pgoyette 
   1928  1.1.1.1.2.2  pgoyette   if (eh->local_ref == 1)
   1929  1.1.1.1.2.2  pgoyette     return FALSE;
   1930  1.1.1.1.2.2  pgoyette 
   1931  1.1.1.1.2.2  pgoyette   /* Unversioned symbols defined in regular objects can be forced local
   1932  1.1.1.1.2.2  pgoyette      by linker version script.  A weak undefined symbol is forced local
   1933  1.1.1.1.2.2  pgoyette      if
   1934  1.1.1.1.2.2  pgoyette      1. It has non-default visibility.  Or
   1935  1.1.1.1.2.2  pgoyette      2. When building executable, there is no dynamic linker.  Or
   1936  1.1.1.1.2.2  pgoyette      3. or "-z nodynamic-undefined-weak" is used.
   1937  1.1.1.1.2.2  pgoyette    */
   1938  1.1.1.1.2.2  pgoyette   if (SYMBOL_REFERENCES_LOCAL (info, h)
   1939  1.1.1.1.2.2  pgoyette       || (h->root.type == bfd_link_hash_undefweak
   1940  1.1.1.1.2.2  pgoyette 	  && (ELF_ST_VISIBILITY (h->other) != STV_DEFAULT
   1941  1.1.1.1.2.2  pgoyette 	      || (bfd_link_executable (info)
   1942  1.1.1.1.2.2  pgoyette 		  && htab->interp == NULL)
   1943  1.1.1.1.2.2  pgoyette 	      || info->dynamic_undefined_weak == 0))
   1944  1.1.1.1.2.2  pgoyette       || ((h->def_regular || ELF_COMMON_DEF_P (h))
   1945  1.1.1.1.2.2  pgoyette 	  && h->versioned == unversioned
   1946  1.1.1.1.2.2  pgoyette 	  && info->version_info != NULL
   1947  1.1.1.1.2.2  pgoyette 	  && bfd_hide_sym_by_version (info->version_info,
   1948  1.1.1.1.2.2  pgoyette 				      h->root.root.string)))
   1949  1.1.1.1.2.2  pgoyette     {
   1950  1.1.1.1.2.2  pgoyette       eh->local_ref = 2;
   1951  1.1.1.1.2.2  pgoyette       return TRUE;
   1952  1.1.1.1.2.2  pgoyette     }
   1953  1.1.1.1.2.2  pgoyette 
   1954  1.1.1.1.2.2  pgoyette   eh->local_ref = 1;
   1955  1.1.1.1.2.2  pgoyette   return FALSE;
   1956  1.1.1.1.2.2  pgoyette }
   1957  1.1.1.1.2.2  pgoyette 
   1958  1.1.1.1.2.2  pgoyette /* Return the section that should be marked against GC for a given
   1959  1.1.1.1.2.2  pgoyette    relocation.	*/
   1960  1.1.1.1.2.2  pgoyette 
   1961  1.1.1.1.2.2  pgoyette asection *
   1962  1.1.1.1.2.2  pgoyette _bfd_x86_elf_gc_mark_hook (asection *sec,
   1963  1.1.1.1.2.2  pgoyette 			   struct bfd_link_info *info,
   1964  1.1.1.1.2.2  pgoyette 			   Elf_Internal_Rela *rel,
   1965  1.1.1.1.2.2  pgoyette 			   struct elf_link_hash_entry *h,
   1966  1.1.1.1.2.2  pgoyette 			   Elf_Internal_Sym *sym)
   1967  1.1.1.1.2.2  pgoyette {
   1968  1.1.1.1.2.2  pgoyette   /* Compiler should optimize this out.  */
   1969  1.1.1.1.2.2  pgoyette   if (((unsigned int) R_X86_64_GNU_VTINHERIT
   1970  1.1.1.1.2.2  pgoyette        != (unsigned int) R_386_GNU_VTINHERIT)
   1971  1.1.1.1.2.2  pgoyette       || ((unsigned int) R_X86_64_GNU_VTENTRY
   1972  1.1.1.1.2.2  pgoyette 	  != (unsigned int) R_386_GNU_VTENTRY))
   1973  1.1.1.1.2.2  pgoyette     abort ();
   1974  1.1.1.1.2.2  pgoyette 
   1975  1.1.1.1.2.2  pgoyette   if (h != NULL)
   1976  1.1.1.1.2.2  pgoyette     switch (ELF32_R_TYPE (rel->r_info))
   1977  1.1.1.1.2.2  pgoyette       {
   1978  1.1.1.1.2.2  pgoyette       case R_X86_64_GNU_VTINHERIT:
   1979  1.1.1.1.2.2  pgoyette       case R_X86_64_GNU_VTENTRY:
   1980  1.1.1.1.2.2  pgoyette 	return NULL;
   1981  1.1.1.1.2.2  pgoyette       }
   1982  1.1.1.1.2.2  pgoyette 
   1983  1.1.1.1.2.2  pgoyette   return _bfd_elf_gc_mark_hook (sec, info, rel, h, sym);
   1984  1.1.1.1.2.2  pgoyette }
   1985  1.1.1.1.2.2  pgoyette 
   1986  1.1.1.1.2.2  pgoyette static bfd_vma
   1987  1.1.1.1.2.2  pgoyette elf_i386_get_plt_got_vma (struct elf_x86_plt *plt_p ATTRIBUTE_UNUSED,
   1988  1.1.1.1.2.2  pgoyette 			  bfd_vma off,
   1989  1.1.1.1.2.2  pgoyette 			  bfd_vma offset ATTRIBUTE_UNUSED,
   1990  1.1.1.1.2.2  pgoyette 			  bfd_vma got_addr)
   1991  1.1.1.1.2.2  pgoyette {
   1992  1.1.1.1.2.2  pgoyette   return got_addr + off;
   1993  1.1.1.1.2.2  pgoyette }
   1994  1.1.1.1.2.2  pgoyette 
   1995  1.1.1.1.2.2  pgoyette static bfd_vma
   1996  1.1.1.1.2.2  pgoyette elf_x86_64_get_plt_got_vma (struct elf_x86_plt *plt_p,
   1997  1.1.1.1.2.2  pgoyette 			    bfd_vma off,
   1998  1.1.1.1.2.2  pgoyette 			    bfd_vma offset,
   1999  1.1.1.1.2.2  pgoyette 			    bfd_vma got_addr ATTRIBUTE_UNUSED)
   2000  1.1.1.1.2.2  pgoyette {
   2001  1.1.1.1.2.2  pgoyette   return plt_p->sec->vma + offset + off + plt_p->plt_got_insn_size;
   2002  1.1.1.1.2.2  pgoyette }
   2003  1.1.1.1.2.2  pgoyette 
   2004  1.1.1.1.2.2  pgoyette static bfd_boolean
   2005  1.1.1.1.2.2  pgoyette elf_i386_valid_plt_reloc_p (unsigned int type)
   2006  1.1.1.1.2.2  pgoyette {
   2007  1.1.1.1.2.2  pgoyette   return (type == R_386_JUMP_SLOT
   2008  1.1.1.1.2.2  pgoyette 	  || type == R_386_GLOB_DAT
   2009  1.1.1.1.2.2  pgoyette 	  || type == R_386_IRELATIVE);
   2010  1.1.1.1.2.2  pgoyette }
   2011  1.1.1.1.2.2  pgoyette 
   2012  1.1.1.1.2.2  pgoyette static bfd_boolean
   2013  1.1.1.1.2.2  pgoyette elf_x86_64_valid_plt_reloc_p (unsigned int type)
   2014  1.1.1.1.2.2  pgoyette {
   2015  1.1.1.1.2.2  pgoyette   return (type == R_X86_64_JUMP_SLOT
   2016  1.1.1.1.2.2  pgoyette 	  || type == R_X86_64_GLOB_DAT
   2017  1.1.1.1.2.2  pgoyette 	  || type == R_X86_64_IRELATIVE);
   2018  1.1.1.1.2.2  pgoyette }
   2019  1.1.1.1.2.2  pgoyette 
   2020  1.1.1.1.2.2  pgoyette long
   2021  1.1.1.1.2.2  pgoyette _bfd_x86_elf_get_synthetic_symtab (bfd *abfd,
   2022  1.1.1.1.2.2  pgoyette 				   long count,
   2023  1.1.1.1.2.2  pgoyette 				   long relsize,
   2024  1.1.1.1.2.2  pgoyette 				   bfd_vma got_addr,
   2025  1.1.1.1.2.2  pgoyette 				   struct elf_x86_plt plts[],
   2026  1.1.1.1.2.2  pgoyette 				   asymbol **dynsyms,
   2027  1.1.1.1.2.2  pgoyette 				   asymbol **ret)
   2028  1.1.1.1.2.2  pgoyette {
   2029  1.1.1.1.2.2  pgoyette   long size, i, n, len;
   2030  1.1.1.1.2.2  pgoyette   int j;
   2031  1.1.1.1.2.2  pgoyette   unsigned int plt_got_offset, plt_entry_size;
   2032  1.1.1.1.2.2  pgoyette   asymbol *s;
   2033  1.1.1.1.2.2  pgoyette   bfd_byte *plt_contents;
   2034  1.1.1.1.2.2  pgoyette   long dynrelcount;
   2035  1.1.1.1.2.2  pgoyette   arelent **dynrelbuf, *p;
   2036  1.1.1.1.2.2  pgoyette   char *names;
   2037  1.1.1.1.2.2  pgoyette   const struct elf_backend_data *bed;
   2038  1.1.1.1.2.2  pgoyette   bfd_vma (*get_plt_got_vma) (struct elf_x86_plt *, bfd_vma, bfd_vma,
   2039  1.1.1.1.2.2  pgoyette 			      bfd_vma);
   2040  1.1.1.1.2.2  pgoyette   bfd_boolean (*valid_plt_reloc_p) (unsigned int);
   2041  1.1.1.1.2.2  pgoyette 
   2042  1.1.1.1.2.2  pgoyette   if (count == 0)
   2043  1.1.1.1.2.2  pgoyette     return -1;
   2044  1.1.1.1.2.2  pgoyette 
   2045  1.1.1.1.2.2  pgoyette   dynrelbuf = (arelent **) bfd_malloc (relsize);
   2046  1.1.1.1.2.2  pgoyette   if (dynrelbuf == NULL)
   2047  1.1.1.1.2.2  pgoyette     return -1;
   2048  1.1.1.1.2.2  pgoyette 
   2049  1.1.1.1.2.2  pgoyette   dynrelcount = bfd_canonicalize_dynamic_reloc (abfd, dynrelbuf,
   2050  1.1.1.1.2.2  pgoyette 						dynsyms);
   2051  1.1.1.1.2.2  pgoyette   if (dynrelcount <= 0)
   2052  1.1.1.1.2.2  pgoyette     return -1;
   2053  1.1.1.1.2.2  pgoyette 
   2054  1.1.1.1.2.2  pgoyette   /* Sort the relocs by address.  */
   2055  1.1.1.1.2.2  pgoyette   qsort (dynrelbuf, dynrelcount, sizeof (arelent *),
   2056  1.1.1.1.2.2  pgoyette 	 _bfd_x86_elf_compare_relocs);
   2057  1.1.1.1.2.2  pgoyette 
   2058  1.1.1.1.2.2  pgoyette   size = count * sizeof (asymbol);
   2059  1.1.1.1.2.2  pgoyette 
   2060  1.1.1.1.2.2  pgoyette   /* Allocate space for @plt suffixes.  */
   2061  1.1.1.1.2.2  pgoyette   n = 0;
   2062  1.1.1.1.2.2  pgoyette   for (i = 0; i < dynrelcount; i++)
   2063  1.1.1.1.2.2  pgoyette     {
   2064  1.1.1.1.2.2  pgoyette       p = dynrelbuf[i];
   2065  1.1.1.1.2.2  pgoyette       size += strlen ((*p->sym_ptr_ptr)->name) + sizeof ("@plt");
   2066  1.1.1.1.2.2  pgoyette       if (p->addend != 0)
   2067  1.1.1.1.2.2  pgoyette 	size += sizeof ("+0x") - 1 + 8 + 8 * ABI_64_P (abfd);
   2068  1.1.1.1.2.2  pgoyette     }
   2069  1.1.1.1.2.2  pgoyette 
   2070  1.1.1.1.2.2  pgoyette   s = *ret = (asymbol *) bfd_zmalloc (size);
   2071  1.1.1.1.2.2  pgoyette   if (s == NULL)
   2072  1.1.1.1.2.2  pgoyette     goto bad_return;
   2073  1.1.1.1.2.2  pgoyette 
   2074  1.1.1.1.2.2  pgoyette   bed = get_elf_backend_data (abfd);
   2075  1.1.1.1.2.2  pgoyette 
   2076  1.1.1.1.2.2  pgoyette   if (bed->target_id == X86_64_ELF_DATA)
   2077  1.1.1.1.2.2  pgoyette     {
   2078  1.1.1.1.2.2  pgoyette       get_plt_got_vma = elf_x86_64_get_plt_got_vma;
   2079  1.1.1.1.2.2  pgoyette       valid_plt_reloc_p = elf_x86_64_valid_plt_reloc_p;
   2080  1.1.1.1.2.2  pgoyette     }
   2081  1.1.1.1.2.2  pgoyette   else
   2082  1.1.1.1.2.2  pgoyette     {
   2083  1.1.1.1.2.2  pgoyette       get_plt_got_vma = elf_i386_get_plt_got_vma;
   2084  1.1.1.1.2.2  pgoyette       valid_plt_reloc_p = elf_i386_valid_plt_reloc_p;
   2085  1.1.1.1.2.2  pgoyette       if (got_addr)
   2086  1.1.1.1.2.2  pgoyette 	{
   2087  1.1.1.1.2.2  pgoyette 	  /* Check .got.plt and then .got to get the _GLOBAL_OFFSET_TABLE_
   2088  1.1.1.1.2.2  pgoyette 	     address.  */
   2089  1.1.1.1.2.2  pgoyette 	  asection *sec = bfd_get_section_by_name (abfd, ".got.plt");
   2090  1.1.1.1.2.2  pgoyette 	  if (sec != NULL)
   2091  1.1.1.1.2.2  pgoyette 	    got_addr = sec->vma;
   2092  1.1.1.1.2.2  pgoyette 	  else
   2093  1.1.1.1.2.2  pgoyette 	    {
   2094  1.1.1.1.2.2  pgoyette 	      sec = bfd_get_section_by_name (abfd, ".got");
   2095  1.1.1.1.2.2  pgoyette 	      if (sec != NULL)
   2096  1.1.1.1.2.2  pgoyette 		got_addr = sec->vma;
   2097  1.1.1.1.2.2  pgoyette 	    }
   2098  1.1.1.1.2.2  pgoyette 
   2099  1.1.1.1.2.2  pgoyette 	  if (got_addr == (bfd_vma) -1)
   2100  1.1.1.1.2.2  pgoyette 	    goto bad_return;
   2101  1.1.1.1.2.2  pgoyette 	}
   2102  1.1.1.1.2.2  pgoyette     }
   2103  1.1.1.1.2.2  pgoyette 
   2104  1.1.1.1.2.2  pgoyette   /* Check for each PLT section.  */
   2105  1.1.1.1.2.2  pgoyette   names = (char *) (s + count);
   2106  1.1.1.1.2.2  pgoyette   size = 0;
   2107  1.1.1.1.2.2  pgoyette   n = 0;
   2108  1.1.1.1.2.2  pgoyette   for (j = 0; plts[j].name != NULL; j++)
   2109  1.1.1.1.2.2  pgoyette     if ((plt_contents = plts[j].contents) != NULL)
   2110  1.1.1.1.2.2  pgoyette       {
   2111  1.1.1.1.2.2  pgoyette 	long k;
   2112  1.1.1.1.2.2  pgoyette 	bfd_vma offset;
   2113  1.1.1.1.2.2  pgoyette 	asection *plt;
   2114  1.1.1.1.2.2  pgoyette 	struct elf_x86_plt *plt_p = &plts[j];
   2115  1.1.1.1.2.2  pgoyette 
   2116  1.1.1.1.2.2  pgoyette 	plt_got_offset = plt_p->plt_got_offset;
   2117  1.1.1.1.2.2  pgoyette 	plt_entry_size = plt_p->plt_entry_size;
   2118  1.1.1.1.2.2  pgoyette 
   2119  1.1.1.1.2.2  pgoyette 	plt = plt_p->sec;
   2120  1.1.1.1.2.2  pgoyette 
   2121  1.1.1.1.2.2  pgoyette 	if ((plt_p->type & plt_lazy))
   2122  1.1.1.1.2.2  pgoyette 	  {
   2123  1.1.1.1.2.2  pgoyette 	    /* Skip PLT0 in lazy PLT.  */
   2124  1.1.1.1.2.2  pgoyette 	    k = 1;
   2125  1.1.1.1.2.2  pgoyette 	    offset = plt_entry_size;
   2126  1.1.1.1.2.2  pgoyette 	  }
   2127  1.1.1.1.2.2  pgoyette 	else
   2128  1.1.1.1.2.2  pgoyette 	  {
   2129  1.1.1.1.2.2  pgoyette 	    k = 0;
   2130  1.1.1.1.2.2  pgoyette 	    offset = 0;
   2131  1.1.1.1.2.2  pgoyette 	  }
   2132  1.1.1.1.2.2  pgoyette 
   2133  1.1.1.1.2.2  pgoyette 	/* Check each PLT entry against dynamic relocations.  */
   2134  1.1.1.1.2.2  pgoyette 	for (; k < plt_p->count; k++)
   2135  1.1.1.1.2.2  pgoyette 	  {
   2136  1.1.1.1.2.2  pgoyette 	    int off;
   2137  1.1.1.1.2.2  pgoyette 	    bfd_vma got_vma;
   2138  1.1.1.1.2.2  pgoyette 	    long min, max, mid;
   2139  1.1.1.1.2.2  pgoyette 
   2140  1.1.1.1.2.2  pgoyette 	    /* Get the GOT offset for i386 or the PC-relative offset
   2141  1.1.1.1.2.2  pgoyette 	       for x86-64, a signed 32-bit integer.  */
   2142  1.1.1.1.2.2  pgoyette 	    off = H_GET_32 (abfd, (plt_contents + offset
   2143  1.1.1.1.2.2  pgoyette 				   + plt_got_offset));
   2144  1.1.1.1.2.2  pgoyette 	    got_vma = get_plt_got_vma (plt_p, off, offset, got_addr);
   2145  1.1.1.1.2.2  pgoyette 
   2146  1.1.1.1.2.2  pgoyette 	    /* Binary search.  */
   2147  1.1.1.1.2.2  pgoyette 	    p = dynrelbuf[0];
   2148  1.1.1.1.2.2  pgoyette 	    min = 0;
   2149  1.1.1.1.2.2  pgoyette 	    max = dynrelcount;
   2150  1.1.1.1.2.2  pgoyette 	    while ((min + 1) < max)
   2151  1.1.1.1.2.2  pgoyette 	      {
   2152  1.1.1.1.2.2  pgoyette 		arelent *r;
   2153  1.1.1.1.2.2  pgoyette 
   2154  1.1.1.1.2.2  pgoyette 		mid = (min + max) / 2;
   2155  1.1.1.1.2.2  pgoyette 		r = dynrelbuf[mid];
   2156  1.1.1.1.2.2  pgoyette 		if (got_vma > r->address)
   2157  1.1.1.1.2.2  pgoyette 		  min = mid;
   2158  1.1.1.1.2.2  pgoyette 		else if (got_vma < r->address)
   2159  1.1.1.1.2.2  pgoyette 		  max = mid;
   2160  1.1.1.1.2.2  pgoyette 		else
   2161  1.1.1.1.2.2  pgoyette 		  {
   2162  1.1.1.1.2.2  pgoyette 		    p = r;
   2163  1.1.1.1.2.2  pgoyette 		    break;
   2164  1.1.1.1.2.2  pgoyette 		  }
   2165  1.1.1.1.2.2  pgoyette 	      }
   2166  1.1.1.1.2.2  pgoyette 
   2167  1.1.1.1.2.2  pgoyette 	    /* Skip unknown relocation.  PR 17512: file: bc9d6cf5.  */
   2168  1.1.1.1.2.2  pgoyette 	    if (got_vma == p->address
   2169  1.1.1.1.2.2  pgoyette 		&& p->howto != NULL
   2170  1.1.1.1.2.2  pgoyette 		&& valid_plt_reloc_p (p->howto->type))
   2171  1.1.1.1.2.2  pgoyette 	      {
   2172  1.1.1.1.2.2  pgoyette 		*s = **p->sym_ptr_ptr;
   2173  1.1.1.1.2.2  pgoyette 		/* Undefined syms won't have BSF_LOCAL or BSF_GLOBAL
   2174  1.1.1.1.2.2  pgoyette 		   set.  Since we are defining a symbol, ensure one
   2175  1.1.1.1.2.2  pgoyette 		   of them is set.  */
   2176  1.1.1.1.2.2  pgoyette 		if ((s->flags & BSF_LOCAL) == 0)
   2177  1.1.1.1.2.2  pgoyette 		  s->flags |= BSF_GLOBAL;
   2178  1.1.1.1.2.2  pgoyette 		s->flags |= BSF_SYNTHETIC;
   2179  1.1.1.1.2.2  pgoyette 		/* This is no longer a section symbol.  */
   2180  1.1.1.1.2.2  pgoyette 		s->flags &= ~BSF_SECTION_SYM;
   2181  1.1.1.1.2.2  pgoyette 		s->section = plt;
   2182  1.1.1.1.2.2  pgoyette 		s->the_bfd = plt->owner;
   2183  1.1.1.1.2.2  pgoyette 		s->value = offset;
   2184  1.1.1.1.2.2  pgoyette 		s->udata.p = NULL;
   2185  1.1.1.1.2.2  pgoyette 		s->name = names;
   2186  1.1.1.1.2.2  pgoyette 		len = strlen ((*p->sym_ptr_ptr)->name);
   2187  1.1.1.1.2.2  pgoyette 		memcpy (names, (*p->sym_ptr_ptr)->name, len);
   2188  1.1.1.1.2.2  pgoyette 		names += len;
   2189  1.1.1.1.2.2  pgoyette 		if (p->addend != 0)
   2190  1.1.1.1.2.2  pgoyette 		  {
   2191  1.1.1.1.2.2  pgoyette 		    char buf[30], *a;
   2192  1.1.1.1.2.2  pgoyette 
   2193  1.1.1.1.2.2  pgoyette 		    memcpy (names, "+0x", sizeof ("+0x") - 1);
   2194  1.1.1.1.2.2  pgoyette 		    names += sizeof ("+0x") - 1;
   2195  1.1.1.1.2.2  pgoyette 		    bfd_sprintf_vma (abfd, buf, p->addend);
   2196  1.1.1.1.2.2  pgoyette 		    for (a = buf; *a == '0'; ++a)
   2197  1.1.1.1.2.2  pgoyette 		      ;
   2198  1.1.1.1.2.2  pgoyette 		    size = strlen (a);
   2199  1.1.1.1.2.2  pgoyette 		    memcpy (names, a, size);
   2200  1.1.1.1.2.2  pgoyette 		    names += size;
   2201  1.1.1.1.2.2  pgoyette 		  }
   2202  1.1.1.1.2.2  pgoyette 		memcpy (names, "@plt", sizeof ("@plt"));
   2203  1.1.1.1.2.2  pgoyette 		names += sizeof ("@plt");
   2204  1.1.1.1.2.2  pgoyette 		n++;
   2205  1.1.1.1.2.2  pgoyette 		s++;
   2206  1.1.1.1.2.2  pgoyette 		/* There should be only one entry in PLT for a given
   2207  1.1.1.1.2.2  pgoyette 		   symbol.  Set howto to NULL after processing a PLT
   2208  1.1.1.1.2.2  pgoyette 		   entry to guard against corrupted PLT.  */
   2209  1.1.1.1.2.2  pgoyette 		p->howto = NULL;
   2210  1.1.1.1.2.2  pgoyette 	      }
   2211  1.1.1.1.2.2  pgoyette 	    offset += plt_entry_size;
   2212  1.1.1.1.2.2  pgoyette 	  }
   2213  1.1.1.1.2.2  pgoyette       }
   2214  1.1.1.1.2.2  pgoyette 
   2215  1.1.1.1.2.2  pgoyette   /* PLT entries with R_386_TLS_DESC relocations are skipped.  */
   2216  1.1.1.1.2.2  pgoyette   if (n == 0)
   2217  1.1.1.1.2.2  pgoyette     {
   2218  1.1.1.1.2.2  pgoyette bad_return:
   2219  1.1.1.1.2.2  pgoyette       count = -1;
   2220  1.1.1.1.2.2  pgoyette     }
   2221  1.1.1.1.2.2  pgoyette   else
   2222  1.1.1.1.2.2  pgoyette     count = n;
   2223  1.1.1.1.2.2  pgoyette 
   2224  1.1.1.1.2.2  pgoyette   for (j = 0; plts[j].name != NULL; j++)
   2225  1.1.1.1.2.2  pgoyette     if (plts[j].contents != NULL)
   2226  1.1.1.1.2.2  pgoyette       free (plts[j].contents);
   2227  1.1.1.1.2.2  pgoyette 
   2228  1.1.1.1.2.2  pgoyette   free (dynrelbuf);
   2229  1.1.1.1.2.2  pgoyette 
   2230  1.1.1.1.2.2  pgoyette   return count;
   2231  1.1.1.1.2.2  pgoyette }
   2232  1.1.1.1.2.2  pgoyette 
   2233  1.1.1.1.2.2  pgoyette /* Parse x86 GNU properties.  */
   2234  1.1.1.1.2.2  pgoyette 
   2235  1.1.1.1.2.2  pgoyette enum elf_property_kind
   2236  1.1.1.1.2.2  pgoyette _bfd_x86_elf_parse_gnu_properties (bfd *abfd, unsigned int type,
   2237  1.1.1.1.2.2  pgoyette 				   bfd_byte *ptr, unsigned int datasz)
   2238  1.1.1.1.2.2  pgoyette {
   2239  1.1.1.1.2.2  pgoyette   elf_property *prop;
   2240  1.1.1.1.2.2  pgoyette 
   2241  1.1.1.1.2.2  pgoyette   switch (type)
   2242  1.1.1.1.2.2  pgoyette     {
   2243  1.1.1.1.2.2  pgoyette     case GNU_PROPERTY_X86_ISA_1_USED:
   2244  1.1.1.1.2.2  pgoyette     case GNU_PROPERTY_X86_ISA_1_NEEDED:
   2245  1.1.1.1.2.2  pgoyette     case GNU_PROPERTY_X86_FEATURE_1_AND:
   2246  1.1.1.1.2.2  pgoyette       if (datasz != 4)
   2247  1.1.1.1.2.2  pgoyette 	{
   2248  1.1.1.1.2.2  pgoyette 	  _bfd_error_handler
   2249  1.1.1.1.2.2  pgoyette 	    ((type == GNU_PROPERTY_X86_ISA_1_USED
   2250  1.1.1.1.2.2  pgoyette 	      ? _("error: %B: <corrupt x86 ISA used size: 0x%x>")
   2251  1.1.1.1.2.2  pgoyette 	      : (type == GNU_PROPERTY_X86_ISA_1_NEEDED
   2252  1.1.1.1.2.2  pgoyette 		 ? _("error: %B: <corrupt x86 ISA needed size: 0x%x>")
   2253  1.1.1.1.2.2  pgoyette 		 : _("error: %B: <corrupt x86 feature size: 0x%x>"))),
   2254  1.1.1.1.2.2  pgoyette 	     abfd, datasz);
   2255  1.1.1.1.2.2  pgoyette 	  return property_corrupt;
   2256  1.1.1.1.2.2  pgoyette 	}
   2257  1.1.1.1.2.2  pgoyette       prop = _bfd_elf_get_property (abfd, type, datasz);
   2258  1.1.1.1.2.2  pgoyette       /* Combine properties of the same type.  */
   2259  1.1.1.1.2.2  pgoyette       prop->u.number |= bfd_h_get_32 (abfd, ptr);
   2260  1.1.1.1.2.2  pgoyette       prop->pr_kind = property_number;
   2261  1.1.1.1.2.2  pgoyette       break;
   2262  1.1.1.1.2.2  pgoyette 
   2263  1.1.1.1.2.2  pgoyette     default:
   2264  1.1.1.1.2.2  pgoyette       return property_ignored;
   2265  1.1.1.1.2.2  pgoyette     }
   2266  1.1.1.1.2.2  pgoyette 
   2267  1.1.1.1.2.2  pgoyette   return property_number;
   2268  1.1.1.1.2.2  pgoyette }
   2269  1.1.1.1.2.2  pgoyette 
   2270  1.1.1.1.2.2  pgoyette /* Merge x86 GNU property BPROP with APROP.  If APROP isn't NULL,
   2271  1.1.1.1.2.2  pgoyette    return TRUE if APROP is updated.  Otherwise, return TRUE if BPROP
   2272  1.1.1.1.2.2  pgoyette    should be merged with ABFD.  */
   2273  1.1.1.1.2.2  pgoyette 
   2274  1.1.1.1.2.2  pgoyette bfd_boolean
   2275  1.1.1.1.2.2  pgoyette _bfd_x86_elf_merge_gnu_properties (struct bfd_link_info *info,
   2276  1.1.1.1.2.2  pgoyette 				   bfd *abfd ATTRIBUTE_UNUSED,
   2277  1.1.1.1.2.2  pgoyette 				   elf_property *aprop,
   2278  1.1.1.1.2.2  pgoyette 				   elf_property *bprop)
   2279  1.1.1.1.2.2  pgoyette {
   2280  1.1.1.1.2.2  pgoyette   unsigned int number, features;
   2281  1.1.1.1.2.2  pgoyette   bfd_boolean updated = FALSE;
   2282  1.1.1.1.2.2  pgoyette   unsigned int pr_type = aprop != NULL ? aprop->pr_type : bprop->pr_type;
   2283  1.1.1.1.2.2  pgoyette 
   2284  1.1.1.1.2.2  pgoyette   switch (pr_type)
   2285  1.1.1.1.2.2  pgoyette     {
   2286  1.1.1.1.2.2  pgoyette     case GNU_PROPERTY_X86_ISA_1_USED:
   2287  1.1.1.1.2.2  pgoyette     case GNU_PROPERTY_X86_ISA_1_NEEDED:
   2288  1.1.1.1.2.2  pgoyette       if (aprop != NULL && bprop != NULL)
   2289  1.1.1.1.2.2  pgoyette 	{
   2290  1.1.1.1.2.2  pgoyette 	  number = aprop->u.number;
   2291  1.1.1.1.2.2  pgoyette 	  aprop->u.number = number | bprop->u.number;
   2292  1.1.1.1.2.2  pgoyette 	  updated = number != (unsigned int) aprop->u.number;
   2293  1.1.1.1.2.2  pgoyette 	}
   2294  1.1.1.1.2.2  pgoyette       else
   2295  1.1.1.1.2.2  pgoyette 	{
   2296  1.1.1.1.2.2  pgoyette 	  /* Return TRUE if APROP is NULL to indicate that BPROP should
   2297  1.1.1.1.2.2  pgoyette 	     be added to ABFD.  */
   2298  1.1.1.1.2.2  pgoyette 	  updated = aprop == NULL;
   2299  1.1.1.1.2.2  pgoyette 	}
   2300  1.1.1.1.2.2  pgoyette       break;
   2301  1.1.1.1.2.2  pgoyette 
   2302  1.1.1.1.2.2  pgoyette     case GNU_PROPERTY_X86_FEATURE_1_AND:
   2303  1.1.1.1.2.2  pgoyette       /* Only one of APROP and BPROP can be NULL:
   2304  1.1.1.1.2.2  pgoyette 	 1. APROP & BPROP when both APROP and BPROP aren't NULL.
   2305  1.1.1.1.2.2  pgoyette 	 2. If APROP is NULL, remove x86 feature.
   2306  1.1.1.1.2.2  pgoyette 	 3. Otherwise, do nothing.
   2307  1.1.1.1.2.2  pgoyette        */
   2308  1.1.1.1.2.2  pgoyette       if (aprop != NULL && bprop != NULL)
   2309  1.1.1.1.2.2  pgoyette 	{
   2310  1.1.1.1.2.2  pgoyette 	  features = 0;
   2311  1.1.1.1.2.2  pgoyette 	  if (info->ibt)
   2312  1.1.1.1.2.2  pgoyette 	    features = GNU_PROPERTY_X86_FEATURE_1_IBT;
   2313  1.1.1.1.2.2  pgoyette 	  if (info->shstk)
   2314  1.1.1.1.2.2  pgoyette 	    features |= GNU_PROPERTY_X86_FEATURE_1_SHSTK;
   2315  1.1.1.1.2.2  pgoyette 	  number = aprop->u.number;
   2316  1.1.1.1.2.2  pgoyette 	  /* Add GNU_PROPERTY_X86_FEATURE_1_IBT and
   2317  1.1.1.1.2.2  pgoyette 	     GNU_PROPERTY_X86_FEATURE_1_SHSTK.  */
   2318  1.1.1.1.2.2  pgoyette 	  aprop->u.number = (number & bprop->u.number) | features;
   2319  1.1.1.1.2.2  pgoyette 	  updated = number != (unsigned int) aprop->u.number;
   2320  1.1.1.1.2.2  pgoyette 	  /* Remove the property if all feature bits are cleared.  */
   2321  1.1.1.1.2.2  pgoyette 	  if (aprop->u.number == 0)
   2322  1.1.1.1.2.2  pgoyette 	    aprop->pr_kind = property_remove;
   2323  1.1.1.1.2.2  pgoyette 	}
   2324  1.1.1.1.2.2  pgoyette       else
   2325  1.1.1.1.2.2  pgoyette 	{
   2326  1.1.1.1.2.2  pgoyette 	  features = 0;
   2327  1.1.1.1.2.2  pgoyette 	  if (info->ibt)
   2328  1.1.1.1.2.2  pgoyette 	    features = GNU_PROPERTY_X86_FEATURE_1_IBT;
   2329  1.1.1.1.2.2  pgoyette 	  if (info->shstk)
   2330  1.1.1.1.2.2  pgoyette 	    features |= GNU_PROPERTY_X86_FEATURE_1_SHSTK;
   2331  1.1.1.1.2.2  pgoyette 	  if (features)
   2332  1.1.1.1.2.2  pgoyette 	    {
   2333  1.1.1.1.2.2  pgoyette 	      /* Add GNU_PROPERTY_X86_FEATURE_1_IBT and
   2334  1.1.1.1.2.2  pgoyette 		 GNU_PROPERTY_X86_FEATURE_1_SHSTK.  */
   2335  1.1.1.1.2.2  pgoyette 	      if (aprop != NULL)
   2336  1.1.1.1.2.2  pgoyette 		{
   2337  1.1.1.1.2.2  pgoyette 		  number = aprop->u.number;
   2338  1.1.1.1.2.2  pgoyette 		  aprop->u.number = number | features;
   2339  1.1.1.1.2.2  pgoyette 		  updated = number != (unsigned int) aprop->u.number;
   2340  1.1.1.1.2.2  pgoyette 		}
   2341  1.1.1.1.2.2  pgoyette 	      else
   2342  1.1.1.1.2.2  pgoyette 		{
   2343  1.1.1.1.2.2  pgoyette 		  bprop->u.number |= features;
   2344  1.1.1.1.2.2  pgoyette 		  updated = TRUE;
   2345  1.1.1.1.2.2  pgoyette 		}
   2346  1.1.1.1.2.2  pgoyette 	    }
   2347  1.1.1.1.2.2  pgoyette 	  else if (aprop != NULL)
   2348  1.1.1.1.2.2  pgoyette 	    {
   2349  1.1.1.1.2.2  pgoyette 	      aprop->pr_kind = property_remove;
   2350  1.1.1.1.2.2  pgoyette 	      updated = TRUE;
   2351  1.1.1.1.2.2  pgoyette 	    }
   2352  1.1.1.1.2.2  pgoyette 	}
   2353  1.1.1.1.2.2  pgoyette       break;
   2354  1.1.1.1.2.2  pgoyette 
   2355  1.1.1.1.2.2  pgoyette     default:
   2356  1.1.1.1.2.2  pgoyette       /* Never should happen.  */
   2357  1.1.1.1.2.2  pgoyette       abort ();
   2358  1.1.1.1.2.2  pgoyette     }
   2359  1.1.1.1.2.2  pgoyette 
   2360  1.1.1.1.2.2  pgoyette   return updated;
   2361  1.1.1.1.2.2  pgoyette }
   2362  1.1.1.1.2.2  pgoyette 
   2363  1.1.1.1.2.2  pgoyette /* Set up x86 GNU properties.  Return the first relocatable ELF input
   2364  1.1.1.1.2.2  pgoyette    with GNU properties if found.  Otherwise, return NULL.  */
   2365  1.1.1.1.2.2  pgoyette 
   2366  1.1.1.1.2.2  pgoyette bfd *
   2367  1.1.1.1.2.2  pgoyette _bfd_x86_elf_link_setup_gnu_properties
   2368  1.1.1.1.2.2  pgoyette   (struct bfd_link_info *info, struct elf_x86_init_table *init_table)
   2369  1.1.1.1.2.2  pgoyette {
   2370  1.1.1.1.2.2  pgoyette   bfd_boolean normal_target;
   2371  1.1.1.1.2.2  pgoyette   bfd_boolean lazy_plt;
   2372  1.1.1.1.2.2  pgoyette   asection *sec, *pltsec;
   2373  1.1.1.1.2.2  pgoyette   bfd *dynobj;
   2374  1.1.1.1.2.2  pgoyette   bfd_boolean use_ibt_plt;
   2375  1.1.1.1.2.2  pgoyette   unsigned int plt_alignment, features;
   2376  1.1.1.1.2.2  pgoyette   struct elf_x86_link_hash_table *htab;
   2377  1.1.1.1.2.2  pgoyette   bfd *pbfd;
   2378  1.1.1.1.2.2  pgoyette   bfd *ebfd = NULL;
   2379  1.1.1.1.2.2  pgoyette   elf_property *prop;
   2380  1.1.1.1.2.2  pgoyette   const struct elf_backend_data *bed;
   2381  1.1.1.1.2.2  pgoyette   unsigned int class_align = ABI_64_P (info->output_bfd) ? 3 : 2;
   2382  1.1.1.1.2.2  pgoyette   unsigned int got_align;
   2383  1.1.1.1.2.2  pgoyette 
   2384  1.1.1.1.2.2  pgoyette   features = 0;
   2385  1.1.1.1.2.2  pgoyette   if (info->ibt)
   2386  1.1.1.1.2.2  pgoyette     features = GNU_PROPERTY_X86_FEATURE_1_IBT;
   2387  1.1.1.1.2.2  pgoyette   if (info->shstk)
   2388  1.1.1.1.2.2  pgoyette     features |= GNU_PROPERTY_X86_FEATURE_1_SHSTK;
   2389  1.1.1.1.2.2  pgoyette 
   2390  1.1.1.1.2.2  pgoyette   /* Find a normal input file with GNU property note.  */
   2391  1.1.1.1.2.2  pgoyette   for (pbfd = info->input_bfds;
   2392  1.1.1.1.2.2  pgoyette        pbfd != NULL;
   2393  1.1.1.1.2.2  pgoyette        pbfd = pbfd->link.next)
   2394  1.1.1.1.2.2  pgoyette     if (bfd_get_flavour (pbfd) == bfd_target_elf_flavour
   2395  1.1.1.1.2.2  pgoyette 	&& bfd_count_sections (pbfd) != 0)
   2396  1.1.1.1.2.2  pgoyette       {
   2397  1.1.1.1.2.2  pgoyette 	ebfd = pbfd;
   2398  1.1.1.1.2.2  pgoyette 
   2399  1.1.1.1.2.2  pgoyette 	if (elf_properties (pbfd) != NULL)
   2400  1.1.1.1.2.2  pgoyette 	  break;
   2401  1.1.1.1.2.2  pgoyette       }
   2402  1.1.1.1.2.2  pgoyette 
   2403  1.1.1.1.2.2  pgoyette   if (ebfd != NULL && features)
   2404  1.1.1.1.2.2  pgoyette     {
   2405  1.1.1.1.2.2  pgoyette       /* If features is set, add GNU_PROPERTY_X86_FEATURE_1_IBT and
   2406  1.1.1.1.2.2  pgoyette 	 GNU_PROPERTY_X86_FEATURE_1_SHSTK.  */
   2407  1.1.1.1.2.2  pgoyette       prop = _bfd_elf_get_property (ebfd,
   2408  1.1.1.1.2.2  pgoyette 				    GNU_PROPERTY_X86_FEATURE_1_AND,
   2409  1.1.1.1.2.2  pgoyette 				    4);
   2410  1.1.1.1.2.2  pgoyette       prop->u.number |= features;
   2411  1.1.1.1.2.2  pgoyette       prop->pr_kind = property_number;
   2412  1.1.1.1.2.2  pgoyette 
   2413  1.1.1.1.2.2  pgoyette       /* Create the GNU property note section if needed.  */
   2414  1.1.1.1.2.2  pgoyette       if (pbfd == NULL)
   2415  1.1.1.1.2.2  pgoyette 	{
   2416  1.1.1.1.2.2  pgoyette 	  sec = bfd_make_section_with_flags (ebfd,
   2417  1.1.1.1.2.2  pgoyette 					     NOTE_GNU_PROPERTY_SECTION_NAME,
   2418  1.1.1.1.2.2  pgoyette 					     (SEC_ALLOC
   2419  1.1.1.1.2.2  pgoyette 					      | SEC_LOAD
   2420  1.1.1.1.2.2  pgoyette 					      | SEC_IN_MEMORY
   2421  1.1.1.1.2.2  pgoyette 					      | SEC_READONLY
   2422  1.1.1.1.2.2  pgoyette 					      | SEC_HAS_CONTENTS
   2423  1.1.1.1.2.2  pgoyette 					      | SEC_DATA));
   2424  1.1.1.1.2.2  pgoyette 	  if (sec == NULL)
   2425  1.1.1.1.2.2  pgoyette 	    info->callbacks->einfo (_("%F%P: failed to create GNU property section\n"));
   2426  1.1.1.1.2.2  pgoyette 
   2427  1.1.1.1.2.2  pgoyette 	  if (!bfd_set_section_alignment (ebfd, sec, class_align))
   2428  1.1.1.1.2.2  pgoyette 	    {
   2429  1.1.1.1.2.2  pgoyette error_alignment:
   2430  1.1.1.1.2.2  pgoyette 	      info->callbacks->einfo (_("%F%A: failed to align section\n"),
   2431  1.1.1.1.2.2  pgoyette 				      sec);
   2432  1.1.1.1.2.2  pgoyette 	    }
   2433  1.1.1.1.2.2  pgoyette 
   2434  1.1.1.1.2.2  pgoyette 	  elf_section_type (sec) = SHT_NOTE;
   2435  1.1.1.1.2.2  pgoyette 	}
   2436  1.1.1.1.2.2  pgoyette     }
   2437  1.1.1.1.2.2  pgoyette 
   2438  1.1.1.1.2.2  pgoyette   pbfd = _bfd_elf_link_setup_gnu_properties (info);
   2439  1.1.1.1.2.2  pgoyette 
   2440  1.1.1.1.2.2  pgoyette   bed = get_elf_backend_data (info->output_bfd);
   2441  1.1.1.1.2.2  pgoyette 
   2442  1.1.1.1.2.2  pgoyette   htab = elf_x86_hash_table (info, bed->target_id);
   2443  1.1.1.1.2.2  pgoyette   if (htab == NULL)
   2444  1.1.1.1.2.2  pgoyette     return pbfd;
   2445  1.1.1.1.2.2  pgoyette 
   2446  1.1.1.1.2.2  pgoyette   htab->r_info = init_table->r_info;
   2447  1.1.1.1.2.2  pgoyette   htab->r_sym = init_table->r_sym;
   2448  1.1.1.1.2.2  pgoyette 
   2449  1.1.1.1.2.2  pgoyette   if (bfd_link_relocatable (info))
   2450  1.1.1.1.2.2  pgoyette     return pbfd;
   2451  1.1.1.1.2.2  pgoyette 
   2452  1.1.1.1.2.2  pgoyette   htab->plt0_pad_byte = init_table->plt0_pad_byte;
   2453  1.1.1.1.2.2  pgoyette 
   2454  1.1.1.1.2.2  pgoyette   use_ibt_plt = info->ibtplt || info->ibt;
   2455  1.1.1.1.2.2  pgoyette   if (!use_ibt_plt && pbfd != NULL)
   2456  1.1.1.1.2.2  pgoyette     {
   2457  1.1.1.1.2.2  pgoyette       /* Check if GNU_PROPERTY_X86_FEATURE_1_IBT is on.  */
   2458  1.1.1.1.2.2  pgoyette       elf_property_list *p;
   2459  1.1.1.1.2.2  pgoyette 
   2460  1.1.1.1.2.2  pgoyette       /* The property list is sorted in order of type.  */
   2461  1.1.1.1.2.2  pgoyette       for (p = elf_properties (pbfd); p; p = p->next)
   2462  1.1.1.1.2.2  pgoyette 	{
   2463  1.1.1.1.2.2  pgoyette 	  if (GNU_PROPERTY_X86_FEATURE_1_AND == p->property.pr_type)
   2464  1.1.1.1.2.2  pgoyette 	    {
   2465  1.1.1.1.2.2  pgoyette 	      use_ibt_plt = !!(p->property.u.number
   2466  1.1.1.1.2.2  pgoyette 			       & GNU_PROPERTY_X86_FEATURE_1_IBT);
   2467  1.1.1.1.2.2  pgoyette 	      break;
   2468  1.1.1.1.2.2  pgoyette 	    }
   2469  1.1.1.1.2.2  pgoyette 	  else if (GNU_PROPERTY_X86_FEATURE_1_AND < p->property.pr_type)
   2470  1.1.1.1.2.2  pgoyette 	    break;
   2471  1.1.1.1.2.2  pgoyette 	}
   2472  1.1.1.1.2.2  pgoyette     }
   2473  1.1.1.1.2.2  pgoyette 
   2474  1.1.1.1.2.2  pgoyette   dynobj = htab->elf.dynobj;
   2475  1.1.1.1.2.2  pgoyette 
   2476  1.1.1.1.2.2  pgoyette   /* Set htab->elf.dynobj here so that there is no need to check and
   2477  1.1.1.1.2.2  pgoyette      set it in check_relocs.  */
   2478  1.1.1.1.2.2  pgoyette   if (dynobj == NULL)
   2479  1.1.1.1.2.2  pgoyette     {
   2480  1.1.1.1.2.2  pgoyette       if (pbfd != NULL)
   2481  1.1.1.1.2.2  pgoyette 	{
   2482  1.1.1.1.2.2  pgoyette 	  htab->elf.dynobj = pbfd;
   2483  1.1.1.1.2.2  pgoyette 	  dynobj = pbfd;
   2484  1.1.1.1.2.2  pgoyette 	}
   2485  1.1.1.1.2.2  pgoyette       else
   2486  1.1.1.1.2.2  pgoyette 	{
   2487  1.1.1.1.2.2  pgoyette 	  bfd *abfd;
   2488  1.1.1.1.2.2  pgoyette 
   2489  1.1.1.1.2.2  pgoyette 	  /* Find a normal input file to hold linker created
   2490  1.1.1.1.2.2  pgoyette 	     sections.  */
   2491  1.1.1.1.2.2  pgoyette 	  for (abfd = info->input_bfds;
   2492  1.1.1.1.2.2  pgoyette 	       abfd != NULL;
   2493  1.1.1.1.2.2  pgoyette 	       abfd = abfd->link.next)
   2494  1.1.1.1.2.2  pgoyette 	    if (bfd_get_flavour (abfd) == bfd_target_elf_flavour
   2495  1.1.1.1.2.2  pgoyette 		&& (abfd->flags
   2496  1.1.1.1.2.2  pgoyette 		    & (DYNAMIC | BFD_LINKER_CREATED | BFD_PLUGIN)) == 0)
   2497  1.1.1.1.2.2  pgoyette 	      {
   2498  1.1.1.1.2.2  pgoyette 		htab->elf.dynobj = abfd;
   2499  1.1.1.1.2.2  pgoyette 		dynobj = abfd;
   2500  1.1.1.1.2.2  pgoyette 		break;
   2501  1.1.1.1.2.2  pgoyette 	      }
   2502  1.1.1.1.2.2  pgoyette 	}
   2503  1.1.1.1.2.2  pgoyette     }
   2504  1.1.1.1.2.2  pgoyette 
   2505  1.1.1.1.2.2  pgoyette   /* Return if there are no normal input files.  */
   2506  1.1.1.1.2.2  pgoyette   if (dynobj == NULL)
   2507  1.1.1.1.2.2  pgoyette     return pbfd;
   2508  1.1.1.1.2.2  pgoyette 
   2509  1.1.1.1.2.2  pgoyette   /* Even when lazy binding is disabled by "-z now", the PLT0 entry may
   2510  1.1.1.1.2.2  pgoyette      still be used with LD_AUDIT or LD_PROFILE if PLT entry is used for
   2511  1.1.1.1.2.2  pgoyette      canonical function address.  */
   2512  1.1.1.1.2.2  pgoyette   htab->plt.has_plt0 = 1;
   2513  1.1.1.1.2.2  pgoyette   normal_target = htab->target_os == is_normal;
   2514  1.1.1.1.2.2  pgoyette 
   2515  1.1.1.1.2.2  pgoyette   if (normal_target)
   2516  1.1.1.1.2.2  pgoyette     {
   2517  1.1.1.1.2.2  pgoyette       if (use_ibt_plt)
   2518  1.1.1.1.2.2  pgoyette 	{
   2519  1.1.1.1.2.2  pgoyette 	  htab->lazy_plt = init_table->lazy_ibt_plt;
   2520  1.1.1.1.2.2  pgoyette 	  htab->non_lazy_plt = init_table->non_lazy_ibt_plt;
   2521  1.1.1.1.2.2  pgoyette 	}
   2522  1.1.1.1.2.2  pgoyette       else
   2523  1.1.1.1.2.2  pgoyette 	{
   2524  1.1.1.1.2.2  pgoyette 	  htab->lazy_plt = init_table->lazy_plt;
   2525  1.1.1.1.2.2  pgoyette 	  htab->non_lazy_plt = init_table->non_lazy_plt;
   2526  1.1.1.1.2.2  pgoyette 	}
   2527  1.1.1.1.2.2  pgoyette     }
   2528  1.1.1.1.2.2  pgoyette   else
   2529  1.1.1.1.2.2  pgoyette     {
   2530  1.1.1.1.2.2  pgoyette       htab->lazy_plt = init_table->lazy_plt;
   2531  1.1.1.1.2.2  pgoyette       htab->non_lazy_plt = NULL;
   2532  1.1.1.1.2.2  pgoyette     }
   2533  1.1.1.1.2.2  pgoyette 
   2534  1.1.1.1.2.2  pgoyette   pltsec = htab->elf.splt;
   2535  1.1.1.1.2.2  pgoyette 
   2536  1.1.1.1.2.2  pgoyette   /* If the non-lazy PLT is available, use it for all PLT entries if
   2537  1.1.1.1.2.2  pgoyette      there are no PLT0 or no .plt section.  */
   2538  1.1.1.1.2.2  pgoyette   if (htab->non_lazy_plt != NULL
   2539  1.1.1.1.2.2  pgoyette       && (!htab->plt.has_plt0 || pltsec == NULL))
   2540  1.1.1.1.2.2  pgoyette     {
   2541  1.1.1.1.2.2  pgoyette       lazy_plt = FALSE;
   2542  1.1.1.1.2.2  pgoyette       if (bfd_link_pic (info))
   2543  1.1.1.1.2.2  pgoyette 	htab->plt.plt_entry = htab->non_lazy_plt->pic_plt_entry;
   2544  1.1.1.1.2.2  pgoyette       else
   2545  1.1.1.1.2.2  pgoyette 	htab->plt.plt_entry = htab->non_lazy_plt->plt_entry;
   2546  1.1.1.1.2.2  pgoyette       htab->plt.plt_entry_size = htab->non_lazy_plt->plt_entry_size;
   2547  1.1.1.1.2.2  pgoyette       htab->plt.plt_got_offset = htab->non_lazy_plt->plt_got_offset;
   2548  1.1.1.1.2.2  pgoyette       htab->plt.plt_got_insn_size
   2549  1.1.1.1.2.2  pgoyette 	= htab->non_lazy_plt->plt_got_insn_size;
   2550  1.1.1.1.2.2  pgoyette       htab->plt.eh_frame_plt_size
   2551  1.1.1.1.2.2  pgoyette 	= htab->non_lazy_plt->eh_frame_plt_size;
   2552  1.1.1.1.2.2  pgoyette       htab->plt.eh_frame_plt = htab->non_lazy_plt->eh_frame_plt;
   2553  1.1.1.1.2.2  pgoyette     }
   2554  1.1.1.1.2.2  pgoyette   else
   2555  1.1.1.1.2.2  pgoyette     {
   2556  1.1.1.1.2.2  pgoyette       lazy_plt = TRUE;
   2557  1.1.1.1.2.2  pgoyette       if (bfd_link_pic (info))
   2558  1.1.1.1.2.2  pgoyette 	{
   2559  1.1.1.1.2.2  pgoyette 	  htab->plt.plt0_entry = htab->lazy_plt->pic_plt0_entry;
   2560  1.1.1.1.2.2  pgoyette 	  htab->plt.plt_entry = htab->lazy_plt->pic_plt_entry;
   2561  1.1.1.1.2.2  pgoyette 	}
   2562  1.1.1.1.2.2  pgoyette       else
   2563  1.1.1.1.2.2  pgoyette 	{
   2564  1.1.1.1.2.2  pgoyette 	  htab->plt.plt0_entry = htab->lazy_plt->plt0_entry;
   2565  1.1.1.1.2.2  pgoyette 	  htab->plt.plt_entry = htab->lazy_plt->plt_entry;
   2566  1.1.1.1.2.2  pgoyette 	}
   2567  1.1.1.1.2.2  pgoyette       htab->plt.plt_entry_size = htab->lazy_plt->plt_entry_size;
   2568  1.1.1.1.2.2  pgoyette       htab->plt.plt_got_offset = htab->lazy_plt->plt_got_offset;
   2569  1.1.1.1.2.2  pgoyette       htab->plt.plt_got_insn_size
   2570  1.1.1.1.2.2  pgoyette 	= htab->lazy_plt->plt_got_insn_size;
   2571  1.1.1.1.2.2  pgoyette       htab->plt.eh_frame_plt_size
   2572  1.1.1.1.2.2  pgoyette 	= htab->lazy_plt->eh_frame_plt_size;
   2573  1.1.1.1.2.2  pgoyette       htab->plt.eh_frame_plt = htab->lazy_plt->eh_frame_plt;
   2574  1.1.1.1.2.2  pgoyette     }
   2575  1.1.1.1.2.2  pgoyette 
   2576  1.1.1.1.2.2  pgoyette   if (htab->target_os == is_vxworks
   2577  1.1.1.1.2.2  pgoyette       && !elf_vxworks_create_dynamic_sections (dynobj, info,
   2578  1.1.1.1.2.2  pgoyette 					       &htab->srelplt2))
   2579  1.1.1.1.2.2  pgoyette     {
   2580  1.1.1.1.2.2  pgoyette       info->callbacks->einfo (_("%F%P: failed to create VxWorks dynamic sections\n"));
   2581  1.1.1.1.2.2  pgoyette       return pbfd;
   2582  1.1.1.1.2.2  pgoyette     }
   2583  1.1.1.1.2.2  pgoyette 
   2584  1.1.1.1.2.2  pgoyette   /* Since create_dynamic_sections isn't always called, but GOT
   2585  1.1.1.1.2.2  pgoyette      relocations need GOT relocations, create them here so that we
   2586  1.1.1.1.2.2  pgoyette      don't need to do it in check_relocs.  */
   2587  1.1.1.1.2.2  pgoyette   if (htab->elf.sgot == NULL
   2588  1.1.1.1.2.2  pgoyette       && !_bfd_elf_create_got_section (dynobj, info))
   2589  1.1.1.1.2.2  pgoyette     info->callbacks->einfo (_("%F%P: failed to create GOT sections\n"));
   2590  1.1.1.1.2.2  pgoyette 
   2591  1.1.1.1.2.2  pgoyette   got_align = (bed->target_id == X86_64_ELF_DATA) ? 3 : 2;
   2592  1.1.1.1.2.2  pgoyette 
   2593  1.1.1.1.2.2  pgoyette   /* Align .got and .got.plt sections to their entry size.  Do it here
   2594  1.1.1.1.2.2  pgoyette      instead of in create_dynamic_sections so that they are always
   2595  1.1.1.1.2.2  pgoyette      properly aligned even if create_dynamic_sections isn't called.  */
   2596  1.1.1.1.2.2  pgoyette   sec = htab->elf.sgot;
   2597  1.1.1.1.2.2  pgoyette   if (!bfd_set_section_alignment (dynobj, sec, got_align))
   2598  1.1.1.1.2.2  pgoyette     goto error_alignment;
   2599  1.1.1.1.2.2  pgoyette 
   2600  1.1.1.1.2.2  pgoyette   sec = htab->elf.sgotplt;
   2601  1.1.1.1.2.2  pgoyette   if (!bfd_set_section_alignment (dynobj, sec, got_align))
   2602  1.1.1.1.2.2  pgoyette     goto error_alignment;
   2603  1.1.1.1.2.2  pgoyette 
   2604  1.1.1.1.2.2  pgoyette   /* Create the ifunc sections here so that check_relocs can be
   2605  1.1.1.1.2.2  pgoyette      simplified.  */
   2606  1.1.1.1.2.2  pgoyette   if (!_bfd_elf_create_ifunc_sections (dynobj, info))
   2607  1.1.1.1.2.2  pgoyette     info->callbacks->einfo (_("%F%P: failed to create ifunc sections\n"));
   2608  1.1.1.1.2.2  pgoyette 
   2609  1.1.1.1.2.2  pgoyette   plt_alignment = bfd_log2 (htab->plt.plt_entry_size);
   2610  1.1.1.1.2.2  pgoyette 
   2611  1.1.1.1.2.2  pgoyette   if (pltsec != NULL)
   2612  1.1.1.1.2.2  pgoyette     {
   2613  1.1.1.1.2.2  pgoyette       /* Whe creating executable, set the contents of the .interp
   2614  1.1.1.1.2.2  pgoyette 	 section to the interpreter.  */
   2615  1.1.1.1.2.2  pgoyette       if (bfd_link_executable (info) && !info->nointerp)
   2616  1.1.1.1.2.2  pgoyette 	{
   2617  1.1.1.1.2.2  pgoyette 	  asection *s = bfd_get_linker_section (dynobj, ".interp");
   2618  1.1.1.1.2.2  pgoyette 	  if (s == NULL)
   2619  1.1.1.1.2.2  pgoyette 	    abort ();
   2620  1.1.1.1.2.2  pgoyette 	  s->size = htab->dynamic_interpreter_size;
   2621  1.1.1.1.2.2  pgoyette 	  s->contents = (unsigned char *) htab->dynamic_interpreter;
   2622  1.1.1.1.2.2  pgoyette 	  htab->interp = s;
   2623  1.1.1.1.2.2  pgoyette 	}
   2624  1.1.1.1.2.2  pgoyette 
   2625  1.1.1.1.2.2  pgoyette       /* Don't change PLT section alignment for NaCl since it uses
   2626  1.1.1.1.2.2  pgoyette 	 64-byte PLT entry and sets PLT section alignment to 32
   2627  1.1.1.1.2.2  pgoyette 	 bytes.  Don't create additional PLT sections for NaCl.  */
   2628  1.1.1.1.2.2  pgoyette       if (normal_target)
   2629  1.1.1.1.2.2  pgoyette 	{
   2630  1.1.1.1.2.2  pgoyette 	  flagword pltflags = (bed->dynamic_sec_flags
   2631  1.1.1.1.2.2  pgoyette 			       | SEC_ALLOC
   2632  1.1.1.1.2.2  pgoyette 			       | SEC_CODE
   2633  1.1.1.1.2.2  pgoyette 			       | SEC_LOAD
   2634  1.1.1.1.2.2  pgoyette 			       | SEC_READONLY);
   2635  1.1.1.1.2.2  pgoyette 	  unsigned int non_lazy_plt_alignment
   2636  1.1.1.1.2.2  pgoyette 	    = bfd_log2 (htab->non_lazy_plt->plt_entry_size);
   2637  1.1.1.1.2.2  pgoyette 
   2638  1.1.1.1.2.2  pgoyette 	  sec = pltsec;
   2639  1.1.1.1.2.2  pgoyette 	  if (!bfd_set_section_alignment (sec->owner, sec,
   2640  1.1.1.1.2.2  pgoyette 					  plt_alignment))
   2641  1.1.1.1.2.2  pgoyette 	    goto error_alignment;
   2642  1.1.1.1.2.2  pgoyette 
   2643  1.1.1.1.2.2  pgoyette 	  /* Create the GOT procedure linkage table.  */
   2644  1.1.1.1.2.2  pgoyette 	  sec = bfd_make_section_anyway_with_flags (dynobj,
   2645  1.1.1.1.2.2  pgoyette 						    ".plt.got",
   2646  1.1.1.1.2.2  pgoyette 						    pltflags);
   2647  1.1.1.1.2.2  pgoyette 	  if (sec == NULL)
   2648  1.1.1.1.2.2  pgoyette 	    info->callbacks->einfo (_("%F%P: failed to create GOT PLT section\n"));
   2649  1.1.1.1.2.2  pgoyette 
   2650  1.1.1.1.2.2  pgoyette 	  if (!bfd_set_section_alignment (dynobj, sec,
   2651  1.1.1.1.2.2  pgoyette 					  non_lazy_plt_alignment))
   2652  1.1.1.1.2.2  pgoyette 	    goto error_alignment;
   2653  1.1.1.1.2.2  pgoyette 
   2654  1.1.1.1.2.2  pgoyette 	  htab->plt_got = sec;
   2655  1.1.1.1.2.2  pgoyette 
   2656  1.1.1.1.2.2  pgoyette 	  if (lazy_plt)
   2657  1.1.1.1.2.2  pgoyette 	    {
   2658  1.1.1.1.2.2  pgoyette 	      sec = NULL;
   2659  1.1.1.1.2.2  pgoyette 
   2660  1.1.1.1.2.2  pgoyette 	      if (use_ibt_plt)
   2661  1.1.1.1.2.2  pgoyette 		{
   2662  1.1.1.1.2.2  pgoyette 		  /* Create the second PLT for Intel IBT support.  IBT
   2663  1.1.1.1.2.2  pgoyette 		     PLT is supported only for non-NaCl target and is
   2664  1.1.1.1.2.2  pgoyette 		     is needed only for lazy binding.  */
   2665  1.1.1.1.2.2  pgoyette 		  sec = bfd_make_section_anyway_with_flags (dynobj,
   2666  1.1.1.1.2.2  pgoyette 							    ".plt.sec",
   2667  1.1.1.1.2.2  pgoyette 							    pltflags);
   2668  1.1.1.1.2.2  pgoyette 		  if (sec == NULL)
   2669  1.1.1.1.2.2  pgoyette 		    info->callbacks->einfo (_("%F%P: failed to create IBT-enabled PLT section\n"));
   2670  1.1.1.1.2.2  pgoyette 
   2671  1.1.1.1.2.2  pgoyette 		  if (!bfd_set_section_alignment (dynobj, sec,
   2672  1.1.1.1.2.2  pgoyette 						  plt_alignment))
   2673  1.1.1.1.2.2  pgoyette 		    goto error_alignment;
   2674  1.1.1.1.2.2  pgoyette 		}
   2675  1.1.1.1.2.2  pgoyette 	      else if (info->bndplt && ABI_64_P (dynobj))
   2676  1.1.1.1.2.2  pgoyette 		{
   2677  1.1.1.1.2.2  pgoyette 		  /* Create the second PLT for Intel MPX support.  MPX
   2678  1.1.1.1.2.2  pgoyette 		     PLT is supported only for non-NaCl target in 64-bit
   2679  1.1.1.1.2.2  pgoyette 		     mode and is needed only for lazy binding.  */
   2680  1.1.1.1.2.2  pgoyette 		  sec = bfd_make_section_anyway_with_flags (dynobj,
   2681  1.1.1.1.2.2  pgoyette 							    ".plt.sec",
   2682  1.1.1.1.2.2  pgoyette 							    pltflags);
   2683  1.1.1.1.2.2  pgoyette 		  if (sec == NULL)
   2684  1.1.1.1.2.2  pgoyette 		    info->callbacks->einfo (_("%F%P: failed to create BND PLT section\n"));
   2685  1.1.1.1.2.2  pgoyette 
   2686  1.1.1.1.2.2  pgoyette 		  if (!bfd_set_section_alignment (dynobj, sec,
   2687  1.1.1.1.2.2  pgoyette 						  non_lazy_plt_alignment))
   2688  1.1.1.1.2.2  pgoyette 		    goto error_alignment;
   2689  1.1.1.1.2.2  pgoyette 		}
   2690  1.1.1.1.2.2  pgoyette 
   2691  1.1.1.1.2.2  pgoyette 	      htab->plt_second = sec;
   2692  1.1.1.1.2.2  pgoyette 	    }
   2693  1.1.1.1.2.2  pgoyette 	}
   2694  1.1.1.1.2.2  pgoyette 
   2695  1.1.1.1.2.2  pgoyette       if (!info->no_ld_generated_unwind_info)
   2696  1.1.1.1.2.2  pgoyette 	{
   2697  1.1.1.1.2.2  pgoyette 	  flagword flags = (SEC_ALLOC | SEC_LOAD | SEC_READONLY
   2698  1.1.1.1.2.2  pgoyette 			    | SEC_HAS_CONTENTS | SEC_IN_MEMORY
   2699  1.1.1.1.2.2  pgoyette 			    | SEC_LINKER_CREATED);
   2700  1.1.1.1.2.2  pgoyette 
   2701  1.1.1.1.2.2  pgoyette 	  sec = bfd_make_section_anyway_with_flags (dynobj,
   2702  1.1.1.1.2.2  pgoyette 						    ".eh_frame",
   2703  1.1.1.1.2.2  pgoyette 						    flags);
   2704  1.1.1.1.2.2  pgoyette 	  if (sec == NULL)
   2705  1.1.1.1.2.2  pgoyette 	    info->callbacks->einfo (_("%F%P: failed to create PLT .eh_frame section\n"));
   2706  1.1.1.1.2.2  pgoyette 
   2707  1.1.1.1.2.2  pgoyette 	  if (!bfd_set_section_alignment (dynobj, sec, class_align))
   2708  1.1.1.1.2.2  pgoyette 	    goto error_alignment;
   2709  1.1.1.1.2.2  pgoyette 
   2710  1.1.1.1.2.2  pgoyette 	  htab->plt_eh_frame = sec;
   2711  1.1.1.1.2.2  pgoyette 
   2712  1.1.1.1.2.2  pgoyette 	  if (htab->plt_got != NULL)
   2713  1.1.1.1.2.2  pgoyette 	    {
   2714  1.1.1.1.2.2  pgoyette 	      sec = bfd_make_section_anyway_with_flags (dynobj,
   2715  1.1.1.1.2.2  pgoyette 							".eh_frame",
   2716  1.1.1.1.2.2  pgoyette 							flags);
   2717  1.1.1.1.2.2  pgoyette 	      if (sec == NULL)
   2718  1.1.1.1.2.2  pgoyette 		info->callbacks->einfo (_("%F%P: failed to create GOT PLT .eh_frame section\n"));
   2719  1.1.1.1.2.2  pgoyette 
   2720  1.1.1.1.2.2  pgoyette 	      if (!bfd_set_section_alignment (dynobj, sec, class_align))
   2721  1.1.1.1.2.2  pgoyette 		goto error_alignment;
   2722  1.1.1.1.2.2  pgoyette 
   2723  1.1.1.1.2.2  pgoyette 	      htab->plt_got_eh_frame = sec;
   2724  1.1.1.1.2.2  pgoyette 	    }
   2725  1.1.1.1.2.2  pgoyette 
   2726  1.1.1.1.2.2  pgoyette 	  if (htab->plt_second != NULL)
   2727  1.1.1.1.2.2  pgoyette 	    {
   2728  1.1.1.1.2.2  pgoyette 	      sec = bfd_make_section_anyway_with_flags (dynobj,
   2729  1.1.1.1.2.2  pgoyette 							".eh_frame",
   2730  1.1.1.1.2.2  pgoyette 							flags);
   2731  1.1.1.1.2.2  pgoyette 	      if (sec == NULL)
   2732  1.1.1.1.2.2  pgoyette 		info->callbacks->einfo (_("%F%P: failed to create the second PLT .eh_frame section\n"));
   2733  1.1.1.1.2.2  pgoyette 
   2734  1.1.1.1.2.2  pgoyette 	      if (!bfd_set_section_alignment (dynobj, sec, class_align))
   2735  1.1.1.1.2.2  pgoyette 		goto error_alignment;
   2736  1.1.1.1.2.2  pgoyette 
   2737  1.1.1.1.2.2  pgoyette 	      htab->plt_second_eh_frame = sec;
   2738  1.1.1.1.2.2  pgoyette 	    }
   2739  1.1.1.1.2.2  pgoyette 	}
   2740  1.1.1.1.2.2  pgoyette     }
   2741  1.1.1.1.2.2  pgoyette 
   2742  1.1.1.1.2.2  pgoyette   if (normal_target)
   2743  1.1.1.1.2.2  pgoyette     {
   2744  1.1.1.1.2.2  pgoyette       /* The .iplt section is used for IFUNC symbols in static
   2745  1.1.1.1.2.2  pgoyette 	 executables.  */
   2746  1.1.1.1.2.2  pgoyette       sec = htab->elf.iplt;
   2747  1.1.1.1.2.2  pgoyette       if (sec != NULL
   2748  1.1.1.1.2.2  pgoyette 	  && !bfd_set_section_alignment (sec->owner, sec,
   2749  1.1.1.1.2.2  pgoyette 					 plt_alignment))
   2750  1.1.1.1.2.2  pgoyette 	goto error_alignment;
   2751  1.1.1.1.2.2  pgoyette     }
   2752  1.1.1.1.2.2  pgoyette 
   2753  1.1.1.1.2.2  pgoyette   return pbfd;
   2754  1.1.1.1.2.2  pgoyette }
   2755