/[gcl]/gcl/binutils/bfd/elf64-x86-64.c
ViewVC logotype

Diff of /gcl/binutils/bfd/elf64-x86-64.c

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 1.1.1.1 by camm, Fri Aug 9 05:35:26 2002 UTC revision 1.2 by camm, Fri Sep 9 23:32:13 2005 UTC
# Line 1  Line 1 
1  /* X86-64 specific support for 64-bit ELF  /* X86-64 specific support for 64-bit ELF
2     Copyright 2000, 2001, 2002 Free Software Foundation, Inc.     Copyright 2000, 2001, 2002, 2003, 2004, 2005
3       Free Software Foundation, Inc.
4     Contributed by Jan Hubicka <jh@suse.cz>.     Contributed by Jan Hubicka <jh@suse.cz>.
5    
6  This file is part of BFD, the Binary File Descriptor library.     This file is part of BFD, the Binary File Descriptor library.
7    
8  This program is free software; you can redistribute it and/or modify     This program is free software; you can redistribute it and/or modify
9  it under the terms of the GNU General Public License as published by     it under the terms of the GNU General Public License as published by
10  the Free Software Foundation; either version 2 of the License, or     the Free Software Foundation; either version 2 of the License, or
11  (at your option) any later version.     (at your option) any later version.
12    
13  This program is distributed in the hope that it will be useful,     This program is distributed in the hope that it will be useful,
14  but WITHOUT ANY WARRANTY; without even the implied warranty of     but WITHOUT ANY WARRANTY; without even the implied warranty of
15  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16  GNU General Public License for more details.     GNU General Public License for more details.
17    
18  You should have received a copy of the GNU General Public License     You should have received a copy of the GNU General Public License
19  along with this program; if not, write to the Free Software     along with this program; if not, write to the Free Software
20  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */     Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
21    
22  #include "bfd.h"  #include "bfd.h"
23  #include "sysdep.h"  #include "sysdep.h"
# Line 26  Foundation, Inc., 59 Temple Place - Suit Line 27  Foundation, Inc., 59 Temple Place - Suit
27    
28  #include "elf/x86-64.h"  #include "elf/x86-64.h"
29    
 /* We use only the RELA entries.  */  
 #define USE_RELA 1  
   
30  /* In case we're on a 32-bit machine, construct a 64-bit "-1" value.  */  /* In case we're on a 32-bit machine, construct a 64-bit "-1" value.  */
31  #define MINUS_ONE (~ (bfd_vma) 0)  #define MINUS_ONE (~ (bfd_vma) 0)
32    
# Line 37  Foundation, Inc., 59 Temple Place - Suit Line 35  Foundation, Inc., 59 Temple Place - Suit
35     special_function, name, partial_inplace, src_mask, dst_pack, pcrel_offset.  */     special_function, name, partial_inplace, src_mask, dst_pack, pcrel_offset.  */
36  static reloc_howto_type x86_64_elf_howto_table[] =  static reloc_howto_type x86_64_elf_howto_table[] =
37  {  {
38    HOWTO(R_X86_64_NONE, 0, 0, 0, false, 0, complain_overflow_dont,    HOWTO(R_X86_64_NONE, 0, 0, 0, FALSE, 0, complain_overflow_dont,
39          bfd_elf_generic_reloc, "R_X86_64_NONE", false, 0x00000000, 0x00000000,          bfd_elf_generic_reloc, "R_X86_64_NONE", FALSE, 0x00000000, 0x00000000,
40          false),          FALSE),
41    HOWTO(R_X86_64_64, 0, 4, 64, false, 0, complain_overflow_bitfield,    HOWTO(R_X86_64_64, 0, 4, 64, FALSE, 0, complain_overflow_bitfield,
42          bfd_elf_generic_reloc, "R_X86_64_64", false, MINUS_ONE, MINUS_ONE,          bfd_elf_generic_reloc, "R_X86_64_64", FALSE, MINUS_ONE, MINUS_ONE,
43          false),          FALSE),
44    HOWTO(R_X86_64_PC32, 0, 4, 32, true, 0, complain_overflow_signed,    HOWTO(R_X86_64_PC32, 0, 2, 32, TRUE, 0, complain_overflow_signed,
45          bfd_elf_generic_reloc, "R_X86_64_PC32", false, 0xffffffff, 0xffffffff,          bfd_elf_generic_reloc, "R_X86_64_PC32", FALSE, 0xffffffff, 0xffffffff,
46          true),          TRUE),
47    HOWTO(R_X86_64_GOT32, 0, 4, 32, false, 0, complain_overflow_signed,    HOWTO(R_X86_64_GOT32, 0, 2, 32, FALSE, 0, complain_overflow_signed,
48          bfd_elf_generic_reloc, "R_X86_64_GOT32", false, 0xffffffff, 0xffffffff,          bfd_elf_generic_reloc, "R_X86_64_GOT32", FALSE, 0xffffffff, 0xffffffff,
49          false),          FALSE),
50    HOWTO(R_X86_64_PLT32, 0, 4, 32, true, 0, complain_overflow_signed,    HOWTO(R_X86_64_PLT32, 0, 2, 32, TRUE, 0, complain_overflow_signed,
51          bfd_elf_generic_reloc, "R_X86_64_PLT32", false, 0xffffffff, 0xffffffff,          bfd_elf_generic_reloc, "R_X86_64_PLT32", FALSE, 0xffffffff, 0xffffffff,
52          true),          TRUE),
53    HOWTO(R_X86_64_COPY, 0, 4, 32, false, 0, complain_overflow_bitfield,    HOWTO(R_X86_64_COPY, 0, 2, 32, FALSE, 0, complain_overflow_bitfield,
54          bfd_elf_generic_reloc, "R_X86_64_COPY", false, 0xffffffff, 0xffffffff,          bfd_elf_generic_reloc, "R_X86_64_COPY", FALSE, 0xffffffff, 0xffffffff,
55          false),          FALSE),
56    HOWTO(R_X86_64_GLOB_DAT, 0, 4, 64, false, 0, complain_overflow_bitfield,    HOWTO(R_X86_64_GLOB_DAT, 0, 4, 64, FALSE, 0, complain_overflow_bitfield,
57          bfd_elf_generic_reloc, "R_X86_64_GLOB_DAT", false, MINUS_ONE,          bfd_elf_generic_reloc, "R_X86_64_GLOB_DAT", FALSE, MINUS_ONE,
58          MINUS_ONE, false),          MINUS_ONE, FALSE),
59    HOWTO(R_X86_64_JUMP_SLOT, 0, 4, 64, false, 0, complain_overflow_bitfield,    HOWTO(R_X86_64_JUMP_SLOT, 0, 4, 64, FALSE, 0, complain_overflow_bitfield,
60          bfd_elf_generic_reloc, "R_X86_64_JUMP_SLOT", false, MINUS_ONE,          bfd_elf_generic_reloc, "R_X86_64_JUMP_SLOT", FALSE, MINUS_ONE,
61          MINUS_ONE, false),          MINUS_ONE, FALSE),
62    HOWTO(R_X86_64_RELATIVE, 0, 4, 64, false, 0, complain_overflow_bitfield,    HOWTO(R_X86_64_RELATIVE, 0, 4, 64, FALSE, 0, complain_overflow_bitfield,
63          bfd_elf_generic_reloc, "R_X86_64_RELATIVE", false, MINUS_ONE,          bfd_elf_generic_reloc, "R_X86_64_RELATIVE", FALSE, MINUS_ONE,
64          MINUS_ONE, false),          MINUS_ONE, FALSE),
65    HOWTO(R_X86_64_GOTPCREL, 0, 4, 32, true,0 , complain_overflow_signed,    HOWTO(R_X86_64_GOTPCREL, 0, 2, 32, TRUE, 0, complain_overflow_signed,
66          bfd_elf_generic_reloc, "R_X86_64_GOTPCREL", false, 0xffffffff,          bfd_elf_generic_reloc, "R_X86_64_GOTPCREL", FALSE, 0xffffffff,
67          0xffffffff, true),          0xffffffff, TRUE),
68    HOWTO(R_X86_64_32, 0, 4, 32, false, 0, complain_overflow_unsigned,    HOWTO(R_X86_64_32, 0, 2, 32, FALSE, 0, complain_overflow_unsigned,
69          bfd_elf_generic_reloc, "R_X86_64_32", false, 0xffffffff, 0xffffffff,          bfd_elf_generic_reloc, "R_X86_64_32", FALSE, 0xffffffff, 0xffffffff,
70          false),          FALSE),
71    HOWTO(R_X86_64_32S, 0, 4, 32, false, 0, complain_overflow_signed,    HOWTO(R_X86_64_32S, 0, 2, 32, FALSE, 0, complain_overflow_signed,
72          bfd_elf_generic_reloc, "R_X86_64_32S", false, 0xffffffff, 0xffffffff,          bfd_elf_generic_reloc, "R_X86_64_32S", FALSE, 0xffffffff, 0xffffffff,
73          false),          FALSE),
74    HOWTO(R_X86_64_16, 0, 1, 16, false, 0, complain_overflow_bitfield,    HOWTO(R_X86_64_16, 0, 1, 16, FALSE, 0, complain_overflow_bitfield,
75          bfd_elf_generic_reloc, "R_X86_64_16", false, 0xffff, 0xffff, false),          bfd_elf_generic_reloc, "R_X86_64_16", FALSE, 0xffff, 0xffff, FALSE),
76    HOWTO(R_X86_64_PC16,0, 1, 16, true, 0, complain_overflow_bitfield,    HOWTO(R_X86_64_PC16,0, 1, 16, TRUE, 0, complain_overflow_bitfield,
77          bfd_elf_generic_reloc, "R_X86_64_PC16", false, 0xffff, 0xffff, true),          bfd_elf_generic_reloc, "R_X86_64_PC16", FALSE, 0xffff, 0xffff, TRUE),
78    HOWTO(R_X86_64_8, 0, 0, 8, false, 0, complain_overflow_signed,    HOWTO(R_X86_64_8, 0, 0, 8, FALSE, 0, complain_overflow_signed,
79          bfd_elf_generic_reloc, "R_X86_64_8", false, 0xff, 0xff, false),          bfd_elf_generic_reloc, "R_X86_64_8", FALSE, 0xff, 0xff, FALSE),
80    HOWTO(R_X86_64_PC8, 0, 0, 8, true, 0, complain_overflow_signed,    HOWTO(R_X86_64_PC8, 0, 0, 8, TRUE, 0, complain_overflow_signed,
81          bfd_elf_generic_reloc, "R_X86_64_PC8", false, 0xff, 0xff, true),          bfd_elf_generic_reloc, "R_X86_64_PC8", FALSE, 0xff, 0xff, TRUE),
82      HOWTO(R_X86_64_DTPMOD64, 0, 4, 64, FALSE, 0, complain_overflow_bitfield,
83            bfd_elf_generic_reloc, "R_X86_64_DTPMOD64", FALSE, MINUS_ONE,
84            MINUS_ONE, FALSE),
85      HOWTO(R_X86_64_DTPOFF64, 0, 4, 64, FALSE, 0, complain_overflow_bitfield,
86            bfd_elf_generic_reloc, "R_X86_64_DTPOFF64", FALSE, MINUS_ONE,
87            MINUS_ONE, FALSE),
88      HOWTO(R_X86_64_TPOFF64, 0, 4, 64, FALSE, 0, complain_overflow_bitfield,
89            bfd_elf_generic_reloc, "R_X86_64_TPOFF64", FALSE, MINUS_ONE,
90            MINUS_ONE, FALSE),
91      HOWTO(R_X86_64_TLSGD, 0, 2, 32, TRUE, 0, complain_overflow_signed,
92            bfd_elf_generic_reloc, "R_X86_64_TLSGD", FALSE, 0xffffffff,
93            0xffffffff, TRUE),
94      HOWTO(R_X86_64_TLSLD, 0, 2, 32, TRUE, 0, complain_overflow_signed,
95            bfd_elf_generic_reloc, "R_X86_64_TLSLD", FALSE, 0xffffffff,
96            0xffffffff, TRUE),
97      HOWTO(R_X86_64_DTPOFF32, 0, 2, 32, FALSE, 0, complain_overflow_bitfield,
98            bfd_elf_generic_reloc, "R_X86_64_DTPOFF32", FALSE, 0xffffffff,
99            0xffffffff, FALSE),
100      HOWTO(R_X86_64_GOTTPOFF, 0, 2, 32, TRUE, 0, complain_overflow_signed,
101            bfd_elf_generic_reloc, "R_X86_64_GOTTPOFF", FALSE, 0xffffffff,
102            0xffffffff, TRUE),
103      HOWTO(R_X86_64_TPOFF32, 0, 2, 32, FALSE, 0, complain_overflow_signed,
104            bfd_elf_generic_reloc, "R_X86_64_TPOFF32", FALSE, 0xffffffff,
105            0xffffffff, FALSE),
106    
107  /* GNU extension to record C++ vtable hierarchy.  */  /* GNU extension to record C++ vtable hierarchy.  */
108    HOWTO (R_X86_64_GNU_VTINHERIT, 0, 4, 0, false, 0, complain_overflow_dont,    HOWTO (R_X86_64_GNU_VTINHERIT, 0, 4, 0, FALSE, 0, complain_overflow_dont,
109           NULL, "R_X86_64_GNU_VTINHERIT", false, 0, 0, false),           NULL, "R_X86_64_GNU_VTINHERIT", FALSE, 0, 0, FALSE),
110    
111  /* GNU extension to record C++ vtable member usage.  */  /* GNU extension to record C++ vtable member usage.  */
112    HOWTO (R_X86_64_GNU_VTENTRY, 0, 4, 0, false, 0, complain_overflow_dont,    HOWTO (R_X86_64_GNU_VTENTRY, 0, 4, 0, FALSE, 0, complain_overflow_dont,
113           _bfd_elf_rel_vtable_reloc_fn, "R_X86_64_GNU_VTENTRY", false, 0, 0,           _bfd_elf_rel_vtable_reloc_fn, "R_X86_64_GNU_VTENTRY", FALSE, 0, 0,
114           false)           FALSE)
115  };  };
116    
117  /* Map BFD relocs to the x86_64 elf relocs.  */  /* Map BFD relocs to the x86_64 elf relocs.  */
# Line 117  static const struct elf_reloc_map x86_64 Line 139  static const struct elf_reloc_map x86_64
139    { BFD_RELOC_16_PCREL,         R_X86_64_PC16, },    { BFD_RELOC_16_PCREL,         R_X86_64_PC16, },
140    { BFD_RELOC_8,                R_X86_64_8, },    { BFD_RELOC_8,                R_X86_64_8, },
141    { BFD_RELOC_8_PCREL,          R_X86_64_PC8, },    { BFD_RELOC_8_PCREL,          R_X86_64_PC8, },
142      { BFD_RELOC_X86_64_DTPMOD64,  R_X86_64_DTPMOD64, },
143      { BFD_RELOC_X86_64_DTPOFF64,  R_X86_64_DTPOFF64, },
144      { BFD_RELOC_X86_64_TPOFF64,   R_X86_64_TPOFF64, },
145      { BFD_RELOC_X86_64_TLSGD,     R_X86_64_TLSGD, },
146      { BFD_RELOC_X86_64_TLSLD,     R_X86_64_TLSLD, },
147      { BFD_RELOC_X86_64_DTPOFF32,  R_X86_64_DTPOFF32, },
148      { BFD_RELOC_X86_64_GOTTPOFF,  R_X86_64_GOTTPOFF, },
149      { BFD_RELOC_X86_64_TPOFF32,   R_X86_64_TPOFF32, },
150    { BFD_RELOC_VTABLE_INHERIT,   R_X86_64_GNU_VTINHERIT, },    { BFD_RELOC_VTABLE_INHERIT,   R_X86_64_GNU_VTINHERIT, },
151    { BFD_RELOC_VTABLE_ENTRY,     R_X86_64_GNU_VTENTRY, },    { BFD_RELOC_VTABLE_ENTRY,     R_X86_64_GNU_VTENTRY, },
152  };  };
153    
 static reloc_howto_type *elf64_x86_64_reloc_type_lookup  
   PARAMS ((bfd *, bfd_reloc_code_real_type));  
 static void elf64_x86_64_info_to_howto  
   PARAMS ((bfd *, arelent *, Elf64_Internal_Rela *));  
 static boolean elf64_x86_64_grok_prstatus  
   PARAMS ((bfd *, Elf_Internal_Note *));  
 static boolean elf64_x86_64_grok_psinfo  
   PARAMS ((bfd *, Elf_Internal_Note *));  
 static struct bfd_link_hash_table *elf64_x86_64_link_hash_table_create  
   PARAMS ((bfd *));  
 static boolean elf64_x86_64_elf_object_p PARAMS ((bfd *abfd));  
 static boolean create_got_section  
   PARAMS((bfd *, struct bfd_link_info *));  
 static boolean elf64_x86_64_create_dynamic_sections  
   PARAMS((bfd *, struct bfd_link_info *));  
 static void elf64_x86_64_copy_indirect_symbol  
   PARAMS ((struct elf_link_hash_entry *, struct elf_link_hash_entry *));  
 static boolean elf64_x86_64_check_relocs  
   PARAMS ((bfd *, struct bfd_link_info *, asection *sec,  
            const Elf_Internal_Rela *));  
 static asection *elf64_x86_64_gc_mark_hook  
   PARAMS ((asection *, struct bfd_link_info *, Elf_Internal_Rela *,  
            struct elf_link_hash_entry *, Elf_Internal_Sym *));  
   
 static boolean elf64_x86_64_gc_sweep_hook  
   PARAMS ((bfd *, struct bfd_link_info *, asection *,  
            const Elf_Internal_Rela *));  
   
 static struct bfd_hash_entry *link_hash_newfunc  
   PARAMS ((struct bfd_hash_entry *, struct bfd_hash_table *, const char *));  
 static boolean elf64_x86_64_adjust_dynamic_symbol  
   PARAMS ((struct bfd_link_info *, struct elf_link_hash_entry *));  
   
 static boolean allocate_dynrelocs  
   PARAMS ((struct elf_link_hash_entry *, PTR));  
 static boolean readonly_dynrelocs  
   PARAMS ((struct elf_link_hash_entry *, PTR));  
 static boolean elf64_x86_64_size_dynamic_sections  
   PARAMS ((bfd *, struct bfd_link_info *));  
 static boolean elf64_x86_64_relocate_section  
   PARAMS ((bfd *, struct bfd_link_info *, bfd *, asection *, bfd_byte *,  
          Elf_Internal_Rela *, Elf_Internal_Sym *, asection **));  
 static boolean elf64_x86_64_finish_dynamic_symbol  
   PARAMS ((bfd *, struct bfd_link_info *, struct elf_link_hash_entry *,  
            Elf_Internal_Sym *sym));  
 static boolean elf64_x86_64_finish_dynamic_sections  
   PARAMS ((bfd *, struct bfd_link_info *));  
 static enum elf_reloc_type_class elf64_x86_64_reloc_type_class  
   PARAMS ((const Elf_Internal_Rela *));  
154    
155  /* Given a BFD reloc type, return a HOWTO structure.  */  /* Given a BFD reloc type, return a HOWTO structure.  */
156  static reloc_howto_type *  static reloc_howto_type *
157  elf64_x86_64_reloc_type_lookup (abfd, code)  elf64_x86_64_reloc_type_lookup (bfd *abfd ATTRIBUTE_UNUSED,
158       bfd *abfd ATTRIBUTE_UNUSED;                                  bfd_reloc_code_real_type code)
      bfd_reloc_code_real_type code;  
159  {  {
160    unsigned int i;    unsigned int i;
161    
162    for (i = 0; i < sizeof (x86_64_reloc_map) / sizeof (struct elf_reloc_map);    for (i = 0; i < sizeof (x86_64_reloc_map) / sizeof (struct elf_reloc_map);
163         i++)         i++)
164      {      {
# Line 190  elf64_x86_64_reloc_type_lookup (abfd, co Line 171  elf64_x86_64_reloc_type_lookup (abfd, co
171  /* Given an x86_64 ELF reloc type, fill in an arelent structure.  */  /* Given an x86_64 ELF reloc type, fill in an arelent structure.  */
172    
173  static void  static void
174  elf64_x86_64_info_to_howto (abfd, cache_ptr, dst)  elf64_x86_64_info_to_howto (bfd *abfd ATTRIBUTE_UNUSED, arelent *cache_ptr,
175       bfd *abfd ATTRIBUTE_UNUSED;                              Elf_Internal_Rela *dst)
      arelent *cache_ptr;  
      Elf64_Internal_Rela *dst;  
176  {  {
177    unsigned r_type, i;    unsigned r_type, i;
178    
179    r_type = ELF64_R_TYPE (dst->r_info);    r_type = ELF64_R_TYPE (dst->r_info);
180    if (r_type < (unsigned int) R_X86_64_GNU_VTINHERIT)    if (r_type < (unsigned int) R_X86_64_GNU_VTINHERIT)
181      {      {
182        BFD_ASSERT (r_type <= (unsigned int) R_X86_64_PC8);        BFD_ASSERT (r_type <= (unsigned int) R_X86_64_TPOFF32);
183        i = r_type;        i = r_type;
184      }      }
185    else    else
186      {      {
187        BFD_ASSERT (r_type < (unsigned int) R_X86_64_max);        BFD_ASSERT (r_type < (unsigned int) R_X86_64_max);
188        i = r_type - ((unsigned int) R_X86_64_GNU_VTINHERIT - R_X86_64_PC8 - 1);        i = r_type - ((unsigned int) R_X86_64_GNU_VTINHERIT - R_X86_64_TPOFF32 - 1);
189      }      }
190    cache_ptr->howto = &x86_64_elf_howto_table[i];    cache_ptr->howto = &x86_64_elf_howto_table[i];
191    BFD_ASSERT (r_type == cache_ptr->howto->type);    BFD_ASSERT (r_type == cache_ptr->howto->type);
192  }  }
193    
194  /* Support for core dump NOTE sections.  */  /* Support for core dump NOTE sections.  */
195  static boolean  static bfd_boolean
196  elf64_x86_64_grok_prstatus (abfd, note)  elf64_x86_64_grok_prstatus (bfd *abfd, Elf_Internal_Note *note)
      bfd *abfd;  
      Elf_Internal_Note *note;  
197  {  {
198    int offset;    int offset;
199    size_t raw_size;    size_t size;
200    
201    switch (note->descsz)    switch (note->descsz)
202      {      {
203        default:        default:
204          return false;          return FALSE;
205    
206        case 336:         /* sizeof(istruct elf_prstatus) on Linux/x86_64 */        case 336:         /* sizeof(istruct elf_prstatus) on Linux/x86_64 */
207          /* pr_cursig */          /* pr_cursig */
# Line 237  elf64_x86_64_grok_prstatus (abfd, note) Line 214  elf64_x86_64_grok_prstatus (abfd, note)
214    
215          /* pr_reg */          /* pr_reg */
216          offset = 112;          offset = 112;
217          raw_size = 216;          size = 216;
218    
219          break;          break;
220      }      }
221    
222    /* Make a ".reg/999" section.  */    /* Make a ".reg/999" section.  */
223    return _bfd_elfcore_make_pseudosection (abfd, ".reg",    return _bfd_elfcore_make_pseudosection (abfd, ".reg",
224                                            raw_size, note->descpos + offset);                                            size, note->descpos + offset);
225  }  }
226    
227  static boolean  static bfd_boolean
228  elf64_x86_64_grok_psinfo (abfd, note)  elf64_x86_64_grok_psinfo (bfd *abfd, Elf_Internal_Note *note)
      bfd *abfd;  
      Elf_Internal_Note *note;  
229  {  {
230    switch (note->descsz)    switch (note->descsz)
231      {      {
232        default:        default:
233          return false;          return FALSE;
234    
235        case 136:         /* sizeof(struct elf_prpsinfo) on Linux/x86_64 */        case 136:         /* sizeof(struct elf_prpsinfo) on Linux/x86_64 */
236          elf_tdata (abfd)->core_program          elf_tdata (abfd)->core_program
# Line 276  elf64_x86_64_grok_psinfo (abfd, note) Line 251  elf64_x86_64_grok_psinfo (abfd, note)
251        command[n - 1] = '\0';        command[n - 1] = '\0';
252    }    }
253    
254    return true;    return TRUE;
255  }  }
256    
257  /* Functions for the x86-64 ELF linker.  */  /* Functions for the x86-64 ELF linker.  */
# Line 286  elf64_x86_64_grok_psinfo (abfd, note) Line 261  elf64_x86_64_grok_psinfo (abfd, note)
261    
262  #define ELF_DYNAMIC_INTERPRETER "/lib/ld64.so.1"  #define ELF_DYNAMIC_INTERPRETER "/lib/ld64.so.1"
263    
264    /* If ELIMINATE_COPY_RELOCS is non-zero, the linker will try to avoid
265       copying dynamic variables from a shared lib into an app's dynbss
266       section, and instead use a dynamic relocation to point into the
267       shared lib.  */
268    #define ELIMINATE_COPY_RELOCS 1
269    
270  /* The size in bytes of an entry in the global offset table.  */  /* The size in bytes of an entry in the global offset table.  */
271    
272  #define GOT_ENTRY_SIZE 8  #define GOT_ENTRY_SIZE 8
# Line 345  struct elf64_x86_64_link_hash_entry Line 326  struct elf64_x86_64_link_hash_entry
326    
327    /* Track dynamic relocs copied for this symbol.  */    /* Track dynamic relocs copied for this symbol.  */
328    struct elf64_x86_64_dyn_relocs *dyn_relocs;    struct elf64_x86_64_dyn_relocs *dyn_relocs;
329    
330    #define GOT_UNKNOWN     0
331    #define GOT_NORMAL      1
332    #define GOT_TLS_GD      2
333    #define GOT_TLS_IE      3
334      unsigned char tls_type;
335    };
336    
337    #define elf64_x86_64_hash_entry(ent) \
338      ((struct elf64_x86_64_link_hash_entry *)(ent))
339    
340    struct elf64_x86_64_obj_tdata
341    {
342      struct elf_obj_tdata root;
343    
344      /* tls_type for each local got entry.  */
345      char *local_got_tls_type;
346  };  };
347    
348    #define elf64_x86_64_tdata(abfd) \
349      ((struct elf64_x86_64_obj_tdata *) (abfd)->tdata.any)
350    
351    #define elf64_x86_64_local_got_tls_type(abfd) \
352      (elf64_x86_64_tdata (abfd)->local_got_tls_type)
353    
354    
355  /* x86-64 ELF linker hash table.  */  /* x86-64 ELF linker hash table.  */
356    
357  struct elf64_x86_64_link_hash_table  struct elf64_x86_64_link_hash_table
# Line 362  struct elf64_x86_64_link_hash_table Line 367  struct elf64_x86_64_link_hash_table
367    asection *sdynbss;    asection *sdynbss;
368    asection *srelbss;    asection *srelbss;
369    
370      union {
371        bfd_signed_vma refcount;
372        bfd_vma offset;
373      } tls_ld_got;
374    
375    /* Small local sym to section mapping cache.  */    /* Small local sym to section mapping cache.  */
376    struct sym_sec_cache sym_sec;    struct sym_sec_cache sym_sec;
377  };  };
# Line 374  struct elf64_x86_64_link_hash_table Line 384  struct elf64_x86_64_link_hash_table
384  /* Create an entry in an x86-64 ELF linker hash table.  */  /* Create an entry in an x86-64 ELF linker hash table.  */
385    
386  static struct bfd_hash_entry *  static struct bfd_hash_entry *
387  link_hash_newfunc (entry, table, string)  link_hash_newfunc (struct bfd_hash_entry *entry, struct bfd_hash_table *table,
388       struct bfd_hash_entry *entry;                     const char *string)
      struct bfd_hash_table *table;  
      const char *string;  
389  {  {
390    /* Allocate the structure if it has not already been allocated by a    /* Allocate the structure if it has not already been allocated by a
391       subclass.  */       subclass.  */
# Line 397  link_hash_newfunc (entry, table, string) Line 405  link_hash_newfunc (entry, table, string)
405    
406        eh = (struct elf64_x86_64_link_hash_entry *) entry;        eh = (struct elf64_x86_64_link_hash_entry *) entry;
407        eh->dyn_relocs = NULL;        eh->dyn_relocs = NULL;
408          eh->tls_type = GOT_UNKNOWN;
409      }      }
410    
411    return entry;    return entry;
# Line 405  link_hash_newfunc (entry, table, string) Line 414  link_hash_newfunc (entry, table, string)
414  /* Create an X86-64 ELF linker hash table.  */  /* Create an X86-64 ELF linker hash table.  */
415    
416  static struct bfd_link_hash_table *  static struct bfd_link_hash_table *
417  elf64_x86_64_link_hash_table_create (abfd)  elf64_x86_64_link_hash_table_create (bfd *abfd)
      bfd *abfd;  
418  {  {
419    struct elf64_x86_64_link_hash_table *ret;    struct elf64_x86_64_link_hash_table *ret;
420    bfd_size_type amt = sizeof (struct elf64_x86_64_link_hash_table);    bfd_size_type amt = sizeof (struct elf64_x86_64_link_hash_table);
# Line 429  elf64_x86_64_link_hash_table_create (abf Line 437  elf64_x86_64_link_hash_table_create (abf
437    ret->sdynbss = NULL;    ret->sdynbss = NULL;
438    ret->srelbss = NULL;    ret->srelbss = NULL;
439    ret->sym_sec.abfd = NULL;    ret->sym_sec.abfd = NULL;
440      ret->tls_ld_got.refcount = 0;
441    
442    return &ret->elf.root;    return &ret->elf.root;
443  }  }
# Line 436  elf64_x86_64_link_hash_table_create (abf Line 445  elf64_x86_64_link_hash_table_create (abf
445  /* Create .got, .gotplt, and .rela.got sections in DYNOBJ, and set up  /* Create .got, .gotplt, and .rela.got sections in DYNOBJ, and set up
446     shortcuts to them in our hash table.  */     shortcuts to them in our hash table.  */
447    
448  static boolean  static bfd_boolean
449  create_got_section (dynobj, info)  create_got_section (bfd *dynobj, struct bfd_link_info *info)
      bfd *dynobj;  
      struct bfd_link_info *info;  
450  {  {
451    struct elf64_x86_64_link_hash_table *htab;    struct elf64_x86_64_link_hash_table *htab;
452    
453    if (! _bfd_elf_create_got_section (dynobj, info))    if (! _bfd_elf_create_got_section (dynobj, info))
454      return false;      return FALSE;
455    
456    htab = elf64_x86_64_hash_table (info);    htab = elf64_x86_64_hash_table (info);
457    htab->sgot = bfd_get_section_by_name (dynobj, ".got");    htab->sgot = bfd_get_section_by_name (dynobj, ".got");
# Line 459  create_got_section (dynobj, info) Line 466  create_got_section (dynobj, info)
466                                     | SEC_IN_MEMORY | SEC_LINKER_CREATED                                     | SEC_IN_MEMORY | SEC_LINKER_CREATED
467                                     | SEC_READONLY))                                     | SEC_READONLY))
468        || ! bfd_set_section_alignment (dynobj, htab->srelgot, 3))        || ! bfd_set_section_alignment (dynobj, htab->srelgot, 3))
469      return false;      return FALSE;
470    return true;    return TRUE;
471  }  }
472    
473  /* Create .plt, .rela.plt, .got, .got.plt, .rela.got, .dynbss, and  /* Create .plt, .rela.plt, .got, .got.plt, .rela.got, .dynbss, and
474     .rela.bss sections in DYNOBJ, and set up shortcuts to them in our     .rela.bss sections in DYNOBJ, and set up shortcuts to them in our
475     hash table.  */     hash table.  */
476    
477  static boolean  static bfd_boolean
478  elf64_x86_64_create_dynamic_sections (dynobj, info)  elf64_x86_64_create_dynamic_sections (bfd *dynobj, struct bfd_link_info *info)
      bfd *dynobj;  
      struct bfd_link_info *info;  
479  {  {
480    struct elf64_x86_64_link_hash_table *htab;    struct elf64_x86_64_link_hash_table *htab;
481    
482    htab = elf64_x86_64_hash_table (info);    htab = elf64_x86_64_hash_table (info);
483    if (!htab->sgot && !create_got_section (dynobj, info))    if (!htab->sgot && !create_got_section (dynobj, info))
484      return false;      return FALSE;
485    
486    if (!_bfd_elf_create_dynamic_sections (dynobj, info))    if (!_bfd_elf_create_dynamic_sections (dynobj, info))
487      return false;      return FALSE;
488    
489    htab->splt = bfd_get_section_by_name (dynobj, ".plt");    htab->splt = bfd_get_section_by_name (dynobj, ".plt");
490    htab->srelplt = bfd_get_section_by_name (dynobj, ".rela.plt");    htab->srelplt = bfd_get_section_by_name (dynobj, ".rela.plt");
# Line 491  elf64_x86_64_create_dynamic_sections (dy Line 496  elf64_x86_64_create_dynamic_sections (dy
496        || (!info->shared && !htab->srelbss))        || (!info->shared && !htab->srelbss))
497      abort ();      abort ();
498    
499    return true;    return TRUE;
500  }  }
501    
502  /* Copy the extra info we tack onto an elf_link_hash_entry.  */  /* Copy the extra info we tack onto an elf_link_hash_entry.  */
503    
504  static void  static void
505  elf64_x86_64_copy_indirect_symbol (dir, ind)  elf64_x86_64_copy_indirect_symbol (const struct elf_backend_data *bed,
506       struct elf_link_hash_entry *dir, *ind;                                     struct elf_link_hash_entry *dir,
507                                       struct elf_link_hash_entry *ind)
508  {  {
509    struct elf64_x86_64_link_hash_entry *edir, *eind;    struct elf64_x86_64_link_hash_entry *edir, *eind;
510    
# Line 539  elf64_x86_64_copy_indirect_symbol (dir, Line 545  elf64_x86_64_copy_indirect_symbol (dir,
545        eind->dyn_relocs = NULL;        eind->dyn_relocs = NULL;
546      }      }
547    
548    _bfd_elf_link_hash_copy_indirect (dir, ind);    if (ind->root.type == bfd_link_hash_indirect
549          && dir->got.refcount <= 0)
550        {
551          edir->tls_type = eind->tls_type;
552          eind->tls_type = GOT_UNKNOWN;
553        }
554    
555      if (ELIMINATE_COPY_RELOCS
556          && ind->root.type != bfd_link_hash_indirect
557          && dir->dynamic_adjusted)
558        {
559          /* If called to transfer flags for a weakdef during processing
560             of elf_adjust_dynamic_symbol, don't copy non_got_ref.
561             We clear it ourselves for ELIMINATE_COPY_RELOCS.  */
562          dir->ref_dynamic |= ind->ref_dynamic;
563          dir->ref_regular |= ind->ref_regular;
564          dir->ref_regular_nonweak |= ind->ref_regular_nonweak;
565          dir->needs_plt |= ind->needs_plt;
566          dir->pointer_equality_needed |= ind->pointer_equality_needed;
567        }
568      else
569        _bfd_elf_link_hash_copy_indirect (bed, dir, ind);
570  }  }
571    
572  static boolean  static bfd_boolean
573  elf64_x86_64_elf_object_p (abfd)  elf64_x86_64_mkobject (bfd *abfd)
574       bfd *abfd;  {
575      bfd_size_type amt = sizeof (struct elf64_x86_64_obj_tdata);
576      abfd->tdata.any = bfd_zalloc (abfd, amt);
577      if (abfd->tdata.any == NULL)
578        return FALSE;
579      return TRUE;
580    }
581    
582    static bfd_boolean
583    elf64_x86_64_elf_object_p (bfd *abfd)
584  {  {
585    /* Set the right machine number for an x86-64 elf64 file.  */    /* Set the right machine number for an x86-64 elf64 file.  */
586    bfd_default_set_arch_mach (abfd, bfd_arch_i386, bfd_mach_x86_64);    bfd_default_set_arch_mach (abfd, bfd_arch_i386, bfd_mach_x86_64);
587    return true;    return TRUE;
588    }
589    
590    static int
591    elf64_x86_64_tls_transition (struct bfd_link_info *info, int r_type, int is_local)
592    {
593      if (info->shared)
594        return r_type;
595    
596      switch (r_type)
597        {
598        case R_X86_64_TLSGD:
599        case R_X86_64_GOTTPOFF:
600          if (is_local)
601            return R_X86_64_TPOFF32;
602          return R_X86_64_GOTTPOFF;
603        case R_X86_64_TLSLD:
604          return R_X86_64_TPOFF32;
605        }
606    
607       return r_type;
608  }  }
609    
610  /* Look through the relocs for a section during the first phase, and  /* Look through the relocs for a section during the first phase, and
611     calculate needed space in the global offset table, procedure     calculate needed space in the global offset table, procedure
612     linkage table, and dynamic reloc sections.  */     linkage table, and dynamic reloc sections.  */
613    
614  static boolean  static bfd_boolean
615  elf64_x86_64_check_relocs (abfd, info, sec, relocs)  elf64_x86_64_check_relocs (bfd *abfd, struct bfd_link_info *info, asection *sec,
616       bfd *abfd;                             const Elf_Internal_Rela *relocs)
      struct bfd_link_info *info;  
      asection *sec;  
      const Elf_Internal_Rela *relocs;  
617  {  {
618    struct elf64_x86_64_link_hash_table *htab;    struct elf64_x86_64_link_hash_table *htab;
619    Elf_Internal_Shdr *symtab_hdr;    Elf_Internal_Shdr *symtab_hdr;
# Line 569  elf64_x86_64_check_relocs (abfd, info, s Line 622  elf64_x86_64_check_relocs (abfd, info, s
622    const Elf_Internal_Rela *rel_end;    const Elf_Internal_Rela *rel_end;
623    asection *sreloc;    asection *sreloc;
624    
625    if (info->relocateable)    if (info->relocatable)
626      return true;      return TRUE;
627    
628    htab = elf64_x86_64_hash_table (info);    htab = elf64_x86_64_hash_table (info);
629    symtab_hdr = &elf_tdata (abfd)->symtab_hdr;    symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
# Line 581  elf64_x86_64_check_relocs (abfd, info, s Line 634  elf64_x86_64_check_relocs (abfd, info, s
634    rel_end = relocs + sec->reloc_count;    rel_end = relocs + sec->reloc_count;
635    for (rel = relocs; rel < rel_end; rel++)    for (rel = relocs; rel < rel_end; rel++)
636      {      {
637          unsigned int r_type;
638        unsigned long r_symndx;        unsigned long r_symndx;
639        struct elf_link_hash_entry *h;        struct elf_link_hash_entry *h;
640    
641        r_symndx = ELF64_R_SYM (rel->r_info);        r_symndx = ELF64_R_SYM (rel->r_info);
642          r_type = ELF64_R_TYPE (rel->r_info);
643    
644        if (r_symndx >= NUM_SHDR_ENTRIES (symtab_hdr))        if (r_symndx >= NUM_SHDR_ENTRIES (symtab_hdr))
645          {          {
646            (*_bfd_error_handler) (_("%s: bad symbol index: %d"),            (*_bfd_error_handler) (_("%B: bad symbol index: %d"),
647                                   bfd_archive_filename (abfd),                                   abfd, r_symndx);
648                                   r_symndx);            return FALSE;
           return false;  
649          }          }
650    
651        if (r_symndx < symtab_hdr->sh_info)        if (r_symndx < symtab_hdr->sh_info)
# Line 599  elf64_x86_64_check_relocs (abfd, info, s Line 653  elf64_x86_64_check_relocs (abfd, info, s
653        else        else
654          h = sym_hashes[r_symndx - symtab_hdr->sh_info];          h = sym_hashes[r_symndx - symtab_hdr->sh_info];
655    
656        switch (ELF64_R_TYPE (rel->r_info))        r_type = elf64_x86_64_tls_transition (info, r_type, h == NULL);
657          switch (r_type)
658          {          {
659            case R_X86_64_TLSLD:
660              htab->tls_ld_got.refcount += 1;
661              goto create_got;
662    
663            case R_X86_64_TPOFF32:
664              if (info->shared)
665                {
666                  (*_bfd_error_handler)
667                    (_("%B: relocation %s against `%s' can not be used when making a shared object; recompile with -fPIC"),
668                     abfd,
669                     x86_64_elf_howto_table[r_type].name,
670                     (h) ? h->root.root.string : "a local symbol");
671                  bfd_set_error (bfd_error_bad_value);
672                  return FALSE;
673                }
674              break;
675    
676            case R_X86_64_GOTTPOFF:
677              if (info->shared)
678                info->flags |= DF_STATIC_TLS;
679              /* Fall through */
680    
681          case R_X86_64_GOT32:          case R_X86_64_GOT32:
682          case R_X86_64_GOTPCREL:          case R_X86_64_GOTPCREL:
683            case R_X86_64_TLSGD:
684            /* This symbol requires a global offset table entry.  */            /* This symbol requires a global offset table entry.  */
685            if (h != NULL)            {
686              {              int tls_type, old_tls_type;
               h->got.refcount += 1;  
             }  
           else  
             {  
               bfd_signed_vma *local_got_refcounts;  
687    
688                /* This is a global offset table entry for a local symbol.  */              switch (r_type)
689                local_got_refcounts = elf_local_got_refcounts (abfd);                {
690                if (local_got_refcounts == NULL)                default: tls_type = GOT_NORMAL; break;
691                  {                case R_X86_64_TLSGD: tls_type = GOT_TLS_GD; break;
692                    bfd_size_type size;                case R_X86_64_GOTTPOFF: tls_type = GOT_TLS_IE; break;
693                  }
694    
695                if (h != NULL)
696                  {
697                    h->got.refcount += 1;
698                    old_tls_type = elf64_x86_64_hash_entry (h)->tls_type;
699                  }
700                else
701                  {
702                    bfd_signed_vma *local_got_refcounts;
703    
704                    /* This is a global offset table entry for a local symbol.  */
705                    local_got_refcounts = elf_local_got_refcounts (abfd);
706                    if (local_got_refcounts == NULL)
707                      {
708                        bfd_size_type size;
709    
710                    size = symtab_hdr->sh_info;                      size = symtab_hdr->sh_info;
711                    size *= sizeof (bfd_signed_vma);                      size *= sizeof (bfd_signed_vma) + sizeof (char);
712                    local_got_refcounts = ((bfd_signed_vma *)                      local_got_refcounts = ((bfd_signed_vma *)
713                                           bfd_zalloc (abfd, size));                                             bfd_zalloc (abfd, size));
714                    if (local_got_refcounts == NULL)                      if (local_got_refcounts == NULL)
715                      return false;                        return FALSE;
716                    elf_local_got_refcounts (abfd) = local_got_refcounts;                      elf_local_got_refcounts (abfd) = local_got_refcounts;
717                  }                      elf64_x86_64_local_got_tls_type (abfd)
718                local_got_refcounts[r_symndx] += 1;                        = (char *) (local_got_refcounts + symtab_hdr->sh_info);
719              }                    }
720                    local_got_refcounts[r_symndx] += 1;
721                    old_tls_type
722                      = elf64_x86_64_local_got_tls_type (abfd) [r_symndx];
723                  }
724    
725                /* If a TLS symbol is accessed using IE at least once,
726                   there is no point to use dynamic model for it.  */
727                if (old_tls_type != tls_type && old_tls_type != GOT_UNKNOWN
728                    && (old_tls_type != GOT_TLS_GD || tls_type != GOT_TLS_IE))
729                  {
730                    if (old_tls_type == GOT_TLS_IE && tls_type == GOT_TLS_GD)
731                      tls_type = old_tls_type;
732                    else
733                      {
734                        (*_bfd_error_handler)
735                          (_("%B: %s' accessed both as normal and thread local symbol"),
736                           abfd, h ? h->root.root.string : "<local>");
737                        return FALSE;
738                      }
739                  }
740    
741                if (old_tls_type != tls_type)
742                  {
743                    if (h != NULL)
744                      elf64_x86_64_hash_entry (h)->tls_type = tls_type;
745                    else
746                      elf64_x86_64_local_got_tls_type (abfd) [r_symndx] = tls_type;
747                  }
748              }
749            /* Fall through */            /* Fall through */
750    
751            //case R_X86_64_GOTPCREL:            //case R_X86_64_GOTPCREL:
752            create_got:
753            if (htab->sgot == NULL)            if (htab->sgot == NULL)
754              {              {
755                if (htab->elf.dynobj == NULL)                if (htab->elf.dynobj == NULL)
756                  htab->elf.dynobj = abfd;                  htab->elf.dynobj = abfd;
757                if (!create_got_section (htab->elf.dynobj, info))                if (!create_got_section (htab->elf.dynobj, info))
758                  return false;                  return FALSE;
759              }              }
760            break;            break;
761    
# Line 653  elf64_x86_64_check_relocs (abfd, info, s Line 772  elf64_x86_64_check_relocs (abfd, info, s
772            if (h == NULL)            if (h == NULL)
773              continue;              continue;
774    
775            h->elf_link_hash_flags |= ELF_LINK_HASH_NEEDS_PLT;            h->needs_plt = 1;
776            h->plt.refcount += 1;            h->plt.refcount += 1;
777            break;            break;
778    
# Line 670  elf64_x86_64_check_relocs (abfd, info, s Line 789  elf64_x86_64_check_relocs (abfd, info, s
789                && (sec->flags & SEC_READONLY) != 0)                && (sec->flags & SEC_READONLY) != 0)
790              {              {
791                (*_bfd_error_handler)                (*_bfd_error_handler)
792                  (_("%s: relocation %s can not be used when making a shared object; recompile with -fPIC"),                  (_("%B: relocation %s against `%s' can not be used when making a shared object; recompile with -fPIC"),
793                   bfd_archive_filename (abfd),                   abfd,
794                   x86_64_elf_howto_table[ELF64_R_TYPE (rel->r_info)].name);                   x86_64_elf_howto_table[r_type].name,
795                     (h) ? h->root.root.string : "a local symbol");
796                bfd_set_error (bfd_error_bad_value);                bfd_set_error (bfd_error_bad_value);
797                return false;                return FALSE;
798              }              }
799            /* Fall through.  */            /* Fall through.  */
800    
# Line 690  elf64_x86_64_check_relocs (abfd, info, s Line 810  elf64_x86_64_check_relocs (abfd, info, s
810                   sections have not yet been mapped to output sections.                   sections have not yet been mapped to output sections.
811                   Tentatively set the flag for now, and correct in                   Tentatively set the flag for now, and correct in
812                   adjust_dynamic_symbol.  */                   adjust_dynamic_symbol.  */
813                h->elf_link_hash_flags |= ELF_LINK_NON_GOT_REF;                h->non_got_ref = 1;
814    
815                /* We may need a .plt entry if the function this reloc                /* We may need a .plt entry if the function this reloc
816                   refers to is in a shared lib.  */                   refers to is in a shared lib.  */
817                h->plt.refcount += 1;                h->plt.refcount += 1;
818                  if (r_type != R_X86_64_PC32)
819                    h->pointer_equality_needed = 1;
820              }              }
821    
822            /* If we are creating a shared library, and this is a reloc            /* If we are creating a shared library, and this is a reloc
# Line 720  elf64_x86_64_check_relocs (abfd, info, s Line 842  elf64_x86_64_check_relocs (abfd, info, s
842               symbol.  */               symbol.  */
843            if ((info->shared            if ((info->shared
844                 && (sec->flags & SEC_ALLOC) != 0                 && (sec->flags & SEC_ALLOC) != 0
845                 && (((ELF64_R_TYPE (rel->r_info) != R_X86_64_PC8)                 && (((r_type != R_X86_64_PC8)
846                      && (ELF64_R_TYPE (rel->r_info) != R_X86_64_PC16)                      && (r_type != R_X86_64_PC16)
847                      && (ELF64_R_TYPE (rel->r_info) != R_X86_64_PC32))                      && (r_type != R_X86_64_PC32))
848                     || (h != NULL                     || (h != NULL
849                         && (! info->symbolic                         && (! info->symbolic
850                             || h->root.type == bfd_link_hash_defweak                             || h->root.type == bfd_link_hash_defweak
851                             || (h->elf_link_hash_flags                             || !h->def_regular))))
852                                 & ELF_LINK_HASH_DEF_REGULAR) == 0))))                || (ELIMINATE_COPY_RELOCS
853                || (!info->shared                    && !info->shared
854                    && (sec->flags & SEC_ALLOC) != 0                    && (sec->flags & SEC_ALLOC) != 0
855                    && h != NULL                    && h != NULL
856                    && (h->root.type == bfd_link_hash_defweak                    && (h->root.type == bfd_link_hash_defweak
857                        || (h->elf_link_hash_flags                        || !h->def_regular)))
                           & ELF_LINK_HASH_DEF_REGULAR) == 0)))  
858              {              {
859                struct elf64_x86_64_dyn_relocs *p;                struct elf64_x86_64_dyn_relocs *p;
860                struct elf64_x86_64_dyn_relocs **head;                struct elf64_x86_64_dyn_relocs **head;
# Line 751  elf64_x86_64_check_relocs (abfd, info, s Line 872  elf64_x86_64_check_relocs (abfd, info, s
872                             elf_elfheader (abfd)->e_shstrndx,                             elf_elfheader (abfd)->e_shstrndx,
873                             elf_section_data (sec)->rel_hdr.sh_name));                             elf_section_data (sec)->rel_hdr.sh_name));
874                    if (name == NULL)                    if (name == NULL)
875                      return false;                      return FALSE;
876    
877                    if (strncmp (name, ".rela", 5) != 0                    if (strncmp (name, ".rela", 5) != 0
878                        || strcmp (bfd_get_section_name (abfd, sec),                        || strcmp (bfd_get_section_name (abfd, sec),
879                                   name + 5) != 0)                                   name + 5) != 0)
880                      {                      {
881                        (*_bfd_error_handler)                        (*_bfd_error_handler)
882                          (_("%s: bad relocation section name `%s\'"),                          (_("%B: bad relocation section name `%s\'"),
883                           bfd_archive_filename (abfd), name);                           abfd, name);
884                      }                      }
885    
886                    if (htab->elf.dynobj == NULL)                    if (htab->elf.dynobj == NULL)
# Line 780  elf64_x86_64_check_relocs (abfd, info, s Line 901  elf64_x86_64_check_relocs (abfd, info, s
901                        if (sreloc == NULL                        if (sreloc == NULL
902                            || ! bfd_set_section_flags (dynobj, sreloc, flags)                            || ! bfd_set_section_flags (dynobj, sreloc, flags)
903                            || ! bfd_set_section_alignment (dynobj, sreloc, 3))                            || ! bfd_set_section_alignment (dynobj, sreloc, 3))
904                          return false;                          return FALSE;
905                      }                      }
906                    elf_section_data (sec)->sreloc = sreloc;                    elf_section_data (sec)->sreloc = sreloc;
907                  }                  }
# Line 801  elf64_x86_64_check_relocs (abfd, info, s Line 922  elf64_x86_64_check_relocs (abfd, info, s
922                    s = bfd_section_from_r_symndx (abfd, &htab->sym_sec,                    s = bfd_section_from_r_symndx (abfd, &htab->sym_sec,
923                                                   sec, r_symndx);                                                   sec, r_symndx);
924                    if (s == NULL)                    if (s == NULL)
925                      return false;                      return FALSE;
926    
927                    head = ((struct elf64_x86_64_dyn_relocs **)                    head = ((struct elf64_x86_64_dyn_relocs **)
928                            &elf_section_data (s)->local_dynrel);                            &elf_section_data (s)->local_dynrel);
# Line 814  elf64_x86_64_check_relocs (abfd, info, s Line 935  elf64_x86_64_check_relocs (abfd, info, s
935                    p = ((struct elf64_x86_64_dyn_relocs *)                    p = ((struct elf64_x86_64_dyn_relocs *)
936                         bfd_alloc (htab->elf.dynobj, amt));                         bfd_alloc (htab->elf.dynobj, amt));
937                    if (p == NULL)                    if (p == NULL)
938                      return false;                      return FALSE;
939                    p->next = *head;                    p->next = *head;
940                    *head = p;                    *head = p;
941                    p->sec = sec;                    p->sec = sec;
# Line 823  elf64_x86_64_check_relocs (abfd, info, s Line 944  elf64_x86_64_check_relocs (abfd, info, s
944                  }                  }
945    
946                p->count += 1;                p->count += 1;
947                if (ELF64_R_TYPE (rel->r_info) == R_X86_64_PC8                if (r_type == R_X86_64_PC8
948                    || ELF64_R_TYPE (rel->r_info) == R_X86_64_PC16                    || r_type == R_X86_64_PC16
949                    || ELF64_R_TYPE (rel->r_info) == R_X86_64_PC32)                    || r_type == R_X86_64_PC32)
950                  p->pc_count += 1;                  p->pc_count += 1;
951              }              }
952            break;            break;
# Line 833  elf64_x86_64_check_relocs (abfd, info, s Line 954  elf64_x86_64_check_relocs (abfd, info, s
954            /* This relocation describes the C++ object vtable hierarchy.            /* This relocation describes the C++ object vtable hierarchy.
955               Reconstruct it for later use during GC.  */               Reconstruct it for later use during GC.  */
956          case R_X86_64_GNU_VTINHERIT:          case R_X86_64_GNU_VTINHERIT:
957            if (!_bfd_elf64_gc_record_vtinherit (abfd, sec, h, rel->r_offset))            if (!bfd_elf_gc_record_vtinherit (abfd, sec, h, rel->r_offset))
958              return false;              return FALSE;
959            break;            break;
960    
961            /* This relocation describes which C++ vtable entries are actually            /* This relocation describes which C++ vtable entries are actually
962               used.  Record for later use during GC.  */               used.  Record for later use during GC.  */
963          case R_X86_64_GNU_VTENTRY:          case R_X86_64_GNU_VTENTRY:
964            if (!_bfd_elf64_gc_record_vtentry (abfd, sec, h, rel->r_addend))            if (!bfd_elf_gc_record_vtentry (abfd, sec, h, rel->r_addend))
965              return false;              return FALSE;
966            break;            break;
967    
968          default:          default:
# Line 849  elf64_x86_64_check_relocs (abfd, info, s Line 970  elf64_x86_64_check_relocs (abfd, info, s
970          }          }
971      }      }
972    
973    return true;    return TRUE;
974  }  }
975    
976  /* Return the section that should be marked against GC for a given  /* Return the section that should be marked against GC for a given
977     relocation.  */     relocation.  */
978    
979  static asection *  static asection *
980  elf64_x86_64_gc_mark_hook (sec, info, rel, h, sym)  elf64_x86_64_gc_mark_hook (asection *sec,
981       asection *sec;                             struct bfd_link_info *info ATTRIBUTE_UNUSED,
982       struct bfd_link_info *info ATTRIBUTE_UNUSED;                             Elf_Internal_Rela *rel,
983       Elf_Internal_Rela *rel;                             struct elf_link_hash_entry *h,
984       struct elf_link_hash_entry *h;                             Elf_Internal_Sym *sym)
      Elf_Internal_Sym *sym;  
985  {  {
986    if (h != NULL)    if (h != NULL)
987      {      {
# Line 894  elf64_x86_64_gc_mark_hook (sec, info, re Line 1014  elf64_x86_64_gc_mark_hook (sec, info, re
1014    
1015  /* Update the got entry reference counts for the section being removed.  */  /* Update the got entry reference counts for the section being removed.  */
1016    
1017  static boolean  static bfd_boolean
1018  elf64_x86_64_gc_sweep_hook (abfd, info, sec, relocs)  elf64_x86_64_gc_sweep_hook (bfd *abfd, struct bfd_link_info *info,
1019       bfd *abfd;                              asection *sec, const Elf_Internal_Rela *relocs)
      struct bfd_link_info *info;  
      asection *sec;  
      const Elf_Internal_Rela *relocs;  
1020  {  {
1021    Elf_Internal_Shdr *symtab_hdr;    Elf_Internal_Shdr *symtab_hdr;
1022    struct elf_link_hash_entry **sym_hashes;    struct elf_link_hash_entry **sym_hashes;
1023    bfd_signed_vma *local_got_refcounts;    bfd_signed_vma *local_got_refcounts;
1024    const Elf_Internal_Rela *rel, *relend;    const Elf_Internal_Rela *rel, *relend;
   unsigned long r_symndx;  
   struct elf_link_hash_entry *h;  
1025    
1026    elf_section_data (sec)->local_dynrel = NULL;    elf_section_data (sec)->local_dynrel = NULL;
1027    
# Line 916  elf64_x86_64_gc_sweep_hook (abfd, info, Line 1031  elf64_x86_64_gc_sweep_hook (abfd, info,
1031    
1032    relend = relocs + sec->reloc_count;    relend = relocs + sec->reloc_count;
1033    for (rel = relocs; rel < relend; rel++)    for (rel = relocs; rel < relend; rel++)
1034      switch (ELF64_R_TYPE (rel->r_info))      {
1035        {        unsigned long r_symndx;
1036        case R_X86_64_GOT32:        unsigned int r_type;
1037        case R_X86_64_GOTPCREL:        struct elf_link_hash_entry *h = NULL;
         r_symndx = ELF64_R_SYM (rel->r_info);  
         if (r_symndx >= symtab_hdr->sh_info)  
           {  
             h = sym_hashes[r_symndx - symtab_hdr->sh_info];  
             if (h->got.refcount > 0)  
               h->got.refcount -= 1;  
           }  
         else if (local_got_refcounts != NULL)  
           {  
             if (local_got_refcounts[r_symndx] > 0)  
               local_got_refcounts[r_symndx] -= 1;  
           }  
         break;  
1038    
1039        case R_X86_64_8:        r_symndx = ELF64_R_SYM (rel->r_info);
1040        case R_X86_64_16:        if (r_symndx >= symtab_hdr->sh_info)
1041        case R_X86_64_32:          {
1042        case R_X86_64_64:            struct elf64_x86_64_link_hash_entry *eh;
1043        case R_X86_64_32S:            struct elf64_x86_64_dyn_relocs **pp;
1044        case R_X86_64_PC8:            struct elf64_x86_64_dyn_relocs *p;
       case R_X86_64_PC16:  
       case R_X86_64_PC32:  
         r_symndx = ELF64_R_SYM (rel->r_info);  
         if (r_symndx >= symtab_hdr->sh_info)  
           {  
             struct elf64_x86_64_link_hash_entry *eh;  
             struct elf64_x86_64_dyn_relocs **pp;  
             struct elf64_x86_64_dyn_relocs *p;  
1045    
1046              h = sym_hashes[r_symndx - symtab_hdr->sh_info];            h = sym_hashes[r_symndx - symtab_hdr->sh_info];
1047              while (h->root.type == bfd_link_hash_indirect
1048                     || h->root.type == bfd_link_hash_warning)
1049                h = (struct elf_link_hash_entry *) h->root.u.i.link;
1050              eh = (struct elf64_x86_64_link_hash_entry *) h;
1051    
1052              if (!info->shared && h->plt.refcount > 0)            for (pp = &eh->dyn_relocs; (p = *pp) != NULL; pp = &p->next)
1053                h->plt.refcount -= 1;              if (p->sec == sec)
1054                  {
1055                    /* Everything must go for SEC.  */
1056                    *pp = p->next;
1057                    break;
1058                  }
1059            }
1060    
1061              eh = (struct elf64_x86_64_link_hash_entry *) h;        r_type = ELF64_R_TYPE (rel->r_info);
1062          r_type = elf64_x86_64_tls_transition (info, r_type, h != NULL);
1063          switch (r_type)
1064            {
1065            case R_X86_64_TLSLD:
1066              if (elf64_x86_64_hash_table (info)->tls_ld_got.refcount > 0)
1067                elf64_x86_64_hash_table (info)->tls_ld_got.refcount -= 1;
1068              break;
1069    
1070              for (pp = &eh->dyn_relocs; (p = *pp) != NULL; pp = &p->next)          case R_X86_64_TLSGD:
1071                if (p->sec == sec)          case R_X86_64_GOTTPOFF:
1072                  {          case R_X86_64_GOT32:
1073                    if (ELF64_R_TYPE (rel->r_info) == R_X86_64_PC8          case R_X86_64_GOTPCREL:
1074                        || ELF64_R_TYPE (rel->r_info) == R_X86_64_PC16            if (h != NULL)
1075                        || ELF64_R_TYPE (rel->r_info) == R_X86_64_PC32)              {
1076                      p->pc_count -= 1;                if (h->got.refcount > 0)
1077                    p->count -= 1;                  h->got.refcount -= 1;
1078                    if (p->count == 0)              }
1079                      *pp = p->next;            else if (local_got_refcounts != NULL)
1080                    break;              {
1081                  }                if (local_got_refcounts[r_symndx] > 0)
1082            }                  local_got_refcounts[r_symndx] -= 1;
1083          break;              }
1084              break;
1085    
1086            case R_X86_64_8:
1087            case R_X86_64_16:
1088            case R_X86_64_32:
1089            case R_X86_64_64:
1090            case R_X86_64_32S:
1091            case R_X86_64_PC8:
1092            case R_X86_64_PC16:
1093            case R_X86_64_PC32:
1094              if (info->shared)
1095                break;
1096              /* Fall thru */
1097    
1098        case R_X86_64_PLT32:          case R_X86_64_PLT32:
1099          r_symndx = ELF64_R_SYM (rel->r_info);            if (h != NULL)
1100          if (r_symndx >= symtab_hdr->sh_info)              {
1101            {                if (h->plt.refcount > 0)
1102              h = sym_hashes[r_symndx - symtab_hdr->sh_info];                  h->plt.refcount -= 1;
1103              if (h->plt.refcount > 0)              }
1104                h->plt.refcount -= 1;            break;
           }  
         break;  
1105    
1106        default:          default:
1107          break;            break;
1108        }          }
1109        }
1110    
1111    return true;    return TRUE;
1112  }  }
1113    
1114  /* Adjust a symbol defined by a dynamic object and referenced by a  /* Adjust a symbol defined by a dynamic object and referenced by a
# Line 995  elf64_x86_64_gc_sweep_hook (abfd, info, Line 1117  elf64_x86_64_gc_sweep_hook (abfd, info,
1117     change the definition to something the rest of the link can     change the definition to something the rest of the link can
1118     understand.  */     understand.  */
1119    
1120  static boolean  static bfd_boolean
1121  elf64_x86_64_adjust_dynamic_symbol (info, h)  elf64_x86_64_adjust_dynamic_symbol (struct bfd_link_info *info,
1122       struct bfd_link_info *info;                                      struct elf_link_hash_entry *h)
      struct elf_link_hash_entry *h;  
1123  {  {
1124    struct elf64_x86_64_link_hash_table *htab;    struct elf64_x86_64_link_hash_table *htab;
   struct elf64_x86_64_link_hash_entry * eh;  
   struct elf64_x86_64_dyn_relocs *p;  
1125    asection *s;    asection *s;
1126    unsigned int power_of_two;    unsigned int power_of_two;
1127    
# Line 1010  elf64_x86_64_adjust_dynamic_symbol (info Line 1129  elf64_x86_64_adjust_dynamic_symbol (info
1129       will fill in the contents of the procedure linkage table later,       will fill in the contents of the procedure linkage table later,
1130       when we know the address of the .got section.  */       when we know the address of the .got section.  */
1131    if (h->type == STT_FUNC    if (h->type == STT_FUNC
1132        || (h->elf_link_hash_flags & ELF_LINK_HASH_NEEDS_PLT) != 0)        || h->needs_plt)
1133      {      {
1134        if (h->plt.refcount <= 0        if (h->plt.refcount <= 0
1135            || (! info->shared            || SYMBOL_CALLS_LOCAL (info, h)
1136                && (h->elf_link_hash_flags & ELF_LINK_HASH_DEF_DYNAMIC) == 0            || (ELF_ST_VISIBILITY (h->other) != STV_DEFAULT
1137                && (h->elf_link_hash_flags & ELF_LINK_HASH_REF_DYNAMIC) == 0                && h->root.type == bfd_link_hash_undefweak))
               && h->root.type != bfd_link_hash_undefweak  
               && h->root.type != bfd_link_hash_undefined))  
1138          {          {
1139            /* This case can occur if we saw a PLT32 reloc in an input            /* This case can occur if we saw a PLT32 reloc in an input
1140               file, but the symbol was never referred to by a dynamic               file, but the symbol was never referred to by a dynamic
# Line 1025  elf64_x86_64_adjust_dynamic_symbol (info Line 1142  elf64_x86_64_adjust_dynamic_symbol (info
1142               such a case, we don't actually need to build a procedure               such a case, we don't actually need to build a procedure
1143               linkage table, and we can just do a PC32 reloc instead.  */               linkage table, and we can just do a PC32 reloc instead.  */
1144            h->plt.offset = (bfd_vma) -1;            h->plt.offset = (bfd_vma) -1;
1145            h->elf_link_hash_flags &= ~ELF_LINK_HASH_NEEDS_PLT;            h->needs_plt = 0;
1146          }          }
1147    
1148        return true;        return TRUE;
1149      }      }
1150    else    else
1151      /* It's possible that we incorrectly decided a .plt reloc was      /* It's possible that we incorrectly decided a .plt reloc was
# Line 1041  elf64_x86_64_adjust_dynamic_symbol (info Line 1158  elf64_x86_64_adjust_dynamic_symbol (info
1158    /* If this is a weak symbol, and there is a real definition, the    /* If this is a weak symbol, and there is a real definition, the
1159       processor independent code will have arranged for us to see the       processor independent code will have arranged for us to see the
1160       real definition first, and we can just use the same value.  */       real definition first, and we can just use the same value.  */
1161    if (h->weakdef != NULL)    if (h->u.weakdef != NULL)
1162      {      {
1163        BFD_ASSERT (h->weakdef->root.type == bfd_link_hash_defined        BFD_ASSERT (h->u.weakdef->root.type == bfd_link_hash_defined
1164                    || h->weakdef->root.type == bfd_link_hash_defweak);                    || h->u.weakdef->root.type == bfd_link_hash_defweak);
1165        h->root.u.def.section = h->weakdef->root.u.def.section;        h->root.u.def.section = h->u.weakdef->root.u.def.section;
1166        h->root.u.def.value = h->weakdef->root.u.def.value;        h->root.u.def.value = h->u.weakdef->root.u.def.value;
1167        return true;        if (ELIMINATE_COPY_RELOCS || info->nocopyreloc)
1168            h->non_got_ref = h->u.weakdef->non_got_ref;
1169          return TRUE;
1170      }      }
1171    
1172    /* This is a reference to a symbol defined by a dynamic object which    /* This is a reference to a symbol defined by a dynamic object which
# Line 1058  elf64_x86_64_adjust_dynamic_symbol (info Line 1177  elf64_x86_64_adjust_dynamic_symbol (info
1177       For such cases we need not do anything here; the relocations will       For such cases we need not do anything here; the relocations will
1178       be handled correctly by relocate_section.  */       be handled correctly by relocate_section.  */
1179    if (info->shared)    if (info->shared)
1180      return true;      return TRUE;
1181    
1182    /* If there are no references to this symbol that do not use the    /* If there are no references to this symbol that do not use the
1183       GOT, we don't need to generate a copy reloc.  */       GOT, we don't need to generate a copy reloc.  */
1184    if ((h->elf_link_hash_flags & ELF_LINK_NON_GOT_REF) == 0)    if (!h->non_got_ref)
1185      return true;      return TRUE;
1186    
1187    /* If -z nocopyreloc was given, we won't generate them either.  */    /* If -z nocopyreloc was given, we won't generate them either.  */
1188    if (info->nocopyreloc)    if (info->nocopyreloc)
1189      {      {
1190        h->elf_link_hash_flags &= ~ELF_LINK_NON_GOT_REF;        h->non_got_ref = 0;
1191        return true;        return TRUE;
1192      }      }
1193    
1194    eh = (struct elf64_x86_64_link_hash_entry *) h;    if (ELIMINATE_COPY_RELOCS)
   for (p = eh->dyn_relocs; p != NULL; p = p->next)  
1195      {      {
1196        s = p->sec->output_section;        struct elf64_x86_64_link_hash_entry * eh;
1197        if (s != NULL && (s->flags & SEC_READONLY) != 0)        struct elf64_x86_64_dyn_relocs *p;
         break;  
     }  
1198    
1199    /* If we didn't find any dynamic relocs in read-only sections, then        eh = (struct elf64_x86_64_link_hash_entry *) h;
1200       we'll be keeping the dynamic relocs and avoiding the copy reloc.  */        for (p = eh->dyn_relocs; p != NULL; p = p->next)
1201    if (p == NULL)          {
1202      {            s = p->sec->output_section;
1203        h->elf_link_hash_flags &= ~ELF_LINK_NON_GOT_REF;            if (s != NULL && (s->flags & SEC_READONLY) != 0)
1204        return true;              break;
1205            }
1206    
1207          /* If we didn't find any dynamic relocs in read-only sections, then
1208             we'll be keeping the dynamic relocs and avoiding the copy reloc.  */
1209          if (p == NULL)
1210            {
1211              h->non_got_ref = 0;
1212              return TRUE;
1213            }
1214      }      }
1215    
1216    /* We must allocate the symbol in our .dynbss section, which will    /* We must allocate the symbol in our .dynbss section, which will
# Line 1105  elf64_x86_64_adjust_dynamic_symbol (info Line 1230  elf64_x86_64_adjust_dynamic_symbol (info
1230       runtime process image.  */       runtime process image.  */
1231    if ((h->root.u.def.section->flags & SEC_ALLOC) != 0)    if ((h->root.u.def.section->flags & SEC_ALLOC) != 0)
1232      {      {
1233        htab->srelbss->_raw_size += sizeof (Elf64_External_Rela);        htab->srelbss->size += sizeof (Elf64_External_Rela);
1234        h->elf_link_hash_flags |= ELF_LINK_HASH_NEEDS_COPY;        h->needs_copy = 1;
1235      }      }
1236    
1237    /* We need to figure out the alignment required for this symbol.  I    /* We need to figure out the alignment required for this symbol.  I
# Line 1120  elf64_x86_64_adjust_dynamic_symbol (info Line 1245  elf64_x86_64_adjust_dynamic_symbol (info
1245    
1246    /* Apply the required alignment.  */    /* Apply the required alignment.  */
1247    s = htab->sdynbss;    s = htab->sdynbss;
1248    s->_raw_size = BFD_ALIGN (s->_raw_size, (bfd_size_type) (1 << power_of_two));    s->size = BFD_ALIGN (s->size, (bfd_size_type) (1 << power_of_two));
1249    if (power_of_two > bfd_get_section_alignment (htab->elf.dynobj, s))    if (power_of_two > bfd_get_section_alignment (htab->elf.dynobj, s))
1250      {      {
1251        if (! bfd_set_section_alignment (htab->elf.dynobj, s, power_of_two))        if (! bfd_set_section_alignment (htab->elf.dynobj, s, power_of_two))
1252          return false;          return FALSE;
1253      }      }
1254    
1255    /* Define the symbol as being at this point in the section.  */    /* Define the symbol as being at this point in the section.  */
1256    h->root.u.def.section = s;    h->root.u.def.section = s;
1257    h->root.u.def.value = s->_raw_size;    h->root.u.def.value = s->size;
1258    
1259    /* Increment the section size to make room for the symbol.  */    /* Increment the section size to make room for the symbol.  */
1260    s->_raw_size += h->size;    s->size += h->size;
1261    
1262    return true;    return TRUE;
1263  }  }
1264    
 /* This is the condition under which elf64_x86_64_finish_dynamic_symbol  
    will be called from elflink.h.  If elflink.h doesn't call our  
    finish_dynamic_symbol routine, we'll need to do something about  
    initializing any .plt and .got entries in elf64_x86_64_relocate_section.  */  
 #define WILL_CALL_FINISH_DYNAMIC_SYMBOL(DYN, INFO, H) \  
   ((DYN)                                                                \  
    && ((INFO)->shared                                                   \  
        || ((H)->elf_link_hash_flags & ELF_LINK_FORCED_LOCAL) == 0)      \  
    && ((H)->dynindx != -1                                               \  
        || ((H)->elf_link_hash_flags & ELF_LINK_FORCED_LOCAL) != 0))  
   
1265  /* Allocate space in .plt, .got and associated reloc sections for  /* Allocate space in .plt, .got and associated reloc sections for
1266     dynamic relocs.  */     dynamic relocs.  */
1267    
1268  static boolean  static bfd_boolean
1269  allocate_dynrelocs (h, inf)  allocate_dynrelocs (struct elf_link_hash_entry *h, void * inf)
      struct elf_link_hash_entry *h;  
      PTR inf;  
1270  {  {
1271    struct bfd_link_info *info;    struct bfd_link_info *info;
1272    struct elf64_x86_64_link_hash_table *htab;    struct elf64_x86_64_link_hash_table *htab;
# Line 1162  allocate_dynrelocs (h, inf) Line 1274  allocate_dynrelocs (h, inf)
1274    struct elf64_x86_64_dyn_relocs *p;    struct elf64_x86_64_dyn_relocs *p;
1275    
1276    if (h->root.type == bfd_link_hash_indirect)    if (h->root.type == bfd_link_hash_indirect)
1277      return true;      return TRUE;
1278    
1279    if (h->root.type == bfd_link_hash_warning)    if (h->root.type == bfd_link_hash_warning)
1280      h = (struct elf_link_hash_entry *) h->root.u.i.link;      h = (struct elf_link_hash_entry *) h->root.u.i.link;
# Line 1176  allocate_dynrelocs (h, inf) Line 1288  allocate_dynrelocs (h, inf)
1288        /* Make sure this symbol is output as a dynamic symbol.        /* Make sure this symbol is output as a dynamic symbol.
1289           Undefined weak syms won't yet be marked as dynamic.  */           Undefined weak syms won't yet be marked as dynamic.  */
1290        if (h->dynindx == -1        if (h->dynindx == -1
1291            && (h->elf_link_hash_flags & ELF_LINK_FORCED_LOCAL) == 0)            && !h->forced_local)
1292          {          {
1293            if (! bfd_elf64_link_record_dynamic_symbol (info, h))            if (! bfd_elf_link_record_dynamic_symbol (info, h))
1294              return false;              return FALSE;
1295          }          }
1296    
1297        if (WILL_CALL_FINISH_DYNAMIC_SYMBOL (1, info, h))        if (info->shared
1298              || WILL_CALL_FINISH_DYNAMIC_SYMBOL (1, 0, h))
1299          {          {
1300            asection *s = htab->splt;            asection *s = htab->splt;
1301    
1302            /* If this is the first .plt entry, make room for the special            /* If this is the first .plt entry, make room for the special
1303               first entry.  */               first entry.  */
1304            if (s->_raw_size == 0)            if (s->size == 0)
1305              s->_raw_size += PLT_ENTRY_SIZE;              s->size += PLT_ENTRY_SIZE;
1306    
1307            h->plt.offset = s->_raw_size;            h->plt.offset = s->size;
1308    
1309            /* If this symbol is not defined in a regular file, and we are            /* If this symbol is not defined in a regular file, and we are
1310               not generating a shared library, then set the symbol to this               not generating a shared library, then set the symbol to this
# Line 1199  allocate_dynrelocs (h, inf) Line 1312  allocate_dynrelocs (h, inf)
1312               pointers compare as equal between the normal executable and               pointers compare as equal between the normal executable and
1313               the shared library.  */               the shared library.  */
1314            if (! info->shared            if (! info->shared
1315                && (h->elf_link_hash_flags & ELF_LINK_HASH_DEF_REGULAR) == 0)                && !h->def_regular)
1316              {              {
1317                h->root.u.def.section = s;                h->root.u.def.section = s;
1318                h->root.u.def.value = h->plt.offset;                h->root.u.def.value = h->plt.offset;
1319              }              }
1320    
1321            /* Make room for this entry.  */            /* Make room for this entry.  */
1322            s->_raw_size += PLT_ENTRY_SIZE;            s->size += PLT_ENTRY_SIZE;
1323    
1324            /* We also need to make an entry in the .got.plt section, which            /* We also need to make an entry in the .got.plt section, which
1325               will be placed in the .got section by the linker script.  */               will be placed in the .got section by the linker script.  */
1326            htab->sgotplt->_raw_size += GOT_ENTRY_SIZE;            htab->sgotplt->size += GOT_ENTRY_SIZE;
1327    
1328            /* We also need to make an entry in the .rela.plt section.  */            /* We also need to make an entry in the .rela.plt section.  */
1329            htab->srelplt->_raw_size += sizeof (Elf64_External_Rela);            htab->srelplt->size += sizeof (Elf64_External_Rela);
1330          }          }
1331        else        else
1332          {          {
1333            h->plt.offset = (bfd_vma) -1;            h->plt.offset = (bfd_vma) -1;
1334            h->elf_link_hash_flags &= ~ELF_LINK_HASH_NEEDS_PLT;            h->needs_plt = 0;
1335          }          }
1336      }      }
1337    else    else
1338      {      {
1339        h->plt.offset = (bfd_vma) -1;        h->plt.offset = (bfd_vma) -1;
1340        h->elf_link_hash_flags &= ~ELF_LINK_HASH_NEEDS_PLT;        h->needs_plt = 0;
1341      }      }
1342    
1343    if (h->got.refcount > 0)    /* If R_X86_64_GOTTPOFF symbol is now local to the binary,
1344         make it a R_X86_64_TPOFF32 requiring no GOT entry.  */
1345      if (h->got.refcount > 0
1346          && !info->shared
1347          && h->dynindx == -1
1348          && elf64_x86_64_hash_entry (h)->tls_type == GOT_TLS_IE)
1349        h->got.offset = (bfd_vma) -1;
1350      else if (h->got.refcount > 0)
1351      {      {
1352        asection *s;        asection *s;
1353        boolean dyn;        bfd_boolean dyn;
1354          int tls_type = elf64_x86_64_hash_entry (h)->tls_type;
1355    
1356        /* Make sure this symbol is output as a dynamic symbol.        /* Make sure this symbol is output as a dynamic symbol.
1357           Undefined weak syms won't yet be marked as dynamic.  */           Undefined weak syms won't yet be marked as dynamic.  */
1358        if (h->dynindx == -1        if (h->dynindx == -1
1359            && (h->elf_link_hash_flags & ELF_LINK_FORCED_LOCAL) == 0)            && !h->forced_local)
1360          {          {
1361            if (! bfd_elf64_link_record_dynamic_symbol (info, h))            if (! bfd_elf_link_record_dynamic_symbol (info, h))
1362              return false;              return FALSE;
1363          }          }
1364    
1365        s = htab->sgot;        s = htab->sgot;
1366        h->got.offset = s->_raw_size;        h->got.offset = s->size;
1367        s->_raw_size += GOT_ENTRY_SIZE;        s->size += GOT_ENTRY_SIZE;
1368          /* R_X86_64_TLSGD needs 2 consecutive GOT slots.  */
1369          if (tls_type == GOT_TLS_GD)
1370            s->size += GOT_ENTRY_SIZE;
1371        dyn = htab->elf.dynamic_sections_created;        dyn = htab->elf.dynamic_sections_created;
1372        if (WILL_CALL_FINISH_DYNAMIC_SYMBOL (dyn, info, h))        /* R_X86_64_TLSGD needs one dynamic relocation if local symbol
1373          htab->srelgot->_raw_size += sizeof (Elf64_External_Rela);           and two if global.
1374             R_X86_64_GOTTPOFF needs one dynamic relocation.  */
1375          if ((tls_type == GOT_TLS_GD && h->dynindx == -1)
1376              || tls_type == GOT_TLS_IE)
1377            htab->srelgot->size += sizeof (Elf64_External_Rela);
1378          else if (tls_type == GOT_TLS_GD)
1379            htab->srelgot->size += 2 * sizeof (Elf64_External_Rela);
1380          else if ((ELF_ST_VISIBILITY (h->other) == STV_DEFAULT
1381                    || h->root.type != bfd_link_hash_undefweak)
1382                   && (info->shared
1383                       || WILL_CALL_FINISH_DYNAMIC_SYMBOL (dyn, 0, h)))
1384            htab->srelgot->size += sizeof (Elf64_External_Rela);
1385      }      }
1386    else    else
1387      h->got.offset = (bfd_vma) -1;      h->got.offset = (bfd_vma) -1;
1388    
1389    eh = (struct elf64_x86_64_link_hash_entry *) h;    eh = (struct elf64_x86_64_link_hash_entry *) h;
1390    if (eh->dyn_relocs == NULL)    if (eh->dyn_relocs == NULL)
1391      return true;      return TRUE;
1392    
1393    /* In the shared -Bsymbolic case, discard space allocated for    /* In the shared -Bsymbolic case, discard space allocated for
1394       dynamic pc-relative relocs against symbols which turn out to be       dynamic pc-relative relocs against symbols which turn out to be
# Line 1263  allocate_dynrelocs (h, inf) Line 1398  allocate_dynrelocs (h, inf)
1398    
1399    if (info->shared)    if (info->shared)
1400      {      {
1401        if ((h->elf_link_hash_flags & ELF_LINK_HASH_DEF_REGULAR) != 0        /* Relocs that use pc_count are those that appear on a call
1402            && ((h->elf_link_hash_flags & ELF_LINK_FORCED_LOCAL) != 0           insn, or certain REL relocs that can generated via assembly.
1403                || info->symbolic))           We want calls to protected symbols to resolve directly to the
1404             function rather than going via the plt.  If people want
1405             function pointer comparisons to work as expected then they
1406             should avoid writing weird assembly.  */
1407          if (SYMBOL_CALLS_LOCAL (info, h))
1408          {          {
1409            struct elf64_x86_64_dyn_relocs **pp;            struct elf64_x86_64_dyn_relocs **pp;
1410    
# Line 1279  allocate_dynrelocs (h, inf) Line 1418  allocate_dynrelocs (h, inf)
1418                  pp = &p->next;                  pp = &p->next;
1419              }              }
1420          }          }
1421    
1422          /* Also discard relocs on undefined weak syms with non-default
1423             visibility.  */
1424          if (ELF_ST_VISIBILITY (h->other) != STV_DEFAULT
1425              && h->root.type == bfd_link_hash_undefweak)
1426            eh->dyn_relocs = NULL;
1427      }      }
1428    else    else if (ELIMINATE_COPY_RELOCS)
1429      {      {
1430        /* For the non-shared case, discard space for relocs against        /* For the non-shared case, discard space for relocs against
1431           symbols which turn out to need copy relocs or are not           symbols which turn out to need copy relocs or are not
1432           dynamic.  */           dynamic.  */
1433    
1434        if ((h->elf_link_hash_flags & ELF_LINK_NON_GOT_REF) == 0        if (!h->non_got_ref
1435            && (((h->elf_link_hash_flags & ELF_LINK_HASH_DEF_DYNAMIC) != 0            && ((h->def_dynamic
1436                 && (h->elf_link_hash_flags & ELF_LINK_HASH_DEF_REGULAR) == 0)                 && !h->def_regular)
1437                || (htab->elf.dynamic_sections_created                || (htab->elf.dynamic_sections_created
1438                    && (h->root.type == bfd_link_hash_undefweak                    && (h->root.type == bfd_link_hash_undefweak
1439                        || h->root.type == bfd_link_hash_undefined))))                        || h->root.type == bfd_link_hash_undefined))))
# Line 1296  allocate_dynrelocs (h, inf) Line 1441  allocate_dynrelocs (h, inf)
1441            /* Make sure this symbol is output as a dynamic symbol.            /* Make sure this symbol is output as a dynamic symbol.
1442               Undefined weak syms won't yet be marked as dynamic.  */               Undefined weak syms won't yet be marked as dynamic.  */
1443            if (h->dynindx == -1            if (h->dynindx == -1
1444                && (h->elf_link_hash_flags & ELF_LINK_FORCED_LOCAL) == 0)                && !h->forced_local)
1445              {              {
1446                if (! bfd_elf64_link_record_dynamic_symbol (info, h))                if (! bfd_elf_link_record_dynamic_symbol (info, h))
1447                  return false;                  return FALSE;
1448              }              }
1449    
1450            /* If that succeeded, we know we'll be keeping all the            /* If that succeeded, we know we'll be keeping all the
# Line 1317  allocate_dynrelocs (h, inf) Line 1462  allocate_dynrelocs (h, inf)
1462    for (p = eh->dyn_relocs; p != NULL; p = p->next)    for (p = eh->dyn_relocs; p != NULL; p = p->next)
1463      {      {
1464        asection *sreloc = elf_section_data (p->sec)->sreloc;        asection *sreloc = elf_section_data (p->sec)->sreloc;
1465        sreloc->_raw_size += p->count * sizeof (Elf64_External_Rela);        sreloc->size += p->count * sizeof (Elf64_External_Rela);
1466      }      }
1467    
1468    return true;    return TRUE;
1469  }  }
1470    
1471  /* Find any dynamic relocs that apply to read-only sections.  */  /* Find any dynamic relocs that apply to read-only sections.  */
1472    
1473  static boolean  static bfd_boolean
1474  readonly_dynrelocs (h, inf)  readonly_dynrelocs (struct elf_link_hash_entry *h, void * inf)
      struct elf_link_hash_entry *h;  
      PTR inf;  
1475  {  {
1476    struct elf64_x86_64_link_hash_entry *eh;    struct elf64_x86_64_link_hash_entry *eh;
1477    struct elf64_x86_64_dyn_relocs *p;    struct elf64_x86_64_dyn_relocs *p;
# Line 1348  readonly_dynrelocs (h, inf) Line 1491  readonly_dynrelocs (h, inf)
1491            info->flags |= DF_TEXTREL;            info->flags |= DF_TEXTREL;
1492    
1493            /* Not an error, just cut short the traversal.  */            /* Not an error, just cut short the traversal.  */
1494            return false;            return FALSE;
1495          }          }
1496      }      }
1497    return true;    return TRUE;
1498  }  }
1499    
1500  /* Set the sizes of the dynamic sections.  */  /* Set the sizes of the dynamic sections.  */
1501    
1502  static boolean  static bfd_boolean
1503  elf64_x86_64_size_dynamic_sections (output_bfd, info)  elf64_x86_64_size_dynamic_sections (bfd *output_bfd ATTRIBUTE_UNUSED,
1504       bfd *output_bfd ATTRIBUTE_UNUSED;                                      struct bfd_link_info *info)
      struct bfd_link_info *info;  
1505  {  {
1506    struct elf64_x86_64_link_hash_table *htab;    struct elf64_x86_64_link_hash_table *htab;
1507    bfd *dynobj;    bfd *dynobj;
1508    asection *s;    asection *s;
1509    boolean relocs;    bfd_boolean relocs;
1510    bfd *ibfd;    bfd *ibfd;
1511    
1512    htab = elf64_x86_64_hash_table (info);    htab = elf64_x86_64_hash_table (info);
# Line 1375  elf64_x86_64_size_dynamic_sections (outp Line 1517  elf64_x86_64_size_dynamic_sections (outp
1517    if (htab->elf.dynamic_sections_created)    if (htab->elf.dynamic_sections_created)
1518      {      {
1519        /* Set the contents of the .interp section to the interpreter.  */        /* Set the contents of the .interp section to the interpreter.  */
1520        if (! info->shared)        if (info->executable)
1521          {          {
1522            s = bfd_get_section_by_name (dynobj, ".interp");            s = bfd_get_section_by_name (dynobj, ".interp");
1523            if (s == NULL)            if (s == NULL)
1524              abort ();              abort ();
1525            s->_raw_size = sizeof ELF_DYNAMIC_INTERPRETER;            s->size = sizeof ELF_DYNAMIC_INTERPRETER;
1526            s->contents = (unsigned char *) ELF_DYNAMIC_INTERPRETER;            s->contents = (unsigned char *) ELF_DYNAMIC_INTERPRETER;
1527          }          }
1528      }      }
# Line 1391  elf64_x86_64_size_dynamic_sections (outp Line 1533  elf64_x86_64_size_dynamic_sections (outp
1533      {      {
1534        bfd_signed_vma *local_got;        bfd_signed_vma *local_got;
1535        bfd_signed_vma *end_local_got;        bfd_signed_vma *end_local_got;
1536          char *local_tls_type;
1537        bfd_size_type locsymcount;        bfd_size_type locsymcount;
1538        Elf_Internal_Shdr *symtab_hdr;        Elf_Internal_Shdr *symtab_hdr;
1539        asection *srel;        asection *srel;
# Line 1418  elf64_x86_64_size_dynamic_sections (outp Line 1561  elf64_x86_64_size_dynamic_sections (outp
1561                else if (p->count != 0)                else if (p->count != 0)
1562                  {                  {
1563                    srel = elf_section_data (p->sec)->sreloc;                    srel = elf_section_data (p->sec)->sreloc;
1564                    srel->_raw_size += p->count * sizeof (Elf64_External_Rela);                    srel->size += p->count * sizeof (Elf64_External_Rela);
1565                    if ((p->sec->output_section->flags & SEC_READONLY) != 0)                    if ((p->sec->output_section->flags & SEC_READONLY) != 0)
1566                      info->flags |= DF_TEXTREL;                      info->flags |= DF_TEXTREL;
1567    
# Line 1433  elf64_x86_64_size_dynamic_sections (outp Line 1576  elf64_x86_64_size_dynamic_sections (outp
1576        symtab_hdr = &elf_tdata (ibfd)->symtab_hdr;        symtab_hdr = &elf_tdata (ibfd)->symtab_hdr;
1577        locsymcount = symtab_hdr->sh_info;        locsymcount = symtab_hdr->sh_info;
1578        end_local_got = local_got + locsymcount;        end_local_got = local_got + locsymcount;
1579          local_tls_type = elf64_x86_64_local_got_tls_type (ibfd);
1580        s = htab->sgot;        s = htab->sgot;
1581        srel = htab->srelgot;        srel = htab->srelgot;
1582        for (; local_got < end_local_got; ++local_got)        for (; local_got < end_local_got; ++local_got, ++local_tls_type)
1583          {          {
1584            if (*local_got > 0)            if (*local_got > 0)
1585              {              {
1586                *local_got = s->_raw_size;                *local_got = s->size;
1587                s->_raw_size += GOT_ENTRY_SIZE;                s->size += GOT_ENTRY_SIZE;
1588                if (info->shared)                if (*local_tls_type == GOT_TLS_GD)
1589                  srel->_raw_size += sizeof (Elf64_External_Rela);                  s->size += GOT_ENTRY_SIZE;
1590                  if (info->shared
1591                      || *local_tls_type == GOT_TLS_GD
1592                      || *local_tls_type == GOT_TLS_IE)
1593                    srel->size += sizeof (Elf64_External_Rela);
1594              }              }
1595            else            else
1596              *local_got = (bfd_vma) -1;              *local_got = (bfd_vma) -1;
1597          }          }
1598      }      }
1599    
1600      if (htab->tls_ld_got.refcount > 0)
1601        {
1602          /* Allocate 2 got entries and 1 dynamic reloc for R_X86_64_TLSLD
1603             relocs.  */
1604          htab->tls_ld_got.offset = htab->sgot->size;
1605          htab->sgot->size += 2 * GOT_ENTRY_SIZE;
1606          htab->srelgot->size += sizeof (Elf64_External_Rela);
1607        }
1608      else
1609        htab->tls_ld_got.offset = -1;
1610    
1611    /* Allocate global sym .plt and .got entries, and space for global    /* Allocate global sym .plt and .got entries, and space for global
1612       sym dynamic relocs.  */       sym dynamic relocs.  */
1613    elf_link_hash_traverse (&htab->elf, allocate_dynrelocs, (PTR) info);    elf_link_hash_traverse (&htab->elf, allocate_dynrelocs, (PTR) info);
1614    
1615    /* We now have determined the sizes of the various dynamic sections.    /* We now have determined the sizes of the various dynamic sections.
1616       Allocate memory for them.  */       Allocate memory for them.  */
1617    relocs = false;    relocs = FALSE;
1618    for (s = dynobj->sections; s != NULL; s = s->next)    for (s = dynobj->sections; s != NULL; s = s->next)
1619      {      {
1620        if ((s->flags & SEC_LINKER_CREATED) == 0)        if ((s->flags & SEC_LINKER_CREATED) == 0)
# Line 1470  elf64_x86_64_size_dynamic_sections (outp Line 1629  elf64_x86_64_size_dynamic_sections (outp
1629          }          }
1630        else if (strncmp (bfd_get_section_name (dynobj, s), ".rela", 5) == 0)        else if (strncmp (bfd_get_section_name (dynobj, s), ".rela", 5) == 0)
1631          {          {
1632            if (s->_raw_size != 0 && s != htab->srelplt)            if (s->size != 0 && s != htab->srelplt)
1633              relocs = true;              relocs = TRUE;
1634    
1635            /* We use the reloc_count field as a counter if we need            /* We use the reloc_count field as a counter if we need
1636               to copy relocs into the output file.  */               to copy relocs into the output file.  */
# Line 1483  elf64_x86_64_size_dynamic_sections (outp Line 1642  elf64_x86_64_size_dynamic_sections (outp
1642            continue;            continue;
1643          }          }
1644    
1645        if (s->_raw_size == 0)        if (s->size == 0)
1646          {          {
1647            /* If we don't need this section, strip it from the            /* If we don't need this section, strip it from the
1648               output file.  This is mostly to handle .rela.bss and               output file.  This is mostly to handle .rela.bss and
# Line 1504  elf64_x86_64_size_dynamic_sections (outp Line 1663  elf64_x86_64_size_dynamic_sections (outp
1663           section's contents are written out.  This should not happen,           section's contents are written out.  This should not happen,
1664           but this way if it does, we get a R_X86_64_NONE reloc instead           but this way if it does, we get a R_X86_64_NONE reloc instead
1665           of garbage.  */           of garbage.  */
1666        s->contents = (bfd_byte *) bfd_zalloc (dynobj, s->_raw_size);        s->contents = (bfd_byte *) bfd_zalloc (dynobj, s->size);
1667        if (s->contents == NULL)        if (s->contents == NULL)
1668          return false;          return FALSE;
1669      }      }
1670    
1671    if (htab->elf.dynamic_sections_created)    if (htab->elf.dynamic_sections_created)
# Line 1517  elf64_x86_64_size_dynamic_sections (outp Line 1676  elf64_x86_64_size_dynamic_sections (outp
1676           the .dynamic section.  The DT_DEBUG entry is filled in by the           the .dynamic section.  The DT_DEBUG entry is filled in by the
1677           dynamic linker and used by the debugger.  */           dynamic linker and used by the debugger.  */
1678  #define add_dynamic_entry(TAG, VAL) \  #define add_dynamic_entry(TAG, VAL) \
1679    bfd_elf64_add_dynamic_entry (info, (bfd_vma) (TAG), (bfd_vma) (VAL))    _bfd_elf_add_dynamic_entry (info, TAG, VAL)
1680    
1681        if (! info->shared)        if (info->executable)
1682          {          {
1683            if (!add_dynamic_entry (DT_DEBUG, 0))            if (!add_dynamic_entry (DT_DEBUG, 0))
1684              return false;              return FALSE;
1685          }          }
1686    
1687        if (htab->splt->_raw_size != 0)        if (htab->splt->size != 0)
1688          {          {
1689            if (!add_dynamic_entry (DT_PLTGOT, 0)            if (!add_dynamic_entry (DT_PLTGOT, 0)
1690                || !add_dynamic_entry (DT_PLTRELSZ, 0)                || !add_dynamic_entry (DT_PLTRELSZ, 0)
1691                || !add_dynamic_entry (DT_PLTREL, DT_RELA)                || !add_dynamic_entry (DT_PLTREL, DT_RELA)
1692                || !add_dynamic_entry (DT_JMPREL, 0))                || !add_dynamic_entry (DT_JMPREL, 0))
1693              return false;              return FALSE;
1694          }          }
1695    
1696        if (relocs)        if (relocs)
# Line 1539  elf64_x86_64_size_dynamic_sections (outp Line 1698  elf64_x86_64_size_dynamic_sections (outp
1698            if (!add_dynamic_entry (DT_RELA, 0)            if (!add_dynamic_entry (DT_RELA, 0)
1699                || !add_dynamic_entry (DT_RELASZ, 0)                || !add_dynamic_entry (DT_RELASZ, 0)
1700                || !add_dynamic_entry (DT_RELAENT, sizeof (Elf64_External_Rela)))                || !add_dynamic_entry (DT_RELAENT, sizeof (Elf64_External_Rela)))
1701              return false;              return FALSE;
1702    
1703            /* If any dynamic relocs apply to a read-only section,            /* If any dynamic relocs apply to a read-only section,
1704               then we need a DT_TEXTREL entry.  */               then we need a DT_TEXTREL entry.  */
# Line 1550  elf64_x86_64_size_dynamic_sections (outp Line 1709  elf64_x86_64_size_dynamic_sections (outp
1709            if ((info->flags & DF_TEXTREL) != 0)            if ((info->flags & DF_TEXTREL) != 0)
1710              {              {
1711                if (!add_dynamic_entry (DT_TEXTREL, 0))                if (!add_dynamic_entry (DT_TEXTREL, 0))
1712                  return false;                  return FALSE;
1713              }              }
1714          }          }
1715      }      }
1716  #undef add_dynamic_entry  #undef add_dynamic_entry
1717    
1718    return true;    return TRUE;
1719    }
1720    
1721    /* Return the base VMA address which should be subtracted from real addresses
1722       when resolving @dtpoff relocation.
1723       This is PT_TLS segment p_vaddr.  */
1724    
1725    static bfd_vma
1726    dtpoff_base (struct bfd_link_info *info)
1727    {
1728      /* If tls_sec is NULL, we should have signalled an error already.  */
1729      if (elf_hash_table (info)->tls_sec == NULL)
1730        return 0;
1731      return elf_hash_table (info)->tls_sec->vma;
1732    }
1733    
1734    /* Return the relocation value for @tpoff relocation
1735       if STT_TLS virtual address is ADDRESS.  */
1736    
1737    static bfd_vma
1738    tpoff (struct bfd_link_info *info, bfd_vma address)
1739    {
1740      struct elf_link_hash_table *htab = elf_hash_table (info);
1741    
1742      /* If tls_segment is NULL, we should have signalled an error already.  */
1743      if (htab->tls_sec == NULL)
1744        return 0;
1745      return address - htab->tls_size - htab->tls_sec->vma;
1746    }
1747    
1748    /* Is the instruction before OFFSET in CONTENTS a 32bit relative
1749       branch?  */
1750    
1751    static bfd_boolean
1752    is_32bit_relative_branch (bfd_byte *contents, bfd_vma offset)
1753    {
1754      /* Opcode             Instruction
1755         0xe8               call
1756         0xe9               jump
1757         0x0f 0x8x          conditional jump */
1758      return ((offset > 0
1759               && (contents [offset - 1] == 0xe8
1760                   || contents [offset - 1] == 0xe9))
1761              || (offset > 1
1762                  && contents [offset - 2] == 0x0f
1763                  && (contents [offset - 1] & 0xf0) == 0x80));
1764  }  }
1765    
1766  /* Relocate an x86_64 ELF section.  */  /* Relocate an x86_64 ELF section.  */
1767    
1768  static boolean  static bfd_boolean
1769  elf64_x86_64_relocate_section (output_bfd, info, input_bfd, input_section,  elf64_x86_64_relocate_section (bfd *output_bfd, struct bfd_link_info *info,
1770                                 contents, relocs, local_syms, local_sections)                                 bfd *input_bfd, asection *input_section,
1771       bfd *output_bfd;                                 bfd_byte *contents, Elf_Internal_Rela *relocs,
1772       struct bfd_link_info *info;                                 Elf_Internal_Sym *local_syms,
1773       bfd *input_bfd;                                 asection **local_sections)
      asection *input_section;  
      bfd_byte *contents;  
      Elf_Internal_Rela *relocs;  
      Elf_Internal_Sym *local_syms;  
      asection **local_sections;  
1774  {  {
1775    struct elf64_x86_64_link_hash_table *htab;    struct elf64_x86_64_link_hash_table *htab;
1776    Elf_Internal_Shdr *symtab_hdr;    Elf_Internal_Shdr *symtab_hdr;
# Line 1580  elf64_x86_64_relocate_section (output_bf Line 1779  elf64_x86_64_relocate_section (output_bf
1779    Elf_Internal_Rela *rel;    Elf_Internal_Rela *rel;
1780    Elf_Internal_Rela *relend;    Elf_Internal_Rela *relend;
1781    
1782    if (info->relocateable)    if (info->relocatable)
1783      return true;      return TRUE;
1784    
1785    htab = elf64_x86_64_hash_table (info);    htab = elf64_x86_64_hash_table (info);
1786    symtab_hdr = &elf_tdata (input_bfd)->symtab_hdr;    symtab_hdr = &elf_tdata (input_bfd)->symtab_hdr;
# Line 1592  elf64_x86_64_relocate_section (output_bf Line 1791  elf64_x86_64_relocate_section (output_bf
1791    relend = relocs + input_section->reloc_count;    relend = relocs + input_section->reloc_count;
1792    for (; rel < relend; rel++)    for (; rel < relend; rel++)
1793      {      {
1794        int r_type;        unsigned int r_type;
1795        reloc_howto_type *howto;        reloc_howto_type *howto;
1796        unsigned long r_symndx;        unsigned long r_symndx;
1797        struct elf_link_hash_entry *h;        struct elf_link_hash_entry *h;
# Line 1600  elf64_x86_64_relocate_section (output_bf Line 1799  elf64_x86_64_relocate_section (output_bf
1799        asection *sec;        asection *sec;
1800        bfd_vma off;        bfd_vma off;
1801        bfd_vma relocation;        bfd_vma relocation;
1802        boolean unresolved_reloc;        bfd_boolean unresolved_reloc;
1803        bfd_reloc_status_type r;        bfd_reloc_status_type r;
1804          int tls_type;
1805    
1806        r_type = ELF64_R_TYPE (rel->r_info);        r_type = ELF64_R_TYPE (rel->r_info);
1807        if (r_type == (int) R_X86_64_GNU_VTINHERIT        if (r_type == (int) R_X86_64_GNU_VTINHERIT
1808            || r_type == (int) R_X86_64_GNU_VTENTRY)            || r_type == (int) R_X86_64_GNU_VTENTRY)
1809          continue;          continue;
1810    
1811        if (r_type < 0 || r_type >= R_X86_64_max)        if (r_type >= R_X86_64_max)
1812          {          {
1813            bfd_set_error (bfd_error_bad_value);            bfd_set_error (bfd_error_bad_value);
1814            return false;            return FALSE;
1815          }          }
1816    
1817        howto = x86_64_elf_howto_table + r_type;        howto = x86_64_elf_howto_table + r_type;
# Line 1619  elf64_x86_64_relocate_section (output_bf Line 1819  elf64_x86_64_relocate_section (output_bf
1819        h = NULL;        h = NULL;
1820        sym = NULL;        sym = NULL;
1821        sec = NULL;        sec = NULL;
1822        unresolved_reloc = false;        unresolved_reloc = FALSE;
1823        if (r_symndx < symtab_hdr->sh_info)        if (r_symndx < symtab_hdr->sh_info)
1824          {          {
1825            sym = local_syms + r_symndx;            sym = local_syms + r_symndx;
1826            sec = local_sections[r_symndx];            sec = local_sections[r_symndx];
1827    
1828            relocation = _bfd_elf_rela_local_sym (output_bfd, sym, sec, rel);            relocation = _bfd_elf_rela_local_sym (output_bfd, sym, &sec, rel);
1829          }          }
1830        else        else
1831          {          {
1832            h = sym_hashes[r_symndx - symtab_hdr->sh_info];            bfd_boolean warned;
           while (h->root.type == bfd_link_hash_indirect  
                  || h->root.type == bfd_link_hash_warning)  
             h = (struct elf_link_hash_entry *) h->root.u.i.link;  
1833    
1834            if (h->root.type == bfd_link_hash_defined            RELOC_FOR_GLOBAL_SYMBOL (info, input_bfd, input_section, rel,
1835                || h->root.type == bfd_link_hash_defweak)                                     r_symndx, symtab_hdr, sym_hashes,
1836              {                                     h, sec, relocation,
1837                sec = h->root.u.def.section;                                     unresolved_reloc, warned);
               if (sec->output_section == NULL)  
                 {  
                   /* Set a flag that will be cleared later if we find a  
                      relocation value for this symbol.  output_section  
                      is typically NULL for symbols satisfied by a shared  
                      library.  */  
                   unresolved_reloc = true;  
                   relocation = 0;  
                 }  
               else  
                 relocation = (h->root.u.def.value  
                               + sec->output_section->vma  
                               + sec->output_offset);  
             }  
           else if (h->root.type == bfd_link_hash_undefweak)  
             relocation = 0;  
           else if (info->shared  
                    && (!info->symbolic || info->allow_shlib_undefined)  
                    && !info->no_undefined  
                    && ELF_ST_VISIBILITY (h->other) == STV_DEFAULT)  
             relocation = 0;  
           else  
             {  
               if (! ((*info->callbacks->undefined_symbol)  
                      (info, h->root.root.string, input_bfd,  
                       input_section, rel->r_offset,  
                       (!info->shared || info->no_undefined  
                        || ELF_ST_VISIBILITY (h->other)))))  
                 return false;  
               relocation = 0;  
             }  
1838          }          }
1839        /* When generating a shared object, the relocations handled here are        /* When generating a shared object, the relocations handled here are
1840           copied into the output file to be resolved at run time.  */           copied into the output file to be resolved at run time.  */
# Line 1684  elf64_x86_64_relocate_section (output_bf Line 1850  elf64_x86_64_relocate_section (output_bf
1850    
1851            if (h != NULL)            if (h != NULL)
1852              {              {
1853                boolean dyn;                bfd_boolean dyn;
1854    
1855                off = h->got.offset;                off = h->got.offset;
1856                dyn = htab->elf.dynamic_sections_created;                dyn = htab->elf.dynamic_sections_created;
1857    
1858                if (! WILL_CALL_FINISH_DYNAMIC_SYMBOL (dyn, info, h)                if (! WILL_CALL_FINISH_DYNAMIC_SYMBOL (dyn, info->shared, h)
1859                    || (info->shared                    || (info->shared
1860                        && (info->symbolic                        && SYMBOL_REFERENCES_LOCAL (info, h))
1861                            || h->dynindx == -1                    || (ELF_ST_VISIBILITY (h->other)
1862                            || (h->elf_link_hash_flags & ELF_LINK_FORCED_LOCAL))                        && h->root.type == bfd_link_hash_undefweak))
                       && (h->elf_link_hash_flags & ELF_LINK_HASH_DEF_REGULAR)))  
1863                  {                  {
1864                    /* This is actually a static link, or it is a -Bsymbolic                    /* This is actually a static link, or it is a -Bsymbolic
1865                       link and the symbol is defined locally, or the symbol                       link and the symbol is defined locally, or the symbol
# Line 1717  elf64_x86_64_relocate_section (output_bf Line 1882  elf64_x86_64_relocate_section (output_bf
1882                      }                      }
1883                  }                  }
1884                else                else
1885                  unresolved_reloc = false;                  unresolved_reloc = FALSE;
1886              }              }
1887            else            else
1888              {              {
# Line 1738  elf64_x86_64_relocate_section (output_bf Line 1903  elf64_x86_64_relocate_section (output_bf
1903    
1904                    if (info->shared)                    if (info->shared)
1905                      {                      {
1906                        asection *srelgot;                        asection *s;
1907                        Elf_Internal_Rela outrel;                        Elf_Internal_Rela outrel;
1908                        Elf64_External_Rela *loc;                        bfd_byte *loc;
1909    
1910                        /* We need to generate a R_X86_64_RELATIVE reloc                        /* We need to generate a R_X86_64_RELATIVE reloc
1911                           for the dynamic linker.  */                           for the dynamic linker.  */
1912                        srelgot = htab->srelgot;                        s = htab->srelgot;
1913                        if (srelgot == NULL)                        if (s == NULL)
1914                          abort ();                          abort ();
1915    
1916                        outrel.r_offset = (htab->sgot->output_section->vma                        outrel.r_offset = (htab->sgot->output_section->vma
# Line 1753  elf64_x86_64_relocate_section (output_bf Line 1918  elf64_x86_64_relocate_section (output_bf
1918                                           + off);                                           + off);
1919                        outrel.r_info = ELF64_R_INFO (0, R_X86_64_RELATIVE);                        outrel.r_info = ELF64_R_INFO (0, R_X86_64_RELATIVE);
1920                        outrel.r_addend = relocation;                        outrel.r_addend = relocation;
1921                        loc = (Elf64_External_Rela *) srelgot->contents;                        loc = s->contents;
1922                        loc += srelgot->reloc_count++;                        loc += s->reloc_count++ * sizeof (Elf64_External_Rela);
1923                        bfd_elf64_swap_reloca_out (output_bfd, &outrel, loc);                        bfd_elf64_swap_reloca_out (output_bfd, &outrel, loc);
1924                      }                      }
1925    
# Line 1765  elf64_x86_64_relocate_section (output_bf Line 1930  elf64_x86_64_relocate_section (output_bf
1930            if (off >= (bfd_vma) -2)            if (off >= (bfd_vma) -2)
1931              abort ();              abort ();
1932    
1933            relocation = htab->sgot->output_offset + off;            relocation = htab->sgot->output_section->vma
1934            if (r_type == R_X86_64_GOTPCREL)                         + htab->sgot->output_offset + off;
1935              relocation += htab->sgot->output_section->vma;            if (r_type != R_X86_64_GOTPCREL)
1936                relocation -= htab->sgotplt->output_section->vma
1937                              - htab->sgotplt->output_offset;
1938    
1939            break;            break;
1940    
# Line 1792  elf64_x86_64_relocate_section (output_bf Line 1959  elf64_x86_64_relocate_section (output_bf
1959            relocation = (htab->splt->output_section->vma            relocation = (htab->splt->output_section->vma
1960                          + htab->splt->output_offset                          + htab->splt->output_offset
1961                          + h->plt.offset);                          + h->plt.offset);
1962            unresolved_reloc = false;            unresolved_reloc = FALSE;
1963            break;            break;
1964    
1965          case R_X86_64_PC8:          case R_X86_64_PC8:
1966          case R_X86_64_PC16:          case R_X86_64_PC16:
1967          case R_X86_64_PC32:          case R_X86_64_PC32:
1968              if (info->shared
1969                  && !SYMBOL_REFERENCES_LOCAL (info, h)
1970                  && (input_section->flags & SEC_ALLOC) != 0
1971                  && (input_section->flags & SEC_READONLY) != 0
1972                  && (!h->def_regular
1973                      || r_type != R_X86_64_PC32
1974                      || h->type != STT_FUNC
1975                      || ELF_ST_VISIBILITY (h->other) != STV_PROTECTED
1976                      || !is_32bit_relative_branch (contents,
1977                                                    rel->r_offset)))
1978                {
1979                  if (h->def_regular
1980                      && r_type == R_X86_64_PC32
1981                      && h->type == STT_FUNC
1982                      && ELF_ST_VISIBILITY (h->other) == STV_PROTECTED)
1983                    (*_bfd_error_handler)
1984                       (_("%B: relocation R_X86_64_PC32 against protected function `%s' can not be used when making a shared object"),
1985                        input_bfd, h->root.root.string);
1986                  else
1987                    (*_bfd_error_handler)
1988                      (_("%B: relocation %s against `%s' can not be used when making a shared object; recompile with -fPIC"),
1989                       input_bfd, x86_64_elf_howto_table[r_type].name,
1990                       h->root.root.string);
1991                  bfd_set_error (bfd_error_bad_value);
1992                  return FALSE;
1993                }
1994              /* Fall through.  */
1995    
1996          case R_X86_64_8:          case R_X86_64_8:
1997          case R_X86_64_16:          case R_X86_64_16:
1998          case R_X86_64_32:          case R_X86_64_32:
# Line 1813  elf64_x86_64_relocate_section (output_bf Line 2008  elf64_x86_64_relocate_section (output_bf
2008              break;              break;
2009    
2010            if ((info->shared            if ((info->shared
2011                   && (h == NULL
2012                       || ELF_ST_VISIBILITY (h->other) == STV_DEFAULT
2013                       || h->root.type != bfd_link_hash_undefweak)
2014                 && ((r_type != R_X86_64_PC8                 && ((r_type != R_X86_64_PC8
2015                      && r_type != R_X86_64_PC16                      && r_type != R_X86_64_PC16
2016                      && r_type != R_X86_64_PC32)                      && r_type != R_X86_64_PC32)
2017                     || (h != NULL                     || !SYMBOL_CALLS_LOCAL (info, h)))
2018                         && h->dynindx != -1                || (ELIMINATE_COPY_RELOCS
2019                         && (! info->symbolic                    && !info->shared
                            || (h->elf_link_hash_flags  
                                & ELF_LINK_HASH_DEF_REGULAR) == 0))))  
               || (!info->shared  
2020                    && h != NULL                    && h != NULL
2021                    && h->dynindx != -1                    && h->dynindx != -1
2022                    && (h->elf_link_hash_flags & ELF_LINK_NON_GOT_REF) == 0                    && !h->non_got_ref
2023                    && (((h->elf_link_hash_flags                    && ((h->def_dynamic
2024                          & ELF_LINK_HASH_DEF_DYNAMIC) != 0                         && !h->def_regular)
                        && (h->elf_link_hash_flags  
                            & ELF_LINK_HASH_DEF_REGULAR) == 0)  
2025                        || h->root.type == bfd_link_hash_undefweak                        || h->root.type == bfd_link_hash_undefweak
2026                        || h->root.type == bfd_link_hash_undefined)))                        || h->root.type == bfd_link_hash_undefined)))
2027              {              {
2028                Elf_Internal_Rela outrel;                Elf_Internal_Rela outrel;
2029                boolean skip, relocate;                bfd_byte *loc;
2030                  bfd_boolean skip, relocate;
2031                asection *sreloc;                asection *sreloc;
               Elf64_External_Rela *loc;  
2032    
2033                /* When generating a shared object, these relocations                /* When generating a shared object, these relocations
2034                   are copied into the output file to be resolved at run                   are copied into the output file to be resolved at run
2035                   time.  */                   time.  */
2036                  skip = FALSE;
2037                skip = false;                relocate = FALSE;
               relocate = false;  
2038    
2039                outrel.r_offset =                outrel.r_offset =
2040                  _bfd_elf_section_offset (output_bfd, info, input_section,                  _bfd_elf_section_offset (output_bfd, info, input_section,
2041                                           rel->r_offset);                                           rel->r_offset);
2042                if (outrel.r_offset == (bfd_vma) -1)                if (outrel.r_offset == (bfd_vma) -1)
2043                  skip = true;                  skip = TRUE;
2044                else if (outrel.r_offset == (bfd_vma) -2)                else if (outrel.r_offset == (bfd_vma) -2)
2045                  skip = true, relocate = true;                  skip = TRUE, relocate = TRUE;
2046    
2047                outrel.r_offset += (input_section->output_section->vma                outrel.r_offset += (input_section->output_section->vma
2048                                    + input_section->output_offset);                                    + input_section->output_offset);
# Line 1867  elf64_x86_64_relocate_section (output_bf Line 2059  elf64_x86_64_relocate_section (output_bf
2059                             || r_type == R_X86_64_PC32                             || r_type == R_X86_64_PC32
2060                             || !info->shared                             || !info->shared
2061                             || !info->symbolic                             || !info->symbolic
2062                             || (h->elf_link_hash_flags                             || !h->def_regular))
                                & ELF_LINK_HASH_DEF_REGULAR) == 0))  
2063                  {                  {
2064                    outrel.r_info = ELF64_R_INFO (h->dynindx, r_type);                    outrel.r_info = ELF64_R_INFO (h->dynindx, r_type);
2065                    outrel.r_addend = rel->r_addend;                    outrel.r_addend = rel->r_addend;
# Line 1878  elf64_x86_64_relocate_section (output_bf Line 2069  elf64_x86_64_relocate_section (output_bf
2069                    /* This symbol is local, or marked to become local.  */                    /* This symbol is local, or marked to become local.  */
2070                    if (r_type == R_X86_64_64)                    if (r_type == R_X86_64_64)
2071                      {                      {
2072                        relocate = true;                        relocate = TRUE;
2073                        outrel.r_info = ELF64_R_INFO (0, R_X86_64_RELATIVE);                        outrel.r_info = ELF64_R_INFO (0, R_X86_64_RELATIVE);
2074                        outrel.r_addend = relocation + rel->r_addend;                        outrel.r_addend = relocation + rel->r_addend;
2075                      }                      }
# Line 1886  elf64_x86_64_relocate_section (output_bf Line 2077  elf64_x86_64_relocate_section (output_bf
2077                      {                      {
2078                        long sindx;                        long sindx;
2079    
2080                        if (h == NULL)                        if (bfd_is_abs_section (sec))
                         sec = local_sections[r_symndx];  
                       else  
                         {  
                           BFD_ASSERT (h->root.type == bfd_link_hash_defined  
                                       || (h->root.type  
                                           == bfd_link_hash_defweak));  
                           sec = h->root.u.def.section;  
                         }  
                       if (sec != NULL && bfd_is_abs_section (sec))  
2081                          sindx = 0;                          sindx = 0;
2082                        else if (sec == NULL || sec->owner == NULL)                        else if (sec == NULL || sec->owner == NULL)
2083                          {                          {
2084                            bfd_set_error (bfd_error_bad_value);                            bfd_set_error (bfd_error_bad_value);
2085                            return false;                            return FALSE;
2086                          }                          }
2087                        else                        else
2088                          {                          {
# Line 1920  elf64_x86_64_relocate_section (output_bf Line 2102  elf64_x86_64_relocate_section (output_bf
2102                if (sreloc == NULL)                if (sreloc == NULL)
2103                  abort ();                  abort ();
2104    
2105                loc = (Elf64_External_Rela *) sreloc->contents;                loc = sreloc->contents;
2106                loc += sreloc->reloc_count++;                loc += sreloc->reloc_count++ * sizeof (Elf64_External_Rela);
2107                bfd_elf64_swap_reloca_out (output_bfd, &outrel, loc);                bfd_elf64_swap_reloca_out (output_bfd, &outrel, loc);
2108    
2109                /* If this reloc is against an external symbol, we do                /* If this reloc is against an external symbol, we do
# Line 1934  elf64_x86_64_relocate_section (output_bf Line 2116  elf64_x86_64_relocate_section (output_bf
2116    
2117            break;            break;
2118    
2119            case R_X86_64_TLSGD:
2120            case R_X86_64_GOTTPOFF:
2121              r_type = elf64_x86_64_tls_transition (info, r_type, h == NULL);
2122              tls_type = GOT_UNKNOWN;
2123              if (h == NULL && local_got_offsets)
2124                tls_type = elf64_x86_64_local_got_tls_type (input_bfd) [r_symndx];
2125              else if (h != NULL)
2126                {
2127                  tls_type = elf64_x86_64_hash_entry (h)->tls_type;
2128                  if (!info->shared && h->dynindx == -1 && tls_type == GOT_TLS_IE)
2129                    r_type = R_X86_64_TPOFF32;
2130                }
2131              if (r_type == R_X86_64_TLSGD)
2132                {
2133                  if (tls_type == GOT_TLS_IE)
2134                    r_type = R_X86_64_GOTTPOFF;
2135                }
2136    
2137              if (r_type == R_X86_64_TPOFF32)
2138                {
2139                  BFD_ASSERT (! unresolved_reloc);
2140                  if (ELF64_R_TYPE (rel->r_info) == R_X86_64_TLSGD)
2141                    {
2142                      unsigned int i;
2143                      static unsigned char tlsgd[8]
2144                        = { 0x66, 0x48, 0x8d, 0x3d, 0x66, 0x66, 0x48, 0xe8 };
2145    
2146                      /* GD->LE transition.
2147                         .byte 0x66; leaq foo@tlsgd(%rip), %rdi
2148                         .word 0x6666; rex64; call __tls_get_addr@plt
2149                         Change it into:
2150                         movq %fs:0, %rax
2151                         leaq foo@tpoff(%rax), %rax */
2152                      BFD_ASSERT (rel->r_offset >= 4);
2153                      for (i = 0; i < 4; i++)
2154                        BFD_ASSERT (bfd_get_8 (input_bfd,
2155                                               contents + rel->r_offset - 4 + i)
2156                                    == tlsgd[i]);
2157                      BFD_ASSERT (rel->r_offset + 12 <= input_section->size);
2158                      for (i = 0; i < 4; i++)
2159                        BFD_ASSERT (bfd_get_8 (input_bfd,
2160                                               contents + rel->r_offset + 4 + i)
2161                                    == tlsgd[i+4]);
2162                      BFD_ASSERT (rel + 1 < relend);
2163                      BFD_ASSERT (ELF64_R_TYPE (rel[1].r_info) == R_X86_64_PLT32);
2164                      memcpy (contents + rel->r_offset - 4,
2165                              "\x64\x48\x8b\x04\x25\0\0\0\0\x48\x8d\x80\0\0\0",
2166                              16);
2167                      bfd_put_32 (output_bfd, tpoff (info, relocation),
2168                                  contents + rel->r_offset + 8);
2169                      /* Skip R_X86_64_PLT32.  */
2170                      rel++;
2171                      continue;
2172                    }
2173                  else
2174                    {
2175                      unsigned int val, type, reg;
2176    
2177                      /* IE->LE transition:
2178                         Originally it can be one of:
2179                         movq foo@gottpoff(%rip), %reg
2180                         addq foo@gottpoff(%rip), %reg
2181                         We change it into:
2182                         movq $foo, %reg
2183                         leaq foo(%reg), %reg
2184                         addq $foo, %reg.  */
2185                      BFD_ASSERT (rel->r_offset >= 3);
2186                      val = bfd_get_8 (input_bfd, contents + rel->r_offset - 3);
2187                      BFD_ASSERT (val == 0x48 || val == 0x4c);
2188                      type = bfd_get_8 (input_bfd, contents + rel->r_offset - 2);
2189                      BFD_ASSERT (type == 0x8b || type == 0x03);
2190                      reg = bfd_get_8 (input_bfd, contents + rel->r_offset - 1);
2191                      BFD_ASSERT ((reg & 0xc7) == 5);
2192                      reg >>= 3;
2193                      BFD_ASSERT (rel->r_offset + 4 <= input_section->size);
2194                      if (type == 0x8b)
2195                        {
2196                          /* movq */
2197                          if (val == 0x4c)
2198                            bfd_put_8 (output_bfd, 0x49,
2199                                       contents + rel->r_offset - 3);
2200                          bfd_put_8 (output_bfd, 0xc7,
2201                                     contents + rel->r_offset - 2);
2202                          bfd_put_8 (output_bfd, 0xc0 | reg,
2203                                     contents + rel->r_offset - 1);
2204                        }
2205                      else if (reg == 4)
2206                        {
2207                          /* addq -> addq - addressing with %rsp/%r12 is
2208                             special  */
2209                          if (val == 0x4c)
2210                            bfd_put_8 (output_bfd, 0x49,
2211                                       contents + rel->r_offset - 3);
2212                          bfd_put_8 (output_bfd, 0x81,
2213                                     contents + rel->r_offset - 2);
2214                          bfd_put_8 (output_bfd, 0xc0 | reg,
2215                                     contents + rel->r_offset - 1);
2216                        }
2217                      else
2218                        {
2219                          /* addq -> leaq */
2220                          if (val == 0x4c)
2221                            bfd_put_8 (output_bfd, 0x4d,
2222                                       contents + rel->r_offset - 3);
2223                          bfd_put_8 (output_bfd, 0x8d,
2224                                     contents + rel->r_offset - 2);
2225                          bfd_put_8 (output_bfd, 0x80 | reg | (reg << 3),
2226                                     contents + rel->r_offset - 1);
2227                        }
2228                      bfd_put_32 (output_bfd, tpoff (info, relocation),
2229                                  contents + rel->r_offset);
2230                      continue;
2231                    }
2232                }
2233    
2234              if (htab->sgot == NULL)
2235                abort ();
2236    
2237              if (h != NULL)
2238                off = h->got.offset;
2239              else
2240                {
2241                  if (local_got_offsets == NULL)
2242                    abort ();
2243    
2244                  off = local_got_offsets[r_symndx];
2245                }
2246    
2247              if ((off & 1) != 0)
2248                off &= ~1;
2249              else
2250                {
2251                  Elf_Internal_Rela outrel;
2252                  bfd_byte *loc;
2253                  int dr_type, indx;
2254    
2255                  if (htab->srelgot == NULL)
2256                    abort ();
2257    
2258                  outrel.r_offset = (htab->sgot->output_section->vma
2259                                     + htab->sgot->output_offset + off);
2260    
2261                  indx = h && h->dynindx != -1 ? h->dynindx : 0;
2262                  if (r_type == R_X86_64_TLSGD)
2263                    dr_type = R_X86_64_DTPMOD64;
2264                  else
2265                    dr_type = R_X86_64_TPOFF64;
2266    
2267                  bfd_put_64 (output_bfd, 0, htab->sgot->contents + off);
2268                  outrel.r_addend = 0;
2269                  if (dr_type == R_X86_64_TPOFF64 && indx == 0)
2270                    outrel.r_addend = relocation - dtpoff_base (info);
2271                  outrel.r_info = ELF64_R_INFO (indx, dr_type);
2272    
2273                  loc = htab->srelgot->contents;
2274                  loc += htab->srelgot->reloc_count++ * sizeof (Elf64_External_Rela);
2275                  bfd_elf64_swap_reloca_out (output_bfd, &outrel, loc);
2276    
2277                  if (r_type == R_X86_64_TLSGD)
2278                    {
2279                      if (indx == 0)
2280                        {
2281                          BFD_ASSERT (! unresolved_reloc);
2282                          bfd_put_64 (output_bfd,
2283                                      relocation - dtpoff_base (info),
2284                                      htab->sgot->contents + off + GOT_ENTRY_SIZE);
2285                        }
2286                      else
2287                        {
2288                          bfd_put_64 (output_bfd, 0,
2289                                      htab->sgot->contents + off + GOT_ENTRY_SIZE);
2290                          outrel.r_info = ELF64_R_INFO (indx,
2291                                                        R_X86_64_DTPOFF64);
2292                          outrel.r_offset += GOT_ENTRY_SIZE;
2293                          htab->srelgot->reloc_count++;
2294                          loc += sizeof (Elf64_External_Rela);
2295                          bfd_elf64_swap_reloca_out (output_bfd, &outrel, loc);
2296                        }
2297                    }
2298    
2299                  if (h != NULL)
2300                    h->got.offset |= 1;
2301                  else
2302                    local_got_offsets[r_symndx] |= 1;
2303                }
2304    
2305              if (off >= (bfd_vma) -2)
2306                abort ();
2307              if (r_type == ELF64_R_TYPE (rel->r_info))
2308                {
2309                  relocation = htab->sgot->output_section->vma
2310                               + htab->sgot->output_offset + off;
2311                  unresolved_reloc = FALSE;
2312                }
2313              else
2314                {
2315                  unsigned int i;
2316                  static unsigned char tlsgd[8]
2317                    = { 0x66, 0x48, 0x8d, 0x3d, 0x66, 0x66, 0x48, 0xe8 };
2318    
2319                  /* GD->IE transition.
2320                     .byte 0x66; leaq foo@tlsgd(%rip), %rdi
2321                     .word 0x6666; rex64; call __tls_get_addr@plt
2322                     Change it into:
2323                     movq %fs:0, %rax
2324                     addq foo@gottpoff(%rip), %rax */
2325                  BFD_ASSERT (rel->r_offset >= 4);
2326                  for (i = 0; i < 4; i++)
2327                    BFD_ASSERT (bfd_get_8 (input_bfd,
2328                                           contents + rel->r_offset - 4 + i)
2329                                == tlsgd[i]);
2330                  BFD_ASSERT (rel->r_offset + 12 <= input_section->size);
2331                  for (i = 0; i < 4; i++)
2332                    BFD_ASSERT (bfd_get_8 (input_bfd,
2333                                           contents + rel->r_offset + 4 + i)
2334                                == tlsgd[i+4]);
2335                  BFD_ASSERT (rel + 1 < relend);
2336                  BFD_ASSERT (ELF64_R_TYPE (rel[1].r_info) == R_X86_64_PLT32);
2337                  memcpy (contents + rel->r_offset - 4,
2338                          "\x64\x48\x8b\x04\x25\0\0\0\0\x48\x03\x05\0\0\0",
2339                          16);
2340    
2341                  relocation = (htab->sgot->output_section->vma
2342                                + htab->sgot->output_offset + off
2343                                - rel->r_offset
2344                                - input_section->output_section->vma
2345                                - input_section->output_offset
2346                                - 12);
2347                  bfd_put_32 (output_bfd, relocation,
2348                              contents + rel->r_offset + 8);
2349                  /* Skip R_X86_64_PLT32.  */
2350                  rel++;
2351                  continue;
2352                }
2353              break;
2354    
2355            case R_X86_64_TLSLD:
2356              if (! info->shared)
2357                {
2358                  /* LD->LE transition:
2359                     Ensure it is:
2360                     leaq foo@tlsld(%rip), %rdi; call __tls_get_addr@plt.
2361                     We change it into:
2362                     .word 0x6666; .byte 0x66; movl %fs:0, %rax.  */
2363                  BFD_ASSERT (rel->r_offset >= 3);
2364                  BFD_ASSERT (bfd_get_8 (input_bfd, contents + rel->r_offset - 3)
2365                              == 0x48);
2366                  BFD_ASSERT (bfd_get_8 (input_bfd, contents + rel->r_offset - 2)
2367                              == 0x8d);
2368                  BFD_ASSERT (bfd_get_8 (input_bfd, contents + rel->r_offset - 1)
2369                              == 0x3d);
2370                  BFD_ASSERT (rel->r_offset + 9 <= input_section->size);
2371                  BFD_ASSERT (bfd_get_8 (input_bfd, contents + rel->r_offset + 4)
2372                              == 0xe8);
2373                  BFD_ASSERT (rel + 1 < relend);
2374                  BFD_ASSERT (ELF64_R_TYPE (rel[1].r_info) == R_X86_64_PLT32);
2375                  memcpy (contents + rel->r_offset - 3,
2376                          "\x66\x66\x66\x64\x48\x8b\x04\x25\0\0\0", 12);
2377                  /* Skip R_X86_64_PLT32.  */
2378                  rel++;
2379                  continue;
2380                }
2381    
2382              if (htab->sgot == NULL)
2383                abort ();
2384    
2385              off = htab->tls_ld_got.offset;
2386              if (off & 1)
2387                off &= ~1;
2388              else
2389                {
2390                  Elf_Internal_Rela outrel;
2391                  bfd_byte *loc;
2392    
2393                  if (htab->srelgot == NULL)
2394                    abort ();
2395    
2396                  outrel.r_offset = (htab->sgot->output_section->vma
2397                                     + htab->sgot->output_offset + off);
2398    
2399                  bfd_put_64 (output_bfd, 0,
2400                              htab->sgot->contents + off);
2401                  bfd_put_64 (output_bfd, 0,
2402                              htab->sgot->contents + off + GOT_ENTRY_SIZE);
2403                  outrel.r_info = ELF64_R_INFO (0, R_X86_64_DTPMOD64);
2404                  outrel.r_addend = 0;
2405                  loc = htab->srelgot->contents;
2406                  loc += htab->srelgot->reloc_count++ * sizeof (Elf64_External_Rela);
2407                  bfd_elf64_swap_reloca_out (output_bfd, &outrel, loc);
2408                  htab->tls_ld_got.offset |= 1;
2409                }
2410              relocation = htab->sgot->output_section->vma
2411                           + htab->sgot->output_offset + off;
2412              unresolved_reloc = FALSE;
2413              break;
2414    
2415            case R_X86_64_DTPOFF32:
2416              if (info->shared || (input_section->flags & SEC_CODE) == 0)
2417                relocation -= dtpoff_base (info);
2418              else
2419                relocation = tpoff (info, relocation);
2420              break;
2421    
2422            case R_X86_64_TPOFF32:
2423              BFD_ASSERT (! info->shared);
2424              relocation = tpoff (info, relocation);
2425              break;
2426    
2427          default:          default:
2428            break;            break;
2429          }          }
# Line 1943  elf64_x86_64_relocate_section (output_bf Line 2433  elf64_x86_64_relocate_section (output_bf
2433           not process them.  */           not process them.  */
2434        if (unresolved_reloc        if (unresolved_reloc
2435            && !((input_section->flags & SEC_DEBUGGING) != 0            && !((input_section->flags & SEC_DEBUGGING) != 0
2436                 && (h->elf_link_hash_flags & ELF_LINK_HASH_DEF_DYNAMIC) != 0))                 && h->def_dynamic))
2437          (*_bfd_error_handler)          (*_bfd_error_handler)
2438            (_("%s(%s+0x%lx): unresolvable relocation against symbol `%s'"),            (_("%B(%A+0x%lx): unresolvable relocation against symbol `%s'"),
2439             bfd_archive_filename (input_bfd),             input_bfd,
2440             bfd_get_section_name (input_bfd, input_section),             input_section,
2441             (long) rel->r_offset,             (long) rel->r_offset,
2442             h->root.root.string);             h->root.root.string);
2443    
# Line 1967  elf64_x86_64_relocate_section (output_bf Line 2457  elf64_x86_64_relocate_section (output_bf
2457                                                        symtab_hdr->sh_link,                                                        symtab_hdr->sh_link,
2458                                                        sym->st_name);                                                        sym->st_name);
2459                if (name == NULL)                if (name == NULL)
2460                  return false;                  return FALSE;
2461                if (*name == '\0')                if (*name == '\0')
2462                  name = bfd_section_name (input_bfd, sec);                  name = bfd_section_name (input_bfd, sec);
2463              }              }
2464    
2465            if (r == bfd_reloc_overflow)            if (r == bfd_reloc_overflow)
2466              {              {
2467                  if (h != NULL
2468                      && h->root.type == bfd_link_hash_undefweak
2469                      && howto->pc_relative)
2470                    /* Ignore reloc overflow on branches to undefweak syms.  */
2471                    continue;
2472    
2473                if (! ((*info->callbacks->reloc_overflow)                if (! ((*info->callbacks->reloc_overflow)
2474                       (info, name, howto->name, (bfd_vma) 0,                       (info, (h ? &h->root : NULL), name, howto->name,
2475                        input_bfd, input_section, rel->r_offset)))                        (bfd_vma) 0, input_bfd, input_section,
2476                  return false;                        rel->r_offset)))
2477                    return FALSE;
2478              }              }
2479            else            else
2480              {              {
2481                (*_bfd_error_handler)                (*_bfd_error_handler)
2482                  (_("%s(%s+0x%lx): reloc against `%s': error %d"),                  (_("%B(%A+0x%lx): reloc against `%s': error %d"),
2483                   bfd_archive_filename (input_bfd),                   input_bfd, input_section,
                  bfd_get_section_name (input_bfd, input_section),  
2484                   (long) rel->r_offset, name, (int) r);                   (long) rel->r_offset, name, (int) r);
2485                return false;                return FALSE;
2486              }              }
2487          }          }
2488      }      }
2489    
2490    return true;    return TRUE;
2491  }  }
2492    
2493  /* Finish up dynamic symbol handling.  We set the contents of various  /* Finish up dynamic symbol handling.  We set the contents of various
2494     dynamic sections here.  */     dynamic sections here.  */
2495    
2496  static boolean  static bfd_boolean
2497  elf64_x86_64_finish_dynamic_symbol (output_bfd, info, h, sym)  elf64_x86_64_finish_dynamic_symbol (bfd *output_bfd,
2498       bfd *output_bfd;                                      struct bfd_link_info *info,
2499       struct bfd_link_info *info;                                      struct elf_link_hash_entry *h,
2500       struct elf_link_hash_entry *h;                                      Elf_Internal_Sym *sym)
      Elf_Internal_Sym *sym;  
2501  {  {
2502    struct elf64_x86_64_link_hash_table *htab;    struct elf64_x86_64_link_hash_table *htab;
2503    
# Line 2014  elf64_x86_64_finish_dynamic_symbol (outp Line 2508  elf64_x86_64_finish_dynamic_symbol (outp
2508        bfd_vma plt_index;        bfd_vma plt_index;
2509        bfd_vma got_offset;        bfd_vma got_offset;
2510        Elf_Internal_Rela rela;        Elf_Internal_Rela rela;
2511        Elf64_External_Rela *loc;        bfd_byte *loc;
2512    
2513        /* This symbol has an entry in the procedure linkage table.  Set        /* This symbol has an entry in the procedure linkage table.  Set
2514           it up.  */           it up.  */
   
2515        if (h->dynindx == -1        if (h->dynindx == -1
2516            || htab->splt == NULL            || htab->splt == NULL
2517            || htab->sgotplt == NULL            || htab->sgotplt == NULL
# Line 2074  elf64_x86_64_finish_dynamic_symbol (outp Line 2567  elf64_x86_64_finish_dynamic_symbol (outp
2567                         + got_offset);                         + got_offset);
2568        rela.r_info = ELF64_R_INFO (h->dynindx, R_X86_64_JUMP_SLOT);        rela.r_info = ELF64_R_INFO (h->dynindx, R_X86_64_JUMP_SLOT);
2569        rela.r_addend = 0;        rela.r_addend = 0;
2570        loc = (Elf64_External_Rela *) htab->srelplt->contents + plt_index;        loc = htab->srelplt->contents + plt_index * sizeof (Elf64_External_Rela);
2571        bfd_elf64_swap_reloca_out (output_bfd, &rela, loc);        bfd_elf64_swap_reloca_out (output_bfd, &rela, loc);
2572    
2573        if ((h->elf_link_hash_flags & ELF_LINK_HASH_DEF_REGULAR) == 0)        if (!h->def_regular)
2574          {          {
2575            /* Mark the symbol as undefined, rather than as defined in            /* Mark the symbol as undefined, rather than as defined in
2576               the .plt section.  Leave the value alone.  This is a clue               the .plt section.  Leave the value if there were any
2577                 relocations where pointer equality matters (this is a clue
2578               for the dynamic linker, to make function pointer               for the dynamic linker, to make function pointer
2579               comparisons work between an application and shared               comparisons work between an application and shared
2580               library.  */               library), otherwise set it to zero.  If a function is only
2581                 called from a binary, there is no need to slow down
2582                 shared libraries because of that.  */
2583            sym->st_shndx = SHN_UNDEF;            sym->st_shndx = SHN_UNDEF;
2584              if (!h->pointer_equality_needed)
2585                sym->st_value = 0;
2586          }          }
2587      }      }
2588    
2589    if (h->got.offset != (bfd_vma) -1)    if (h->got.offset != (bfd_vma) -1
2590          && elf64_x86_64_hash_entry (h)->tls_type != GOT_TLS_GD
2591          && elf64_x86_64_hash_entry (h)->tls_type != GOT_TLS_IE)
2592      {      {
2593        Elf_Internal_Rela rela;        Elf_Internal_Rela rela;
2594        Elf64_External_Rela *loc;        bfd_byte *loc;
2595    
2596        /* This symbol has an entry in the global offset table.  Set it        /* This symbol has an entry in the global offset table.  Set it
2597           up.  */           up.  */
   
2598        if (htab->sgot == NULL || htab->srelgot == NULL)        if (htab->sgot == NULL || htab->srelgot == NULL)
2599          abort ();          abort ();
2600    
# Line 2109  elf64_x86_64_finish_dynamic_symbol (outp Line 2608  elf64_x86_64_finish_dynamic_symbol (outp
2608           The entry in the global offset table will already have been           The entry in the global offset table will already have been
2609           initialized in the relocate_section function.  */           initialized in the relocate_section function.  */
2610        if (info->shared        if (info->shared
2611            && (info->symbolic            && SYMBOL_REFERENCES_LOCAL (info, h))
               || h->dynindx == -1  
               || (h->elf_link_hash_flags & ELF_LINK_FORCED_LOCAL))  
           && (h->elf_link_hash_flags & ELF_LINK_HASH_DEF_REGULAR))  
2612          {          {
2613            BFD_ASSERT((h->got.offset & 1) != 0);            BFD_ASSERT((h->got.offset & 1) != 0);
2614            rela.r_info = ELF64_R_INFO (0, R_X86_64_RELATIVE);            rela.r_info = ELF64_R_INFO (0, R_X86_64_RELATIVE);
# Line 2129  elf64_x86_64_finish_dynamic_symbol (outp Line 2625  elf64_x86_64_finish_dynamic_symbol (outp
2625            rela.r_addend = 0;            rela.r_addend = 0;
2626          }          }
2627    
2628        loc = (Elf64_External_Rela *) htab->srelgot->contents;        loc = htab->srelgot->contents;
2629        loc += htab->srelgot->reloc_count++;        loc += htab->srelgot->reloc_count++ * sizeof (Elf64_External_Rela);
2630        bfd_elf64_swap_reloca_out (output_bfd, &rela, loc);        bfd_elf64_swap_reloca_out (output_bfd, &rela, loc);
2631      }      }
2632    
2633    if ((h->elf_link_hash_flags & ELF_LINK_HASH_NEEDS_COPY) != 0)    if (h->needs_copy)
2634      {      {
2635        Elf_Internal_Rela rela;        Elf_Internal_Rela rela;
2636        Elf64_External_Rela *loc;        bfd_byte *loc;
2637    
2638        /* This symbol needs a copy reloc.  Set it up.  */        /* This symbol needs a copy reloc.  Set it up.  */
2639    
# Line 2152  elf64_x86_64_finish_dynamic_symbol (outp Line 2648  elf64_x86_64_finish_dynamic_symbol (outp
2648                         + h->root.u.def.section->output_offset);                         + h->root.u.def.section->output_offset);
2649        rela.r_info = ELF64_R_INFO (h->dynindx, R_X86_64_COPY);        rela.r_info = ELF64_R_INFO (h->dynindx, R_X86_64_COPY);
2650        rela.r_addend = 0;        rela.r_addend = 0;
2651        loc = (Elf64_External_Rela *) htab->srelbss->contents;        loc = htab->srelbss->contents;
2652        loc += htab->srelbss->reloc_count++;        loc += htab->srelbss->reloc_count++ * sizeof (Elf64_External_Rela);
2653        bfd_elf64_swap_reloca_out (output_bfd, &rela, loc);        bfd_elf64_swap_reloca_out (output_bfd, &rela, loc);
2654      }      }
2655    
# Line 2162  elf64_x86_64_finish_dynamic_symbol (outp Line 2658  elf64_x86_64_finish_dynamic_symbol (outp
2658        || strcmp (h->root.root.string, "_GLOBAL_OFFSET_TABLE_") == 0)        || strcmp (h->root.root.string, "_GLOBAL_OFFSET_TABLE_") == 0)
2659      sym->st_shndx = SHN_ABS;      sym->st_shndx = SHN_ABS;
2660    
2661    return true;    return TRUE;
2662  }  }
2663    
2664  /* Used to decide how to sort relocs in an optimal manner for the  /* Used to decide how to sort relocs in an optimal manner for the
2665     dynamic linker, before writing them out.  */     dynamic linker, before writing them out.  */
2666    
2667  static enum elf_reloc_type_class  static enum elf_reloc_type_class
2668  elf64_x86_64_reloc_type_class (rela)  elf64_x86_64_reloc_type_class (const Elf_Internal_Rela *rela)
      const Elf_Internal_Rela *rela;  
2669  {  {
2670    switch ((int) ELF64_R_TYPE (rela->r_info))    switch ((int) ELF64_R_TYPE (rela->r_info))
2671      {      {
# Line 2187  elf64_x86_64_reloc_type_class (rela) Line 2682  elf64_x86_64_reloc_type_class (rela)
2682    
2683  /* Finish up the dynamic sections.  */  /* Finish up the dynamic sections.  */
2684    
2685  static boolean  static bfd_boolean
2686  elf64_x86_64_finish_dynamic_sections (output_bfd, info)  elf64_x86_64_finish_dynamic_sections (bfd *output_bfd, struct bfd_link_info *info)
      bfd *output_bfd;  
      struct bfd_link_info *info;  
2687  {  {
2688    struct elf64_x86_64_link_hash_table *htab;    struct elf64_x86_64_link_hash_table *htab;
2689    bfd *dynobj;    bfd *dynobj;
# Line 2208  elf64_x86_64_finish_dynamic_sections (ou Line 2701  elf64_x86_64_finish_dynamic_sections (ou
2701          abort ();          abort ();
2702    
2703        dyncon = (Elf64_External_Dyn *) sdyn->contents;        dyncon = (Elf64_External_Dyn *) sdyn->contents;
2704        dynconend = (Elf64_External_Dyn *) (sdyn->contents + sdyn->_raw_size);        dynconend = (Elf64_External_Dyn *) (sdyn->contents + sdyn->size);
2705        for (; dyncon < dynconend; dyncon++)        for (; dyncon < dynconend; dyncon++)
2706          {          {
2707            Elf_Internal_Dyn dyn;            Elf_Internal_Dyn dyn;
# Line 2222  elf64_x86_64_finish_dynamic_sections (ou Line 2715  elf64_x86_64_finish_dynamic_sections (ou
2715                continue;                continue;
2716    
2717              case DT_PLTGOT:              case DT_PLTGOT:
2718                dyn.d_un.d_ptr = htab->sgot->output_section->vma;                s = htab->sgotplt;
2719                  dyn.d_un.d_ptr = s->output_section->vma + s->output_offset;
2720                break;                break;
2721    
2722              case DT_JMPREL:              case DT_JMPREL:
# Line 2231  elf64_x86_64_finish_dynamic_sections (ou Line 2725  elf64_x86_64_finish_dynamic_sections (ou
2725    
2726              case DT_PLTRELSZ:              case DT_PLTRELSZ:
2727                s = htab->srelplt->output_section;                s = htab->srelplt->output_section;
2728                if (s->_cooked_size != 0)                dyn.d_un.d_val = s->size;
                 dyn.d_un.d_val = s->_cooked_size;  
               else  
                 dyn.d_un.d_val = s->_raw_size;  
2729                break;                break;
2730    
2731              case DT_RELASZ:              case DT_RELASZ:
# Line 2248  elf64_x86_64_finish_dynamic_sections (ou Line 2739  elf64_x86_64_finish_dynamic_sections (ou
2739                if (htab->srelplt != NULL)                if (htab->srelplt != NULL)
2740                  {                  {
2741                    s = htab->srelplt->output_section;                    s = htab->srelplt->output_section;
2742                    if (s->_cooked_size != 0)                    dyn.d_un.d_val -= s->size;
                     dyn.d_un.d_val -= s->_cooked_size;  
                   else  
                     dyn.d_un.d_val -= s->_raw_size;  
2743                  }                  }
2744                break;                break;
2745              }              }
# Line 2260  elf64_x86_64_finish_dynamic_sections (ou Line 2748  elf64_x86_64_finish_dynamic_sections (ou
2748          }          }
2749    
2750        /* Fill in the special first entry in the procedure linkage table.  */        /* Fill in the special first entry in the procedure linkage table.  */
2751        if (htab->splt && htab->splt->_raw_size > 0)        if (htab->splt && htab->splt->size > 0)
2752          {          {
2753            /* Fill in the first entry in the procedure linkage table.  */            /* Fill in the first entry in the procedure linkage table.  */
2754            memcpy (htab->splt->contents, elf64_x86_64_plt0_entry,            memcpy (htab->splt->contents, elf64_x86_64_plt0_entry,
# Line 2294  elf64_x86_64_finish_dynamic_sections (ou Line 2782  elf64_x86_64_finish_dynamic_sections (ou
2782    if (htab->sgotplt)    if (htab->sgotplt)
2783      {      {
2784        /* Fill in the first three entries in the global offset table.  */        /* Fill in the first three entries in the global offset table.  */
2785        if (htab->sgotplt->_raw_size > 0)        if (htab->sgotplt->size > 0)
2786          {          {
2787            /* Set the first entry in the global offset table to the address of            /* Set the first entry in the global offset table to the address of
2788               the dynamic section.  */               the dynamic section.  */
# Line 2313  elf64_x86_64_finish_dynamic_sections (ou Line 2801  elf64_x86_64_finish_dynamic_sections (ou
2801          GOT_ENTRY_SIZE;          GOT_ENTRY_SIZE;
2802      }      }
2803    
2804    return true;    if (htab->sgot && htab->sgot->size > 0)
2805        elf_section_data (htab->sgot->output_section)->this_hdr.sh_entsize
2806          = GOT_ENTRY_SIZE;
2807    
2808      return TRUE;
2809  }  }
2810    
2811    /* Return address for Ith PLT stub in section PLT, for relocation REL
2812       or (bfd_vma) -1 if it should not be included.  */
2813    
2814    static bfd_vma
2815    elf64_x86_64_plt_sym_val (bfd_vma i, const asection *plt,
2816                              const arelent *rel ATTRIBUTE_UNUSED)
2817    {
2818      return plt->vma + (i + 1) * PLT_ENTRY_SIZE;
2819    }
2820    
2821    /* Handle an x86-64 specific section when reading an object file.  This
2822       is called when elfcode.h finds a section with an unknown type.  */
2823    
2824    static bfd_boolean
2825    elf64_x86_64_section_from_shdr (bfd *abfd, Elf_Internal_Shdr *hdr, const char *name)
2826    {
2827      if (hdr->sh_type != SHT_X86_64_UNWIND)
2828        return FALSE;
2829    
2830      if (! _bfd_elf_make_section_from_shdr (abfd, hdr, name))
2831        return FALSE;
2832    
2833      return TRUE;
2834    }
2835    
2836  #define TARGET_LITTLE_SYM                   bfd_elf64_x86_64_vec  #define TARGET_LITTLE_SYM                   bfd_elf64_x86_64_vec
2837  #define TARGET_LITTLE_NAME                  "elf64-x86-64"  #define TARGET_LITTLE_NAME                  "elf64-x86-64"
# Line 2329  elf64_x86_64_finish_dynamic_sections (ou Line 2845  elf64_x86_64_finish_dynamic_sections (ou
2845  #define elf_backend_plt_readonly            1  #define elf_backend_plt_readonly            1
2846  #define elf_backend_want_plt_sym            0  #define elf_backend_want_plt_sym            0
2847  #define elf_backend_got_header_size         (GOT_ENTRY_SIZE*3)  #define elf_backend_got_header_size         (GOT_ENTRY_SIZE*3)
 #define elf_backend_plt_header_size         PLT_ENTRY_SIZE  
2848  #define elf_backend_rela_normal             1  #define elf_backend_rela_normal             1
2849    
2850  #define elf_info_to_howto                   elf64_x86_64_info_to_howto  #define elf_info_to_howto                   elf64_x86_64_info_to_howto
# Line 2351  elf64_x86_64_finish_dynamic_sections (ou Line 2866  elf64_x86_64_finish_dynamic_sections (ou
2866  #define elf_backend_reloc_type_class        elf64_x86_64_reloc_type_class  #define elf_backend_reloc_type_class        elf64_x86_64_reloc_type_class
2867  #define elf_backend_relocate_section        elf64_x86_64_relocate_section  #define elf_backend_relocate_section        elf64_x86_64_relocate_section
2868  #define elf_backend_size_dynamic_sections   elf64_x86_64_size_dynamic_sections  #define elf_backend_size_dynamic_sections   elf64_x86_64_size_dynamic_sections
2869    #define elf_backend_plt_sym_val             elf64_x86_64_plt_sym_val
2870  #define elf_backend_object_p                elf64_x86_64_elf_object_p  #define elf_backend_object_p                elf64_x86_64_elf_object_p
2871    #define bfd_elf64_mkobject                  elf64_x86_64_mkobject
2872    
2873    #define elf_backend_section_from_shdr \
2874            elf64_x86_64_section_from_shdr
2875    
2876  #include "elf64-target.h"  #include "elf64-target.h"

Legend:
Removed from v.1.1.1.1  
changed lines
  Added in v.1.2

savannah-hackers-public@gnu.org
ViewVC Help
Powered by ViewVC 1.1.26