xref: /dflybsd-src/contrib/binutils-2.27/bfd/elf64-x86-64.c (revision 14cfea9901210cefd3a1d65dc15887461b194bde)
1a9fa9459Szrj /* X86-64 specific support for ELF
2a9fa9459Szrj    Copyright (C) 2000-2016 Free Software Foundation, Inc.
3a9fa9459Szrj    Contributed by Jan Hubicka <jh@suse.cz>.
4a9fa9459Szrj 
5a9fa9459Szrj    This file is part of BFD, the Binary File Descriptor library.
6a9fa9459Szrj 
7a9fa9459Szrj    This program is free software; you can redistribute it and/or modify
8a9fa9459Szrj    it under the terms of the GNU General Public License as published by
9a9fa9459Szrj    the Free Software Foundation; either version 3 of the License, or
10a9fa9459Szrj    (at your option) any later version.
11a9fa9459Szrj 
12a9fa9459Szrj    This program is distributed in the hope that it will be useful,
13a9fa9459Szrj    but WITHOUT ANY WARRANTY; without even the implied warranty of
14a9fa9459Szrj    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15a9fa9459Szrj    GNU General Public License for more details.
16a9fa9459Szrj 
17a9fa9459Szrj    You should have received a copy of the GNU General Public License
18a9fa9459Szrj    along with this program; if not, write to the Free Software
19a9fa9459Szrj    Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
20a9fa9459Szrj    MA 02110-1301, USA.  */
21a9fa9459Szrj 
22a9fa9459Szrj #include "sysdep.h"
23a9fa9459Szrj #include "bfd.h"
24a9fa9459Szrj #include "bfdlink.h"
25a9fa9459Szrj #include "libbfd.h"
26a9fa9459Szrj #include "elf-bfd.h"
27a9fa9459Szrj #include "elf-nacl.h"
28a9fa9459Szrj #include "bfd_stdint.h"
29a9fa9459Szrj #include "objalloc.h"
30a9fa9459Szrj #include "hashtab.h"
31a9fa9459Szrj #include "dwarf2.h"
32a9fa9459Szrj #include "libiberty.h"
33a9fa9459Szrj 
34a9fa9459Szrj #include "opcode/i386.h"
35a9fa9459Szrj #include "elf/x86-64.h"
36a9fa9459Szrj 
37a9fa9459Szrj #ifdef CORE_HEADER
38a9fa9459Szrj #include <stdarg.h>
39a9fa9459Szrj #include CORE_HEADER
40a9fa9459Szrj #endif
41a9fa9459Szrj 
42a9fa9459Szrj /* In case we're on a 32-bit machine, construct a 64-bit "-1" value.  */
43a9fa9459Szrj #define MINUS_ONE (~ (bfd_vma) 0)
44a9fa9459Szrj 
45a9fa9459Szrj /* Since both 32-bit and 64-bit x86-64 encode relocation type in the
46a9fa9459Szrj    identical manner, we use ELF32_R_TYPE instead of ELF64_R_TYPE to get
47a9fa9459Szrj    relocation type.  We also use ELF_ST_TYPE instead of ELF64_ST_TYPE
48a9fa9459Szrj    since they are the same.  */
49a9fa9459Szrj 
50a9fa9459Szrj #define ABI_64_P(abfd) \
51a9fa9459Szrj   (get_elf_backend_data (abfd)->s->elfclass == ELFCLASS64)
52a9fa9459Szrj 
53a9fa9459Szrj /* The relocation "howto" table.  Order of fields:
54a9fa9459Szrj    type, rightshift, size, bitsize, pc_relative, bitpos, complain_on_overflow,
55a9fa9459Szrj    special_function, name, partial_inplace, src_mask, dst_mask, pcrel_offset.  */
56a9fa9459Szrj static reloc_howto_type x86_64_elf_howto_table[] =
57a9fa9459Szrj {
58a9fa9459Szrj   HOWTO(R_X86_64_NONE, 0, 3, 0, FALSE, 0, complain_overflow_dont,
59a9fa9459Szrj 	bfd_elf_generic_reloc, "R_X86_64_NONE",	FALSE, 0x00000000, 0x00000000,
60a9fa9459Szrj 	FALSE),
61a9fa9459Szrj   HOWTO(R_X86_64_64, 0, 4, 64, FALSE, 0, complain_overflow_bitfield,
62a9fa9459Szrj 	bfd_elf_generic_reloc, "R_X86_64_64", FALSE, MINUS_ONE, MINUS_ONE,
63a9fa9459Szrj 	FALSE),
64a9fa9459Szrj   HOWTO(R_X86_64_PC32, 0, 2, 32, TRUE, 0, complain_overflow_signed,
65a9fa9459Szrj 	bfd_elf_generic_reloc, "R_X86_64_PC32", FALSE, 0xffffffff, 0xffffffff,
66a9fa9459Szrj 	TRUE),
67a9fa9459Szrj   HOWTO(R_X86_64_GOT32, 0, 2, 32, FALSE, 0, complain_overflow_signed,
68a9fa9459Szrj 	bfd_elf_generic_reloc, "R_X86_64_GOT32", FALSE, 0xffffffff, 0xffffffff,
69a9fa9459Szrj 	FALSE),
70a9fa9459Szrj   HOWTO(R_X86_64_PLT32, 0, 2, 32, TRUE, 0, complain_overflow_signed,
71a9fa9459Szrj 	bfd_elf_generic_reloc, "R_X86_64_PLT32", FALSE, 0xffffffff, 0xffffffff,
72a9fa9459Szrj 	TRUE),
73a9fa9459Szrj   HOWTO(R_X86_64_COPY, 0, 2, 32, FALSE, 0, complain_overflow_bitfield,
74a9fa9459Szrj 	bfd_elf_generic_reloc, "R_X86_64_COPY", FALSE, 0xffffffff, 0xffffffff,
75a9fa9459Szrj 	FALSE),
76a9fa9459Szrj   HOWTO(R_X86_64_GLOB_DAT, 0, 4, 64, FALSE, 0, complain_overflow_bitfield,
77a9fa9459Szrj 	bfd_elf_generic_reloc, "R_X86_64_GLOB_DAT", FALSE, MINUS_ONE,
78a9fa9459Szrj 	MINUS_ONE, FALSE),
79a9fa9459Szrj   HOWTO(R_X86_64_JUMP_SLOT, 0, 4, 64, FALSE, 0, complain_overflow_bitfield,
80a9fa9459Szrj 	bfd_elf_generic_reloc, "R_X86_64_JUMP_SLOT", FALSE, MINUS_ONE,
81a9fa9459Szrj 	MINUS_ONE, FALSE),
82a9fa9459Szrj   HOWTO(R_X86_64_RELATIVE, 0, 4, 64, FALSE, 0, complain_overflow_bitfield,
83a9fa9459Szrj 	bfd_elf_generic_reloc, "R_X86_64_RELATIVE", FALSE, MINUS_ONE,
84a9fa9459Szrj 	MINUS_ONE, FALSE),
85a9fa9459Szrj   HOWTO(R_X86_64_GOTPCREL, 0, 2, 32, TRUE, 0, complain_overflow_signed,
86a9fa9459Szrj 	bfd_elf_generic_reloc, "R_X86_64_GOTPCREL", FALSE, 0xffffffff,
87a9fa9459Szrj 	0xffffffff, TRUE),
88a9fa9459Szrj   HOWTO(R_X86_64_32, 0, 2, 32, FALSE, 0, complain_overflow_unsigned,
89a9fa9459Szrj 	bfd_elf_generic_reloc, "R_X86_64_32", FALSE, 0xffffffff, 0xffffffff,
90a9fa9459Szrj 	FALSE),
91a9fa9459Szrj   HOWTO(R_X86_64_32S, 0, 2, 32, FALSE, 0, complain_overflow_signed,
92a9fa9459Szrj 	bfd_elf_generic_reloc, "R_X86_64_32S", FALSE, 0xffffffff, 0xffffffff,
93a9fa9459Szrj 	FALSE),
94a9fa9459Szrj   HOWTO(R_X86_64_16, 0, 1, 16, FALSE, 0, complain_overflow_bitfield,
95a9fa9459Szrj 	bfd_elf_generic_reloc, "R_X86_64_16", FALSE, 0xffff, 0xffff, FALSE),
96a9fa9459Szrj   HOWTO(R_X86_64_PC16,0, 1, 16, TRUE, 0, complain_overflow_bitfield,
97a9fa9459Szrj 	bfd_elf_generic_reloc, "R_X86_64_PC16", FALSE, 0xffff, 0xffff, TRUE),
98a9fa9459Szrj   HOWTO(R_X86_64_8, 0, 0, 8, FALSE, 0, complain_overflow_bitfield,
99a9fa9459Szrj 	bfd_elf_generic_reloc, "R_X86_64_8", FALSE, 0xff, 0xff, FALSE),
100a9fa9459Szrj   HOWTO(R_X86_64_PC8, 0, 0, 8, TRUE, 0, complain_overflow_signed,
101a9fa9459Szrj 	bfd_elf_generic_reloc, "R_X86_64_PC8", FALSE, 0xff, 0xff, TRUE),
102a9fa9459Szrj   HOWTO(R_X86_64_DTPMOD64, 0, 4, 64, FALSE, 0, complain_overflow_bitfield,
103a9fa9459Szrj 	bfd_elf_generic_reloc, "R_X86_64_DTPMOD64", FALSE, MINUS_ONE,
104a9fa9459Szrj 	MINUS_ONE, FALSE),
105a9fa9459Szrj   HOWTO(R_X86_64_DTPOFF64, 0, 4, 64, FALSE, 0, complain_overflow_bitfield,
106a9fa9459Szrj 	bfd_elf_generic_reloc, "R_X86_64_DTPOFF64", FALSE, MINUS_ONE,
107a9fa9459Szrj 	MINUS_ONE, FALSE),
108a9fa9459Szrj   HOWTO(R_X86_64_TPOFF64, 0, 4, 64, FALSE, 0, complain_overflow_bitfield,
109a9fa9459Szrj 	bfd_elf_generic_reloc, "R_X86_64_TPOFF64", FALSE, MINUS_ONE,
110a9fa9459Szrj 	MINUS_ONE, FALSE),
111a9fa9459Szrj   HOWTO(R_X86_64_TLSGD, 0, 2, 32, TRUE, 0, complain_overflow_signed,
112a9fa9459Szrj 	bfd_elf_generic_reloc, "R_X86_64_TLSGD", FALSE, 0xffffffff,
113a9fa9459Szrj 	0xffffffff, TRUE),
114a9fa9459Szrj   HOWTO(R_X86_64_TLSLD, 0, 2, 32, TRUE, 0, complain_overflow_signed,
115a9fa9459Szrj 	bfd_elf_generic_reloc, "R_X86_64_TLSLD", FALSE, 0xffffffff,
116a9fa9459Szrj 	0xffffffff, TRUE),
117a9fa9459Szrj   HOWTO(R_X86_64_DTPOFF32, 0, 2, 32, FALSE, 0, complain_overflow_signed,
118a9fa9459Szrj 	bfd_elf_generic_reloc, "R_X86_64_DTPOFF32", FALSE, 0xffffffff,
119a9fa9459Szrj 	0xffffffff, FALSE),
120a9fa9459Szrj   HOWTO(R_X86_64_GOTTPOFF, 0, 2, 32, TRUE, 0, complain_overflow_signed,
121a9fa9459Szrj 	bfd_elf_generic_reloc, "R_X86_64_GOTTPOFF", FALSE, 0xffffffff,
122a9fa9459Szrj 	0xffffffff, TRUE),
123a9fa9459Szrj   HOWTO(R_X86_64_TPOFF32, 0, 2, 32, FALSE, 0, complain_overflow_signed,
124a9fa9459Szrj 	bfd_elf_generic_reloc, "R_X86_64_TPOFF32", FALSE, 0xffffffff,
125a9fa9459Szrj 	0xffffffff, FALSE),
126a9fa9459Szrj   HOWTO(R_X86_64_PC64, 0, 4, 64, TRUE, 0, complain_overflow_bitfield,
127a9fa9459Szrj 	bfd_elf_generic_reloc, "R_X86_64_PC64", FALSE, MINUS_ONE, MINUS_ONE,
128a9fa9459Szrj 	TRUE),
129a9fa9459Szrj   HOWTO(R_X86_64_GOTOFF64, 0, 4, 64, FALSE, 0, complain_overflow_bitfield,
130a9fa9459Szrj 	bfd_elf_generic_reloc, "R_X86_64_GOTOFF64",
131a9fa9459Szrj 	FALSE, MINUS_ONE, MINUS_ONE, FALSE),
132a9fa9459Szrj   HOWTO(R_X86_64_GOTPC32, 0, 2, 32, TRUE, 0, complain_overflow_signed,
133a9fa9459Szrj 	bfd_elf_generic_reloc, "R_X86_64_GOTPC32",
134a9fa9459Szrj 	FALSE, 0xffffffff, 0xffffffff, TRUE),
135a9fa9459Szrj   HOWTO(R_X86_64_GOT64, 0, 4, 64, FALSE, 0, complain_overflow_signed,
136a9fa9459Szrj 	bfd_elf_generic_reloc, "R_X86_64_GOT64", FALSE, MINUS_ONE, MINUS_ONE,
137a9fa9459Szrj 	FALSE),
138a9fa9459Szrj   HOWTO(R_X86_64_GOTPCREL64, 0, 4, 64, TRUE, 0, complain_overflow_signed,
139a9fa9459Szrj 	bfd_elf_generic_reloc, "R_X86_64_GOTPCREL64", FALSE, MINUS_ONE,
140a9fa9459Szrj 	MINUS_ONE, TRUE),
141a9fa9459Szrj   HOWTO(R_X86_64_GOTPC64, 0, 4, 64, TRUE, 0, complain_overflow_signed,
142a9fa9459Szrj 	bfd_elf_generic_reloc, "R_X86_64_GOTPC64",
143a9fa9459Szrj 	FALSE, MINUS_ONE, MINUS_ONE, TRUE),
144a9fa9459Szrj   HOWTO(R_X86_64_GOTPLT64, 0, 4, 64, FALSE, 0, complain_overflow_signed,
145a9fa9459Szrj 	bfd_elf_generic_reloc, "R_X86_64_GOTPLT64", FALSE, MINUS_ONE,
146a9fa9459Szrj 	MINUS_ONE, FALSE),
147a9fa9459Szrj   HOWTO(R_X86_64_PLTOFF64, 0, 4, 64, FALSE, 0, complain_overflow_signed,
148a9fa9459Szrj 	bfd_elf_generic_reloc, "R_X86_64_PLTOFF64", FALSE, MINUS_ONE,
149a9fa9459Szrj 	MINUS_ONE, FALSE),
150a9fa9459Szrj   HOWTO(R_X86_64_SIZE32, 0, 2, 32, FALSE, 0, complain_overflow_unsigned,
151a9fa9459Szrj 	bfd_elf_generic_reloc, "R_X86_64_SIZE32", FALSE, 0xffffffff, 0xffffffff,
152a9fa9459Szrj 	FALSE),
153a9fa9459Szrj   HOWTO(R_X86_64_SIZE64, 0, 4, 64, FALSE, 0, complain_overflow_unsigned,
154a9fa9459Szrj 	bfd_elf_generic_reloc, "R_X86_64_SIZE64", FALSE, MINUS_ONE, MINUS_ONE,
155a9fa9459Szrj 	FALSE),
156a9fa9459Szrj   HOWTO(R_X86_64_GOTPC32_TLSDESC, 0, 2, 32, TRUE, 0,
157a9fa9459Szrj 	complain_overflow_bitfield, bfd_elf_generic_reloc,
158a9fa9459Szrj 	"R_X86_64_GOTPC32_TLSDESC",
159a9fa9459Szrj 	FALSE, 0xffffffff, 0xffffffff, TRUE),
160a9fa9459Szrj   HOWTO(R_X86_64_TLSDESC_CALL, 0, 0, 0, FALSE, 0,
161a9fa9459Szrj 	complain_overflow_dont, bfd_elf_generic_reloc,
162a9fa9459Szrj 	"R_X86_64_TLSDESC_CALL",
163a9fa9459Szrj 	FALSE, 0, 0, FALSE),
164a9fa9459Szrj   HOWTO(R_X86_64_TLSDESC, 0, 4, 64, FALSE, 0,
165a9fa9459Szrj 	complain_overflow_bitfield, bfd_elf_generic_reloc,
166a9fa9459Szrj 	"R_X86_64_TLSDESC",
167a9fa9459Szrj 	FALSE, MINUS_ONE, MINUS_ONE, FALSE),
168a9fa9459Szrj   HOWTO(R_X86_64_IRELATIVE, 0, 4, 64, FALSE, 0, complain_overflow_bitfield,
169a9fa9459Szrj 	bfd_elf_generic_reloc, "R_X86_64_IRELATIVE", FALSE, MINUS_ONE,
170a9fa9459Szrj 	MINUS_ONE, FALSE),
171a9fa9459Szrj   HOWTO(R_X86_64_RELATIVE64, 0, 4, 64, FALSE, 0, complain_overflow_bitfield,
172a9fa9459Szrj 	bfd_elf_generic_reloc, "R_X86_64_RELATIVE64", FALSE, MINUS_ONE,
173a9fa9459Szrj 	MINUS_ONE, FALSE),
174a9fa9459Szrj   HOWTO(R_X86_64_PC32_BND, 0, 2, 32, TRUE, 0, complain_overflow_signed,
175a9fa9459Szrj 	bfd_elf_generic_reloc, "R_X86_64_PC32_BND", FALSE, 0xffffffff, 0xffffffff,
176a9fa9459Szrj 	TRUE),
177a9fa9459Szrj   HOWTO(R_X86_64_PLT32_BND, 0, 2, 32, TRUE, 0, complain_overflow_signed,
178a9fa9459Szrj 	bfd_elf_generic_reloc, "R_X86_64_PLT32_BND", FALSE, 0xffffffff, 0xffffffff,
179a9fa9459Szrj 	TRUE),
180a9fa9459Szrj   HOWTO(R_X86_64_GOTPCRELX, 0, 2, 32, TRUE, 0, complain_overflow_signed,
181a9fa9459Szrj 	bfd_elf_generic_reloc, "R_X86_64_GOTPCRELX", FALSE, 0xffffffff,
182a9fa9459Szrj 	0xffffffff, TRUE),
183a9fa9459Szrj   HOWTO(R_X86_64_REX_GOTPCRELX, 0, 2, 32, TRUE, 0, complain_overflow_signed,
184a9fa9459Szrj 	bfd_elf_generic_reloc, "R_X86_64_REX_GOTPCRELX", FALSE, 0xffffffff,
185a9fa9459Szrj 	0xffffffff, TRUE),
186a9fa9459Szrj 
187a9fa9459Szrj   /* We have a gap in the reloc numbers here.
188a9fa9459Szrj      R_X86_64_standard counts the number up to this point, and
189a9fa9459Szrj      R_X86_64_vt_offset is the value to subtract from a reloc type of
190a9fa9459Szrj      R_X86_64_GNU_VT* to form an index into this table.  */
191a9fa9459Szrj #define R_X86_64_standard (R_X86_64_REX_GOTPCRELX + 1)
192a9fa9459Szrj #define R_X86_64_vt_offset (R_X86_64_GNU_VTINHERIT - R_X86_64_standard)
193a9fa9459Szrj 
194a9fa9459Szrj /* GNU extension to record C++ vtable hierarchy.  */
195a9fa9459Szrj   HOWTO (R_X86_64_GNU_VTINHERIT, 0, 4, 0, FALSE, 0, complain_overflow_dont,
196a9fa9459Szrj 	 NULL, "R_X86_64_GNU_VTINHERIT", FALSE, 0, 0, FALSE),
197a9fa9459Szrj 
198a9fa9459Szrj /* GNU extension to record C++ vtable member usage.  */
199a9fa9459Szrj   HOWTO (R_X86_64_GNU_VTENTRY, 0, 4, 0, FALSE, 0, complain_overflow_dont,
200a9fa9459Szrj 	 _bfd_elf_rel_vtable_reloc_fn, "R_X86_64_GNU_VTENTRY", FALSE, 0, 0,
201a9fa9459Szrj 	 FALSE),
202a9fa9459Szrj 
203a9fa9459Szrj /* Use complain_overflow_bitfield on R_X86_64_32 for x32.  */
204a9fa9459Szrj   HOWTO(R_X86_64_32, 0, 2, 32, FALSE, 0, complain_overflow_bitfield,
205a9fa9459Szrj 	bfd_elf_generic_reloc, "R_X86_64_32", FALSE, 0xffffffff, 0xffffffff,
206a9fa9459Szrj 	FALSE)
207a9fa9459Szrj };
208a9fa9459Szrj 
209a9fa9459Szrj #define IS_X86_64_PCREL_TYPE(TYPE)	\
210a9fa9459Szrj   (   ((TYPE) == R_X86_64_PC8)		\
211a9fa9459Szrj    || ((TYPE) == R_X86_64_PC16)		\
212a9fa9459Szrj    || ((TYPE) == R_X86_64_PC32)		\
213a9fa9459Szrj    || ((TYPE) == R_X86_64_PC32_BND)	\
214a9fa9459Szrj    || ((TYPE) == R_X86_64_PC64))
215a9fa9459Szrj 
216a9fa9459Szrj /* Map BFD relocs to the x86_64 elf relocs.  */
217a9fa9459Szrj struct elf_reloc_map
218a9fa9459Szrj {
219a9fa9459Szrj   bfd_reloc_code_real_type bfd_reloc_val;
220a9fa9459Szrj   unsigned char elf_reloc_val;
221a9fa9459Szrj };
222a9fa9459Szrj 
223a9fa9459Szrj static const struct elf_reloc_map x86_64_reloc_map[] =
224a9fa9459Szrj {
225a9fa9459Szrj   { BFD_RELOC_NONE,		R_X86_64_NONE, },
226a9fa9459Szrj   { BFD_RELOC_64,		R_X86_64_64,   },
227a9fa9459Szrj   { BFD_RELOC_32_PCREL,		R_X86_64_PC32, },
228a9fa9459Szrj   { BFD_RELOC_X86_64_GOT32,	R_X86_64_GOT32,},
229a9fa9459Szrj   { BFD_RELOC_X86_64_PLT32,	R_X86_64_PLT32,},
230a9fa9459Szrj   { BFD_RELOC_X86_64_COPY,	R_X86_64_COPY, },
231a9fa9459Szrj   { BFD_RELOC_X86_64_GLOB_DAT,	R_X86_64_GLOB_DAT, },
232a9fa9459Szrj   { BFD_RELOC_X86_64_JUMP_SLOT, R_X86_64_JUMP_SLOT, },
233a9fa9459Szrj   { BFD_RELOC_X86_64_RELATIVE,	R_X86_64_RELATIVE, },
234a9fa9459Szrj   { BFD_RELOC_X86_64_GOTPCREL,	R_X86_64_GOTPCREL, },
235a9fa9459Szrj   { BFD_RELOC_32,		R_X86_64_32, },
236a9fa9459Szrj   { BFD_RELOC_X86_64_32S,	R_X86_64_32S, },
237a9fa9459Szrj   { BFD_RELOC_16,		R_X86_64_16, },
238a9fa9459Szrj   { BFD_RELOC_16_PCREL,		R_X86_64_PC16, },
239a9fa9459Szrj   { BFD_RELOC_8,		R_X86_64_8, },
240a9fa9459Szrj   { BFD_RELOC_8_PCREL,		R_X86_64_PC8, },
241a9fa9459Szrj   { BFD_RELOC_X86_64_DTPMOD64,	R_X86_64_DTPMOD64, },
242a9fa9459Szrj   { BFD_RELOC_X86_64_DTPOFF64,	R_X86_64_DTPOFF64, },
243a9fa9459Szrj   { BFD_RELOC_X86_64_TPOFF64,	R_X86_64_TPOFF64, },
244a9fa9459Szrj   { BFD_RELOC_X86_64_TLSGD,	R_X86_64_TLSGD, },
245a9fa9459Szrj   { BFD_RELOC_X86_64_TLSLD,	R_X86_64_TLSLD, },
246a9fa9459Szrj   { BFD_RELOC_X86_64_DTPOFF32,	R_X86_64_DTPOFF32, },
247a9fa9459Szrj   { BFD_RELOC_X86_64_GOTTPOFF,	R_X86_64_GOTTPOFF, },
248a9fa9459Szrj   { BFD_RELOC_X86_64_TPOFF32,	R_X86_64_TPOFF32, },
249a9fa9459Szrj   { BFD_RELOC_64_PCREL,		R_X86_64_PC64, },
250a9fa9459Szrj   { BFD_RELOC_X86_64_GOTOFF64,	R_X86_64_GOTOFF64, },
251a9fa9459Szrj   { BFD_RELOC_X86_64_GOTPC32,	R_X86_64_GOTPC32, },
252a9fa9459Szrj   { BFD_RELOC_X86_64_GOT64,	R_X86_64_GOT64, },
253a9fa9459Szrj   { BFD_RELOC_X86_64_GOTPCREL64,R_X86_64_GOTPCREL64, },
254a9fa9459Szrj   { BFD_RELOC_X86_64_GOTPC64,	R_X86_64_GOTPC64, },
255a9fa9459Szrj   { BFD_RELOC_X86_64_GOTPLT64,	R_X86_64_GOTPLT64, },
256a9fa9459Szrj   { BFD_RELOC_X86_64_PLTOFF64,	R_X86_64_PLTOFF64, },
257a9fa9459Szrj   { BFD_RELOC_SIZE32,		R_X86_64_SIZE32, },
258a9fa9459Szrj   { BFD_RELOC_SIZE64,		R_X86_64_SIZE64, },
259a9fa9459Szrj   { BFD_RELOC_X86_64_GOTPC32_TLSDESC, R_X86_64_GOTPC32_TLSDESC, },
260a9fa9459Szrj   { BFD_RELOC_X86_64_TLSDESC_CALL, R_X86_64_TLSDESC_CALL, },
261a9fa9459Szrj   { BFD_RELOC_X86_64_TLSDESC,	R_X86_64_TLSDESC, },
262a9fa9459Szrj   { BFD_RELOC_X86_64_IRELATIVE,	R_X86_64_IRELATIVE, },
263a9fa9459Szrj   { BFD_RELOC_X86_64_PC32_BND,	R_X86_64_PC32_BND, },
264a9fa9459Szrj   { BFD_RELOC_X86_64_PLT32_BND,	R_X86_64_PLT32_BND, },
265a9fa9459Szrj   { BFD_RELOC_X86_64_GOTPCRELX, R_X86_64_GOTPCRELX, },
266a9fa9459Szrj   { BFD_RELOC_X86_64_REX_GOTPCRELX, R_X86_64_REX_GOTPCRELX, },
267a9fa9459Szrj   { BFD_RELOC_VTABLE_INHERIT,	R_X86_64_GNU_VTINHERIT, },
268a9fa9459Szrj   { BFD_RELOC_VTABLE_ENTRY,	R_X86_64_GNU_VTENTRY, },
269a9fa9459Szrj };
270a9fa9459Szrj 
271a9fa9459Szrj static reloc_howto_type *
elf_x86_64_rtype_to_howto(bfd * abfd,unsigned r_type)272a9fa9459Szrj elf_x86_64_rtype_to_howto (bfd *abfd, unsigned r_type)
273a9fa9459Szrj {
274a9fa9459Szrj   unsigned i;
275a9fa9459Szrj 
276a9fa9459Szrj   if (r_type == (unsigned int) R_X86_64_32)
277a9fa9459Szrj     {
278a9fa9459Szrj       if (ABI_64_P (abfd))
279a9fa9459Szrj 	i = r_type;
280a9fa9459Szrj       else
281a9fa9459Szrj 	i = ARRAY_SIZE (x86_64_elf_howto_table) - 1;
282a9fa9459Szrj     }
283a9fa9459Szrj   else if (r_type < (unsigned int) R_X86_64_GNU_VTINHERIT
284a9fa9459Szrj 	   || r_type >= (unsigned int) R_X86_64_max)
285a9fa9459Szrj     {
286a9fa9459Szrj       if (r_type >= (unsigned int) R_X86_64_standard)
287a9fa9459Szrj 	{
288a9fa9459Szrj 	  (*_bfd_error_handler) (_("%B: invalid relocation type %d"),
289a9fa9459Szrj 				 abfd, (int) r_type);
290a9fa9459Szrj 	  r_type = R_X86_64_NONE;
291a9fa9459Szrj 	}
292a9fa9459Szrj       i = r_type;
293a9fa9459Szrj     }
294a9fa9459Szrj   else
295a9fa9459Szrj     i = r_type - (unsigned int) R_X86_64_vt_offset;
296a9fa9459Szrj   BFD_ASSERT (x86_64_elf_howto_table[i].type == r_type);
297a9fa9459Szrj   return &x86_64_elf_howto_table[i];
298a9fa9459Szrj }
299a9fa9459Szrj 
300a9fa9459Szrj /* Given a BFD reloc type, return a HOWTO structure.  */
301a9fa9459Szrj static reloc_howto_type *
elf_x86_64_reloc_type_lookup(bfd * abfd,bfd_reloc_code_real_type code)302a9fa9459Szrj elf_x86_64_reloc_type_lookup (bfd *abfd,
303a9fa9459Szrj 			      bfd_reloc_code_real_type code)
304a9fa9459Szrj {
305a9fa9459Szrj   unsigned int i;
306a9fa9459Szrj 
307a9fa9459Szrj   for (i = 0; i < sizeof (x86_64_reloc_map) / sizeof (struct elf_reloc_map);
308a9fa9459Szrj        i++)
309a9fa9459Szrj     {
310a9fa9459Szrj       if (x86_64_reloc_map[i].bfd_reloc_val == code)
311a9fa9459Szrj 	return elf_x86_64_rtype_to_howto (abfd,
312a9fa9459Szrj 					  x86_64_reloc_map[i].elf_reloc_val);
313a9fa9459Szrj     }
314a9fa9459Szrj   return NULL;
315a9fa9459Szrj }
316a9fa9459Szrj 
317a9fa9459Szrj static reloc_howto_type *
elf_x86_64_reloc_name_lookup(bfd * abfd,const char * r_name)318a9fa9459Szrj elf_x86_64_reloc_name_lookup (bfd *abfd,
319a9fa9459Szrj 			      const char *r_name)
320a9fa9459Szrj {
321a9fa9459Szrj   unsigned int i;
322a9fa9459Szrj 
323a9fa9459Szrj   if (!ABI_64_P (abfd) && strcasecmp (r_name, "R_X86_64_32") == 0)
324a9fa9459Szrj     {
325a9fa9459Szrj       /* Get x32 R_X86_64_32.  */
326a9fa9459Szrj       reloc_howto_type *reloc
327a9fa9459Szrj 	= &x86_64_elf_howto_table[ARRAY_SIZE (x86_64_elf_howto_table) - 1];
328a9fa9459Szrj       BFD_ASSERT (reloc->type == (unsigned int) R_X86_64_32);
329a9fa9459Szrj       return reloc;
330a9fa9459Szrj     }
331a9fa9459Szrj 
332a9fa9459Szrj   for (i = 0; i < ARRAY_SIZE (x86_64_elf_howto_table); i++)
333a9fa9459Szrj     if (x86_64_elf_howto_table[i].name != NULL
334a9fa9459Szrj 	&& strcasecmp (x86_64_elf_howto_table[i].name, r_name) == 0)
335a9fa9459Szrj       return &x86_64_elf_howto_table[i];
336a9fa9459Szrj 
337a9fa9459Szrj   return NULL;
338a9fa9459Szrj }
339a9fa9459Szrj 
340a9fa9459Szrj /* Given an x86_64 ELF reloc type, fill in an arelent structure.  */
341a9fa9459Szrj 
342a9fa9459Szrj static void
elf_x86_64_info_to_howto(bfd * abfd ATTRIBUTE_UNUSED,arelent * cache_ptr,Elf_Internal_Rela * dst)343a9fa9459Szrj elf_x86_64_info_to_howto (bfd *abfd ATTRIBUTE_UNUSED, arelent *cache_ptr,
344a9fa9459Szrj 			  Elf_Internal_Rela *dst)
345a9fa9459Szrj {
346a9fa9459Szrj   unsigned r_type;
347a9fa9459Szrj 
348a9fa9459Szrj   r_type = ELF32_R_TYPE (dst->r_info);
349a9fa9459Szrj   cache_ptr->howto = elf_x86_64_rtype_to_howto (abfd, r_type);
350a9fa9459Szrj   BFD_ASSERT (r_type == cache_ptr->howto->type);
351a9fa9459Szrj }
352a9fa9459Szrj 
353a9fa9459Szrj /* Support for core dump NOTE sections.  */
354a9fa9459Szrj static bfd_boolean
elf_x86_64_grok_prstatus(bfd * abfd,Elf_Internal_Note * note)355a9fa9459Szrj elf_x86_64_grok_prstatus (bfd *abfd, Elf_Internal_Note *note)
356a9fa9459Szrj {
357a9fa9459Szrj   int offset;
358a9fa9459Szrj   size_t size;
359a9fa9459Szrj 
360a9fa9459Szrj   switch (note->descsz)
361a9fa9459Szrj     {
362a9fa9459Szrj       default:
363a9fa9459Szrj 	return FALSE;
364a9fa9459Szrj 
365a9fa9459Szrj       case 296:		/* sizeof(istruct elf_prstatus) on Linux/x32 */
366a9fa9459Szrj 	/* pr_cursig */
367a9fa9459Szrj 	elf_tdata (abfd)->core->signal = bfd_get_16 (abfd, note->descdata + 12);
368a9fa9459Szrj 
369a9fa9459Szrj 	/* pr_pid */
370a9fa9459Szrj 	elf_tdata (abfd)->core->lwpid = bfd_get_32 (abfd, note->descdata + 24);
371a9fa9459Szrj 
372a9fa9459Szrj 	/* pr_reg */
373a9fa9459Szrj 	offset = 72;
374a9fa9459Szrj 	size = 216;
375a9fa9459Szrj 
376a9fa9459Szrj 	break;
377a9fa9459Szrj 
378a9fa9459Szrj       case 336:		/* sizeof(istruct elf_prstatus) on Linux/x86_64 */
379a9fa9459Szrj 	/* pr_cursig */
380a9fa9459Szrj 	elf_tdata (abfd)->core->signal
381a9fa9459Szrj 	  = bfd_get_16 (abfd, note->descdata + 12);
382a9fa9459Szrj 
383a9fa9459Szrj 	/* pr_pid */
384a9fa9459Szrj 	elf_tdata (abfd)->core->lwpid
385a9fa9459Szrj 	  = bfd_get_32 (abfd, note->descdata + 32);
386a9fa9459Szrj 
387a9fa9459Szrj 	/* pr_reg */
388a9fa9459Szrj 	offset = 112;
389a9fa9459Szrj 	size = 216;
390a9fa9459Szrj 
391a9fa9459Szrj 	break;
392a9fa9459Szrj     }
393a9fa9459Szrj 
394a9fa9459Szrj   /* Make a ".reg/999" section.  */
395a9fa9459Szrj   return _bfd_elfcore_make_pseudosection (abfd, ".reg",
396a9fa9459Szrj 					  size, note->descpos + offset);
397a9fa9459Szrj }
398a9fa9459Szrj 
399a9fa9459Szrj static bfd_boolean
elf_x86_64_grok_psinfo(bfd * abfd,Elf_Internal_Note * note)400a9fa9459Szrj elf_x86_64_grok_psinfo (bfd *abfd, Elf_Internal_Note *note)
401a9fa9459Szrj {
402a9fa9459Szrj   switch (note->descsz)
403a9fa9459Szrj     {
404a9fa9459Szrj       default:
405a9fa9459Szrj 	return FALSE;
406a9fa9459Szrj 
407a9fa9459Szrj       case 124:		/* sizeof(struct elf_prpsinfo) on Linux/x32 */
408a9fa9459Szrj 	elf_tdata (abfd)->core->pid
409a9fa9459Szrj 	  = bfd_get_32 (abfd, note->descdata + 12);
410a9fa9459Szrj 	elf_tdata (abfd)->core->program
411a9fa9459Szrj 	  = _bfd_elfcore_strndup (abfd, note->descdata + 28, 16);
412a9fa9459Szrj 	elf_tdata (abfd)->core->command
413a9fa9459Szrj 	  = _bfd_elfcore_strndup (abfd, note->descdata + 44, 80);
414a9fa9459Szrj 	break;
415a9fa9459Szrj 
416a9fa9459Szrj       case 136:		/* sizeof(struct elf_prpsinfo) on Linux/x86_64 */
417a9fa9459Szrj 	elf_tdata (abfd)->core->pid
418a9fa9459Szrj 	  = bfd_get_32 (abfd, note->descdata + 24);
419a9fa9459Szrj 	elf_tdata (abfd)->core->program
420a9fa9459Szrj 	 = _bfd_elfcore_strndup (abfd, note->descdata + 40, 16);
421a9fa9459Szrj 	elf_tdata (abfd)->core->command
422a9fa9459Szrj 	 = _bfd_elfcore_strndup (abfd, note->descdata + 56, 80);
423a9fa9459Szrj     }
424a9fa9459Szrj 
425a9fa9459Szrj   /* Note that for some reason, a spurious space is tacked
426a9fa9459Szrj      onto the end of the args in some (at least one anyway)
427a9fa9459Szrj      implementations, so strip it off if it exists.  */
428a9fa9459Szrj 
429a9fa9459Szrj   {
430a9fa9459Szrj     char *command = elf_tdata (abfd)->core->command;
431a9fa9459Szrj     int n = strlen (command);
432a9fa9459Szrj 
433a9fa9459Szrj     if (0 < n && command[n - 1] == ' ')
434a9fa9459Szrj       command[n - 1] = '\0';
435a9fa9459Szrj   }
436a9fa9459Szrj 
437a9fa9459Szrj   return TRUE;
438a9fa9459Szrj }
439a9fa9459Szrj 
440a9fa9459Szrj #ifdef CORE_HEADER
441a9fa9459Szrj static char *
elf_x86_64_write_core_note(bfd * abfd,char * buf,int * bufsiz,int note_type,...)442a9fa9459Szrj elf_x86_64_write_core_note (bfd *abfd, char *buf, int *bufsiz,
443a9fa9459Szrj 			    int note_type, ...)
444a9fa9459Szrj {
445a9fa9459Szrj   const struct elf_backend_data *bed = get_elf_backend_data (abfd);
446a9fa9459Szrj   va_list ap;
447a9fa9459Szrj   const char *fname, *psargs;
448a9fa9459Szrj   long pid;
449a9fa9459Szrj   int cursig;
450a9fa9459Szrj   const void *gregs;
451a9fa9459Szrj 
452a9fa9459Szrj   switch (note_type)
453a9fa9459Szrj     {
454a9fa9459Szrj     default:
455a9fa9459Szrj       return NULL;
456a9fa9459Szrj 
457a9fa9459Szrj     case NT_PRPSINFO:
458a9fa9459Szrj       va_start (ap, note_type);
459a9fa9459Szrj       fname = va_arg (ap, const char *);
460a9fa9459Szrj       psargs = va_arg (ap, const char *);
461a9fa9459Szrj       va_end (ap);
462a9fa9459Szrj 
463a9fa9459Szrj       if (bed->s->elfclass == ELFCLASS32)
464a9fa9459Szrj 	{
465a9fa9459Szrj 	  prpsinfo32_t data;
466a9fa9459Szrj 	  memset (&data, 0, sizeof (data));
467a9fa9459Szrj 	  strncpy (data.pr_fname, fname, sizeof (data.pr_fname));
468a9fa9459Szrj 	  strncpy (data.pr_psargs, psargs, sizeof (data.pr_psargs));
469a9fa9459Szrj 	  return elfcore_write_note (abfd, buf, bufsiz, "CORE", note_type,
470a9fa9459Szrj 				     &data, sizeof (data));
471a9fa9459Szrj 	}
472a9fa9459Szrj       else
473a9fa9459Szrj 	{
474a9fa9459Szrj 	  prpsinfo64_t data;
475a9fa9459Szrj 	  memset (&data, 0, sizeof (data));
476a9fa9459Szrj 	  strncpy (data.pr_fname, fname, sizeof (data.pr_fname));
477a9fa9459Szrj 	  strncpy (data.pr_psargs, psargs, sizeof (data.pr_psargs));
478a9fa9459Szrj 	  return elfcore_write_note (abfd, buf, bufsiz, "CORE", note_type,
479a9fa9459Szrj 				     &data, sizeof (data));
480a9fa9459Szrj 	}
481a9fa9459Szrj       /* NOTREACHED */
482a9fa9459Szrj 
483a9fa9459Szrj     case NT_PRSTATUS:
484a9fa9459Szrj       va_start (ap, note_type);
485a9fa9459Szrj       pid = va_arg (ap, long);
486a9fa9459Szrj       cursig = va_arg (ap, int);
487a9fa9459Szrj       gregs = va_arg (ap, const void *);
488a9fa9459Szrj       va_end (ap);
489a9fa9459Szrj 
490a9fa9459Szrj       if (bed->s->elfclass == ELFCLASS32)
491a9fa9459Szrj 	{
492a9fa9459Szrj 	  if (bed->elf_machine_code == EM_X86_64)
493a9fa9459Szrj 	    {
494a9fa9459Szrj 	      prstatusx32_t prstat;
495a9fa9459Szrj 	      memset (&prstat, 0, sizeof (prstat));
496a9fa9459Szrj 	      prstat.pr_pid = pid;
497a9fa9459Szrj 	      prstat.pr_cursig = cursig;
498a9fa9459Szrj 	      memcpy (&prstat.pr_reg, gregs, sizeof (prstat.pr_reg));
499a9fa9459Szrj 	      return elfcore_write_note (abfd, buf, bufsiz, "CORE", note_type,
500a9fa9459Szrj 					 &prstat, sizeof (prstat));
501a9fa9459Szrj 	    }
502a9fa9459Szrj 	  else
503a9fa9459Szrj 	    {
504a9fa9459Szrj 	      prstatus32_t prstat;
505a9fa9459Szrj 	      memset (&prstat, 0, sizeof (prstat));
506a9fa9459Szrj 	      prstat.pr_pid = pid;
507a9fa9459Szrj 	      prstat.pr_cursig = cursig;
508a9fa9459Szrj 	      memcpy (&prstat.pr_reg, gregs, sizeof (prstat.pr_reg));
509a9fa9459Szrj 	      return elfcore_write_note (abfd, buf, bufsiz, "CORE", note_type,
510a9fa9459Szrj 					 &prstat, sizeof (prstat));
511a9fa9459Szrj 	    }
512a9fa9459Szrj 	}
513a9fa9459Szrj       else
514a9fa9459Szrj 	{
515a9fa9459Szrj 	  prstatus64_t prstat;
516a9fa9459Szrj 	  memset (&prstat, 0, sizeof (prstat));
517a9fa9459Szrj 	  prstat.pr_pid = pid;
518a9fa9459Szrj 	  prstat.pr_cursig = cursig;
519a9fa9459Szrj 	  memcpy (&prstat.pr_reg, gregs, sizeof (prstat.pr_reg));
520a9fa9459Szrj 	  return elfcore_write_note (abfd, buf, bufsiz, "CORE", note_type,
521a9fa9459Szrj 				     &prstat, sizeof (prstat));
522a9fa9459Szrj 	}
523a9fa9459Szrj     }
524a9fa9459Szrj   /* NOTREACHED */
525a9fa9459Szrj }
526a9fa9459Szrj #endif
527a9fa9459Szrj 
528a9fa9459Szrj /* Functions for the x86-64 ELF linker.	 */
529a9fa9459Szrj 
530a9fa9459Szrj /* The name of the dynamic interpreter.	 This is put in the .interp
531a9fa9459Szrj    section.  */
532a9fa9459Szrj 
533*14cfea99Szrj #define ELF64_DYNAMIC_INTERPRETER "/libexec/ld-elf.so.2"
534a9fa9459Szrj #define ELF32_DYNAMIC_INTERPRETER "/lib/ldx32.so.1"
535a9fa9459Szrj 
536a9fa9459Szrj /* If ELIMINATE_COPY_RELOCS is non-zero, the linker will try to avoid
537a9fa9459Szrj    copying dynamic variables from a shared lib into an app's dynbss
538a9fa9459Szrj    section, and instead use a dynamic relocation to point into the
539a9fa9459Szrj    shared lib.  */
540a9fa9459Szrj #define ELIMINATE_COPY_RELOCS 1
541a9fa9459Szrj 
542a9fa9459Szrj /* The size in bytes of an entry in the global offset table.  */
543a9fa9459Szrj 
544a9fa9459Szrj #define GOT_ENTRY_SIZE 8
545a9fa9459Szrj 
546a9fa9459Szrj /* The size in bytes of an entry in the procedure linkage table.  */
547a9fa9459Szrj 
548a9fa9459Szrj #define PLT_ENTRY_SIZE 16
549a9fa9459Szrj 
550a9fa9459Szrj /* The first entry in a procedure linkage table looks like this.  See the
551a9fa9459Szrj    SVR4 ABI i386 supplement and the x86-64 ABI to see how this works.  */
552a9fa9459Szrj 
553a9fa9459Szrj static const bfd_byte elf_x86_64_plt0_entry[PLT_ENTRY_SIZE] =
554a9fa9459Szrj {
555a9fa9459Szrj   0xff, 0x35, 8, 0, 0, 0,	/* pushq GOT+8(%rip)  */
556a9fa9459Szrj   0xff, 0x25, 16, 0, 0, 0,	/* jmpq *GOT+16(%rip) */
557a9fa9459Szrj   0x0f, 0x1f, 0x40, 0x00	/* nopl 0(%rax)       */
558a9fa9459Szrj };
559a9fa9459Szrj 
560a9fa9459Szrj /* Subsequent entries in a procedure linkage table look like this.  */
561a9fa9459Szrj 
562a9fa9459Szrj static const bfd_byte elf_x86_64_plt_entry[PLT_ENTRY_SIZE] =
563a9fa9459Szrj {
564a9fa9459Szrj   0xff, 0x25,	/* jmpq *name@GOTPC(%rip) */
565a9fa9459Szrj   0, 0, 0, 0,	/* replaced with offset to this symbol in .got.	 */
566a9fa9459Szrj   0x68,		/* pushq immediate */
567a9fa9459Szrj   0, 0, 0, 0,	/* replaced with index into relocation table.  */
568a9fa9459Szrj   0xe9,		/* jmp relative */
569a9fa9459Szrj   0, 0, 0, 0	/* replaced with offset to start of .plt0.  */
570a9fa9459Szrj };
571a9fa9459Szrj 
572a9fa9459Szrj /* The first entry in a procedure linkage table with BND relocations
573a9fa9459Szrj    like this.  */
574a9fa9459Szrj 
575a9fa9459Szrj static const bfd_byte elf_x86_64_bnd_plt0_entry[PLT_ENTRY_SIZE] =
576a9fa9459Szrj {
577a9fa9459Szrj   0xff, 0x35, 8, 0, 0, 0,         /* pushq GOT+8(%rip)        */
578a9fa9459Szrj   0xf2, 0xff, 0x25, 16, 0, 0, 0,  /* bnd jmpq *GOT+16(%rip)   */
579a9fa9459Szrj   0x0f, 0x1f, 0                   /* nopl (%rax)              */
580a9fa9459Szrj };
581a9fa9459Szrj 
582a9fa9459Szrj /* Subsequent entries for legacy branches in a procedure linkage table
583a9fa9459Szrj    with BND relocations look like this.  */
584a9fa9459Szrj 
585a9fa9459Szrj static const bfd_byte elf_x86_64_legacy_plt_entry[PLT_ENTRY_SIZE] =
586a9fa9459Szrj {
587a9fa9459Szrj   0x68, 0, 0, 0, 0,             /* pushq immediate            */
588a9fa9459Szrj   0xe9, 0, 0, 0, 0,             /* jmpq relative              */
589a9fa9459Szrj   0x66, 0x0f, 0x1f, 0x44, 0, 0  /* nopw (%rax,%rax,1)         */
590a9fa9459Szrj };
591a9fa9459Szrj 
592a9fa9459Szrj /* Subsequent entries for branches with BND prefx in a procedure linkage
593a9fa9459Szrj    table with BND relocations look like this.  */
594a9fa9459Szrj 
595a9fa9459Szrj static const bfd_byte elf_x86_64_bnd_plt_entry[PLT_ENTRY_SIZE] =
596a9fa9459Szrj {
597a9fa9459Szrj   0x68, 0, 0, 0, 0,             /* pushq immediate            */
598a9fa9459Szrj   0xf2, 0xe9, 0, 0, 0, 0,       /* bnd jmpq relative          */
599a9fa9459Szrj   0x0f, 0x1f, 0x44, 0, 0        /* nopl 0(%rax,%rax,1)        */
600a9fa9459Szrj };
601a9fa9459Szrj 
602a9fa9459Szrj /* Entries for legacy branches in the second procedure linkage table
603a9fa9459Szrj    look like this.  */
604a9fa9459Szrj 
605a9fa9459Szrj static const bfd_byte elf_x86_64_legacy_plt2_entry[8] =
606a9fa9459Szrj {
607a9fa9459Szrj   0xff, 0x25,                    /* jmpq *name@GOTPC(%rip)      */
608a9fa9459Szrj   0, 0, 0, 0,  /* replaced with offset to this symbol in .got.  */
609a9fa9459Szrj   0x66, 0x90                     /* xchg %ax,%ax                */
610a9fa9459Szrj };
611a9fa9459Szrj 
612a9fa9459Szrj /* Entries for branches with BND prefix in the second procedure linkage
613a9fa9459Szrj    table look like this.  */
614a9fa9459Szrj 
615a9fa9459Szrj static const bfd_byte elf_x86_64_bnd_plt2_entry[8] =
616a9fa9459Szrj {
617a9fa9459Szrj   0xf2, 0xff, 0x25,              /* bnd jmpq *name@GOTPC(%rip)  */
618a9fa9459Szrj   0, 0, 0, 0,  /* replaced with offset to this symbol in .got.  */
619a9fa9459Szrj   0x90                           /* nop                         */
620a9fa9459Szrj };
621a9fa9459Szrj 
622a9fa9459Szrj /* .eh_frame covering the .plt section.  */
623a9fa9459Szrj 
624a9fa9459Szrj static const bfd_byte elf_x86_64_eh_frame_plt[] =
625a9fa9459Szrj {
626a9fa9459Szrj #define PLT_CIE_LENGTH		20
627a9fa9459Szrj #define PLT_FDE_LENGTH		36
628a9fa9459Szrj #define PLT_FDE_START_OFFSET	4 + PLT_CIE_LENGTH + 8
629a9fa9459Szrj #define PLT_FDE_LEN_OFFSET	4 + PLT_CIE_LENGTH + 12
630a9fa9459Szrj   PLT_CIE_LENGTH, 0, 0, 0,	/* CIE length */
631a9fa9459Szrj   0, 0, 0, 0,			/* CIE ID */
632a9fa9459Szrj   1,				/* CIE version */
633a9fa9459Szrj   'z', 'R', 0,			/* Augmentation string */
634a9fa9459Szrj   1,				/* Code alignment factor */
635a9fa9459Szrj   0x78,				/* Data alignment factor */
636a9fa9459Szrj   16,				/* Return address column */
637a9fa9459Szrj   1,				/* Augmentation size */
638a9fa9459Szrj   DW_EH_PE_pcrel | DW_EH_PE_sdata4, /* FDE encoding */
639a9fa9459Szrj   DW_CFA_def_cfa, 7, 8,		/* DW_CFA_def_cfa: r7 (rsp) ofs 8 */
640a9fa9459Szrj   DW_CFA_offset + 16, 1,	/* DW_CFA_offset: r16 (rip) at cfa-8 */
641a9fa9459Szrj   DW_CFA_nop, DW_CFA_nop,
642a9fa9459Szrj 
643a9fa9459Szrj   PLT_FDE_LENGTH, 0, 0, 0,	/* FDE length */
644a9fa9459Szrj   PLT_CIE_LENGTH + 8, 0, 0, 0,	/* CIE pointer */
645a9fa9459Szrj   0, 0, 0, 0,			/* R_X86_64_PC32 .plt goes here */
646a9fa9459Szrj   0, 0, 0, 0,			/* .plt size goes here */
647a9fa9459Szrj   0,				/* Augmentation size */
648a9fa9459Szrj   DW_CFA_def_cfa_offset, 16,	/* DW_CFA_def_cfa_offset: 16 */
649a9fa9459Szrj   DW_CFA_advance_loc + 6,	/* DW_CFA_advance_loc: 6 to __PLT__+6 */
650a9fa9459Szrj   DW_CFA_def_cfa_offset, 24,	/* DW_CFA_def_cfa_offset: 24 */
651a9fa9459Szrj   DW_CFA_advance_loc + 10,	/* DW_CFA_advance_loc: 10 to __PLT__+16 */
652a9fa9459Szrj   DW_CFA_def_cfa_expression,	/* DW_CFA_def_cfa_expression */
653a9fa9459Szrj   11,				/* Block length */
654a9fa9459Szrj   DW_OP_breg7, 8,		/* DW_OP_breg7 (rsp): 8 */
655a9fa9459Szrj   DW_OP_breg16, 0,		/* DW_OP_breg16 (rip): 0 */
656a9fa9459Szrj   DW_OP_lit15, DW_OP_and, DW_OP_lit11, DW_OP_ge,
657a9fa9459Szrj   DW_OP_lit3, DW_OP_shl, DW_OP_plus,
658a9fa9459Szrj   DW_CFA_nop, DW_CFA_nop, DW_CFA_nop, DW_CFA_nop
659a9fa9459Szrj };
660a9fa9459Szrj 
661a9fa9459Szrj /* Architecture-specific backend data for x86-64.  */
662a9fa9459Szrj 
663a9fa9459Szrj struct elf_x86_64_backend_data
664a9fa9459Szrj {
665a9fa9459Szrj   /* Templates for the initial PLT entry and for subsequent entries.  */
666a9fa9459Szrj   const bfd_byte *plt0_entry;
667a9fa9459Szrj   const bfd_byte *plt_entry;
668a9fa9459Szrj   unsigned int plt_entry_size;          /* Size of each PLT entry.  */
669a9fa9459Szrj 
670a9fa9459Szrj   /* Offsets into plt0_entry that are to be replaced with GOT[1] and GOT[2].  */
671a9fa9459Szrj   unsigned int plt0_got1_offset;
672a9fa9459Szrj   unsigned int plt0_got2_offset;
673a9fa9459Szrj 
674a9fa9459Szrj   /* Offset of the end of the PC-relative instruction containing
675a9fa9459Szrj      plt0_got2_offset.  */
676a9fa9459Szrj   unsigned int plt0_got2_insn_end;
677a9fa9459Szrj 
678a9fa9459Szrj   /* Offsets into plt_entry that are to be replaced with...  */
679a9fa9459Szrj   unsigned int plt_got_offset;    /* ... address of this symbol in .got. */
680a9fa9459Szrj   unsigned int plt_reloc_offset;  /* ... offset into relocation table. */
681a9fa9459Szrj   unsigned int plt_plt_offset;    /* ... offset to start of .plt. */
682a9fa9459Szrj 
683a9fa9459Szrj   /* Length of the PC-relative instruction containing plt_got_offset.  */
684a9fa9459Szrj   unsigned int plt_got_insn_size;
685a9fa9459Szrj 
686a9fa9459Szrj   /* Offset of the end of the PC-relative jump to plt0_entry.  */
687a9fa9459Szrj   unsigned int plt_plt_insn_end;
688a9fa9459Szrj 
689a9fa9459Szrj   /* Offset into plt_entry where the initial value of the GOT entry points.  */
690a9fa9459Szrj   unsigned int plt_lazy_offset;
691a9fa9459Szrj 
692a9fa9459Szrj   /* .eh_frame covering the .plt section.  */
693a9fa9459Szrj   const bfd_byte *eh_frame_plt;
694a9fa9459Szrj   unsigned int eh_frame_plt_size;
695a9fa9459Szrj };
696a9fa9459Szrj 
697a9fa9459Szrj #define get_elf_x86_64_arch_data(bed) \
698a9fa9459Szrj   ((const struct elf_x86_64_backend_data *) (bed)->arch_data)
699a9fa9459Szrj 
700a9fa9459Szrj #define get_elf_x86_64_backend_data(abfd) \
701a9fa9459Szrj   get_elf_x86_64_arch_data (get_elf_backend_data (abfd))
702a9fa9459Szrj 
703a9fa9459Szrj #define GET_PLT_ENTRY_SIZE(abfd) \
704a9fa9459Szrj   get_elf_x86_64_backend_data (abfd)->plt_entry_size
705a9fa9459Szrj 
706a9fa9459Szrj /* These are the standard parameters.  */
707a9fa9459Szrj static const struct elf_x86_64_backend_data elf_x86_64_arch_bed =
708a9fa9459Szrj   {
709a9fa9459Szrj     elf_x86_64_plt0_entry,              /* plt0_entry */
710a9fa9459Szrj     elf_x86_64_plt_entry,               /* plt_entry */
711a9fa9459Szrj     sizeof (elf_x86_64_plt_entry),      /* plt_entry_size */
712a9fa9459Szrj     2,                                  /* plt0_got1_offset */
713a9fa9459Szrj     8,                                  /* plt0_got2_offset */
714a9fa9459Szrj     12,                                 /* plt0_got2_insn_end */
715a9fa9459Szrj     2,                                  /* plt_got_offset */
716a9fa9459Szrj     7,                                  /* plt_reloc_offset */
717a9fa9459Szrj     12,                                 /* plt_plt_offset */
718a9fa9459Szrj     6,                                  /* plt_got_insn_size */
719a9fa9459Szrj     PLT_ENTRY_SIZE,                     /* plt_plt_insn_end */
720a9fa9459Szrj     6,                                  /* plt_lazy_offset */
721a9fa9459Szrj     elf_x86_64_eh_frame_plt,            /* eh_frame_plt */
722a9fa9459Szrj     sizeof (elf_x86_64_eh_frame_plt),   /* eh_frame_plt_size */
723a9fa9459Szrj   };
724a9fa9459Szrj 
725a9fa9459Szrj static const struct elf_x86_64_backend_data elf_x86_64_bnd_arch_bed =
726a9fa9459Szrj   {
727a9fa9459Szrj     elf_x86_64_bnd_plt0_entry,          /* plt0_entry */
728a9fa9459Szrj     elf_x86_64_bnd_plt_entry,           /* plt_entry */
729a9fa9459Szrj     sizeof (elf_x86_64_bnd_plt_entry),  /* plt_entry_size */
730a9fa9459Szrj     2,                                  /* plt0_got1_offset */
731a9fa9459Szrj     1+8,                                /* plt0_got2_offset */
732a9fa9459Szrj     1+12,                               /* plt0_got2_insn_end */
733a9fa9459Szrj     1+2,                                /* plt_got_offset */
734a9fa9459Szrj     1,                                  /* plt_reloc_offset */
735a9fa9459Szrj     7,                                  /* plt_plt_offset */
736a9fa9459Szrj     1+6,                                /* plt_got_insn_size */
737a9fa9459Szrj     11,                                 /* plt_plt_insn_end */
738a9fa9459Szrj     0,                                  /* plt_lazy_offset */
739a9fa9459Szrj     elf_x86_64_eh_frame_plt,            /* eh_frame_plt */
740a9fa9459Szrj     sizeof (elf_x86_64_eh_frame_plt),   /* eh_frame_plt_size */
741a9fa9459Szrj   };
742a9fa9459Szrj 
743a9fa9459Szrj #define	elf_backend_arch_data	&elf_x86_64_arch_bed
744a9fa9459Szrj 
745a9fa9459Szrj /* Is a undefined weak symbol which is resolved to 0.  Reference to an
746a9fa9459Szrj    undefined weak symbol is resolved to 0 when building executable if
747a9fa9459Szrj    it isn't dynamic and
748a9fa9459Szrj    1. Has non-GOT/non-PLT relocations in text section.  Or
749a9fa9459Szrj    2. Has no GOT/PLT relocation.
750a9fa9459Szrj  */
751a9fa9459Szrj #define UNDEFINED_WEAK_RESOLVED_TO_ZERO(INFO, GOT_RELOC, EH)	\
752a9fa9459Szrj   ((EH)->elf.root.type == bfd_link_hash_undefweak		\
753a9fa9459Szrj    && bfd_link_executable (INFO)				\
754a9fa9459Szrj    && (elf_x86_64_hash_table (INFO)->interp == NULL	 	\
755a9fa9459Szrj        || !(GOT_RELOC)						\
756a9fa9459Szrj        || (EH)->has_non_got_reloc				\
757a9fa9459Szrj        || !(INFO)->dynamic_undefined_weak))
758a9fa9459Szrj 
759a9fa9459Szrj /* x86-64 ELF linker hash entry.  */
760a9fa9459Szrj 
761a9fa9459Szrj struct elf_x86_64_link_hash_entry
762a9fa9459Szrj {
763a9fa9459Szrj   struct elf_link_hash_entry elf;
764a9fa9459Szrj 
765a9fa9459Szrj   /* Track dynamic relocs copied for this symbol.  */
766a9fa9459Szrj   struct elf_dyn_relocs *dyn_relocs;
767a9fa9459Szrj 
768a9fa9459Szrj #define GOT_UNKNOWN	0
769a9fa9459Szrj #define GOT_NORMAL	1
770a9fa9459Szrj #define GOT_TLS_GD	2
771a9fa9459Szrj #define GOT_TLS_IE	3
772a9fa9459Szrj #define GOT_TLS_GDESC	4
773a9fa9459Szrj #define GOT_TLS_GD_BOTH_P(type) \
774a9fa9459Szrj   ((type) == (GOT_TLS_GD | GOT_TLS_GDESC))
775a9fa9459Szrj #define GOT_TLS_GD_P(type) \
776a9fa9459Szrj   ((type) == GOT_TLS_GD || GOT_TLS_GD_BOTH_P (type))
777a9fa9459Szrj #define GOT_TLS_GDESC_P(type) \
778a9fa9459Szrj   ((type) == GOT_TLS_GDESC || GOT_TLS_GD_BOTH_P (type))
779a9fa9459Szrj #define GOT_TLS_GD_ANY_P(type) \
780a9fa9459Szrj   (GOT_TLS_GD_P (type) || GOT_TLS_GDESC_P (type))
781a9fa9459Szrj   unsigned char tls_type;
782a9fa9459Szrj 
783a9fa9459Szrj   /* TRUE if a weak symbol with a real definition needs a copy reloc.
784a9fa9459Szrj      When there is a weak symbol with a real definition, the processor
785a9fa9459Szrj      independent code will have arranged for us to see the real
786a9fa9459Szrj      definition first.  We need to copy the needs_copy bit from the
787a9fa9459Szrj      real definition and check it when allowing copy reloc in PIE.  */
788a9fa9459Szrj   unsigned int needs_copy : 1;
789a9fa9459Szrj 
790a9fa9459Szrj   /* TRUE if symbol has at least one BND relocation.  */
791a9fa9459Szrj   unsigned int has_bnd_reloc : 1;
792a9fa9459Szrj 
793a9fa9459Szrj   /* TRUE if symbol has GOT or PLT relocations.  */
794a9fa9459Szrj   unsigned int has_got_reloc : 1;
795a9fa9459Szrj 
796a9fa9459Szrj   /* TRUE if symbol has non-GOT/non-PLT relocations in text sections.  */
797a9fa9459Szrj   unsigned int has_non_got_reloc : 1;
798a9fa9459Szrj 
799a9fa9459Szrj   /* 0: symbol isn't __tls_get_addr.
800a9fa9459Szrj      1: symbol is __tls_get_addr.
801a9fa9459Szrj      2: symbol is unknown.  */
802a9fa9459Szrj   unsigned int tls_get_addr : 2;
803a9fa9459Szrj 
804a9fa9459Szrj   /* Reference count of C/C++ function pointer relocations in read-write
805a9fa9459Szrj      section which can be resolved at run-time.  */
806a9fa9459Szrj   bfd_signed_vma func_pointer_refcount;
807a9fa9459Szrj 
808a9fa9459Szrj   /* Information about the GOT PLT entry. Filled when there are both
809a9fa9459Szrj      GOT and PLT relocations against the same function.  */
810a9fa9459Szrj   union gotplt_union plt_got;
811a9fa9459Szrj 
812a9fa9459Szrj   /* Information about the second PLT entry. Filled when has_bnd_reloc is
813a9fa9459Szrj      set.  */
814a9fa9459Szrj   union gotplt_union plt_bnd;
815a9fa9459Szrj 
816a9fa9459Szrj   /* Offset of the GOTPLT entry reserved for the TLS descriptor,
817a9fa9459Szrj      starting at the end of the jump table.  */
818a9fa9459Szrj   bfd_vma tlsdesc_got;
819a9fa9459Szrj };
820a9fa9459Szrj 
821a9fa9459Szrj #define elf_x86_64_hash_entry(ent) \
822a9fa9459Szrj   ((struct elf_x86_64_link_hash_entry *)(ent))
823a9fa9459Szrj 
824a9fa9459Szrj struct elf_x86_64_obj_tdata
825a9fa9459Szrj {
826a9fa9459Szrj   struct elf_obj_tdata root;
827a9fa9459Szrj 
828a9fa9459Szrj   /* tls_type for each local got entry.  */
829a9fa9459Szrj   char *local_got_tls_type;
830a9fa9459Szrj 
831a9fa9459Szrj   /* GOTPLT entries for TLS descriptors.  */
832a9fa9459Szrj   bfd_vma *local_tlsdesc_gotent;
833a9fa9459Szrj };
834a9fa9459Szrj 
835a9fa9459Szrj #define elf_x86_64_tdata(abfd) \
836a9fa9459Szrj   ((struct elf_x86_64_obj_tdata *) (abfd)->tdata.any)
837a9fa9459Szrj 
838a9fa9459Szrj #define elf_x86_64_local_got_tls_type(abfd) \
839a9fa9459Szrj   (elf_x86_64_tdata (abfd)->local_got_tls_type)
840a9fa9459Szrj 
841a9fa9459Szrj #define elf_x86_64_local_tlsdesc_gotent(abfd) \
842a9fa9459Szrj   (elf_x86_64_tdata (abfd)->local_tlsdesc_gotent)
843a9fa9459Szrj 
844a9fa9459Szrj #define is_x86_64_elf(bfd)				\
845a9fa9459Szrj   (bfd_get_flavour (bfd) == bfd_target_elf_flavour	\
846a9fa9459Szrj    && elf_tdata (bfd) != NULL				\
847a9fa9459Szrj    && elf_object_id (bfd) == X86_64_ELF_DATA)
848a9fa9459Szrj 
849a9fa9459Szrj static bfd_boolean
elf_x86_64_mkobject(bfd * abfd)850a9fa9459Szrj elf_x86_64_mkobject (bfd *abfd)
851a9fa9459Szrj {
852a9fa9459Szrj   return bfd_elf_allocate_object (abfd, sizeof (struct elf_x86_64_obj_tdata),
853a9fa9459Szrj 				  X86_64_ELF_DATA);
854a9fa9459Szrj }
855a9fa9459Szrj 
856a9fa9459Szrj /* x86-64 ELF linker hash table.  */
857a9fa9459Szrj 
858a9fa9459Szrj struct elf_x86_64_link_hash_table
859a9fa9459Szrj {
860a9fa9459Szrj   struct elf_link_hash_table elf;
861a9fa9459Szrj 
862a9fa9459Szrj   /* Short-cuts to get to dynamic linker sections.  */
863a9fa9459Szrj   asection *interp;
864a9fa9459Szrj   asection *sdynbss;
865a9fa9459Szrj   asection *srelbss;
866a9fa9459Szrj   asection *plt_eh_frame;
867a9fa9459Szrj   asection *plt_bnd;
868a9fa9459Szrj   asection *plt_got;
869a9fa9459Szrj 
870a9fa9459Szrj   union
871a9fa9459Szrj   {
872a9fa9459Szrj     bfd_signed_vma refcount;
873a9fa9459Szrj     bfd_vma offset;
874a9fa9459Szrj   } tls_ld_got;
875a9fa9459Szrj 
876a9fa9459Szrj   /* The amount of space used by the jump slots in the GOT.  */
877a9fa9459Szrj   bfd_vma sgotplt_jump_table_size;
878a9fa9459Szrj 
879a9fa9459Szrj   /* Small local sym cache.  */
880a9fa9459Szrj   struct sym_cache sym_cache;
881a9fa9459Szrj 
882a9fa9459Szrj   bfd_vma (*r_info) (bfd_vma, bfd_vma);
883a9fa9459Szrj   bfd_vma (*r_sym) (bfd_vma);
884a9fa9459Szrj   unsigned int pointer_r_type;
885a9fa9459Szrj   const char *dynamic_interpreter;
886a9fa9459Szrj   int dynamic_interpreter_size;
887a9fa9459Szrj 
888a9fa9459Szrj   /* _TLS_MODULE_BASE_ symbol.  */
889a9fa9459Szrj   struct bfd_link_hash_entry *tls_module_base;
890a9fa9459Szrj 
891a9fa9459Szrj   /* Used by local STT_GNU_IFUNC symbols.  */
892a9fa9459Szrj   htab_t loc_hash_table;
893a9fa9459Szrj   void * loc_hash_memory;
894a9fa9459Szrj 
895a9fa9459Szrj   /* The offset into splt of the PLT entry for the TLS descriptor
896a9fa9459Szrj      resolver.  Special values are 0, if not necessary (or not found
897a9fa9459Szrj      to be necessary yet), and -1 if needed but not determined
898a9fa9459Szrj      yet.  */
899a9fa9459Szrj   bfd_vma tlsdesc_plt;
900a9fa9459Szrj   /* The offset into sgot of the GOT entry used by the PLT entry
901a9fa9459Szrj      above.  */
902a9fa9459Szrj   bfd_vma tlsdesc_got;
903a9fa9459Szrj 
904a9fa9459Szrj   /* The index of the next R_X86_64_JUMP_SLOT entry in .rela.plt.  */
905a9fa9459Szrj   bfd_vma next_jump_slot_index;
906a9fa9459Szrj   /* The index of the next R_X86_64_IRELATIVE entry in .rela.plt.  */
907a9fa9459Szrj   bfd_vma next_irelative_index;
908a9fa9459Szrj 
909a9fa9459Szrj   /* TRUE if there are dynamic relocs against IFUNC symbols that apply
910a9fa9459Szrj      to read-only sections.  */
911a9fa9459Szrj   bfd_boolean readonly_dynrelocs_against_ifunc;
912a9fa9459Szrj };
913a9fa9459Szrj 
914a9fa9459Szrj /* Get the x86-64 ELF linker hash table from a link_info structure.  */
915a9fa9459Szrj 
916a9fa9459Szrj #define elf_x86_64_hash_table(p) \
917a9fa9459Szrj   (elf_hash_table_id ((struct elf_link_hash_table *) ((p)->hash)) \
918a9fa9459Szrj   == X86_64_ELF_DATA ? ((struct elf_x86_64_link_hash_table *) ((p)->hash)) : NULL)
919a9fa9459Szrj 
920a9fa9459Szrj #define elf_x86_64_compute_jump_table_size(htab) \
921a9fa9459Szrj   ((htab)->elf.srelplt->reloc_count * GOT_ENTRY_SIZE)
922a9fa9459Szrj 
923a9fa9459Szrj /* Create an entry in an x86-64 ELF linker hash table.	*/
924a9fa9459Szrj 
925a9fa9459Szrj static struct bfd_hash_entry *
elf_x86_64_link_hash_newfunc(struct bfd_hash_entry * entry,struct bfd_hash_table * table,const char * string)926a9fa9459Szrj elf_x86_64_link_hash_newfunc (struct bfd_hash_entry *entry,
927a9fa9459Szrj 			      struct bfd_hash_table *table,
928a9fa9459Szrj 			      const char *string)
929a9fa9459Szrj {
930a9fa9459Szrj   /* Allocate the structure if it has not already been allocated by a
931a9fa9459Szrj      subclass.  */
932a9fa9459Szrj   if (entry == NULL)
933a9fa9459Szrj     {
934a9fa9459Szrj       entry = (struct bfd_hash_entry *)
935a9fa9459Szrj 	  bfd_hash_allocate (table,
936a9fa9459Szrj 			     sizeof (struct elf_x86_64_link_hash_entry));
937a9fa9459Szrj       if (entry == NULL)
938a9fa9459Szrj 	return entry;
939a9fa9459Szrj     }
940a9fa9459Szrj 
941a9fa9459Szrj   /* Call the allocation method of the superclass.  */
942a9fa9459Szrj   entry = _bfd_elf_link_hash_newfunc (entry, table, string);
943a9fa9459Szrj   if (entry != NULL)
944a9fa9459Szrj     {
945a9fa9459Szrj       struct elf_x86_64_link_hash_entry *eh;
946a9fa9459Szrj 
947a9fa9459Szrj       eh = (struct elf_x86_64_link_hash_entry *) entry;
948a9fa9459Szrj       eh->dyn_relocs = NULL;
949a9fa9459Szrj       eh->tls_type = GOT_UNKNOWN;
950a9fa9459Szrj       eh->needs_copy = 0;
951a9fa9459Szrj       eh->has_bnd_reloc = 0;
952a9fa9459Szrj       eh->has_got_reloc = 0;
953a9fa9459Szrj       eh->has_non_got_reloc = 0;
954a9fa9459Szrj       eh->tls_get_addr = 2;
955a9fa9459Szrj       eh->func_pointer_refcount = 0;
956a9fa9459Szrj       eh->plt_bnd.offset = (bfd_vma) -1;
957a9fa9459Szrj       eh->plt_got.offset = (bfd_vma) -1;
958a9fa9459Szrj       eh->tlsdesc_got = (bfd_vma) -1;
959a9fa9459Szrj     }
960a9fa9459Szrj 
961a9fa9459Szrj   return entry;
962a9fa9459Szrj }
963a9fa9459Szrj 
964a9fa9459Szrj /* Compute a hash of a local hash entry.  We use elf_link_hash_entry
965a9fa9459Szrj   for local symbol so that we can handle local STT_GNU_IFUNC symbols
966a9fa9459Szrj   as global symbol.  We reuse indx and dynstr_index for local symbol
967a9fa9459Szrj   hash since they aren't used by global symbols in this backend.  */
968a9fa9459Szrj 
969a9fa9459Szrj static hashval_t
elf_x86_64_local_htab_hash(const void * ptr)970a9fa9459Szrj elf_x86_64_local_htab_hash (const void *ptr)
971a9fa9459Szrj {
972a9fa9459Szrj   struct elf_link_hash_entry *h
973a9fa9459Szrj     = (struct elf_link_hash_entry *) ptr;
974a9fa9459Szrj   return ELF_LOCAL_SYMBOL_HASH (h->indx, h->dynstr_index);
975a9fa9459Szrj }
976a9fa9459Szrj 
977a9fa9459Szrj /* Compare local hash entries.  */
978a9fa9459Szrj 
979a9fa9459Szrj static int
elf_x86_64_local_htab_eq(const void * ptr1,const void * ptr2)980a9fa9459Szrj elf_x86_64_local_htab_eq (const void *ptr1, const void *ptr2)
981a9fa9459Szrj {
982a9fa9459Szrj   struct elf_link_hash_entry *h1
983a9fa9459Szrj      = (struct elf_link_hash_entry *) ptr1;
984a9fa9459Szrj   struct elf_link_hash_entry *h2
985a9fa9459Szrj     = (struct elf_link_hash_entry *) ptr2;
986a9fa9459Szrj 
987a9fa9459Szrj   return h1->indx == h2->indx && h1->dynstr_index == h2->dynstr_index;
988a9fa9459Szrj }
989a9fa9459Szrj 
990a9fa9459Szrj /* Find and/or create a hash entry for local symbol.  */
991a9fa9459Szrj 
992a9fa9459Szrj static struct elf_link_hash_entry *
elf_x86_64_get_local_sym_hash(struct elf_x86_64_link_hash_table * htab,bfd * abfd,const Elf_Internal_Rela * rel,bfd_boolean create)993a9fa9459Szrj elf_x86_64_get_local_sym_hash (struct elf_x86_64_link_hash_table *htab,
994a9fa9459Szrj 			       bfd *abfd, const Elf_Internal_Rela *rel,
995a9fa9459Szrj 			       bfd_boolean create)
996a9fa9459Szrj {
997a9fa9459Szrj   struct elf_x86_64_link_hash_entry e, *ret;
998a9fa9459Szrj   asection *sec = abfd->sections;
999a9fa9459Szrj   hashval_t h = ELF_LOCAL_SYMBOL_HASH (sec->id,
1000a9fa9459Szrj 				       htab->r_sym (rel->r_info));
1001a9fa9459Szrj   void **slot;
1002a9fa9459Szrj 
1003a9fa9459Szrj   e.elf.indx = sec->id;
1004a9fa9459Szrj   e.elf.dynstr_index = htab->r_sym (rel->r_info);
1005a9fa9459Szrj   slot = htab_find_slot_with_hash (htab->loc_hash_table, &e, h,
1006a9fa9459Szrj 				   create ? INSERT : NO_INSERT);
1007a9fa9459Szrj 
1008a9fa9459Szrj   if (!slot)
1009a9fa9459Szrj     return NULL;
1010a9fa9459Szrj 
1011a9fa9459Szrj   if (*slot)
1012a9fa9459Szrj     {
1013a9fa9459Szrj       ret = (struct elf_x86_64_link_hash_entry *) *slot;
1014a9fa9459Szrj       return &ret->elf;
1015a9fa9459Szrj     }
1016a9fa9459Szrj 
1017a9fa9459Szrj   ret = (struct elf_x86_64_link_hash_entry *)
1018a9fa9459Szrj 	objalloc_alloc ((struct objalloc *) htab->loc_hash_memory,
1019a9fa9459Szrj 			sizeof (struct elf_x86_64_link_hash_entry));
1020a9fa9459Szrj   if (ret)
1021a9fa9459Szrj     {
1022a9fa9459Szrj       memset (ret, 0, sizeof (*ret));
1023a9fa9459Szrj       ret->elf.indx = sec->id;
1024a9fa9459Szrj       ret->elf.dynstr_index = htab->r_sym (rel->r_info);
1025a9fa9459Szrj       ret->elf.dynindx = -1;
1026a9fa9459Szrj       ret->func_pointer_refcount = 0;
1027a9fa9459Szrj       ret->plt_got.offset = (bfd_vma) -1;
1028a9fa9459Szrj       *slot = ret;
1029a9fa9459Szrj     }
1030a9fa9459Szrj   return &ret->elf;
1031a9fa9459Szrj }
1032a9fa9459Szrj 
1033a9fa9459Szrj /* Destroy an X86-64 ELF linker hash table.  */
1034a9fa9459Szrj 
1035a9fa9459Szrj static void
elf_x86_64_link_hash_table_free(bfd * obfd)1036a9fa9459Szrj elf_x86_64_link_hash_table_free (bfd *obfd)
1037a9fa9459Szrj {
1038a9fa9459Szrj   struct elf_x86_64_link_hash_table *htab
1039a9fa9459Szrj     = (struct elf_x86_64_link_hash_table *) obfd->link.hash;
1040a9fa9459Szrj 
1041a9fa9459Szrj   if (htab->loc_hash_table)
1042a9fa9459Szrj     htab_delete (htab->loc_hash_table);
1043a9fa9459Szrj   if (htab->loc_hash_memory)
1044a9fa9459Szrj     objalloc_free ((struct objalloc *) htab->loc_hash_memory);
1045a9fa9459Szrj   _bfd_elf_link_hash_table_free (obfd);
1046a9fa9459Szrj }
1047a9fa9459Szrj 
1048a9fa9459Szrj /* Create an X86-64 ELF linker hash table.  */
1049a9fa9459Szrj 
1050a9fa9459Szrj static struct bfd_link_hash_table *
elf_x86_64_link_hash_table_create(bfd * abfd)1051a9fa9459Szrj elf_x86_64_link_hash_table_create (bfd *abfd)
1052a9fa9459Szrj {
1053a9fa9459Szrj   struct elf_x86_64_link_hash_table *ret;
1054a9fa9459Szrj   bfd_size_type amt = sizeof (struct elf_x86_64_link_hash_table);
1055a9fa9459Szrj 
1056a9fa9459Szrj   ret = (struct elf_x86_64_link_hash_table *) bfd_zmalloc (amt);
1057a9fa9459Szrj   if (ret == NULL)
1058a9fa9459Szrj     return NULL;
1059a9fa9459Szrj 
1060a9fa9459Szrj   if (!_bfd_elf_link_hash_table_init (&ret->elf, abfd,
1061a9fa9459Szrj 				      elf_x86_64_link_hash_newfunc,
1062a9fa9459Szrj 				      sizeof (struct elf_x86_64_link_hash_entry),
1063a9fa9459Szrj 				      X86_64_ELF_DATA))
1064a9fa9459Szrj     {
1065a9fa9459Szrj       free (ret);
1066a9fa9459Szrj       return NULL;
1067a9fa9459Szrj     }
1068a9fa9459Szrj 
1069a9fa9459Szrj   if (ABI_64_P (abfd))
1070a9fa9459Szrj     {
1071a9fa9459Szrj       ret->r_info = elf64_r_info;
1072a9fa9459Szrj       ret->r_sym = elf64_r_sym;
1073a9fa9459Szrj       ret->pointer_r_type = R_X86_64_64;
1074a9fa9459Szrj       ret->dynamic_interpreter = ELF64_DYNAMIC_INTERPRETER;
1075a9fa9459Szrj       ret->dynamic_interpreter_size = sizeof ELF64_DYNAMIC_INTERPRETER;
1076a9fa9459Szrj     }
1077a9fa9459Szrj   else
1078a9fa9459Szrj     {
1079a9fa9459Szrj       ret->r_info = elf32_r_info;
1080a9fa9459Szrj       ret->r_sym = elf32_r_sym;
1081a9fa9459Szrj       ret->pointer_r_type = R_X86_64_32;
1082a9fa9459Szrj       ret->dynamic_interpreter = ELF32_DYNAMIC_INTERPRETER;
1083a9fa9459Szrj       ret->dynamic_interpreter_size = sizeof ELF32_DYNAMIC_INTERPRETER;
1084a9fa9459Szrj     }
1085a9fa9459Szrj 
1086a9fa9459Szrj   ret->loc_hash_table = htab_try_create (1024,
1087a9fa9459Szrj 					 elf_x86_64_local_htab_hash,
1088a9fa9459Szrj 					 elf_x86_64_local_htab_eq,
1089a9fa9459Szrj 					 NULL);
1090a9fa9459Szrj   ret->loc_hash_memory = objalloc_create ();
1091a9fa9459Szrj   if (!ret->loc_hash_table || !ret->loc_hash_memory)
1092a9fa9459Szrj     {
1093a9fa9459Szrj       elf_x86_64_link_hash_table_free (abfd);
1094a9fa9459Szrj       return NULL;
1095a9fa9459Szrj     }
1096a9fa9459Szrj   ret->elf.root.hash_table_free = elf_x86_64_link_hash_table_free;
1097a9fa9459Szrj 
1098a9fa9459Szrj   return &ret->elf.root;
1099a9fa9459Szrj }
1100a9fa9459Szrj 
1101a9fa9459Szrj /* Create .plt, .rela.plt, .got, .got.plt, .rela.got, .dynbss, and
1102a9fa9459Szrj    .rela.bss sections in DYNOBJ, and set up shortcuts to them in our
1103a9fa9459Szrj    hash table.  */
1104a9fa9459Szrj 
1105a9fa9459Szrj static bfd_boolean
elf_x86_64_create_dynamic_sections(bfd * dynobj,struct bfd_link_info * info)1106a9fa9459Szrj elf_x86_64_create_dynamic_sections (bfd *dynobj,
1107a9fa9459Szrj 				    struct bfd_link_info *info)
1108a9fa9459Szrj {
1109a9fa9459Szrj   struct elf_x86_64_link_hash_table *htab;
1110a9fa9459Szrj 
1111a9fa9459Szrj   if (!_bfd_elf_create_dynamic_sections (dynobj, info))
1112a9fa9459Szrj     return FALSE;
1113a9fa9459Szrj 
1114a9fa9459Szrj   htab = elf_x86_64_hash_table (info);
1115a9fa9459Szrj   if (htab == NULL)
1116a9fa9459Szrj     return FALSE;
1117a9fa9459Szrj 
1118a9fa9459Szrj   /* Set the contents of the .interp section to the interpreter.  */
1119a9fa9459Szrj   if (bfd_link_executable (info) && !info->nointerp)
1120a9fa9459Szrj     {
1121a9fa9459Szrj       asection *s = bfd_get_linker_section (dynobj, ".interp");
1122a9fa9459Szrj       if (s == NULL)
1123a9fa9459Szrj 	abort ();
1124a9fa9459Szrj       s->size = htab->dynamic_interpreter_size;
1125a9fa9459Szrj       s->contents = (unsigned char *) htab->dynamic_interpreter;
1126a9fa9459Szrj       htab->interp = s;
1127a9fa9459Szrj     }
1128a9fa9459Szrj 
1129a9fa9459Szrj   htab->sdynbss = bfd_get_linker_section (dynobj, ".dynbss");
1130a9fa9459Szrj   if (!htab->sdynbss)
1131a9fa9459Szrj     abort ();
1132a9fa9459Szrj 
1133a9fa9459Szrj   if (bfd_link_executable (info))
1134a9fa9459Szrj     {
1135a9fa9459Szrj       /* Always allow copy relocs for building executables.  */
1136a9fa9459Szrj       asection *s = bfd_get_linker_section (dynobj, ".rela.bss");
1137a9fa9459Szrj       if (s == NULL)
1138a9fa9459Szrj 	{
1139a9fa9459Szrj 	  const struct elf_backend_data *bed = get_elf_backend_data (dynobj);
1140a9fa9459Szrj 	  s = bfd_make_section_anyway_with_flags (dynobj,
1141a9fa9459Szrj 						  ".rela.bss",
1142a9fa9459Szrj 						  (bed->dynamic_sec_flags
1143a9fa9459Szrj 						   | SEC_READONLY));
1144a9fa9459Szrj 	  if (s == NULL
1145a9fa9459Szrj 	      || ! bfd_set_section_alignment (dynobj, s,
1146a9fa9459Szrj 					      bed->s->log_file_align))
1147a9fa9459Szrj 	    return FALSE;
1148a9fa9459Szrj 	}
1149a9fa9459Szrj       htab->srelbss = s;
1150a9fa9459Szrj     }
1151a9fa9459Szrj 
1152a9fa9459Szrj   if (!info->no_ld_generated_unwind_info
1153a9fa9459Szrj       && htab->plt_eh_frame == NULL
1154a9fa9459Szrj       && htab->elf.splt != NULL)
1155a9fa9459Szrj     {
1156a9fa9459Szrj       flagword flags = (SEC_ALLOC | SEC_LOAD | SEC_READONLY
1157a9fa9459Szrj 			| SEC_HAS_CONTENTS | SEC_IN_MEMORY
1158a9fa9459Szrj 			| SEC_LINKER_CREATED);
1159a9fa9459Szrj       htab->plt_eh_frame
1160a9fa9459Szrj 	= bfd_make_section_anyway_with_flags (dynobj, ".eh_frame", flags);
1161a9fa9459Szrj       if (htab->plt_eh_frame == NULL
1162a9fa9459Szrj 	  || !bfd_set_section_alignment (dynobj, htab->plt_eh_frame, 3))
1163a9fa9459Szrj 	return FALSE;
1164a9fa9459Szrj     }
1165a9fa9459Szrj   return TRUE;
1166a9fa9459Szrj }
1167a9fa9459Szrj 
1168a9fa9459Szrj /* Copy the extra info we tack onto an elf_link_hash_entry.  */
1169a9fa9459Szrj 
1170a9fa9459Szrj static void
elf_x86_64_copy_indirect_symbol(struct bfd_link_info * info,struct elf_link_hash_entry * dir,struct elf_link_hash_entry * ind)1171a9fa9459Szrj elf_x86_64_copy_indirect_symbol (struct bfd_link_info *info,
1172a9fa9459Szrj 				 struct elf_link_hash_entry *dir,
1173a9fa9459Szrj 				 struct elf_link_hash_entry *ind)
1174a9fa9459Szrj {
1175a9fa9459Szrj   struct elf_x86_64_link_hash_entry *edir, *eind;
1176a9fa9459Szrj 
1177a9fa9459Szrj   edir = (struct elf_x86_64_link_hash_entry *) dir;
1178a9fa9459Szrj   eind = (struct elf_x86_64_link_hash_entry *) ind;
1179a9fa9459Szrj 
1180a9fa9459Szrj   if (!edir->has_bnd_reloc)
1181a9fa9459Szrj     edir->has_bnd_reloc = eind->has_bnd_reloc;
1182a9fa9459Szrj 
1183a9fa9459Szrj   if (!edir->has_got_reloc)
1184a9fa9459Szrj     edir->has_got_reloc = eind->has_got_reloc;
1185a9fa9459Szrj 
1186a9fa9459Szrj   if (!edir->has_non_got_reloc)
1187a9fa9459Szrj     edir->has_non_got_reloc = eind->has_non_got_reloc;
1188a9fa9459Szrj 
1189a9fa9459Szrj   if (eind->dyn_relocs != NULL)
1190a9fa9459Szrj     {
1191a9fa9459Szrj       if (edir->dyn_relocs != NULL)
1192a9fa9459Szrj 	{
1193a9fa9459Szrj 	  struct elf_dyn_relocs **pp;
1194a9fa9459Szrj 	  struct elf_dyn_relocs *p;
1195a9fa9459Szrj 
1196a9fa9459Szrj 	  /* Add reloc counts against the indirect sym to the direct sym
1197a9fa9459Szrj 	     list.  Merge any entries against the same section.  */
1198a9fa9459Szrj 	  for (pp = &eind->dyn_relocs; (p = *pp) != NULL; )
1199a9fa9459Szrj 	    {
1200a9fa9459Szrj 	      struct elf_dyn_relocs *q;
1201a9fa9459Szrj 
1202a9fa9459Szrj 	      for (q = edir->dyn_relocs; q != NULL; q = q->next)
1203a9fa9459Szrj 		if (q->sec == p->sec)
1204a9fa9459Szrj 		  {
1205a9fa9459Szrj 		    q->pc_count += p->pc_count;
1206a9fa9459Szrj 		    q->count += p->count;
1207a9fa9459Szrj 		    *pp = p->next;
1208a9fa9459Szrj 		    break;
1209a9fa9459Szrj 		  }
1210a9fa9459Szrj 	      if (q == NULL)
1211a9fa9459Szrj 		pp = &p->next;
1212a9fa9459Szrj 	    }
1213a9fa9459Szrj 	  *pp = edir->dyn_relocs;
1214a9fa9459Szrj 	}
1215a9fa9459Szrj 
1216a9fa9459Szrj       edir->dyn_relocs = eind->dyn_relocs;
1217a9fa9459Szrj       eind->dyn_relocs = NULL;
1218a9fa9459Szrj     }
1219a9fa9459Szrj 
1220a9fa9459Szrj   if (ind->root.type == bfd_link_hash_indirect
1221a9fa9459Szrj       && dir->got.refcount <= 0)
1222a9fa9459Szrj     {
1223a9fa9459Szrj       edir->tls_type = eind->tls_type;
1224a9fa9459Szrj       eind->tls_type = GOT_UNKNOWN;
1225a9fa9459Szrj     }
1226a9fa9459Szrj 
1227a9fa9459Szrj   if (ELIMINATE_COPY_RELOCS
1228a9fa9459Szrj       && ind->root.type != bfd_link_hash_indirect
1229a9fa9459Szrj       && dir->dynamic_adjusted)
1230a9fa9459Szrj     {
1231a9fa9459Szrj       /* If called to transfer flags for a weakdef during processing
1232a9fa9459Szrj 	 of elf_adjust_dynamic_symbol, don't copy non_got_ref.
1233a9fa9459Szrj 	 We clear it ourselves for ELIMINATE_COPY_RELOCS.  */
1234a9fa9459Szrj       dir->ref_dynamic |= ind->ref_dynamic;
1235a9fa9459Szrj       dir->ref_regular |= ind->ref_regular;
1236a9fa9459Szrj       dir->ref_regular_nonweak |= ind->ref_regular_nonweak;
1237a9fa9459Szrj       dir->needs_plt |= ind->needs_plt;
1238a9fa9459Szrj       dir->pointer_equality_needed |= ind->pointer_equality_needed;
1239a9fa9459Szrj     }
1240a9fa9459Szrj   else
1241a9fa9459Szrj     {
1242a9fa9459Szrj       if (eind->func_pointer_refcount > 0)
1243a9fa9459Szrj 	{
1244a9fa9459Szrj 	  edir->func_pointer_refcount += eind->func_pointer_refcount;
1245a9fa9459Szrj 	  eind->func_pointer_refcount = 0;
1246a9fa9459Szrj 	}
1247a9fa9459Szrj 
1248a9fa9459Szrj       _bfd_elf_link_hash_copy_indirect (info, dir, ind);
1249a9fa9459Szrj     }
1250a9fa9459Szrj }
1251a9fa9459Szrj 
1252a9fa9459Szrj static bfd_boolean
elf64_x86_64_elf_object_p(bfd * abfd)1253a9fa9459Szrj elf64_x86_64_elf_object_p (bfd *abfd)
1254a9fa9459Szrj {
1255a9fa9459Szrj   /* Set the right machine number for an x86-64 elf64 file.  */
1256a9fa9459Szrj   bfd_default_set_arch_mach (abfd, bfd_arch_i386, bfd_mach_x86_64);
1257a9fa9459Szrj   return TRUE;
1258a9fa9459Szrj }
1259a9fa9459Szrj 
1260a9fa9459Szrj static bfd_boolean
elf32_x86_64_elf_object_p(bfd * abfd)1261a9fa9459Szrj elf32_x86_64_elf_object_p (bfd *abfd)
1262a9fa9459Szrj {
1263a9fa9459Szrj   /* Set the right machine number for an x86-64 elf32 file.  */
1264a9fa9459Szrj   bfd_default_set_arch_mach (abfd, bfd_arch_i386, bfd_mach_x64_32);
1265a9fa9459Szrj   return TRUE;
1266a9fa9459Szrj }
1267a9fa9459Szrj 
1268a9fa9459Szrj /* Return TRUE if the TLS access code sequence support transition
1269a9fa9459Szrj    from R_TYPE.  */
1270a9fa9459Szrj 
1271a9fa9459Szrj static bfd_boolean
elf_x86_64_check_tls_transition(bfd * abfd,struct bfd_link_info * info,asection * sec,bfd_byte * contents,Elf_Internal_Shdr * symtab_hdr,struct elf_link_hash_entry ** sym_hashes,unsigned int r_type,const Elf_Internal_Rela * rel,const Elf_Internal_Rela * relend)1272a9fa9459Szrj elf_x86_64_check_tls_transition (bfd *abfd,
1273a9fa9459Szrj 				 struct bfd_link_info *info,
1274a9fa9459Szrj 				 asection *sec,
1275a9fa9459Szrj 				 bfd_byte *contents,
1276a9fa9459Szrj 				 Elf_Internal_Shdr *symtab_hdr,
1277a9fa9459Szrj 				 struct elf_link_hash_entry **sym_hashes,
1278a9fa9459Szrj 				 unsigned int r_type,
1279a9fa9459Szrj 				 const Elf_Internal_Rela *rel,
1280a9fa9459Szrj 				 const Elf_Internal_Rela *relend)
1281a9fa9459Szrj {
1282a9fa9459Szrj   unsigned int val;
1283a9fa9459Szrj   unsigned long r_symndx;
1284a9fa9459Szrj   bfd_boolean largepic = FALSE;
1285a9fa9459Szrj   struct elf_link_hash_entry *h;
1286a9fa9459Szrj   bfd_vma offset;
1287a9fa9459Szrj   struct elf_x86_64_link_hash_table *htab;
1288a9fa9459Szrj   bfd_byte *call;
1289a9fa9459Szrj   bfd_boolean indirect_call, tls_get_addr;
1290a9fa9459Szrj 
1291a9fa9459Szrj   htab = elf_x86_64_hash_table (info);
1292a9fa9459Szrj   offset = rel->r_offset;
1293a9fa9459Szrj   switch (r_type)
1294a9fa9459Szrj     {
1295a9fa9459Szrj     case R_X86_64_TLSGD:
1296a9fa9459Szrj     case R_X86_64_TLSLD:
1297a9fa9459Szrj       if ((rel + 1) >= relend)
1298a9fa9459Szrj 	return FALSE;
1299a9fa9459Szrj 
1300a9fa9459Szrj       if (r_type == R_X86_64_TLSGD)
1301a9fa9459Szrj 	{
1302a9fa9459Szrj 	  /* Check transition from GD access model.  For 64bit, only
1303a9fa9459Szrj 		.byte 0x66; leaq foo@tlsgd(%rip), %rdi
1304a9fa9459Szrj 		.word 0x6666; rex64; call __tls_get_addr@PLT
1305a9fa9459Szrj 	     or
1306a9fa9459Szrj 		.byte 0x66; leaq foo@tlsgd(%rip), %rdi
1307a9fa9459Szrj 		.byte 0x66; rex64
1308a9fa9459Szrj 		call *__tls_get_addr@GOTPCREL(%rip)
1309a9fa9459Szrj 		which may be converted to
1310a9fa9459Szrj 		addr32 call __tls_get_addr
1311a9fa9459Szrj 	     can transit to different access model.  For 32bit, only
1312a9fa9459Szrj 		leaq foo@tlsgd(%rip), %rdi
1313a9fa9459Szrj 		.word 0x6666; rex64; call __tls_get_addr@PLT
1314a9fa9459Szrj 	     or
1315a9fa9459Szrj 		leaq foo@tlsgd(%rip), %rdi
1316a9fa9459Szrj 		.byte 0x66; rex64
1317a9fa9459Szrj 		call *__tls_get_addr@GOTPCREL(%rip)
1318a9fa9459Szrj 		which may be converted to
1319a9fa9459Szrj 		addr32 call __tls_get_addr
1320a9fa9459Szrj 	     can transit to different access model.  For largepic,
1321a9fa9459Szrj 	     we also support:
1322a9fa9459Szrj 	        leaq foo@tlsgd(%rip), %rdi
1323a9fa9459Szrj 	        movabsq $__tls_get_addr@pltoff, %rax
1324a9fa9459Szrj 	        addq $r15, %rax
1325a9fa9459Szrj 	        call *%rax
1326a9fa9459Szrj 	     or
1327a9fa9459Szrj 	        leaq foo@tlsgd(%rip), %rdi
1328a9fa9459Szrj 	        movabsq $__tls_get_addr@pltoff, %rax
1329a9fa9459Szrj 	        addq $rbx, %rax
1330a9fa9459Szrj 	        call *%rax  */
1331a9fa9459Szrj 
1332a9fa9459Szrj 	  static const unsigned char leaq[] = { 0x66, 0x48, 0x8d, 0x3d };
1333a9fa9459Szrj 
1334a9fa9459Szrj 	  if ((offset + 12) > sec->size)
1335a9fa9459Szrj 	    return FALSE;
1336a9fa9459Szrj 
1337a9fa9459Szrj 	  call = contents + offset + 4;
1338a9fa9459Szrj 	  if (call[0] != 0x66
1339a9fa9459Szrj 	      || !((call[1] == 0x48
1340a9fa9459Szrj 		    && call[2] == 0xff
1341a9fa9459Szrj 		    && call[3] == 0x15)
1342a9fa9459Szrj 		   || (call[1] == 0x48
1343a9fa9459Szrj 		       && call[2] == 0x67
1344a9fa9459Szrj 		       && call[3] == 0xe8)
1345a9fa9459Szrj 		   || (call[1] == 0x66
1346a9fa9459Szrj 		       && call[2] == 0x48
1347a9fa9459Szrj 		       && call[3] == 0xe8)))
1348a9fa9459Szrj 	    {
1349a9fa9459Szrj 	      if (!ABI_64_P (abfd)
1350a9fa9459Szrj 		  || (offset + 19) > sec->size
1351a9fa9459Szrj 		  || offset < 3
1352a9fa9459Szrj 		  || memcmp (call - 7, leaq + 1, 3) != 0
1353a9fa9459Szrj 		  || memcmp (call, "\x48\xb8", 2) != 0
1354a9fa9459Szrj 		  || call[11] != 0x01
1355a9fa9459Szrj 		  || call[13] != 0xff
1356a9fa9459Szrj 		  || call[14] != 0xd0
1357a9fa9459Szrj 		  || !((call[10] == 0x48 && call[12] == 0xd8)
1358a9fa9459Szrj 		       || (call[10] == 0x4c && call[12] == 0xf8)))
1359a9fa9459Szrj 		return FALSE;
1360a9fa9459Szrj 	      largepic = TRUE;
1361a9fa9459Szrj 	    }
1362a9fa9459Szrj 	  else if (ABI_64_P (abfd))
1363a9fa9459Szrj 	    {
1364a9fa9459Szrj 	      if (offset < 4
1365a9fa9459Szrj 		  || memcmp (contents + offset - 4, leaq, 4) != 0)
1366a9fa9459Szrj 		return FALSE;
1367a9fa9459Szrj 	    }
1368a9fa9459Szrj 	  else
1369a9fa9459Szrj 	    {
1370a9fa9459Szrj 	      if (offset < 3
1371a9fa9459Szrj 		  || memcmp (contents + offset - 3, leaq + 1, 3) != 0)
1372a9fa9459Szrj 		return FALSE;
1373a9fa9459Szrj 	    }
1374a9fa9459Szrj 	  indirect_call = call[2] == 0xff;
1375a9fa9459Szrj 	}
1376a9fa9459Szrj       else
1377a9fa9459Szrj 	{
1378a9fa9459Szrj 	  /* Check transition from LD access model.  Only
1379a9fa9459Szrj 		leaq foo@tlsld(%rip), %rdi;
1380a9fa9459Szrj 		call __tls_get_addr@PLT
1381a9fa9459Szrj              or
1382a9fa9459Szrj 		leaq foo@tlsld(%rip), %rdi;
1383a9fa9459Szrj 		call *__tls_get_addr@GOTPCREL(%rip)
1384a9fa9459Szrj 		which may be converted to
1385a9fa9459Szrj 		addr32 call __tls_get_addr
1386a9fa9459Szrj 	     can transit to different access model.  For largepic
1387a9fa9459Szrj 	     we also support:
1388a9fa9459Szrj 	        leaq foo@tlsld(%rip), %rdi
1389a9fa9459Szrj 	        movabsq $__tls_get_addr@pltoff, %rax
1390a9fa9459Szrj 	        addq $r15, %rax
1391a9fa9459Szrj 	        call *%rax
1392a9fa9459Szrj 	     or
1393a9fa9459Szrj 	        leaq foo@tlsld(%rip), %rdi
1394a9fa9459Szrj 	        movabsq $__tls_get_addr@pltoff, %rax
1395a9fa9459Szrj 	        addq $rbx, %rax
1396a9fa9459Szrj 	        call *%rax  */
1397a9fa9459Szrj 
1398a9fa9459Szrj 	  static const unsigned char lea[] = { 0x48, 0x8d, 0x3d };
1399a9fa9459Szrj 
1400a9fa9459Szrj 	  if (offset < 3 || (offset + 9) > sec->size)
1401a9fa9459Szrj 	    return FALSE;
1402a9fa9459Szrj 
1403a9fa9459Szrj 	  if (memcmp (contents + offset - 3, lea, 3) != 0)
1404a9fa9459Szrj 	    return FALSE;
1405a9fa9459Szrj 
1406a9fa9459Szrj 	  call = contents + offset + 4;
1407a9fa9459Szrj 	  if (!(call[0] == 0xe8
1408a9fa9459Szrj 		|| (call[0] == 0xff && call[1] == 0x15)
1409a9fa9459Szrj 		|| (call[0] == 0x67 && call[1] == 0xe8)))
1410a9fa9459Szrj 	    {
1411a9fa9459Szrj 	      if (!ABI_64_P (abfd)
1412a9fa9459Szrj 		  || (offset + 19) > sec->size
1413a9fa9459Szrj 		  || memcmp (call, "\x48\xb8", 2) != 0
1414a9fa9459Szrj 		  || call[11] != 0x01
1415a9fa9459Szrj 		  || call[13] != 0xff
1416a9fa9459Szrj 		  || call[14] != 0xd0
1417a9fa9459Szrj 		  || !((call[10] == 0x48 && call[12] == 0xd8)
1418a9fa9459Szrj 		       || (call[10] == 0x4c && call[12] == 0xf8)))
1419a9fa9459Szrj 		return FALSE;
1420a9fa9459Szrj 	      largepic = TRUE;
1421a9fa9459Szrj 	    }
1422a9fa9459Szrj 	  indirect_call = call[0] == 0xff;
1423a9fa9459Szrj 	}
1424a9fa9459Szrj 
1425a9fa9459Szrj       r_symndx = htab->r_sym (rel[1].r_info);
1426a9fa9459Szrj       if (r_symndx < symtab_hdr->sh_info)
1427a9fa9459Szrj 	return FALSE;
1428a9fa9459Szrj 
1429a9fa9459Szrj       tls_get_addr = FALSE;
1430a9fa9459Szrj       h = sym_hashes[r_symndx - symtab_hdr->sh_info];
1431a9fa9459Szrj       if (h != NULL && h->root.root.string != NULL)
1432a9fa9459Szrj 	{
1433a9fa9459Szrj 	  struct elf_x86_64_link_hash_entry *eh
1434a9fa9459Szrj 	    = (struct elf_x86_64_link_hash_entry *) h;
1435a9fa9459Szrj 	  tls_get_addr = eh->tls_get_addr == 1;
1436a9fa9459Szrj 	  if (eh->tls_get_addr > 1)
1437a9fa9459Szrj 	    {
1438a9fa9459Szrj 	      /* Use strncmp to check __tls_get_addr since
1439a9fa9459Szrj 		 __tls_get_addr may be versioned.  */
1440a9fa9459Szrj 	      if (strncmp (h->root.root.string, "__tls_get_addr", 14)
1441a9fa9459Szrj 		  == 0)
1442a9fa9459Szrj 		{
1443a9fa9459Szrj 		  eh->tls_get_addr = 1;
1444a9fa9459Szrj 		  tls_get_addr = TRUE;
1445a9fa9459Szrj 		}
1446a9fa9459Szrj 	      else
1447a9fa9459Szrj 		eh->tls_get_addr = 0;
1448a9fa9459Szrj 	    }
1449a9fa9459Szrj 	}
1450a9fa9459Szrj 
1451a9fa9459Szrj       if (!tls_get_addr)
1452a9fa9459Szrj 	return FALSE;
1453a9fa9459Szrj       else if (largepic)
1454a9fa9459Szrj 	return ELF32_R_TYPE (rel[1].r_info) == R_X86_64_PLTOFF64;
1455a9fa9459Szrj       else if (indirect_call)
1456a9fa9459Szrj 	return ELF32_R_TYPE (rel[1].r_info) == R_X86_64_GOTPCRELX;
1457a9fa9459Szrj       else
1458a9fa9459Szrj 	return (ELF32_R_TYPE (rel[1].r_info) == R_X86_64_PC32
1459a9fa9459Szrj 		|| ELF32_R_TYPE (rel[1].r_info) == R_X86_64_PLT32);
1460a9fa9459Szrj 
1461a9fa9459Szrj     case R_X86_64_GOTTPOFF:
1462a9fa9459Szrj       /* Check transition from IE access model:
1463a9fa9459Szrj 		mov foo@gottpoff(%rip), %reg
1464a9fa9459Szrj 		add foo@gottpoff(%rip), %reg
1465a9fa9459Szrj        */
1466a9fa9459Szrj 
1467a9fa9459Szrj       /* Check REX prefix first.  */
1468a9fa9459Szrj       if (offset >= 3 && (offset + 4) <= sec->size)
1469a9fa9459Szrj 	{
1470a9fa9459Szrj 	  val = bfd_get_8 (abfd, contents + offset - 3);
1471a9fa9459Szrj 	  if (val != 0x48 && val != 0x4c)
1472a9fa9459Szrj 	    {
1473a9fa9459Szrj 	      /* X32 may have 0x44 REX prefix or no REX prefix.  */
1474a9fa9459Szrj 	      if (ABI_64_P (abfd))
1475a9fa9459Szrj 		return FALSE;
1476a9fa9459Szrj 	    }
1477a9fa9459Szrj 	}
1478a9fa9459Szrj       else
1479a9fa9459Szrj 	{
1480a9fa9459Szrj 	  /* X32 may not have any REX prefix.  */
1481a9fa9459Szrj 	  if (ABI_64_P (abfd))
1482a9fa9459Szrj 	    return FALSE;
1483a9fa9459Szrj 	  if (offset < 2 || (offset + 3) > sec->size)
1484a9fa9459Szrj 	    return FALSE;
1485a9fa9459Szrj 	}
1486a9fa9459Szrj 
1487a9fa9459Szrj       val = bfd_get_8 (abfd, contents + offset - 2);
1488a9fa9459Szrj       if (val != 0x8b && val != 0x03)
1489a9fa9459Szrj 	return FALSE;
1490a9fa9459Szrj 
1491a9fa9459Szrj       val = bfd_get_8 (abfd, contents + offset - 1);
1492a9fa9459Szrj       return (val & 0xc7) == 5;
1493a9fa9459Szrj 
1494a9fa9459Szrj     case R_X86_64_GOTPC32_TLSDESC:
1495a9fa9459Szrj       /* Check transition from GDesc access model:
1496a9fa9459Szrj 		leaq x@tlsdesc(%rip), %rax
1497a9fa9459Szrj 
1498a9fa9459Szrj 	 Make sure it's a leaq adding rip to a 32-bit offset
1499a9fa9459Szrj 	 into any register, although it's probably almost always
1500a9fa9459Szrj 	 going to be rax.  */
1501a9fa9459Szrj 
1502a9fa9459Szrj       if (offset < 3 || (offset + 4) > sec->size)
1503a9fa9459Szrj 	return FALSE;
1504a9fa9459Szrj 
1505a9fa9459Szrj       val = bfd_get_8 (abfd, contents + offset - 3);
1506a9fa9459Szrj       if ((val & 0xfb) != 0x48)
1507a9fa9459Szrj 	return FALSE;
1508a9fa9459Szrj 
1509a9fa9459Szrj       if (bfd_get_8 (abfd, contents + offset - 2) != 0x8d)
1510a9fa9459Szrj 	return FALSE;
1511a9fa9459Szrj 
1512a9fa9459Szrj       val = bfd_get_8 (abfd, contents + offset - 1);
1513a9fa9459Szrj       return (val & 0xc7) == 0x05;
1514a9fa9459Szrj 
1515a9fa9459Szrj     case R_X86_64_TLSDESC_CALL:
1516a9fa9459Szrj       /* Check transition from GDesc access model:
1517a9fa9459Szrj 		call *x@tlsdesc(%rax)
1518a9fa9459Szrj        */
1519a9fa9459Szrj       if (offset + 2 <= sec->size)
1520a9fa9459Szrj 	{
1521a9fa9459Szrj 	  /* Make sure that it's a call *x@tlsdesc(%rax).  */
1522a9fa9459Szrj 	  call = contents + offset;
1523a9fa9459Szrj 	  return call[0] == 0xff && call[1] == 0x10;
1524a9fa9459Szrj 	}
1525a9fa9459Szrj 
1526a9fa9459Szrj       return FALSE;
1527a9fa9459Szrj 
1528a9fa9459Szrj     default:
1529a9fa9459Szrj       abort ();
1530a9fa9459Szrj     }
1531a9fa9459Szrj }
1532a9fa9459Szrj 
1533a9fa9459Szrj /* Return TRUE if the TLS access transition is OK or no transition
1534a9fa9459Szrj    will be performed.  Update R_TYPE if there is a transition.  */
1535a9fa9459Szrj 
1536a9fa9459Szrj static bfd_boolean
elf_x86_64_tls_transition(struct bfd_link_info * info,bfd * abfd,asection * sec,bfd_byte * contents,Elf_Internal_Shdr * symtab_hdr,struct elf_link_hash_entry ** sym_hashes,unsigned int * r_type,int tls_type,const Elf_Internal_Rela * rel,const Elf_Internal_Rela * relend,struct elf_link_hash_entry * h,unsigned long r_symndx,bfd_boolean from_relocate_section)1537a9fa9459Szrj elf_x86_64_tls_transition (struct bfd_link_info *info, bfd *abfd,
1538a9fa9459Szrj 			   asection *sec, bfd_byte *contents,
1539a9fa9459Szrj 			   Elf_Internal_Shdr *symtab_hdr,
1540a9fa9459Szrj 			   struct elf_link_hash_entry **sym_hashes,
1541a9fa9459Szrj 			   unsigned int *r_type, int tls_type,
1542a9fa9459Szrj 			   const Elf_Internal_Rela *rel,
1543a9fa9459Szrj 			   const Elf_Internal_Rela *relend,
1544a9fa9459Szrj 			   struct elf_link_hash_entry *h,
1545a9fa9459Szrj 			   unsigned long r_symndx,
1546a9fa9459Szrj 			   bfd_boolean from_relocate_section)
1547a9fa9459Szrj {
1548a9fa9459Szrj   unsigned int from_type = *r_type;
1549a9fa9459Szrj   unsigned int to_type = from_type;
1550a9fa9459Szrj   bfd_boolean check = TRUE;
1551a9fa9459Szrj 
1552a9fa9459Szrj   /* Skip TLS transition for functions.  */
1553a9fa9459Szrj   if (h != NULL
1554a9fa9459Szrj       && (h->type == STT_FUNC
1555a9fa9459Szrj 	  || h->type == STT_GNU_IFUNC))
1556a9fa9459Szrj     return TRUE;
1557a9fa9459Szrj 
1558a9fa9459Szrj   switch (from_type)
1559a9fa9459Szrj     {
1560a9fa9459Szrj     case R_X86_64_TLSGD:
1561a9fa9459Szrj     case R_X86_64_GOTPC32_TLSDESC:
1562a9fa9459Szrj     case R_X86_64_TLSDESC_CALL:
1563a9fa9459Szrj     case R_X86_64_GOTTPOFF:
1564a9fa9459Szrj       if (bfd_link_executable (info))
1565a9fa9459Szrj 	{
1566a9fa9459Szrj 	  if (h == NULL)
1567a9fa9459Szrj 	    to_type = R_X86_64_TPOFF32;
1568a9fa9459Szrj 	  else
1569a9fa9459Szrj 	    to_type = R_X86_64_GOTTPOFF;
1570a9fa9459Szrj 	}
1571a9fa9459Szrj 
1572a9fa9459Szrj       /* When we are called from elf_x86_64_relocate_section, there may
1573a9fa9459Szrj 	 be additional transitions based on TLS_TYPE.  */
1574a9fa9459Szrj       if (from_relocate_section)
1575a9fa9459Szrj 	{
1576a9fa9459Szrj 	  unsigned int new_to_type = to_type;
1577a9fa9459Szrj 
1578a9fa9459Szrj 	  if (bfd_link_executable (info)
1579a9fa9459Szrj 	      && h != NULL
1580a9fa9459Szrj 	      && h->dynindx == -1
1581a9fa9459Szrj 	      && tls_type == GOT_TLS_IE)
1582a9fa9459Szrj 	    new_to_type = R_X86_64_TPOFF32;
1583a9fa9459Szrj 
1584a9fa9459Szrj 	  if (to_type == R_X86_64_TLSGD
1585a9fa9459Szrj 	      || to_type == R_X86_64_GOTPC32_TLSDESC
1586a9fa9459Szrj 	      || to_type == R_X86_64_TLSDESC_CALL)
1587a9fa9459Szrj 	    {
1588a9fa9459Szrj 	      if (tls_type == GOT_TLS_IE)
1589a9fa9459Szrj 		new_to_type = R_X86_64_GOTTPOFF;
1590a9fa9459Szrj 	    }
1591a9fa9459Szrj 
1592a9fa9459Szrj 	  /* We checked the transition before when we were called from
1593a9fa9459Szrj 	     elf_x86_64_check_relocs.  We only want to check the new
1594a9fa9459Szrj 	     transition which hasn't been checked before.  */
1595a9fa9459Szrj 	  check = new_to_type != to_type && from_type == to_type;
1596a9fa9459Szrj 	  to_type = new_to_type;
1597a9fa9459Szrj 	}
1598a9fa9459Szrj 
1599a9fa9459Szrj       break;
1600a9fa9459Szrj 
1601a9fa9459Szrj     case R_X86_64_TLSLD:
1602a9fa9459Szrj       if (bfd_link_executable (info))
1603a9fa9459Szrj 	to_type = R_X86_64_TPOFF32;
1604a9fa9459Szrj       break;
1605a9fa9459Szrj 
1606a9fa9459Szrj     default:
1607a9fa9459Szrj       return TRUE;
1608a9fa9459Szrj     }
1609a9fa9459Szrj 
1610a9fa9459Szrj   /* Return TRUE if there is no transition.  */
1611a9fa9459Szrj   if (from_type == to_type)
1612a9fa9459Szrj     return TRUE;
1613a9fa9459Szrj 
1614a9fa9459Szrj   /* Check if the transition can be performed.  */
1615a9fa9459Szrj   if (check
1616a9fa9459Szrj       && ! elf_x86_64_check_tls_transition (abfd, info, sec, contents,
1617a9fa9459Szrj 					    symtab_hdr, sym_hashes,
1618a9fa9459Szrj 					    from_type, rel, relend))
1619a9fa9459Szrj     {
1620a9fa9459Szrj       reloc_howto_type *from, *to;
1621a9fa9459Szrj       const char *name;
1622a9fa9459Szrj 
1623a9fa9459Szrj       from = elf_x86_64_rtype_to_howto (abfd, from_type);
1624a9fa9459Szrj       to = elf_x86_64_rtype_to_howto (abfd, to_type);
1625a9fa9459Szrj 
1626a9fa9459Szrj       if (h)
1627a9fa9459Szrj 	name = h->root.root.string;
1628a9fa9459Szrj       else
1629a9fa9459Szrj 	{
1630a9fa9459Szrj 	  struct elf_x86_64_link_hash_table *htab;
1631a9fa9459Szrj 
1632a9fa9459Szrj 	  htab = elf_x86_64_hash_table (info);
1633a9fa9459Szrj 	  if (htab == NULL)
1634a9fa9459Szrj 	    name = "*unknown*";
1635a9fa9459Szrj 	  else
1636a9fa9459Szrj 	    {
1637a9fa9459Szrj 	      Elf_Internal_Sym *isym;
1638a9fa9459Szrj 
1639a9fa9459Szrj 	      isym = bfd_sym_from_r_symndx (&htab->sym_cache,
1640a9fa9459Szrj 					    abfd, r_symndx);
1641a9fa9459Szrj 	      name = bfd_elf_sym_name (abfd, symtab_hdr, isym, NULL);
1642a9fa9459Szrj 	    }
1643a9fa9459Szrj 	}
1644a9fa9459Szrj 
1645a9fa9459Szrj       (*_bfd_error_handler)
1646a9fa9459Szrj 	(_("%B: TLS transition from %s to %s against `%s' at 0x%lx "
1647a9fa9459Szrj 	   "in section `%A' failed"),
1648a9fa9459Szrj 	 abfd, sec, from->name, to->name, name,
1649a9fa9459Szrj 	 (unsigned long) rel->r_offset);
1650a9fa9459Szrj       bfd_set_error (bfd_error_bad_value);
1651a9fa9459Szrj       return FALSE;
1652a9fa9459Szrj     }
1653a9fa9459Szrj 
1654a9fa9459Szrj   *r_type = to_type;
1655a9fa9459Szrj   return TRUE;
1656a9fa9459Szrj }
1657a9fa9459Szrj 
1658a9fa9459Szrj /* Rename some of the generic section flags to better document how they
1659a9fa9459Szrj    are used here.  */
1660a9fa9459Szrj #define need_convert_load	sec_flg0
1661a9fa9459Szrj #define check_relocs_failed	sec_flg1
1662a9fa9459Szrj 
1663a9fa9459Szrj static bfd_boolean
elf_x86_64_need_pic(bfd * input_bfd,asection * sec,struct elf_link_hash_entry * h,Elf_Internal_Shdr * symtab_hdr,Elf_Internal_Sym * isym,reloc_howto_type * howto)1664a9fa9459Szrj elf_x86_64_need_pic (bfd *input_bfd, asection *sec,
1665a9fa9459Szrj 		     struct elf_link_hash_entry *h,
1666a9fa9459Szrj 		     Elf_Internal_Shdr *symtab_hdr,
1667a9fa9459Szrj 		     Elf_Internal_Sym *isym,
1668a9fa9459Szrj 		     reloc_howto_type *howto)
1669a9fa9459Szrj {
1670a9fa9459Szrj   const char *v = "";
1671a9fa9459Szrj   const char *und = "";
1672a9fa9459Szrj   const char *pic = "";
1673a9fa9459Szrj 
1674a9fa9459Szrj   const char *name;
1675a9fa9459Szrj   if (h)
1676a9fa9459Szrj     {
1677a9fa9459Szrj       name = h->root.root.string;
1678a9fa9459Szrj       switch (ELF_ST_VISIBILITY (h->other))
1679a9fa9459Szrj 	{
1680a9fa9459Szrj 	case STV_HIDDEN:
1681a9fa9459Szrj 	  v = _("hidden symbol ");
1682a9fa9459Szrj 	  break;
1683a9fa9459Szrj 	case STV_INTERNAL:
1684a9fa9459Szrj 	  v = _("internal symbol ");
1685a9fa9459Szrj 	  break;
1686a9fa9459Szrj 	case STV_PROTECTED:
1687a9fa9459Szrj 	  v = _("protected symbol ");
1688a9fa9459Szrj 	  break;
1689a9fa9459Szrj 	default:
1690a9fa9459Szrj 	  v = _("symbol ");
1691a9fa9459Szrj 	  pic = _("; recompile with -fPIC");
1692a9fa9459Szrj 	  break;
1693a9fa9459Szrj 	}
1694a9fa9459Szrj 
1695a9fa9459Szrj       if (!h->def_regular && !h->def_dynamic)
1696a9fa9459Szrj 	und = _("undefined ");
1697a9fa9459Szrj     }
1698a9fa9459Szrj   else
1699a9fa9459Szrj     {
1700a9fa9459Szrj       name = bfd_elf_sym_name (input_bfd, symtab_hdr, isym, NULL);
1701a9fa9459Szrj       pic = _("; recompile with -fPIC");
1702a9fa9459Szrj     }
1703a9fa9459Szrj 
1704a9fa9459Szrj   (*_bfd_error_handler) (_("%B: relocation %s against %s%s`%s' can "
1705a9fa9459Szrj 			   "not be used when making a shared object%s"),
1706a9fa9459Szrj 			 input_bfd, howto->name, und, v, name, pic);
1707a9fa9459Szrj   bfd_set_error (bfd_error_bad_value);
1708a9fa9459Szrj   sec->check_relocs_failed = 1;
1709a9fa9459Szrj   return FALSE;
1710a9fa9459Szrj }
1711a9fa9459Szrj 
1712a9fa9459Szrj /* With the local symbol, foo, we convert
1713a9fa9459Szrj    mov foo@GOTPCREL(%rip), %reg
1714a9fa9459Szrj    to
1715a9fa9459Szrj    lea foo(%rip), %reg
1716a9fa9459Szrj    and convert
1717a9fa9459Szrj    call/jmp *foo@GOTPCREL(%rip)
1718a9fa9459Szrj    to
1719a9fa9459Szrj    nop call foo/jmp foo nop
1720a9fa9459Szrj    When PIC is false, convert
1721a9fa9459Szrj    test %reg, foo@GOTPCREL(%rip)
1722a9fa9459Szrj    to
1723a9fa9459Szrj    test $foo, %reg
1724a9fa9459Szrj    and convert
1725a9fa9459Szrj    binop foo@GOTPCREL(%rip), %reg
1726a9fa9459Szrj    to
1727a9fa9459Szrj    binop $foo, %reg
1728a9fa9459Szrj    where binop is one of adc, add, and, cmp, or, sbb, sub, xor
1729a9fa9459Szrj    instructions.  */
1730a9fa9459Szrj 
1731a9fa9459Szrj static bfd_boolean
elf_x86_64_convert_load_reloc(bfd * abfd,asection * sec,bfd_byte * contents,Elf_Internal_Rela * irel,struct elf_link_hash_entry * h,bfd_boolean * converted,struct bfd_link_info * link_info)1732a9fa9459Szrj elf_x86_64_convert_load_reloc (bfd *abfd, asection *sec,
1733a9fa9459Szrj 			       bfd_byte *contents,
1734a9fa9459Szrj 			       Elf_Internal_Rela *irel,
1735a9fa9459Szrj 			       struct elf_link_hash_entry *h,
1736a9fa9459Szrj 			       bfd_boolean *converted,
1737a9fa9459Szrj 			       struct bfd_link_info *link_info)
1738a9fa9459Szrj {
1739a9fa9459Szrj   struct elf_x86_64_link_hash_table *htab;
1740a9fa9459Szrj   bfd_boolean is_pic;
1741a9fa9459Szrj   bfd_boolean require_reloc_pc32;
1742a9fa9459Szrj   bfd_boolean relocx;
1743a9fa9459Szrj   bfd_boolean to_reloc_pc32;
1744a9fa9459Szrj   asection *tsec;
1745a9fa9459Szrj   char symtype;
1746a9fa9459Szrj   bfd_signed_vma raddend;
1747a9fa9459Szrj   unsigned int opcode;
1748a9fa9459Szrj   unsigned int modrm;
1749a9fa9459Szrj   unsigned int r_type = ELF32_R_TYPE (irel->r_info);
1750a9fa9459Szrj   unsigned int r_symndx;
1751a9fa9459Szrj   bfd_vma toff;
1752a9fa9459Szrj   bfd_vma roff = irel->r_offset;
1753a9fa9459Szrj 
1754a9fa9459Szrj   if (roff < (r_type == R_X86_64_REX_GOTPCRELX ? 3 : 2))
1755a9fa9459Szrj     return TRUE;
1756a9fa9459Szrj 
1757a9fa9459Szrj   raddend = irel->r_addend;
1758a9fa9459Szrj   /* Addend for 32-bit PC-relative relocation must be -4.  */
1759a9fa9459Szrj   if (raddend != -4)
1760a9fa9459Szrj     return TRUE;
1761a9fa9459Szrj 
1762a9fa9459Szrj   htab = elf_x86_64_hash_table (link_info);
1763a9fa9459Szrj   is_pic = bfd_link_pic (link_info);
1764a9fa9459Szrj 
1765a9fa9459Szrj   relocx = (r_type == R_X86_64_GOTPCRELX
1766a9fa9459Szrj 	    || r_type == R_X86_64_REX_GOTPCRELX);
1767a9fa9459Szrj 
1768a9fa9459Szrj   /* TRUE if we can convert only to R_X86_64_PC32.  Enable it for
1769a9fa9459Szrj      --no-relax.  */
1770a9fa9459Szrj   require_reloc_pc32
1771a9fa9459Szrj     = link_info->disable_target_specific_optimizations > 1;
1772a9fa9459Szrj 
1773a9fa9459Szrj   r_symndx = htab->r_sym (irel->r_info);
1774a9fa9459Szrj 
1775a9fa9459Szrj   opcode = bfd_get_8 (abfd, contents + roff - 2);
1776a9fa9459Szrj 
1777a9fa9459Szrj   /* Convert mov to lea since it has been done for a while.  */
1778a9fa9459Szrj   if (opcode != 0x8b)
1779a9fa9459Szrj     {
1780a9fa9459Szrj       /* Only convert R_X86_64_GOTPCRELX and R_X86_64_REX_GOTPCRELX
1781a9fa9459Szrj 	 for call, jmp or one of adc, add, and, cmp, or, sbb, sub,
1782a9fa9459Szrj 	 test, xor instructions.  */
1783a9fa9459Szrj       if (!relocx)
1784a9fa9459Szrj 	return TRUE;
1785a9fa9459Szrj     }
1786a9fa9459Szrj 
1787a9fa9459Szrj   /* We convert only to R_X86_64_PC32:
1788a9fa9459Szrj      1. Branch.
1789a9fa9459Szrj      2. R_X86_64_GOTPCREL since we can't modify REX byte.
1790a9fa9459Szrj      3. require_reloc_pc32 is true.
1791a9fa9459Szrj      4. PIC.
1792a9fa9459Szrj      */
1793a9fa9459Szrj   to_reloc_pc32 = (opcode == 0xff
1794a9fa9459Szrj 		   || !relocx
1795a9fa9459Szrj 		   || require_reloc_pc32
1796a9fa9459Szrj 		   || is_pic);
1797a9fa9459Szrj 
1798a9fa9459Szrj   /* Get the symbol referred to by the reloc.  */
1799a9fa9459Szrj   if (h == NULL)
1800a9fa9459Szrj     {
1801a9fa9459Szrj       Elf_Internal_Sym *isym
1802a9fa9459Szrj 	= bfd_sym_from_r_symndx (&htab->sym_cache, abfd, r_symndx);
1803a9fa9459Szrj 
1804a9fa9459Szrj       /* Skip relocation against undefined symbols.  */
1805a9fa9459Szrj       if (isym->st_shndx == SHN_UNDEF)
1806a9fa9459Szrj 	return TRUE;
1807a9fa9459Szrj 
1808a9fa9459Szrj       symtype = ELF_ST_TYPE (isym->st_info);
1809a9fa9459Szrj 
1810a9fa9459Szrj       if (isym->st_shndx == SHN_ABS)
1811a9fa9459Szrj 	tsec = bfd_abs_section_ptr;
1812a9fa9459Szrj       else if (isym->st_shndx == SHN_COMMON)
1813a9fa9459Szrj 	tsec = bfd_com_section_ptr;
1814a9fa9459Szrj       else if (isym->st_shndx == SHN_X86_64_LCOMMON)
1815a9fa9459Szrj 	tsec = &_bfd_elf_large_com_section;
1816a9fa9459Szrj       else
1817a9fa9459Szrj 	tsec = bfd_section_from_elf_index (abfd, isym->st_shndx);
1818a9fa9459Szrj 
1819a9fa9459Szrj       toff = isym->st_value;
1820a9fa9459Szrj     }
1821a9fa9459Szrj   else
1822a9fa9459Szrj     {
1823a9fa9459Szrj       /* Undefined weak symbol is only bound locally in executable
1824a9fa9459Szrj 	 and its reference is resolved as 0 without relocation
1825a9fa9459Szrj 	 overflow.  We can only perform this optimization for
1826a9fa9459Szrj 	 GOTPCRELX relocations since we need to modify REX byte.
1827a9fa9459Szrj 	 It is OK convert mov with R_X86_64_GOTPCREL to
1828a9fa9459Szrj 	 R_X86_64_PC32.  */
1829a9fa9459Szrj       if ((relocx || opcode == 0x8b)
1830a9fa9459Szrj 	  && UNDEFINED_WEAK_RESOLVED_TO_ZERO (link_info,
1831a9fa9459Szrj 					      TRUE,
1832a9fa9459Szrj 					      elf_x86_64_hash_entry (h)))
1833a9fa9459Szrj 	{
1834a9fa9459Szrj 	  if (opcode == 0xff)
1835a9fa9459Szrj 	    {
1836a9fa9459Szrj 	      /* Skip for branch instructions since R_X86_64_PC32
1837a9fa9459Szrj 		 may overflow.  */
1838a9fa9459Szrj 	      if (require_reloc_pc32)
1839a9fa9459Szrj 		return TRUE;
1840a9fa9459Szrj 	    }
1841a9fa9459Szrj 	  else if (relocx)
1842a9fa9459Szrj 	    {
1843a9fa9459Szrj 	      /* For non-branch instructions, we can convert to
1844a9fa9459Szrj 		 R_X86_64_32/R_X86_64_32S since we know if there
1845a9fa9459Szrj 		 is a REX byte.  */
1846a9fa9459Szrj 	      to_reloc_pc32 = FALSE;
1847a9fa9459Szrj 	    }
1848a9fa9459Szrj 
1849a9fa9459Szrj 	  /* Since we don't know the current PC when PIC is true,
1850a9fa9459Szrj 	     we can't convert to R_X86_64_PC32.  */
1851a9fa9459Szrj 	  if (to_reloc_pc32 && is_pic)
1852a9fa9459Szrj 	    return TRUE;
1853a9fa9459Szrj 
1854a9fa9459Szrj 	  goto convert;
1855a9fa9459Szrj 	}
1856a9fa9459Szrj       /* Avoid optimizing GOTPCREL relocations againt _DYNAMIC since
1857a9fa9459Szrj 	 ld.so may use its link-time address.  */
1858a9fa9459Szrj       else if ((h->def_regular
1859a9fa9459Szrj 		|| h->root.type == bfd_link_hash_defined
1860a9fa9459Szrj 		|| h->root.type == bfd_link_hash_defweak)
1861a9fa9459Szrj 	       && h != htab->elf.hdynamic
1862a9fa9459Szrj 	       && SYMBOL_REFERENCES_LOCAL (link_info, h))
1863a9fa9459Szrj 	{
1864a9fa9459Szrj 	  /* bfd_link_hash_new or bfd_link_hash_undefined is
1865a9fa9459Szrj 	     set by an assignment in a linker script in
1866a9fa9459Szrj 	     bfd_elf_record_link_assignment.   */
1867a9fa9459Szrj 	  if (h->def_regular
1868a9fa9459Szrj 	      && (h->root.type == bfd_link_hash_new
1869a9fa9459Szrj 		  || h->root.type == bfd_link_hash_undefined))
1870a9fa9459Szrj 	    {
1871a9fa9459Szrj 	      /* Skip since R_X86_64_32/R_X86_64_32S may overflow.  */
1872a9fa9459Szrj 	      if (require_reloc_pc32)
1873a9fa9459Szrj 		return TRUE;
1874a9fa9459Szrj 	      goto convert;
1875a9fa9459Szrj 	    }
1876a9fa9459Szrj 	  tsec = h->root.u.def.section;
1877a9fa9459Szrj 	  toff = h->root.u.def.value;
1878a9fa9459Szrj 	  symtype = h->type;
1879a9fa9459Szrj 	}
1880a9fa9459Szrj       else
1881a9fa9459Szrj 	return TRUE;
1882a9fa9459Szrj     }
1883a9fa9459Szrj 
1884a9fa9459Szrj   /* Don't convert GOTPCREL relocation against large section.  */
1885a9fa9459Szrj   if (elf_section_data (tsec) !=  NULL
1886a9fa9459Szrj       && (elf_section_flags (tsec) & SHF_X86_64_LARGE) != 0)
1887a9fa9459Szrj     return TRUE;
1888a9fa9459Szrj 
1889a9fa9459Szrj   /* We can only estimate relocation overflow for R_X86_64_PC32.  */
1890a9fa9459Szrj   if (!to_reloc_pc32)
1891a9fa9459Szrj     goto convert;
1892a9fa9459Szrj 
1893a9fa9459Szrj   if (tsec->sec_info_type == SEC_INFO_TYPE_MERGE)
1894a9fa9459Szrj     {
1895a9fa9459Szrj       /* At this stage in linking, no SEC_MERGE symbol has been
1896a9fa9459Szrj 	 adjusted, so all references to such symbols need to be
1897a9fa9459Szrj 	 passed through _bfd_merged_section_offset.  (Later, in
1898a9fa9459Szrj 	 relocate_section, all SEC_MERGE symbols *except* for
1899a9fa9459Szrj 	 section symbols have been adjusted.)
1900a9fa9459Szrj 
1901a9fa9459Szrj 	 gas may reduce relocations against symbols in SEC_MERGE
1902a9fa9459Szrj 	 sections to a relocation against the section symbol when
1903a9fa9459Szrj 	 the original addend was zero.  When the reloc is against
1904a9fa9459Szrj 	 a section symbol we should include the addend in the
1905a9fa9459Szrj 	 offset passed to _bfd_merged_section_offset, since the
1906a9fa9459Szrj 	 location of interest is the original symbol.  On the
1907a9fa9459Szrj 	 other hand, an access to "sym+addend" where "sym" is not
1908a9fa9459Szrj 	 a section symbol should not include the addend;  Such an
1909a9fa9459Szrj 	 access is presumed to be an offset from "sym";  The
1910a9fa9459Szrj 	 location of interest is just "sym".  */
1911a9fa9459Szrj       if (symtype == STT_SECTION)
1912a9fa9459Szrj 	toff += raddend;
1913a9fa9459Szrj 
1914a9fa9459Szrj       toff = _bfd_merged_section_offset (abfd, &tsec,
1915a9fa9459Szrj 					 elf_section_data (tsec)->sec_info,
1916a9fa9459Szrj 					 toff);
1917a9fa9459Szrj 
1918a9fa9459Szrj       if (symtype != STT_SECTION)
1919a9fa9459Szrj 	toff += raddend;
1920a9fa9459Szrj     }
1921a9fa9459Szrj   else
1922a9fa9459Szrj     toff += raddend;
1923a9fa9459Szrj 
1924a9fa9459Szrj   /* Don't convert if R_X86_64_PC32 relocation overflows.  */
1925a9fa9459Szrj   if (tsec->output_section == sec->output_section)
1926a9fa9459Szrj     {
1927a9fa9459Szrj       if ((toff - roff + 0x80000000) > 0xffffffff)
1928a9fa9459Szrj 	return TRUE;
1929a9fa9459Szrj     }
1930a9fa9459Szrj   else
1931a9fa9459Szrj     {
1932a9fa9459Szrj       bfd_signed_vma distance;
1933a9fa9459Szrj 
1934a9fa9459Szrj       /* At this point, we don't know the load addresses of TSEC
1935a9fa9459Szrj 	 section nor SEC section.  We estimate the distrance between
1936a9fa9459Szrj 	 SEC and TSEC.  We store the estimated distances in the
1937a9fa9459Szrj 	 compressed_size field of the output section, which is only
1938a9fa9459Szrj 	 used to decompress the compressed input section.  */
1939a9fa9459Szrj       if (sec->output_section->compressed_size == 0)
1940a9fa9459Szrj 	{
1941a9fa9459Szrj 	  asection *asect;
1942a9fa9459Szrj 	  bfd_size_type size = 0;
1943a9fa9459Szrj 	  for (asect = link_info->output_bfd->sections;
1944a9fa9459Szrj 	       asect != NULL;
1945a9fa9459Szrj 	       asect = asect->next)
1946a9fa9459Szrj 	    /* Skip debug sections since compressed_size is used to
1947a9fa9459Szrj 	       compress debug sections.  */
1948a9fa9459Szrj 	    if ((asect->flags & SEC_DEBUGGING) == 0)
1949a9fa9459Szrj 	      {
1950a9fa9459Szrj 		asection *i;
1951a9fa9459Szrj 		for (i = asect->map_head.s;
1952a9fa9459Szrj 		     i != NULL;
1953a9fa9459Szrj 		     i = i->map_head.s)
1954a9fa9459Szrj 		  {
1955a9fa9459Szrj 		    size = align_power (size, i->alignment_power);
1956a9fa9459Szrj 		    size += i->size;
1957a9fa9459Szrj 		  }
1958a9fa9459Szrj 		asect->compressed_size = size;
1959a9fa9459Szrj 	      }
1960a9fa9459Szrj 	}
1961a9fa9459Szrj 
1962a9fa9459Szrj       /* Don't convert GOTPCREL relocations if TSEC isn't placed
1963a9fa9459Szrj 	 after SEC.  */
1964a9fa9459Szrj       distance = (tsec->output_section->compressed_size
1965a9fa9459Szrj 		  - sec->output_section->compressed_size);
1966a9fa9459Szrj       if (distance < 0)
1967a9fa9459Szrj 	return TRUE;
1968a9fa9459Szrj 
1969a9fa9459Szrj       /* Take PT_GNU_RELRO segment into account by adding
1970a9fa9459Szrj 	 maxpagesize.  */
1971a9fa9459Szrj       if ((toff + distance + get_elf_backend_data (abfd)->maxpagesize
1972a9fa9459Szrj 	   - roff + 0x80000000) > 0xffffffff)
1973a9fa9459Szrj 	return TRUE;
1974a9fa9459Szrj     }
1975a9fa9459Szrj 
1976a9fa9459Szrj convert:
1977a9fa9459Szrj   if (opcode == 0xff)
1978a9fa9459Szrj     {
1979a9fa9459Szrj       /* We have "call/jmp *foo@GOTPCREL(%rip)".  */
1980a9fa9459Szrj       unsigned int nop;
1981a9fa9459Szrj       unsigned int disp;
1982a9fa9459Szrj       bfd_vma nop_offset;
1983a9fa9459Szrj 
1984a9fa9459Szrj       /* Convert R_X86_64_GOTPCRELX and R_X86_64_REX_GOTPCRELX to
1985a9fa9459Szrj 	 R_X86_64_PC32.  */
1986a9fa9459Szrj       modrm = bfd_get_8 (abfd, contents + roff - 1);
1987a9fa9459Szrj       if (modrm == 0x25)
1988a9fa9459Szrj 	{
1989a9fa9459Szrj 	  /* Convert to "jmp foo nop".  */
1990a9fa9459Szrj 	  modrm = 0xe9;
1991a9fa9459Szrj 	  nop = NOP_OPCODE;
1992a9fa9459Szrj 	  nop_offset = irel->r_offset + 3;
1993a9fa9459Szrj 	  disp = bfd_get_32 (abfd, contents + irel->r_offset);
1994a9fa9459Szrj 	  irel->r_offset -= 1;
1995a9fa9459Szrj 	  bfd_put_32 (abfd, disp, contents + irel->r_offset);
1996a9fa9459Szrj 	}
1997a9fa9459Szrj       else
1998a9fa9459Szrj 	{
1999a9fa9459Szrj 	  struct elf_x86_64_link_hash_entry *eh
2000a9fa9459Szrj 	    = (struct elf_x86_64_link_hash_entry *) h;
2001a9fa9459Szrj 
2002a9fa9459Szrj 	  /* Convert to "nop call foo".  ADDR_PREFIX_OPCODE
2003a9fa9459Szrj 	     is a nop prefix.  */
2004a9fa9459Szrj 	  modrm = 0xe8;
2005a9fa9459Szrj 	  /* To support TLS optimization, always use addr32 prefix for
2006a9fa9459Szrj 	     "call *__tls_get_addr@GOTPCREL(%rip)".  */
2007a9fa9459Szrj 	  if (eh && eh->tls_get_addr == 1)
2008a9fa9459Szrj 	    {
2009a9fa9459Szrj 	      nop = 0x67;
2010a9fa9459Szrj 	      nop_offset = irel->r_offset - 2;
2011a9fa9459Szrj 	    }
2012a9fa9459Szrj 	  else
2013a9fa9459Szrj 	    {
2014a9fa9459Szrj 	      nop = link_info->call_nop_byte;
2015a9fa9459Szrj 	      if (link_info->call_nop_as_suffix)
2016a9fa9459Szrj 		{
2017a9fa9459Szrj 		  nop_offset = irel->r_offset + 3;
2018a9fa9459Szrj 		  disp = bfd_get_32 (abfd, contents + irel->r_offset);
2019a9fa9459Szrj 		  irel->r_offset -= 1;
2020a9fa9459Szrj 		  bfd_put_32 (abfd, disp, contents + irel->r_offset);
2021a9fa9459Szrj 		}
2022a9fa9459Szrj 	      else
2023a9fa9459Szrj 		nop_offset = irel->r_offset - 2;
2024a9fa9459Szrj 	    }
2025a9fa9459Szrj 	}
2026a9fa9459Szrj       bfd_put_8 (abfd, nop, contents + nop_offset);
2027a9fa9459Szrj       bfd_put_8 (abfd, modrm, contents + irel->r_offset - 1);
2028a9fa9459Szrj       r_type = R_X86_64_PC32;
2029a9fa9459Szrj     }
2030a9fa9459Szrj   else
2031a9fa9459Szrj     {
2032a9fa9459Szrj       unsigned int rex;
2033a9fa9459Szrj       unsigned int rex_mask = REX_R;
2034a9fa9459Szrj 
2035a9fa9459Szrj       if (r_type == R_X86_64_REX_GOTPCRELX)
2036a9fa9459Szrj 	rex = bfd_get_8 (abfd, contents + roff - 3);
2037a9fa9459Szrj       else
2038a9fa9459Szrj 	rex = 0;
2039a9fa9459Szrj 
2040a9fa9459Szrj       if (opcode == 0x8b)
2041a9fa9459Szrj 	{
2042a9fa9459Szrj 	  if (to_reloc_pc32)
2043a9fa9459Szrj 	    {
2044a9fa9459Szrj 	      /* Convert "mov foo@GOTPCREL(%rip), %reg" to
2045a9fa9459Szrj 		 "lea foo(%rip), %reg".  */
2046a9fa9459Szrj 	      opcode = 0x8d;
2047a9fa9459Szrj 	      r_type = R_X86_64_PC32;
2048a9fa9459Szrj 	    }
2049a9fa9459Szrj 	  else
2050a9fa9459Szrj 	    {
2051a9fa9459Szrj 	      /* Convert "mov foo@GOTPCREL(%rip), %reg" to
2052a9fa9459Szrj 		 "mov $foo, %reg".  */
2053a9fa9459Szrj 	      opcode = 0xc7;
2054a9fa9459Szrj 	      modrm = bfd_get_8 (abfd, contents + roff - 1);
2055a9fa9459Szrj 	      modrm = 0xc0 | (modrm & 0x38) >> 3;
2056a9fa9459Szrj 	      if ((rex & REX_W) != 0
2057a9fa9459Szrj 		  && ABI_64_P (link_info->output_bfd))
2058a9fa9459Szrj 		{
2059a9fa9459Szrj 		  /* Keep the REX_W bit in REX byte for LP64.  */
2060a9fa9459Szrj 		  r_type = R_X86_64_32S;
2061a9fa9459Szrj 		  goto rewrite_modrm_rex;
2062a9fa9459Szrj 		}
2063a9fa9459Szrj 	      else
2064a9fa9459Szrj 		{
2065a9fa9459Szrj 		  /* If the REX_W bit in REX byte isn't needed,
2066a9fa9459Szrj 		     use R_X86_64_32 and clear the W bit to avoid
2067a9fa9459Szrj 		     sign-extend imm32 to imm64.  */
2068a9fa9459Szrj 		  r_type = R_X86_64_32;
2069a9fa9459Szrj 		  /* Clear the W bit in REX byte.  */
2070a9fa9459Szrj 		  rex_mask |= REX_W;
2071a9fa9459Szrj 		  goto rewrite_modrm_rex;
2072a9fa9459Szrj 		}
2073a9fa9459Szrj 	    }
2074a9fa9459Szrj 	}
2075a9fa9459Szrj       else
2076a9fa9459Szrj 	{
2077a9fa9459Szrj 	  /* R_X86_64_PC32 isn't supported.  */
2078a9fa9459Szrj 	  if (to_reloc_pc32)
2079a9fa9459Szrj 	    return TRUE;
2080a9fa9459Szrj 
2081a9fa9459Szrj 	  modrm = bfd_get_8 (abfd, contents + roff - 1);
2082a9fa9459Szrj 	  if (opcode == 0x85)
2083a9fa9459Szrj 	    {
2084a9fa9459Szrj 	      /* Convert "test %reg, foo@GOTPCREL(%rip)" to
2085a9fa9459Szrj 		 "test $foo, %reg".  */
2086a9fa9459Szrj 	      modrm = 0xc0 | (modrm & 0x38) >> 3;
2087a9fa9459Szrj 	      opcode = 0xf7;
2088a9fa9459Szrj 	    }
2089a9fa9459Szrj 	  else
2090a9fa9459Szrj 	    {
2091a9fa9459Szrj 	      /* Convert "binop foo@GOTPCREL(%rip), %reg" to
2092a9fa9459Szrj 		 "binop $foo, %reg".  */
2093a9fa9459Szrj 	      modrm = 0xc0 | (modrm & 0x38) >> 3 | (opcode & 0x3c);
2094a9fa9459Szrj 	      opcode = 0x81;
2095a9fa9459Szrj 	    }
2096a9fa9459Szrj 
2097a9fa9459Szrj 	  /* Use R_X86_64_32 with 32-bit operand to avoid relocation
2098a9fa9459Szrj 	     overflow when sign-extending imm32 to imm64.  */
2099a9fa9459Szrj 	  r_type = (rex & REX_W) != 0 ? R_X86_64_32S : R_X86_64_32;
2100a9fa9459Szrj 
2101a9fa9459Szrj rewrite_modrm_rex:
2102a9fa9459Szrj 	  bfd_put_8 (abfd, modrm, contents + roff - 1);
2103a9fa9459Szrj 
2104a9fa9459Szrj 	  if (rex)
2105a9fa9459Szrj 	    {
2106a9fa9459Szrj 	      /* Move the R bit to the B bit in REX byte.  */
2107a9fa9459Szrj 	      rex = (rex & ~rex_mask) | (rex & REX_R) >> 2;
2108a9fa9459Szrj 	      bfd_put_8 (abfd, rex, contents + roff - 3);
2109a9fa9459Szrj 	    }
2110a9fa9459Szrj 
2111a9fa9459Szrj 	  /* No addend for R_X86_64_32/R_X86_64_32S relocations.  */
2112a9fa9459Szrj 	  irel->r_addend = 0;
2113a9fa9459Szrj 	}
2114a9fa9459Szrj 
2115a9fa9459Szrj       bfd_put_8 (abfd, opcode, contents + roff - 2);
2116a9fa9459Szrj     }
2117a9fa9459Szrj 
2118a9fa9459Szrj   irel->r_info = htab->r_info (r_symndx, r_type);
2119a9fa9459Szrj 
2120a9fa9459Szrj   *converted = TRUE;
2121a9fa9459Szrj 
2122a9fa9459Szrj   return TRUE;
2123a9fa9459Szrj }
2124a9fa9459Szrj 
2125a9fa9459Szrj /* Look through the relocs for a section during the first phase, and
2126a9fa9459Szrj    calculate needed space in the global offset table, procedure
2127a9fa9459Szrj    linkage table, and dynamic reloc sections.  */
2128a9fa9459Szrj 
2129a9fa9459Szrj static bfd_boolean
elf_x86_64_check_relocs(bfd * abfd,struct bfd_link_info * info,asection * sec,const Elf_Internal_Rela * relocs)2130a9fa9459Szrj elf_x86_64_check_relocs (bfd *abfd, struct bfd_link_info *info,
2131a9fa9459Szrj 			 asection *sec,
2132a9fa9459Szrj 			 const Elf_Internal_Rela *relocs)
2133a9fa9459Szrj {
2134a9fa9459Szrj   struct elf_x86_64_link_hash_table *htab;
2135a9fa9459Szrj   Elf_Internal_Shdr *symtab_hdr;
2136a9fa9459Szrj   struct elf_link_hash_entry **sym_hashes;
2137a9fa9459Szrj   const Elf_Internal_Rela *rel;
2138a9fa9459Szrj   const Elf_Internal_Rela *rel_end;
2139a9fa9459Szrj   asection *sreloc;
2140a9fa9459Szrj   bfd_byte *contents;
2141a9fa9459Szrj   bfd_boolean use_plt_got;
2142a9fa9459Szrj 
2143a9fa9459Szrj   if (bfd_link_relocatable (info))
2144a9fa9459Szrj     return TRUE;
2145a9fa9459Szrj 
2146a9fa9459Szrj   /* Don't do anything special with non-loaded, non-alloced sections.
2147a9fa9459Szrj      In particular, any relocs in such sections should not affect GOT
2148a9fa9459Szrj      and PLT reference counting (ie. we don't allow them to create GOT
2149a9fa9459Szrj      or PLT entries), there's no possibility or desire to optimize TLS
2150a9fa9459Szrj      relocs, and there's not much point in propagating relocs to shared
2151a9fa9459Szrj      libs that the dynamic linker won't relocate.  */
2152a9fa9459Szrj   if ((sec->flags & SEC_ALLOC) == 0)
2153a9fa9459Szrj     return TRUE;
2154a9fa9459Szrj 
2155a9fa9459Szrj   BFD_ASSERT (is_x86_64_elf (abfd));
2156a9fa9459Szrj 
2157a9fa9459Szrj   htab = elf_x86_64_hash_table (info);
2158a9fa9459Szrj   if (htab == NULL)
2159a9fa9459Szrj     {
2160a9fa9459Szrj       sec->check_relocs_failed = 1;
2161a9fa9459Szrj       return FALSE;
2162a9fa9459Szrj     }
2163a9fa9459Szrj 
2164a9fa9459Szrj   /* Get the section contents.  */
2165a9fa9459Szrj   if (elf_section_data (sec)->this_hdr.contents != NULL)
2166a9fa9459Szrj     contents = elf_section_data (sec)->this_hdr.contents;
2167a9fa9459Szrj   else if (!bfd_malloc_and_get_section (abfd, sec, &contents))
2168a9fa9459Szrj     {
2169a9fa9459Szrj       sec->check_relocs_failed = 1;
2170a9fa9459Szrj       return FALSE;
2171a9fa9459Szrj     }
2172a9fa9459Szrj 
2173a9fa9459Szrj   use_plt_got = get_elf_x86_64_backend_data (abfd) == &elf_x86_64_arch_bed;
2174a9fa9459Szrj 
2175a9fa9459Szrj   symtab_hdr = &elf_symtab_hdr (abfd);
2176a9fa9459Szrj   sym_hashes = elf_sym_hashes (abfd);
2177a9fa9459Szrj 
2178a9fa9459Szrj   sreloc = NULL;
2179a9fa9459Szrj 
2180a9fa9459Szrj   rel_end = relocs + sec->reloc_count;
2181a9fa9459Szrj   for (rel = relocs; rel < rel_end; rel++)
2182a9fa9459Szrj     {
2183a9fa9459Szrj       unsigned int r_type;
2184a9fa9459Szrj       unsigned long r_symndx;
2185a9fa9459Szrj       struct elf_link_hash_entry *h;
2186a9fa9459Szrj       struct elf_x86_64_link_hash_entry *eh;
2187a9fa9459Szrj       Elf_Internal_Sym *isym;
2188a9fa9459Szrj       const char *name;
2189a9fa9459Szrj       bfd_boolean size_reloc;
2190a9fa9459Szrj 
2191a9fa9459Szrj       r_symndx = htab->r_sym (rel->r_info);
2192a9fa9459Szrj       r_type = ELF32_R_TYPE (rel->r_info);
2193a9fa9459Szrj 
2194a9fa9459Szrj       if (r_symndx >= NUM_SHDR_ENTRIES (symtab_hdr))
2195a9fa9459Szrj 	{
2196a9fa9459Szrj 	  (*_bfd_error_handler) (_("%B: bad symbol index: %d"),
2197a9fa9459Szrj 				 abfd, r_symndx);
2198a9fa9459Szrj 	  goto error_return;
2199a9fa9459Szrj 	}
2200a9fa9459Szrj 
2201a9fa9459Szrj       if (r_symndx < symtab_hdr->sh_info)
2202a9fa9459Szrj 	{
2203a9fa9459Szrj 	  /* A local symbol.  */
2204a9fa9459Szrj 	  isym = bfd_sym_from_r_symndx (&htab->sym_cache,
2205a9fa9459Szrj 					abfd, r_symndx);
2206a9fa9459Szrj 	  if (isym == NULL)
2207a9fa9459Szrj 	    goto error_return;
2208a9fa9459Szrj 
2209a9fa9459Szrj 	  /* Check relocation against local STT_GNU_IFUNC symbol.  */
2210a9fa9459Szrj 	  if (ELF_ST_TYPE (isym->st_info) == STT_GNU_IFUNC)
2211a9fa9459Szrj 	    {
2212a9fa9459Szrj 	      h = elf_x86_64_get_local_sym_hash (htab, abfd, rel,
2213a9fa9459Szrj 						 TRUE);
2214a9fa9459Szrj 	      if (h == NULL)
2215a9fa9459Szrj 		goto error_return;
2216a9fa9459Szrj 
2217a9fa9459Szrj 	      /* Fake a STT_GNU_IFUNC symbol.  */
2218a9fa9459Szrj 	      h->type = STT_GNU_IFUNC;
2219a9fa9459Szrj 	      h->def_regular = 1;
2220a9fa9459Szrj 	      h->ref_regular = 1;
2221a9fa9459Szrj 	      h->forced_local = 1;
2222a9fa9459Szrj 	      h->root.type = bfd_link_hash_defined;
2223a9fa9459Szrj 	    }
2224a9fa9459Szrj 	  else
2225a9fa9459Szrj 	    h = NULL;
2226a9fa9459Szrj 	}
2227a9fa9459Szrj       else
2228a9fa9459Szrj 	{
2229a9fa9459Szrj 	  isym = NULL;
2230a9fa9459Szrj 	  h = sym_hashes[r_symndx - symtab_hdr->sh_info];
2231a9fa9459Szrj 	  while (h->root.type == bfd_link_hash_indirect
2232a9fa9459Szrj 		 || h->root.type == bfd_link_hash_warning)
2233a9fa9459Szrj 	    h = (struct elf_link_hash_entry *) h->root.u.i.link;
2234a9fa9459Szrj 	}
2235a9fa9459Szrj 
2236a9fa9459Szrj       /* Check invalid x32 relocations.  */
2237a9fa9459Szrj       if (!ABI_64_P (abfd))
2238a9fa9459Szrj 	switch (r_type)
2239a9fa9459Szrj 	  {
2240a9fa9459Szrj 	  default:
2241a9fa9459Szrj 	    break;
2242a9fa9459Szrj 
2243a9fa9459Szrj 	  case R_X86_64_DTPOFF64:
2244a9fa9459Szrj 	  case R_X86_64_TPOFF64:
2245a9fa9459Szrj 	  case R_X86_64_PC64:
2246a9fa9459Szrj 	  case R_X86_64_GOTOFF64:
2247a9fa9459Szrj 	  case R_X86_64_GOT64:
2248a9fa9459Szrj 	  case R_X86_64_GOTPCREL64:
2249a9fa9459Szrj 	  case R_X86_64_GOTPC64:
2250a9fa9459Szrj 	  case R_X86_64_GOTPLT64:
2251a9fa9459Szrj 	  case R_X86_64_PLTOFF64:
2252a9fa9459Szrj 	      {
2253a9fa9459Szrj 		if (h)
2254a9fa9459Szrj 		  name = h->root.root.string;
2255a9fa9459Szrj 		else
2256a9fa9459Szrj 		  name = bfd_elf_sym_name (abfd, symtab_hdr, isym,
2257a9fa9459Szrj 					   NULL);
2258a9fa9459Szrj 		(*_bfd_error_handler)
2259a9fa9459Szrj 		  (_("%B: relocation %s against symbol `%s' isn't "
2260a9fa9459Szrj 		     "supported in x32 mode"), abfd,
2261a9fa9459Szrj 		   x86_64_elf_howto_table[r_type].name, name);
2262a9fa9459Szrj 		bfd_set_error (bfd_error_bad_value);
2263a9fa9459Szrj 		goto error_return;
2264a9fa9459Szrj 	      }
2265a9fa9459Szrj 	    break;
2266a9fa9459Szrj 	  }
2267a9fa9459Szrj 
2268a9fa9459Szrj       if (h != NULL)
2269a9fa9459Szrj 	{
2270a9fa9459Szrj 	  switch (r_type)
2271a9fa9459Szrj 	    {
2272a9fa9459Szrj 	    default:
2273a9fa9459Szrj 	      break;
2274a9fa9459Szrj 
2275a9fa9459Szrj 	    case R_X86_64_PC32_BND:
2276a9fa9459Szrj 	    case R_X86_64_PLT32_BND:
2277a9fa9459Szrj 	    case R_X86_64_PC32:
2278a9fa9459Szrj 	    case R_X86_64_PLT32:
2279a9fa9459Szrj 	    case R_X86_64_32:
2280a9fa9459Szrj 	    case R_X86_64_64:
2281a9fa9459Szrj 	      /* MPX PLT is supported only if elf_x86_64_arch_bed
2282a9fa9459Szrj 		 is used in 64-bit mode.  */
2283a9fa9459Szrj 	      if (ABI_64_P (abfd)
2284a9fa9459Szrj 		      && info->bndplt
2285a9fa9459Szrj 		      && (get_elf_x86_64_backend_data (abfd)
2286a9fa9459Szrj 			  == &elf_x86_64_arch_bed))
2287a9fa9459Szrj 		{
2288a9fa9459Szrj 		  elf_x86_64_hash_entry (h)->has_bnd_reloc = 1;
2289a9fa9459Szrj 
2290a9fa9459Szrj 		  /* Create the second PLT for Intel MPX support.  */
2291a9fa9459Szrj 		  if (htab->plt_bnd == NULL)
2292a9fa9459Szrj 		    {
2293a9fa9459Szrj 		      unsigned int plt_bnd_align;
2294a9fa9459Szrj 		      const struct elf_backend_data *bed;
2295a9fa9459Szrj 
2296a9fa9459Szrj 		      bed = get_elf_backend_data (info->output_bfd);
2297a9fa9459Szrj 		      BFD_ASSERT (sizeof (elf_x86_64_bnd_plt2_entry) == 8
2298a9fa9459Szrj 				  && (sizeof (elf_x86_64_bnd_plt2_entry)
2299a9fa9459Szrj 				      == sizeof (elf_x86_64_legacy_plt2_entry)));
2300a9fa9459Szrj 		      plt_bnd_align = 3;
2301a9fa9459Szrj 
2302a9fa9459Szrj 		      if (htab->elf.dynobj == NULL)
2303a9fa9459Szrj 			htab->elf.dynobj = abfd;
2304a9fa9459Szrj 		      htab->plt_bnd
2305a9fa9459Szrj 			= bfd_make_section_anyway_with_flags (htab->elf.dynobj,
2306a9fa9459Szrj 							      ".plt.bnd",
2307a9fa9459Szrj 							     (bed->dynamic_sec_flags
2308a9fa9459Szrj 							      | SEC_ALLOC
2309a9fa9459Szrj 							      | SEC_CODE
2310a9fa9459Szrj 							      | SEC_LOAD
2311a9fa9459Szrj 							      | SEC_READONLY));
2312a9fa9459Szrj 		      if (htab->plt_bnd == NULL
2313a9fa9459Szrj 			  || !bfd_set_section_alignment (htab->elf.dynobj,
2314a9fa9459Szrj 							 htab->plt_bnd,
2315a9fa9459Szrj 							 plt_bnd_align))
2316a9fa9459Szrj 			goto error_return;
2317a9fa9459Szrj 		    }
2318a9fa9459Szrj 		}
2319a9fa9459Szrj 
2320a9fa9459Szrj 	    case R_X86_64_32S:
2321a9fa9459Szrj 	    case R_X86_64_PC64:
2322a9fa9459Szrj 	    case R_X86_64_GOTPCREL:
2323a9fa9459Szrj 	    case R_X86_64_GOTPCRELX:
2324a9fa9459Szrj 	    case R_X86_64_REX_GOTPCRELX:
2325a9fa9459Szrj 	    case R_X86_64_GOTPCREL64:
2326a9fa9459Szrj 	      if (htab->elf.dynobj == NULL)
2327a9fa9459Szrj 		htab->elf.dynobj = abfd;
2328a9fa9459Szrj 	      /* Create the ifunc sections for static executables.  */
2329a9fa9459Szrj 	      if (h->type == STT_GNU_IFUNC
2330a9fa9459Szrj 		  && !_bfd_elf_create_ifunc_sections (htab->elf.dynobj,
2331a9fa9459Szrj 						      info))
2332a9fa9459Szrj 		goto error_return;
2333a9fa9459Szrj 	      break;
2334a9fa9459Szrj 	    }
2335a9fa9459Szrj 
2336a9fa9459Szrj 	  /* It is referenced by a non-shared object. */
2337a9fa9459Szrj 	  h->ref_regular = 1;
2338a9fa9459Szrj 	  h->root.non_ir_ref = 1;
2339a9fa9459Szrj 
2340a9fa9459Szrj 	  if (h->type == STT_GNU_IFUNC)
2341a9fa9459Szrj 	    elf_tdata (info->output_bfd)->has_gnu_symbols
2342a9fa9459Szrj 	      |= elf_gnu_symbol_ifunc;
2343a9fa9459Szrj 	}
2344a9fa9459Szrj 
2345a9fa9459Szrj       if (! elf_x86_64_tls_transition (info, abfd, sec, contents,
2346a9fa9459Szrj 				       symtab_hdr, sym_hashes,
2347a9fa9459Szrj 				       &r_type, GOT_UNKNOWN,
2348a9fa9459Szrj 				       rel, rel_end, h, r_symndx, FALSE))
2349a9fa9459Szrj 	goto error_return;
2350a9fa9459Szrj 
2351a9fa9459Szrj       eh = (struct elf_x86_64_link_hash_entry *) h;
2352a9fa9459Szrj       switch (r_type)
2353a9fa9459Szrj 	{
2354a9fa9459Szrj 	case R_X86_64_TLSLD:
2355a9fa9459Szrj 	  htab->tls_ld_got.refcount += 1;
2356a9fa9459Szrj 	  goto create_got;
2357a9fa9459Szrj 
2358a9fa9459Szrj 	case R_X86_64_TPOFF32:
2359a9fa9459Szrj 	  if (!bfd_link_executable (info) && ABI_64_P (abfd))
2360a9fa9459Szrj 	    return elf_x86_64_need_pic (abfd, sec, h, symtab_hdr, isym,
2361a9fa9459Szrj 					&x86_64_elf_howto_table[r_type]);
2362a9fa9459Szrj 	  if (eh != NULL)
2363a9fa9459Szrj 	    eh->has_got_reloc = 1;
2364a9fa9459Szrj 	  break;
2365a9fa9459Szrj 
2366a9fa9459Szrj 	case R_X86_64_GOTTPOFF:
2367a9fa9459Szrj 	  if (!bfd_link_executable (info))
2368a9fa9459Szrj 	    info->flags |= DF_STATIC_TLS;
2369a9fa9459Szrj 	  /* Fall through */
2370a9fa9459Szrj 
2371a9fa9459Szrj 	case R_X86_64_GOT32:
2372a9fa9459Szrj 	case R_X86_64_GOTPCREL:
2373a9fa9459Szrj 	case R_X86_64_GOTPCRELX:
2374a9fa9459Szrj 	case R_X86_64_REX_GOTPCRELX:
2375a9fa9459Szrj 	case R_X86_64_TLSGD:
2376a9fa9459Szrj 	case R_X86_64_GOT64:
2377a9fa9459Szrj 	case R_X86_64_GOTPCREL64:
2378a9fa9459Szrj 	case R_X86_64_GOTPLT64:
2379a9fa9459Szrj 	case R_X86_64_GOTPC32_TLSDESC:
2380a9fa9459Szrj 	case R_X86_64_TLSDESC_CALL:
2381a9fa9459Szrj 	  /* This symbol requires a global offset table entry.	*/
2382a9fa9459Szrj 	  {
2383a9fa9459Szrj 	    int tls_type, old_tls_type;
2384a9fa9459Szrj 
2385a9fa9459Szrj 	    switch (r_type)
2386a9fa9459Szrj 	      {
2387a9fa9459Szrj 	      default: tls_type = GOT_NORMAL; break;
2388a9fa9459Szrj 	      case R_X86_64_TLSGD: tls_type = GOT_TLS_GD; break;
2389a9fa9459Szrj 	      case R_X86_64_GOTTPOFF: tls_type = GOT_TLS_IE; break;
2390a9fa9459Szrj 	      case R_X86_64_GOTPC32_TLSDESC:
2391a9fa9459Szrj 	      case R_X86_64_TLSDESC_CALL:
2392a9fa9459Szrj 		tls_type = GOT_TLS_GDESC; break;
2393a9fa9459Szrj 	      }
2394a9fa9459Szrj 
2395a9fa9459Szrj 	    if (h != NULL)
2396a9fa9459Szrj 	      {
2397a9fa9459Szrj 		h->got.refcount += 1;
2398a9fa9459Szrj 		old_tls_type = eh->tls_type;
2399a9fa9459Szrj 	      }
2400a9fa9459Szrj 	    else
2401a9fa9459Szrj 	      {
2402a9fa9459Szrj 		bfd_signed_vma *local_got_refcounts;
2403a9fa9459Szrj 
2404a9fa9459Szrj 		/* This is a global offset table entry for a local symbol.  */
2405a9fa9459Szrj 		local_got_refcounts = elf_local_got_refcounts (abfd);
2406a9fa9459Szrj 		if (local_got_refcounts == NULL)
2407a9fa9459Szrj 		  {
2408a9fa9459Szrj 		    bfd_size_type size;
2409a9fa9459Szrj 
2410a9fa9459Szrj 		    size = symtab_hdr->sh_info;
2411a9fa9459Szrj 		    size *= sizeof (bfd_signed_vma)
2412a9fa9459Szrj 		      + sizeof (bfd_vma) + sizeof (char);
2413a9fa9459Szrj 		    local_got_refcounts = ((bfd_signed_vma *)
2414a9fa9459Szrj 					   bfd_zalloc (abfd, size));
2415a9fa9459Szrj 		    if (local_got_refcounts == NULL)
2416a9fa9459Szrj 		      goto error_return;
2417a9fa9459Szrj 		    elf_local_got_refcounts (abfd) = local_got_refcounts;
2418a9fa9459Szrj 		    elf_x86_64_local_tlsdesc_gotent (abfd)
2419a9fa9459Szrj 		      = (bfd_vma *) (local_got_refcounts + symtab_hdr->sh_info);
2420a9fa9459Szrj 		    elf_x86_64_local_got_tls_type (abfd)
2421a9fa9459Szrj 		      = (char *) (local_got_refcounts + 2 * symtab_hdr->sh_info);
2422a9fa9459Szrj 		  }
2423a9fa9459Szrj 		local_got_refcounts[r_symndx] += 1;
2424a9fa9459Szrj 		old_tls_type
2425a9fa9459Szrj 		  = elf_x86_64_local_got_tls_type (abfd) [r_symndx];
2426a9fa9459Szrj 	      }
2427a9fa9459Szrj 
2428a9fa9459Szrj 	    /* If a TLS symbol is accessed using IE at least once,
2429a9fa9459Szrj 	       there is no point to use dynamic model for it.  */
2430a9fa9459Szrj 	    if (old_tls_type != tls_type && old_tls_type != GOT_UNKNOWN
2431a9fa9459Szrj 		&& (! GOT_TLS_GD_ANY_P (old_tls_type)
2432a9fa9459Szrj 		    || tls_type != GOT_TLS_IE))
2433a9fa9459Szrj 	      {
2434a9fa9459Szrj 		if (old_tls_type == GOT_TLS_IE && GOT_TLS_GD_ANY_P (tls_type))
2435a9fa9459Szrj 		  tls_type = old_tls_type;
2436a9fa9459Szrj 		else if (GOT_TLS_GD_ANY_P (old_tls_type)
2437a9fa9459Szrj 			 && GOT_TLS_GD_ANY_P (tls_type))
2438a9fa9459Szrj 		  tls_type |= old_tls_type;
2439a9fa9459Szrj 		else
2440a9fa9459Szrj 		  {
2441a9fa9459Szrj 		    if (h)
2442a9fa9459Szrj 		      name = h->root.root.string;
2443a9fa9459Szrj 		    else
2444a9fa9459Szrj 		      name = bfd_elf_sym_name (abfd, symtab_hdr,
2445a9fa9459Szrj 					       isym, NULL);
2446a9fa9459Szrj 		    (*_bfd_error_handler)
2447a9fa9459Szrj 		      (_("%B: '%s' accessed both as normal and thread local symbol"),
2448a9fa9459Szrj 		       abfd, name);
2449a9fa9459Szrj 		    bfd_set_error (bfd_error_bad_value);
2450a9fa9459Szrj 		    goto error_return;
2451a9fa9459Szrj 		  }
2452a9fa9459Szrj 	      }
2453a9fa9459Szrj 
2454a9fa9459Szrj 	    if (old_tls_type != tls_type)
2455a9fa9459Szrj 	      {
2456a9fa9459Szrj 		if (eh != NULL)
2457a9fa9459Szrj 		  eh->tls_type = tls_type;
2458a9fa9459Szrj 		else
2459a9fa9459Szrj 		  elf_x86_64_local_got_tls_type (abfd) [r_symndx] = tls_type;
2460a9fa9459Szrj 	      }
2461a9fa9459Szrj 	  }
2462a9fa9459Szrj 	  /* Fall through */
2463a9fa9459Szrj 
2464a9fa9459Szrj 	case R_X86_64_GOTOFF64:
2465a9fa9459Szrj 	case R_X86_64_GOTPC32:
2466a9fa9459Szrj 	case R_X86_64_GOTPC64:
2467a9fa9459Szrj 	create_got:
2468a9fa9459Szrj 	  if (eh != NULL)
2469a9fa9459Szrj 	    eh->has_got_reloc = 1;
2470a9fa9459Szrj 	  if (htab->elf.sgot == NULL)
2471a9fa9459Szrj 	    {
2472a9fa9459Szrj 	      if (htab->elf.dynobj == NULL)
2473a9fa9459Szrj 		htab->elf.dynobj = abfd;
2474a9fa9459Szrj 	      if (!_bfd_elf_create_got_section (htab->elf.dynobj,
2475a9fa9459Szrj 						info))
2476a9fa9459Szrj 		goto error_return;
2477a9fa9459Szrj 	    }
2478a9fa9459Szrj 	  break;
2479a9fa9459Szrj 
2480a9fa9459Szrj 	case R_X86_64_PLT32:
2481a9fa9459Szrj 	case R_X86_64_PLT32_BND:
2482a9fa9459Szrj 	  /* This symbol requires a procedure linkage table entry.  We
2483a9fa9459Szrj 	     actually build the entry in adjust_dynamic_symbol,
2484a9fa9459Szrj 	     because this might be a case of linking PIC code which is
2485a9fa9459Szrj 	     never referenced by a dynamic object, in which case we
2486a9fa9459Szrj 	     don't need to generate a procedure linkage table entry
2487a9fa9459Szrj 	     after all.	 */
2488a9fa9459Szrj 
2489a9fa9459Szrj 	  /* If this is a local symbol, we resolve it directly without
2490a9fa9459Szrj 	     creating a procedure linkage table entry.	*/
2491a9fa9459Szrj 	  if (h == NULL)
2492a9fa9459Szrj 	    continue;
2493a9fa9459Szrj 
2494a9fa9459Szrj 	  eh->has_got_reloc = 1;
2495a9fa9459Szrj 	  h->needs_plt = 1;
2496a9fa9459Szrj 	  h->plt.refcount += 1;
2497a9fa9459Szrj 	  break;
2498a9fa9459Szrj 
2499a9fa9459Szrj 	case R_X86_64_PLTOFF64:
2500a9fa9459Szrj 	  /* This tries to form the 'address' of a function relative
2501a9fa9459Szrj 	     to GOT.  For global symbols we need a PLT entry.  */
2502a9fa9459Szrj 	  if (h != NULL)
2503a9fa9459Szrj 	    {
2504a9fa9459Szrj 	      h->needs_plt = 1;
2505a9fa9459Szrj 	      h->plt.refcount += 1;
2506a9fa9459Szrj 	    }
2507a9fa9459Szrj 	  goto create_got;
2508a9fa9459Szrj 
2509a9fa9459Szrj 	case R_X86_64_SIZE32:
2510a9fa9459Szrj 	case R_X86_64_SIZE64:
2511a9fa9459Szrj 	  size_reloc = TRUE;
2512a9fa9459Szrj 	  goto do_size;
2513a9fa9459Szrj 
2514a9fa9459Szrj 	case R_X86_64_32:
2515a9fa9459Szrj 	  if (!ABI_64_P (abfd))
2516a9fa9459Szrj 	    goto pointer;
2517a9fa9459Szrj 	case R_X86_64_8:
2518a9fa9459Szrj 	case R_X86_64_16:
2519a9fa9459Szrj 	case R_X86_64_32S:
2520a9fa9459Szrj 	  /* Check relocation overflow as these relocs may lead to
2521a9fa9459Szrj 	     run-time relocation overflow.  Don't error out for
2522a9fa9459Szrj 	     sections we don't care about, such as debug sections or
2523a9fa9459Szrj 	     when relocation overflow check is disabled.  */
2524a9fa9459Szrj 	  if (!info->no_reloc_overflow_check
2525a9fa9459Szrj 	      && (bfd_link_pic (info)
2526a9fa9459Szrj 		  || (bfd_link_executable (info)
2527a9fa9459Szrj 		      && h != NULL
2528a9fa9459Szrj 		      && !h->def_regular
2529a9fa9459Szrj 		      && h->def_dynamic
2530a9fa9459Szrj 		      && (sec->flags & SEC_READONLY) == 0)))
2531a9fa9459Szrj 	    return elf_x86_64_need_pic (abfd, sec, h, symtab_hdr, isym,
2532a9fa9459Szrj 					&x86_64_elf_howto_table[r_type]);
2533a9fa9459Szrj 	  /* Fall through.  */
2534a9fa9459Szrj 
2535a9fa9459Szrj 	case R_X86_64_PC8:
2536a9fa9459Szrj 	case R_X86_64_PC16:
2537a9fa9459Szrj 	case R_X86_64_PC32:
2538a9fa9459Szrj 	case R_X86_64_PC32_BND:
2539a9fa9459Szrj 	case R_X86_64_PC64:
2540a9fa9459Szrj 	case R_X86_64_64:
2541a9fa9459Szrj pointer:
2542a9fa9459Szrj 	  if (eh != NULL && (sec->flags & SEC_CODE) != 0)
2543a9fa9459Szrj 	    eh->has_non_got_reloc = 1;
2544a9fa9459Szrj 	  /* We are called after all symbols have been resolved.  Only
2545a9fa9459Szrj 	     relocation against STT_GNU_IFUNC symbol must go through
2546a9fa9459Szrj 	     PLT.  */
2547a9fa9459Szrj 	  if (h != NULL
2548a9fa9459Szrj 	      && (bfd_link_executable (info)
2549a9fa9459Szrj 		  || h->type == STT_GNU_IFUNC))
2550a9fa9459Szrj 	    {
2551a9fa9459Szrj 	      /* If this reloc is in a read-only section, we might
2552a9fa9459Szrj 		 need a copy reloc.  We can't check reliably at this
2553a9fa9459Szrj 		 stage whether the section is read-only, as input
2554a9fa9459Szrj 		 sections have not yet been mapped to output sections.
2555a9fa9459Szrj 		 Tentatively set the flag for now, and correct in
2556a9fa9459Szrj 		 adjust_dynamic_symbol.  */
2557a9fa9459Szrj 	      h->non_got_ref = 1;
2558a9fa9459Szrj 
2559a9fa9459Szrj 	      /* We may need a .plt entry if the symbol is a function
2560a9fa9459Szrj 		 defined in a shared lib or is a STT_GNU_IFUNC function
2561a9fa9459Szrj 		 referenced from the code or read-only section.  */
2562a9fa9459Szrj 	      if (!h->def_regular
2563a9fa9459Szrj 		  || (sec->flags & (SEC_CODE | SEC_READONLY)) != 0)
2564a9fa9459Szrj 		h->plt.refcount += 1;
2565a9fa9459Szrj 
2566a9fa9459Szrj 	      if (r_type == R_X86_64_PC32)
2567a9fa9459Szrj 		{
2568a9fa9459Szrj 		  /* Since something like ".long foo - ." may be used
2569a9fa9459Szrj 		     as pointer, make sure that PLT is used if foo is
2570a9fa9459Szrj 		     a function defined in a shared library.  */
2571a9fa9459Szrj 		  if ((sec->flags & SEC_CODE) == 0)
2572a9fa9459Szrj 		    h->pointer_equality_needed = 1;
2573a9fa9459Szrj 		}
2574a9fa9459Szrj 	      else if (r_type != R_X86_64_PC32_BND
2575a9fa9459Szrj 		       && r_type != R_X86_64_PC64)
2576a9fa9459Szrj 		{
2577a9fa9459Szrj 		  h->pointer_equality_needed = 1;
2578a9fa9459Szrj 		  /* At run-time, R_X86_64_64 can be resolved for both
2579a9fa9459Szrj 		     x86-64 and x32. But R_X86_64_32 and R_X86_64_32S
2580a9fa9459Szrj 		     can only be resolved for x32.  */
2581a9fa9459Szrj 		  if ((sec->flags & SEC_READONLY) == 0
2582a9fa9459Szrj 		      && (r_type == R_X86_64_64
2583a9fa9459Szrj 			  || (!ABI_64_P (abfd)
2584a9fa9459Szrj 			      && (r_type == R_X86_64_32
2585a9fa9459Szrj 				  || r_type == R_X86_64_32S))))
2586a9fa9459Szrj 		    eh->func_pointer_refcount += 1;
2587a9fa9459Szrj 		}
2588a9fa9459Szrj 	    }
2589a9fa9459Szrj 
2590a9fa9459Szrj 	  size_reloc = FALSE;
2591a9fa9459Szrj do_size:
2592a9fa9459Szrj 	  /* If we are creating a shared library, and this is a reloc
2593a9fa9459Szrj 	     against a global symbol, or a non PC relative reloc
2594a9fa9459Szrj 	     against a local symbol, then we need to copy the reloc
2595a9fa9459Szrj 	     into the shared library.  However, if we are linking with
2596a9fa9459Szrj 	     -Bsymbolic, we do not need to copy a reloc against a
2597a9fa9459Szrj 	     global symbol which is defined in an object we are
2598a9fa9459Szrj 	     including in the link (i.e., DEF_REGULAR is set).	At
2599a9fa9459Szrj 	     this point we have not seen all the input files, so it is
2600a9fa9459Szrj 	     possible that DEF_REGULAR is not set now but will be set
2601a9fa9459Szrj 	     later (it is never cleared).  In case of a weak definition,
2602a9fa9459Szrj 	     DEF_REGULAR may be cleared later by a strong definition in
2603a9fa9459Szrj 	     a shared library.  We account for that possibility below by
2604a9fa9459Szrj 	     storing information in the relocs_copied field of the hash
2605a9fa9459Szrj 	     table entry.  A similar situation occurs when creating
2606a9fa9459Szrj 	     shared libraries and symbol visibility changes render the
2607a9fa9459Szrj 	     symbol local.
2608a9fa9459Szrj 
2609a9fa9459Szrj 	     If on the other hand, we are creating an executable, we
2610a9fa9459Szrj 	     may need to keep relocations for symbols satisfied by a
2611a9fa9459Szrj 	     dynamic library if we manage to avoid copy relocs for the
2612a9fa9459Szrj 	     symbol.
2613a9fa9459Szrj 
2614a9fa9459Szrj 	     Generate dynamic pointer relocation against STT_GNU_IFUNC
2615a9fa9459Szrj 	     symbol in the non-code section.  */
2616a9fa9459Szrj 	  if ((bfd_link_pic (info)
2617a9fa9459Szrj 	       && (! IS_X86_64_PCREL_TYPE (r_type)
2618a9fa9459Szrj 		   || (h != NULL
2619a9fa9459Szrj 		       && (! (bfd_link_pie (info)
2620a9fa9459Szrj 			      || SYMBOLIC_BIND (info, h))
2621a9fa9459Szrj 			   || h->root.type == bfd_link_hash_defweak
2622a9fa9459Szrj 			   || !h->def_regular))))
2623a9fa9459Szrj 	      || (h != NULL
2624a9fa9459Szrj 		  && h->type == STT_GNU_IFUNC
2625a9fa9459Szrj 		  && r_type == htab->pointer_r_type
2626a9fa9459Szrj 		  && (sec->flags & SEC_CODE) == 0)
2627a9fa9459Szrj 	      || (ELIMINATE_COPY_RELOCS
2628a9fa9459Szrj 		  && !bfd_link_pic (info)
2629a9fa9459Szrj 		  && h != NULL
2630a9fa9459Szrj 		  && (h->root.type == bfd_link_hash_defweak
2631a9fa9459Szrj 		      || !h->def_regular)))
2632a9fa9459Szrj 	    {
2633a9fa9459Szrj 	      struct elf_dyn_relocs *p;
2634a9fa9459Szrj 	      struct elf_dyn_relocs **head;
2635a9fa9459Szrj 
2636a9fa9459Szrj 	      /* We must copy these reloc types into the output file.
2637a9fa9459Szrj 		 Create a reloc section in dynobj and make room for
2638a9fa9459Szrj 		 this reloc.  */
2639a9fa9459Szrj 	      if (sreloc == NULL)
2640a9fa9459Szrj 		{
2641a9fa9459Szrj 		  if (htab->elf.dynobj == NULL)
2642a9fa9459Szrj 		    htab->elf.dynobj = abfd;
2643a9fa9459Szrj 
2644a9fa9459Szrj 		  sreloc = _bfd_elf_make_dynamic_reloc_section
2645a9fa9459Szrj 		    (sec, htab->elf.dynobj, ABI_64_P (abfd) ? 3 : 2,
2646a9fa9459Szrj 		     abfd, /*rela?*/ TRUE);
2647a9fa9459Szrj 
2648a9fa9459Szrj 		  if (sreloc == NULL)
2649a9fa9459Szrj 		    goto error_return;
2650a9fa9459Szrj 		}
2651a9fa9459Szrj 
2652a9fa9459Szrj 	      /* If this is a global symbol, we count the number of
2653a9fa9459Szrj 		 relocations we need for this symbol.  */
2654a9fa9459Szrj 	      if (h != NULL)
2655a9fa9459Szrj 		head = &eh->dyn_relocs;
2656a9fa9459Szrj 	      else
2657a9fa9459Szrj 		{
2658a9fa9459Szrj 		  /* Track dynamic relocs needed for local syms too.
2659a9fa9459Szrj 		     We really need local syms available to do this
2660a9fa9459Szrj 		     easily.  Oh well.  */
2661a9fa9459Szrj 		  asection *s;
2662a9fa9459Szrj 		  void **vpp;
2663a9fa9459Szrj 
2664a9fa9459Szrj 		  isym = bfd_sym_from_r_symndx (&htab->sym_cache,
2665a9fa9459Szrj 						abfd, r_symndx);
2666a9fa9459Szrj 		  if (isym == NULL)
2667a9fa9459Szrj 		    goto error_return;
2668a9fa9459Szrj 
2669a9fa9459Szrj 		  s = bfd_section_from_elf_index (abfd, isym->st_shndx);
2670a9fa9459Szrj 		  if (s == NULL)
2671a9fa9459Szrj 		    s = sec;
2672a9fa9459Szrj 
2673a9fa9459Szrj 		  /* Beware of type punned pointers vs strict aliasing
2674a9fa9459Szrj 		     rules.  */
2675a9fa9459Szrj 		  vpp = &(elf_section_data (s)->local_dynrel);
2676a9fa9459Szrj 		  head = (struct elf_dyn_relocs **)vpp;
2677a9fa9459Szrj 		}
2678a9fa9459Szrj 
2679a9fa9459Szrj 	      p = *head;
2680a9fa9459Szrj 	      if (p == NULL || p->sec != sec)
2681a9fa9459Szrj 		{
2682a9fa9459Szrj 		  bfd_size_type amt = sizeof *p;
2683a9fa9459Szrj 
2684a9fa9459Szrj 		  p = ((struct elf_dyn_relocs *)
2685a9fa9459Szrj 		       bfd_alloc (htab->elf.dynobj, amt));
2686a9fa9459Szrj 		  if (p == NULL)
2687a9fa9459Szrj 		    goto error_return;
2688a9fa9459Szrj 		  p->next = *head;
2689a9fa9459Szrj 		  *head = p;
2690a9fa9459Szrj 		  p->sec = sec;
2691a9fa9459Szrj 		  p->count = 0;
2692a9fa9459Szrj 		  p->pc_count = 0;
2693a9fa9459Szrj 		}
2694a9fa9459Szrj 
2695a9fa9459Szrj 	      p->count += 1;
2696a9fa9459Szrj 	      /* Count size relocation as PC-relative relocation.  */
2697a9fa9459Szrj 	      if (IS_X86_64_PCREL_TYPE (r_type) || size_reloc)
2698a9fa9459Szrj 		p->pc_count += 1;
2699a9fa9459Szrj 	    }
2700a9fa9459Szrj 	  break;
2701a9fa9459Szrj 
2702a9fa9459Szrj 	  /* This relocation describes the C++ object vtable hierarchy.
2703a9fa9459Szrj 	     Reconstruct it for later use during GC.  */
2704a9fa9459Szrj 	case R_X86_64_GNU_VTINHERIT:
2705a9fa9459Szrj 	  if (!bfd_elf_gc_record_vtinherit (abfd, sec, h, rel->r_offset))
2706a9fa9459Szrj 	    goto error_return;
2707a9fa9459Szrj 	  break;
2708a9fa9459Szrj 
2709a9fa9459Szrj 	  /* This relocation describes which C++ vtable entries are actually
2710a9fa9459Szrj 	     used.  Record for later use during GC.  */
2711a9fa9459Szrj 	case R_X86_64_GNU_VTENTRY:
2712a9fa9459Szrj 	  BFD_ASSERT (h != NULL);
2713a9fa9459Szrj 	  if (h != NULL
2714a9fa9459Szrj 	      && !bfd_elf_gc_record_vtentry (abfd, sec, h, rel->r_addend))
2715a9fa9459Szrj 	    goto error_return;
2716a9fa9459Szrj 	  break;
2717a9fa9459Szrj 
2718a9fa9459Szrj 	default:
2719a9fa9459Szrj 	  break;
2720a9fa9459Szrj 	}
2721a9fa9459Szrj 
2722a9fa9459Szrj       if (use_plt_got
2723a9fa9459Szrj 	  && h != NULL
2724a9fa9459Szrj 	  && h->plt.refcount > 0
2725a9fa9459Szrj 	  && (((info->flags & DF_BIND_NOW) && !h->pointer_equality_needed)
2726a9fa9459Szrj 	      || h->got.refcount > 0)
2727a9fa9459Szrj 	  && htab->plt_got == NULL)
2728a9fa9459Szrj 	{
2729a9fa9459Szrj 	  /* Create the GOT procedure linkage table.  */
2730a9fa9459Szrj 	  unsigned int plt_got_align;
2731a9fa9459Szrj 	  const struct elf_backend_data *bed;
2732a9fa9459Szrj 
2733a9fa9459Szrj 	  bed = get_elf_backend_data (info->output_bfd);
2734a9fa9459Szrj 	  BFD_ASSERT (sizeof (elf_x86_64_legacy_plt2_entry) == 8
2735a9fa9459Szrj 		      && (sizeof (elf_x86_64_bnd_plt2_entry)
2736a9fa9459Szrj 			  == sizeof (elf_x86_64_legacy_plt2_entry)));
2737a9fa9459Szrj 	  plt_got_align = 3;
2738a9fa9459Szrj 
2739a9fa9459Szrj 	  if (htab->elf.dynobj == NULL)
2740a9fa9459Szrj 	    htab->elf.dynobj = abfd;
2741a9fa9459Szrj 	  htab->plt_got
2742a9fa9459Szrj 	    = bfd_make_section_anyway_with_flags (htab->elf.dynobj,
2743a9fa9459Szrj 						  ".plt.got",
2744a9fa9459Szrj 						  (bed->dynamic_sec_flags
2745a9fa9459Szrj 						   | SEC_ALLOC
2746a9fa9459Szrj 						   | SEC_CODE
2747a9fa9459Szrj 						   | SEC_LOAD
2748a9fa9459Szrj 						   | SEC_READONLY));
2749a9fa9459Szrj 	  if (htab->plt_got == NULL
2750a9fa9459Szrj 	      || !bfd_set_section_alignment (htab->elf.dynobj,
2751a9fa9459Szrj 					     htab->plt_got,
2752a9fa9459Szrj 					     plt_got_align))
2753a9fa9459Szrj 	    goto error_return;
2754a9fa9459Szrj 	}
2755a9fa9459Szrj 
2756a9fa9459Szrj       if ((r_type == R_X86_64_GOTPCREL
2757a9fa9459Szrj 	   || r_type == R_X86_64_GOTPCRELX
2758a9fa9459Szrj 	   || r_type == R_X86_64_REX_GOTPCRELX)
2759a9fa9459Szrj 	  && (h == NULL || h->type != STT_GNU_IFUNC))
2760a9fa9459Szrj 	sec->need_convert_load = 1;
2761a9fa9459Szrj     }
2762a9fa9459Szrj 
2763a9fa9459Szrj   if (elf_section_data (sec)->this_hdr.contents != contents)
2764a9fa9459Szrj     {
2765a9fa9459Szrj       if (!info->keep_memory)
2766a9fa9459Szrj 	free (contents);
2767a9fa9459Szrj       else
2768a9fa9459Szrj 	{
2769a9fa9459Szrj 	  /* Cache the section contents for elf_link_input_bfd.  */
2770a9fa9459Szrj 	  elf_section_data (sec)->this_hdr.contents = contents;
2771a9fa9459Szrj 	}
2772a9fa9459Szrj     }
2773a9fa9459Szrj 
2774a9fa9459Szrj   return TRUE;
2775a9fa9459Szrj 
2776a9fa9459Szrj error_return:
2777a9fa9459Szrj   if (elf_section_data (sec)->this_hdr.contents != contents)
2778a9fa9459Szrj     free (contents);
2779a9fa9459Szrj   sec->check_relocs_failed = 1;
2780a9fa9459Szrj   return FALSE;
2781a9fa9459Szrj }
2782a9fa9459Szrj 
2783a9fa9459Szrj /* Return the section that should be marked against GC for a given
2784a9fa9459Szrj    relocation.	*/
2785a9fa9459Szrj 
2786a9fa9459Szrj static asection *
elf_x86_64_gc_mark_hook(asection * sec,struct bfd_link_info * info,Elf_Internal_Rela * rel,struct elf_link_hash_entry * h,Elf_Internal_Sym * sym)2787a9fa9459Szrj elf_x86_64_gc_mark_hook (asection *sec,
2788a9fa9459Szrj 			 struct bfd_link_info *info,
2789a9fa9459Szrj 			 Elf_Internal_Rela *rel,
2790a9fa9459Szrj 			 struct elf_link_hash_entry *h,
2791a9fa9459Szrj 			 Elf_Internal_Sym *sym)
2792a9fa9459Szrj {
2793a9fa9459Szrj   if (h != NULL)
2794a9fa9459Szrj     switch (ELF32_R_TYPE (rel->r_info))
2795a9fa9459Szrj       {
2796a9fa9459Szrj       case R_X86_64_GNU_VTINHERIT:
2797a9fa9459Szrj       case R_X86_64_GNU_VTENTRY:
2798a9fa9459Szrj 	return NULL;
2799a9fa9459Szrj       }
2800a9fa9459Szrj 
2801a9fa9459Szrj   return _bfd_elf_gc_mark_hook (sec, info, rel, h, sym);
2802a9fa9459Szrj }
2803a9fa9459Szrj 
2804a9fa9459Szrj /* Remove undefined weak symbol from the dynamic symbol table if it
2805a9fa9459Szrj    is resolved to 0.   */
2806a9fa9459Szrj 
2807a9fa9459Szrj static bfd_boolean
elf_x86_64_fixup_symbol(struct bfd_link_info * info,struct elf_link_hash_entry * h)2808a9fa9459Szrj elf_x86_64_fixup_symbol (struct bfd_link_info *info,
2809a9fa9459Szrj 		       struct elf_link_hash_entry *h)
2810a9fa9459Szrj {
2811a9fa9459Szrj   if (h->dynindx != -1
2812a9fa9459Szrj       && UNDEFINED_WEAK_RESOLVED_TO_ZERO (info,
2813a9fa9459Szrj 					  elf_x86_64_hash_entry (h)->has_got_reloc,
2814a9fa9459Szrj 					  elf_x86_64_hash_entry (h)))
2815a9fa9459Szrj     {
2816a9fa9459Szrj       h->dynindx = -1;
2817a9fa9459Szrj       _bfd_elf_strtab_delref (elf_hash_table (info)->dynstr,
2818a9fa9459Szrj 			      h->dynstr_index);
2819a9fa9459Szrj     }
2820a9fa9459Szrj   return TRUE;
2821a9fa9459Szrj }
2822a9fa9459Szrj 
2823a9fa9459Szrj /* Adjust a symbol defined by a dynamic object and referenced by a
2824a9fa9459Szrj    regular object.  The current definition is in some section of the
2825a9fa9459Szrj    dynamic object, but we're not including those sections.  We have to
2826a9fa9459Szrj    change the definition to something the rest of the link can
2827a9fa9459Szrj    understand.	*/
2828a9fa9459Szrj 
2829a9fa9459Szrj static bfd_boolean
elf_x86_64_adjust_dynamic_symbol(struct bfd_link_info * info,struct elf_link_hash_entry * h)2830a9fa9459Szrj elf_x86_64_adjust_dynamic_symbol (struct bfd_link_info *info,
2831a9fa9459Szrj 				  struct elf_link_hash_entry *h)
2832a9fa9459Szrj {
2833a9fa9459Szrj   struct elf_x86_64_link_hash_table *htab;
2834a9fa9459Szrj   asection *s;
2835a9fa9459Szrj   struct elf_x86_64_link_hash_entry *eh;
2836a9fa9459Szrj   struct elf_dyn_relocs *p;
2837a9fa9459Szrj 
2838a9fa9459Szrj   /* STT_GNU_IFUNC symbol must go through PLT. */
2839a9fa9459Szrj   if (h->type == STT_GNU_IFUNC)
2840a9fa9459Szrj     {
2841a9fa9459Szrj       /* All local STT_GNU_IFUNC references must be treate as local
2842a9fa9459Szrj 	 calls via local PLT.  */
2843a9fa9459Szrj       if (h->ref_regular
2844a9fa9459Szrj 	  && SYMBOL_CALLS_LOCAL (info, h))
2845a9fa9459Szrj 	{
2846a9fa9459Szrj 	  bfd_size_type pc_count = 0, count = 0;
2847a9fa9459Szrj 	  struct elf_dyn_relocs **pp;
2848a9fa9459Szrj 
2849a9fa9459Szrj 	  eh = (struct elf_x86_64_link_hash_entry *) h;
2850a9fa9459Szrj 	  for (pp = &eh->dyn_relocs; (p = *pp) != NULL; )
2851a9fa9459Szrj 	    {
2852a9fa9459Szrj 	      pc_count += p->pc_count;
2853a9fa9459Szrj 	      p->count -= p->pc_count;
2854a9fa9459Szrj 	      p->pc_count = 0;
2855a9fa9459Szrj 	      count += p->count;
2856a9fa9459Szrj 	      if (p->count == 0)
2857a9fa9459Szrj 		*pp = p->next;
2858a9fa9459Szrj 	      else
2859a9fa9459Szrj 		pp = &p->next;
2860a9fa9459Szrj 	    }
2861a9fa9459Szrj 
2862a9fa9459Szrj 	  if (pc_count || count)
2863a9fa9459Szrj 	    {
2864a9fa9459Szrj 	      h->non_got_ref = 1;
2865a9fa9459Szrj 	      if (pc_count)
2866a9fa9459Szrj 		{
2867a9fa9459Szrj 		  /* Increment PLT reference count only for PC-relative
2868a9fa9459Szrj 		     references.  */
2869a9fa9459Szrj 		  h->needs_plt = 1;
2870a9fa9459Szrj 		  if (h->plt.refcount <= 0)
2871a9fa9459Szrj 		    h->plt.refcount = 1;
2872a9fa9459Szrj 		  else
2873a9fa9459Szrj 		    h->plt.refcount += 1;
2874a9fa9459Szrj 		}
2875a9fa9459Szrj 	    }
2876a9fa9459Szrj 	}
2877a9fa9459Szrj 
2878a9fa9459Szrj       if (h->plt.refcount <= 0)
2879a9fa9459Szrj 	{
2880a9fa9459Szrj 	  h->plt.offset = (bfd_vma) -1;
2881a9fa9459Szrj 	  h->needs_plt = 0;
2882a9fa9459Szrj 	}
2883a9fa9459Szrj       return TRUE;
2884a9fa9459Szrj     }
2885a9fa9459Szrj 
2886a9fa9459Szrj   /* If this is a function, put it in the procedure linkage table.  We
2887a9fa9459Szrj      will fill in the contents of the procedure linkage table later,
2888a9fa9459Szrj      when we know the address of the .got section.  */
2889a9fa9459Szrj   if (h->type == STT_FUNC
2890a9fa9459Szrj       || h->needs_plt)
2891a9fa9459Szrj     {
2892a9fa9459Szrj       if (h->plt.refcount <= 0
2893a9fa9459Szrj 	  || SYMBOL_CALLS_LOCAL (info, h)
2894a9fa9459Szrj 	  || (ELF_ST_VISIBILITY (h->other) != STV_DEFAULT
2895a9fa9459Szrj 	      && h->root.type == bfd_link_hash_undefweak))
2896a9fa9459Szrj 	{
2897a9fa9459Szrj 	  /* This case can occur if we saw a PLT32 reloc in an input
2898a9fa9459Szrj 	     file, but the symbol was never referred to by a dynamic
2899a9fa9459Szrj 	     object, or if all references were garbage collected.  In
2900a9fa9459Szrj 	     such a case, we don't actually need to build a procedure
2901a9fa9459Szrj 	     linkage table, and we can just do a PC32 reloc instead.  */
2902a9fa9459Szrj 	  h->plt.offset = (bfd_vma) -1;
2903a9fa9459Szrj 	  h->needs_plt = 0;
2904a9fa9459Szrj 	}
2905a9fa9459Szrj 
2906a9fa9459Szrj       return TRUE;
2907a9fa9459Szrj     }
2908a9fa9459Szrj   else
2909a9fa9459Szrj     /* It's possible that we incorrectly decided a .plt reloc was
2910a9fa9459Szrj        needed for an R_X86_64_PC32 reloc to a non-function sym in
2911a9fa9459Szrj        check_relocs.  We can't decide accurately between function and
2912a9fa9459Szrj        non-function syms in check-relocs;  Objects loaded later in
2913a9fa9459Szrj        the link may change h->type.  So fix it now.  */
2914a9fa9459Szrj     h->plt.offset = (bfd_vma) -1;
2915a9fa9459Szrj 
2916a9fa9459Szrj   /* If this is a weak symbol, and there is a real definition, the
2917a9fa9459Szrj      processor independent code will have arranged for us to see the
2918a9fa9459Szrj      real definition first, and we can just use the same value.	 */
2919a9fa9459Szrj   if (h->u.weakdef != NULL)
2920a9fa9459Szrj     {
2921a9fa9459Szrj       BFD_ASSERT (h->u.weakdef->root.type == bfd_link_hash_defined
2922a9fa9459Szrj 		  || h->u.weakdef->root.type == bfd_link_hash_defweak);
2923a9fa9459Szrj       h->root.u.def.section = h->u.weakdef->root.u.def.section;
2924a9fa9459Szrj       h->root.u.def.value = h->u.weakdef->root.u.def.value;
2925a9fa9459Szrj       if (ELIMINATE_COPY_RELOCS || info->nocopyreloc)
2926a9fa9459Szrj 	{
2927a9fa9459Szrj 	  eh = (struct elf_x86_64_link_hash_entry *) h;
2928a9fa9459Szrj 	  h->non_got_ref = h->u.weakdef->non_got_ref;
2929a9fa9459Szrj 	  eh->needs_copy = h->u.weakdef->needs_copy;
2930a9fa9459Szrj 	}
2931a9fa9459Szrj       return TRUE;
2932a9fa9459Szrj     }
2933a9fa9459Szrj 
2934a9fa9459Szrj   /* This is a reference to a symbol defined by a dynamic object which
2935a9fa9459Szrj      is not a function.	 */
2936a9fa9459Szrj 
2937a9fa9459Szrj   /* If we are creating a shared library, we must presume that the
2938a9fa9459Szrj      only references to the symbol are via the global offset table.
2939a9fa9459Szrj      For such cases we need not do anything here; the relocations will
2940a9fa9459Szrj      be handled correctly by relocate_section.	*/
2941a9fa9459Szrj   if (!bfd_link_executable (info))
2942a9fa9459Szrj     return TRUE;
2943a9fa9459Szrj 
2944a9fa9459Szrj   /* If there are no references to this symbol that do not use the
2945a9fa9459Szrj      GOT, we don't need to generate a copy reloc.  */
2946a9fa9459Szrj   if (!h->non_got_ref)
2947a9fa9459Szrj     return TRUE;
2948a9fa9459Szrj 
2949a9fa9459Szrj   /* If -z nocopyreloc was given, we won't generate them either.  */
2950a9fa9459Szrj   if (info->nocopyreloc)
2951a9fa9459Szrj     {
2952a9fa9459Szrj       h->non_got_ref = 0;
2953a9fa9459Szrj       return TRUE;
2954a9fa9459Szrj     }
2955a9fa9459Szrj 
2956a9fa9459Szrj   if (ELIMINATE_COPY_RELOCS)
2957a9fa9459Szrj     {
2958a9fa9459Szrj       eh = (struct elf_x86_64_link_hash_entry *) h;
2959a9fa9459Szrj       for (p = eh->dyn_relocs; p != NULL; p = p->next)
2960a9fa9459Szrj 	{
2961a9fa9459Szrj 	  s = p->sec->output_section;
2962a9fa9459Szrj 	  if (s != NULL && (s->flags & SEC_READONLY) != 0)
2963a9fa9459Szrj 	    break;
2964a9fa9459Szrj 	}
2965a9fa9459Szrj 
2966a9fa9459Szrj       /* If we didn't find any dynamic relocs in read-only sections, then
2967a9fa9459Szrj 	 we'll be keeping the dynamic relocs and avoiding the copy reloc.  */
2968a9fa9459Szrj       if (p == NULL)
2969a9fa9459Szrj 	{
2970a9fa9459Szrj 	  h->non_got_ref = 0;
2971a9fa9459Szrj 	  return TRUE;
2972a9fa9459Szrj 	}
2973a9fa9459Szrj     }
2974a9fa9459Szrj 
2975a9fa9459Szrj   /* We must allocate the symbol in our .dynbss section, which will
2976a9fa9459Szrj      become part of the .bss section of the executable.	 There will be
2977a9fa9459Szrj      an entry for this symbol in the .dynsym section.  The dynamic
2978a9fa9459Szrj      object will contain position independent code, so all references
2979a9fa9459Szrj      from the dynamic object to this symbol will go through the global
2980a9fa9459Szrj      offset table.  The dynamic linker will use the .dynsym entry to
2981a9fa9459Szrj      determine the address it must put in the global offset table, so
2982a9fa9459Szrj      both the dynamic object and the regular object will refer to the
2983a9fa9459Szrj      same memory location for the variable.  */
2984a9fa9459Szrj 
2985a9fa9459Szrj   htab = elf_x86_64_hash_table (info);
2986a9fa9459Szrj   if (htab == NULL)
2987a9fa9459Szrj     return FALSE;
2988a9fa9459Szrj 
2989a9fa9459Szrj   /* We must generate a R_X86_64_COPY reloc to tell the dynamic linker
2990a9fa9459Szrj      to copy the initial value out of the dynamic object and into the
2991a9fa9459Szrj      runtime process image.  */
2992a9fa9459Szrj   if ((h->root.u.def.section->flags & SEC_ALLOC) != 0 && h->size != 0)
2993a9fa9459Szrj     {
2994a9fa9459Szrj       const struct elf_backend_data *bed;
2995a9fa9459Szrj       bed = get_elf_backend_data (info->output_bfd);
2996a9fa9459Szrj       htab->srelbss->size += bed->s->sizeof_rela;
2997a9fa9459Szrj       h->needs_copy = 1;
2998a9fa9459Szrj     }
2999a9fa9459Szrj 
3000a9fa9459Szrj   s = htab->sdynbss;
3001a9fa9459Szrj 
3002a9fa9459Szrj   return _bfd_elf_adjust_dynamic_copy (info, h, s);
3003a9fa9459Szrj }
3004a9fa9459Szrj 
3005a9fa9459Szrj /* Allocate space in .plt, .got and associated reloc sections for
3006a9fa9459Szrj    dynamic relocs.  */
3007a9fa9459Szrj 
3008a9fa9459Szrj static bfd_boolean
elf_x86_64_allocate_dynrelocs(struct elf_link_hash_entry * h,void * inf)3009a9fa9459Szrj elf_x86_64_allocate_dynrelocs (struct elf_link_hash_entry *h, void * inf)
3010a9fa9459Szrj {
3011a9fa9459Szrj   struct bfd_link_info *info;
3012a9fa9459Szrj   struct elf_x86_64_link_hash_table *htab;
3013a9fa9459Szrj   struct elf_x86_64_link_hash_entry *eh;
3014a9fa9459Szrj   struct elf_dyn_relocs *p;
3015a9fa9459Szrj   const struct elf_backend_data *bed;
3016a9fa9459Szrj   unsigned int plt_entry_size;
3017a9fa9459Szrj   bfd_boolean resolved_to_zero;
3018a9fa9459Szrj 
3019a9fa9459Szrj   if (h->root.type == bfd_link_hash_indirect)
3020a9fa9459Szrj     return TRUE;
3021a9fa9459Szrj 
3022a9fa9459Szrj   eh = (struct elf_x86_64_link_hash_entry *) h;
3023a9fa9459Szrj 
3024a9fa9459Szrj   info = (struct bfd_link_info *) inf;
3025a9fa9459Szrj   htab = elf_x86_64_hash_table (info);
3026a9fa9459Szrj   if (htab == NULL)
3027a9fa9459Szrj     return FALSE;
3028a9fa9459Szrj   bed = get_elf_backend_data (info->output_bfd);
3029a9fa9459Szrj   plt_entry_size = GET_PLT_ENTRY_SIZE (info->output_bfd);
3030a9fa9459Szrj 
3031a9fa9459Szrj   resolved_to_zero = UNDEFINED_WEAK_RESOLVED_TO_ZERO (info,
3032a9fa9459Szrj 						      eh->has_got_reloc,
3033a9fa9459Szrj 						      eh);
3034a9fa9459Szrj 
3035a9fa9459Szrj   /* We can't use the GOT PLT if pointer equality is needed since
3036a9fa9459Szrj      finish_dynamic_symbol won't clear symbol value and the dynamic
3037a9fa9459Szrj      linker won't update the GOT slot.  We will get into an infinite
3038a9fa9459Szrj      loop at run-time.  */
3039a9fa9459Szrj   if (htab->plt_got != NULL
3040a9fa9459Szrj       && h->type != STT_GNU_IFUNC
3041a9fa9459Szrj       && !h->pointer_equality_needed
3042a9fa9459Szrj       && h->plt.refcount > 0
3043a9fa9459Szrj       && h->got.refcount > 0)
3044a9fa9459Szrj     {
3045a9fa9459Szrj       /* Don't use the regular PLT if there are both GOT and GOTPLT
3046a9fa9459Szrj          reloctions.  */
3047a9fa9459Szrj       h->plt.offset = (bfd_vma) -1;
3048a9fa9459Szrj 
3049a9fa9459Szrj       /* Use the GOT PLT.  */
3050a9fa9459Szrj       eh->plt_got.refcount = 1;
3051a9fa9459Szrj     }
3052a9fa9459Szrj 
3053a9fa9459Szrj   /* Clear the reference count of function pointer relocations if
3054a9fa9459Szrj      symbol isn't a normal function.  */
3055a9fa9459Szrj   if (h->type != STT_FUNC)
3056a9fa9459Szrj     eh->func_pointer_refcount = 0;
3057a9fa9459Szrj 
3058a9fa9459Szrj   /* Since STT_GNU_IFUNC symbol must go through PLT, we handle it
3059a9fa9459Szrj      here if it is defined and referenced in a non-shared object.  */
3060a9fa9459Szrj   if (h->type == STT_GNU_IFUNC
3061a9fa9459Szrj       && h->def_regular)
3062a9fa9459Szrj     {
3063a9fa9459Szrj       if (_bfd_elf_allocate_ifunc_dyn_relocs (info, h,
3064a9fa9459Szrj 					      &eh->dyn_relocs,
3065a9fa9459Szrj 					      &htab->readonly_dynrelocs_against_ifunc,
3066a9fa9459Szrj 					      plt_entry_size,
3067a9fa9459Szrj 					      plt_entry_size,
3068a9fa9459Szrj 					      GOT_ENTRY_SIZE, TRUE))
3069a9fa9459Szrj 	{
3070a9fa9459Szrj 	  asection *s = htab->plt_bnd;
3071a9fa9459Szrj 	  if (h->plt.offset != (bfd_vma) -1 && s != NULL)
3072a9fa9459Szrj 	    {
3073a9fa9459Szrj 	      /* Use the .plt.bnd section if it is created.  */
3074a9fa9459Szrj 	      eh->plt_bnd.offset = s->size;
3075a9fa9459Szrj 
3076a9fa9459Szrj 	      /* Make room for this entry in the .plt.bnd section.  */
3077a9fa9459Szrj 	      s->size += sizeof (elf_x86_64_legacy_plt2_entry);
3078a9fa9459Szrj 	    }
3079a9fa9459Szrj 
3080a9fa9459Szrj 	  return TRUE;
3081a9fa9459Szrj 	}
3082a9fa9459Szrj       else
3083a9fa9459Szrj 	return FALSE;
3084a9fa9459Szrj     }
3085a9fa9459Szrj   /* Don't create the PLT entry if there are only function pointer
3086a9fa9459Szrj      relocations which can be resolved at run-time.  */
3087a9fa9459Szrj   else if (htab->elf.dynamic_sections_created
3088a9fa9459Szrj 	   && (h->plt.refcount > eh->func_pointer_refcount
3089a9fa9459Szrj 	       || eh->plt_got.refcount > 0))
3090a9fa9459Szrj     {
3091a9fa9459Szrj       bfd_boolean use_plt_got;
3092a9fa9459Szrj 
3093a9fa9459Szrj       /* Clear the reference count of function pointer relocations
3094a9fa9459Szrj 	 if PLT is used.  */
3095a9fa9459Szrj       eh->func_pointer_refcount = 0;
3096a9fa9459Szrj 
3097a9fa9459Szrj       if ((info->flags & DF_BIND_NOW) && !h->pointer_equality_needed)
3098a9fa9459Szrj 	{
3099a9fa9459Szrj 	  /* Don't use the regular PLT for DF_BIND_NOW. */
3100a9fa9459Szrj 	  h->plt.offset = (bfd_vma) -1;
3101a9fa9459Szrj 
3102a9fa9459Szrj 	  /* Use the GOT PLT.  */
3103a9fa9459Szrj 	  h->got.refcount = 1;
3104a9fa9459Szrj 	  eh->plt_got.refcount = 1;
3105a9fa9459Szrj 	}
3106a9fa9459Szrj 
3107a9fa9459Szrj       use_plt_got = eh->plt_got.refcount > 0;
3108a9fa9459Szrj 
3109a9fa9459Szrj       /* Make sure this symbol is output as a dynamic symbol.
3110a9fa9459Szrj 	 Undefined weak syms won't yet be marked as dynamic.  */
3111a9fa9459Szrj       if (h->dynindx == -1
3112a9fa9459Szrj 	  && !h->forced_local
3113a9fa9459Szrj 	  && !resolved_to_zero)
3114a9fa9459Szrj 	{
3115a9fa9459Szrj 	  if (! bfd_elf_link_record_dynamic_symbol (info, h))
3116a9fa9459Szrj 	    return FALSE;
3117a9fa9459Szrj 	}
3118a9fa9459Szrj 
3119a9fa9459Szrj       if (bfd_link_pic (info)
3120a9fa9459Szrj 	  || WILL_CALL_FINISH_DYNAMIC_SYMBOL (1, 0, h))
3121a9fa9459Szrj 	{
3122a9fa9459Szrj 	  asection *s = htab->elf.splt;
3123a9fa9459Szrj 	  asection *bnd_s = htab->plt_bnd;
3124a9fa9459Szrj 	  asection *got_s = htab->plt_got;
3125a9fa9459Szrj 
3126a9fa9459Szrj 	  /* If this is the first .plt entry, make room for the special
3127a9fa9459Szrj 	     first entry.  The .plt section is used by prelink to undo
3128a9fa9459Szrj 	     prelinking for dynamic relocations.  */
3129a9fa9459Szrj 	  if (s->size == 0)
3130a9fa9459Szrj 	    s->size = plt_entry_size;
3131a9fa9459Szrj 
3132a9fa9459Szrj 	  if (use_plt_got)
3133a9fa9459Szrj 	    eh->plt_got.offset = got_s->size;
3134a9fa9459Szrj 	  else
3135a9fa9459Szrj 	    {
3136a9fa9459Szrj 	      h->plt.offset = s->size;
3137a9fa9459Szrj 	      if (bnd_s)
3138a9fa9459Szrj 		eh->plt_bnd.offset = bnd_s->size;
3139a9fa9459Szrj 	    }
3140a9fa9459Szrj 
3141a9fa9459Szrj 	  /* If this symbol is not defined in a regular file, and we are
3142a9fa9459Szrj 	     not generating a shared library, then set the symbol to this
3143a9fa9459Szrj 	     location in the .plt.  This is required to make function
3144a9fa9459Szrj 	     pointers compare as equal between the normal executable and
3145a9fa9459Szrj 	     the shared library.  */
3146a9fa9459Szrj 	  if (! bfd_link_pic (info)
3147a9fa9459Szrj 	      && !h->def_regular)
3148a9fa9459Szrj 	    {
3149a9fa9459Szrj 	      if (use_plt_got)
3150a9fa9459Szrj 		{
3151a9fa9459Szrj 		  /* We need to make a call to the entry of the GOT PLT
3152a9fa9459Szrj 		     instead of regular PLT entry.  */
3153a9fa9459Szrj 		  h->root.u.def.section = got_s;
3154a9fa9459Szrj 		  h->root.u.def.value = eh->plt_got.offset;
3155a9fa9459Szrj 		}
3156a9fa9459Szrj 	      else
3157a9fa9459Szrj 		{
3158a9fa9459Szrj 		  if (bnd_s)
3159a9fa9459Szrj 		    {
3160a9fa9459Szrj 		      /* We need to make a call to the entry of the second
3161a9fa9459Szrj 			 PLT instead of regular PLT entry.  */
3162a9fa9459Szrj 		      h->root.u.def.section = bnd_s;
3163a9fa9459Szrj 		      h->root.u.def.value = eh->plt_bnd.offset;
3164a9fa9459Szrj 		    }
3165a9fa9459Szrj 		  else
3166a9fa9459Szrj 		    {
3167a9fa9459Szrj 		      h->root.u.def.section = s;
3168a9fa9459Szrj 		      h->root.u.def.value = h->plt.offset;
3169a9fa9459Szrj 		    }
3170a9fa9459Szrj 		}
3171a9fa9459Szrj 	    }
3172a9fa9459Szrj 
3173a9fa9459Szrj 	  /* Make room for this entry.  */
3174a9fa9459Szrj 	  if (use_plt_got)
3175a9fa9459Szrj 	    got_s->size += sizeof (elf_x86_64_legacy_plt2_entry);
3176a9fa9459Szrj 	  else
3177a9fa9459Szrj 	    {
3178a9fa9459Szrj 	      s->size += plt_entry_size;
3179a9fa9459Szrj 	      if (bnd_s)
3180a9fa9459Szrj 		bnd_s->size += sizeof (elf_x86_64_legacy_plt2_entry);
3181a9fa9459Szrj 
3182a9fa9459Szrj 	      /* We also need to make an entry in the .got.plt section,
3183a9fa9459Szrj 		 which will be placed in the .got section by the linker
3184a9fa9459Szrj 		 script.  */
3185a9fa9459Szrj 	      htab->elf.sgotplt->size += GOT_ENTRY_SIZE;
3186a9fa9459Szrj 
3187a9fa9459Szrj 	      /* There should be no PLT relocation against resolved
3188a9fa9459Szrj 		 undefined weak symbol in executable.  */
3189a9fa9459Szrj 	      if (!resolved_to_zero)
3190a9fa9459Szrj 		{
3191a9fa9459Szrj 		  /* We also need to make an entry in the .rela.plt
3192a9fa9459Szrj 		     section.  */
3193a9fa9459Szrj 		  htab->elf.srelplt->size += bed->s->sizeof_rela;
3194a9fa9459Szrj 		  htab->elf.srelplt->reloc_count++;
3195a9fa9459Szrj 		}
3196a9fa9459Szrj 	    }
3197a9fa9459Szrj 	}
3198a9fa9459Szrj       else
3199a9fa9459Szrj 	{
3200a9fa9459Szrj 	  eh->plt_got.offset = (bfd_vma) -1;
3201a9fa9459Szrj 	  h->plt.offset = (bfd_vma) -1;
3202a9fa9459Szrj 	  h->needs_plt = 0;
3203a9fa9459Szrj 	}
3204a9fa9459Szrj     }
3205a9fa9459Szrj   else
3206a9fa9459Szrj     {
3207a9fa9459Szrj       eh->plt_got.offset = (bfd_vma) -1;
3208a9fa9459Szrj       h->plt.offset = (bfd_vma) -1;
3209a9fa9459Szrj       h->needs_plt = 0;
3210a9fa9459Szrj     }
3211a9fa9459Szrj 
3212a9fa9459Szrj   eh->tlsdesc_got = (bfd_vma) -1;
3213a9fa9459Szrj 
3214a9fa9459Szrj   /* If R_X86_64_GOTTPOFF symbol is now local to the binary,
3215a9fa9459Szrj      make it a R_X86_64_TPOFF32 requiring no GOT entry.  */
3216a9fa9459Szrj   if (h->got.refcount > 0
3217a9fa9459Szrj       && bfd_link_executable (info)
3218a9fa9459Szrj       && h->dynindx == -1
3219a9fa9459Szrj       && elf_x86_64_hash_entry (h)->tls_type == GOT_TLS_IE)
3220a9fa9459Szrj     {
3221a9fa9459Szrj       h->got.offset = (bfd_vma) -1;
3222a9fa9459Szrj     }
3223a9fa9459Szrj   else if (h->got.refcount > 0)
3224a9fa9459Szrj     {
3225a9fa9459Szrj       asection *s;
3226a9fa9459Szrj       bfd_boolean dyn;
3227a9fa9459Szrj       int tls_type = elf_x86_64_hash_entry (h)->tls_type;
3228a9fa9459Szrj 
3229a9fa9459Szrj       /* Make sure this symbol is output as a dynamic symbol.
3230a9fa9459Szrj 	 Undefined weak syms won't yet be marked as dynamic.  */
3231a9fa9459Szrj       if (h->dynindx == -1
3232a9fa9459Szrj 	  && !h->forced_local
3233a9fa9459Szrj 	  && !resolved_to_zero)
3234a9fa9459Szrj 	{
3235a9fa9459Szrj 	  if (! bfd_elf_link_record_dynamic_symbol (info, h))
3236a9fa9459Szrj 	    return FALSE;
3237a9fa9459Szrj 	}
3238a9fa9459Szrj 
3239a9fa9459Szrj       if (GOT_TLS_GDESC_P (tls_type))
3240a9fa9459Szrj 	{
3241a9fa9459Szrj 	  eh->tlsdesc_got = htab->elf.sgotplt->size
3242a9fa9459Szrj 	    - elf_x86_64_compute_jump_table_size (htab);
3243a9fa9459Szrj 	  htab->elf.sgotplt->size += 2 * GOT_ENTRY_SIZE;
3244a9fa9459Szrj 	  h->got.offset = (bfd_vma) -2;
3245a9fa9459Szrj 	}
3246a9fa9459Szrj       if (! GOT_TLS_GDESC_P (tls_type)
3247a9fa9459Szrj 	  || GOT_TLS_GD_P (tls_type))
3248a9fa9459Szrj 	{
3249a9fa9459Szrj 	  s = htab->elf.sgot;
3250a9fa9459Szrj 	  h->got.offset = s->size;
3251a9fa9459Szrj 	  s->size += GOT_ENTRY_SIZE;
3252a9fa9459Szrj 	  if (GOT_TLS_GD_P (tls_type))
3253a9fa9459Szrj 	    s->size += GOT_ENTRY_SIZE;
3254a9fa9459Szrj 	}
3255a9fa9459Szrj       dyn = htab->elf.dynamic_sections_created;
3256a9fa9459Szrj       /* R_X86_64_TLSGD needs one dynamic relocation if local symbol
3257a9fa9459Szrj 	 and two if global.  R_X86_64_GOTTPOFF needs one dynamic
3258a9fa9459Szrj 	 relocation.  No dynamic relocation against resolved undefined
3259a9fa9459Szrj 	 weak symbol in executable.  */
3260a9fa9459Szrj       if ((GOT_TLS_GD_P (tls_type) && h->dynindx == -1)
3261a9fa9459Szrj 	  || tls_type == GOT_TLS_IE)
3262a9fa9459Szrj 	htab->elf.srelgot->size += bed->s->sizeof_rela;
3263a9fa9459Szrj       else if (GOT_TLS_GD_P (tls_type))
3264a9fa9459Szrj 	htab->elf.srelgot->size += 2 * bed->s->sizeof_rela;
3265a9fa9459Szrj       else if (! GOT_TLS_GDESC_P (tls_type)
3266a9fa9459Szrj 	       && ((ELF_ST_VISIBILITY (h->other) == STV_DEFAULT
3267a9fa9459Szrj 		    && !resolved_to_zero)
3268a9fa9459Szrj 		   || h->root.type != bfd_link_hash_undefweak)
3269a9fa9459Szrj 	       && (bfd_link_pic (info)
3270a9fa9459Szrj 		   || WILL_CALL_FINISH_DYNAMIC_SYMBOL (dyn, 0, h)))
3271a9fa9459Szrj 	htab->elf.srelgot->size += bed->s->sizeof_rela;
3272a9fa9459Szrj       if (GOT_TLS_GDESC_P (tls_type))
3273a9fa9459Szrj 	{
3274a9fa9459Szrj 	  htab->elf.srelplt->size += bed->s->sizeof_rela;
3275a9fa9459Szrj 	  htab->tlsdesc_plt = (bfd_vma) -1;
3276a9fa9459Szrj 	}
3277a9fa9459Szrj     }
3278a9fa9459Szrj   else
3279a9fa9459Szrj     h->got.offset = (bfd_vma) -1;
3280a9fa9459Szrj 
3281a9fa9459Szrj   if (eh->dyn_relocs == NULL)
3282a9fa9459Szrj     return TRUE;
3283a9fa9459Szrj 
3284a9fa9459Szrj   /* In the shared -Bsymbolic case, discard space allocated for
3285a9fa9459Szrj      dynamic pc-relative relocs against symbols which turn out to be
3286a9fa9459Szrj      defined in regular objects.  For the normal shared case, discard
3287a9fa9459Szrj      space for pc-relative relocs that have become local due to symbol
3288a9fa9459Szrj      visibility changes.  */
3289a9fa9459Szrj 
3290a9fa9459Szrj   if (bfd_link_pic (info))
3291a9fa9459Szrj     {
3292a9fa9459Szrj       /* Relocs that use pc_count are those that appear on a call
3293a9fa9459Szrj 	 insn, or certain REL relocs that can generated via assembly.
3294a9fa9459Szrj 	 We want calls to protected symbols to resolve directly to the
3295a9fa9459Szrj 	 function rather than going via the plt.  If people want
3296a9fa9459Szrj 	 function pointer comparisons to work as expected then they
3297a9fa9459Szrj 	 should avoid writing weird assembly.  */
3298a9fa9459Szrj       if (SYMBOL_CALLS_LOCAL (info, h))
3299a9fa9459Szrj 	{
3300a9fa9459Szrj 	  struct elf_dyn_relocs **pp;
3301a9fa9459Szrj 
3302a9fa9459Szrj 	  for (pp = &eh->dyn_relocs; (p = *pp) != NULL; )
3303a9fa9459Szrj 	    {
3304a9fa9459Szrj 	      p->count -= p->pc_count;
3305a9fa9459Szrj 	      p->pc_count = 0;
3306a9fa9459Szrj 	      if (p->count == 0)
3307a9fa9459Szrj 		*pp = p->next;
3308a9fa9459Szrj 	      else
3309a9fa9459Szrj 		pp = &p->next;
3310a9fa9459Szrj 	    }
3311a9fa9459Szrj 	}
3312a9fa9459Szrj 
3313a9fa9459Szrj       /* Also discard relocs on undefined weak syms with non-default
3314a9fa9459Szrj 	 visibility or in PIE.  */
3315a9fa9459Szrj       if (eh->dyn_relocs != NULL)
3316a9fa9459Szrj 	{
3317a9fa9459Szrj 	  if (h->root.type == bfd_link_hash_undefweak)
3318a9fa9459Szrj 	    {
3319a9fa9459Szrj 	      /* Undefined weak symbol is never bound locally in shared
3320a9fa9459Szrj 		 library.  */
3321a9fa9459Szrj 	      if (ELF_ST_VISIBILITY (h->other) != STV_DEFAULT
3322a9fa9459Szrj 		  || resolved_to_zero)
3323a9fa9459Szrj 		eh->dyn_relocs = NULL;
3324a9fa9459Szrj 	      else if (h->dynindx == -1
3325a9fa9459Szrj 		       && ! h->forced_local
3326a9fa9459Szrj 		       && ! bfd_elf_link_record_dynamic_symbol (info, h))
3327a9fa9459Szrj 		return FALSE;
3328a9fa9459Szrj 	    }
3329a9fa9459Szrj 	  /* For PIE, discard space for pc-relative relocs against
3330a9fa9459Szrj 	     symbols which turn out to need copy relocs.  */
3331a9fa9459Szrj 	  else if (bfd_link_executable (info)
3332a9fa9459Szrj 		   && (h->needs_copy || eh->needs_copy)
3333a9fa9459Szrj 		   && h->def_dynamic
3334a9fa9459Szrj 		   && !h->def_regular)
3335a9fa9459Szrj 	    {
3336a9fa9459Szrj 	      struct elf_dyn_relocs **pp;
3337a9fa9459Szrj 
3338a9fa9459Szrj 	      for (pp = &eh->dyn_relocs; (p = *pp) != NULL; )
3339a9fa9459Szrj 		{
3340a9fa9459Szrj 		  if (p->pc_count != 0)
3341a9fa9459Szrj 		    *pp = p->next;
3342a9fa9459Szrj 		  else
3343a9fa9459Szrj 		    pp = &p->next;
3344a9fa9459Szrj 		}
3345a9fa9459Szrj 	    }
3346a9fa9459Szrj 	}
3347a9fa9459Szrj     }
3348a9fa9459Szrj   else if (ELIMINATE_COPY_RELOCS)
3349a9fa9459Szrj     {
3350a9fa9459Szrj       /* For the non-shared case, discard space for relocs against
3351a9fa9459Szrj 	 symbols which turn out to need copy relocs or are not
3352a9fa9459Szrj 	 dynamic.  Keep dynamic relocations for run-time function
3353a9fa9459Szrj 	 pointer initialization.  */
3354a9fa9459Szrj 
3355a9fa9459Szrj       if ((!h->non_got_ref
3356a9fa9459Szrj 	   || eh->func_pointer_refcount > 0
3357a9fa9459Szrj 	   || (h->root.type == bfd_link_hash_undefweak
3358a9fa9459Szrj 	       && !resolved_to_zero))
3359a9fa9459Szrj 	  && ((h->def_dynamic
3360a9fa9459Szrj 	       && !h->def_regular)
3361a9fa9459Szrj 	      || (htab->elf.dynamic_sections_created
3362a9fa9459Szrj 		  && (h->root.type == bfd_link_hash_undefweak
3363a9fa9459Szrj 		      || h->root.type == bfd_link_hash_undefined))))
3364a9fa9459Szrj 	{
3365a9fa9459Szrj 	  /* Make sure this symbol is output as a dynamic symbol.
3366a9fa9459Szrj 	     Undefined weak syms won't yet be marked as dynamic.  */
3367a9fa9459Szrj 	  if (h->dynindx == -1
3368a9fa9459Szrj 	      && ! h->forced_local
3369a9fa9459Szrj 	      && ! resolved_to_zero
3370a9fa9459Szrj 	      && ! bfd_elf_link_record_dynamic_symbol (info, h))
3371a9fa9459Szrj 	    return FALSE;
3372a9fa9459Szrj 
3373a9fa9459Szrj 	  /* If that succeeded, we know we'll be keeping all the
3374a9fa9459Szrj 	     relocs.  */
3375a9fa9459Szrj 	  if (h->dynindx != -1)
3376a9fa9459Szrj 	    goto keep;
3377a9fa9459Szrj 	}
3378a9fa9459Szrj 
3379a9fa9459Szrj       eh->dyn_relocs = NULL;
3380a9fa9459Szrj       eh->func_pointer_refcount = 0;
3381a9fa9459Szrj 
3382a9fa9459Szrj     keep: ;
3383a9fa9459Szrj     }
3384a9fa9459Szrj 
3385a9fa9459Szrj   /* Finally, allocate space.  */
3386a9fa9459Szrj   for (p = eh->dyn_relocs; p != NULL; p = p->next)
3387a9fa9459Szrj     {
3388a9fa9459Szrj       asection * sreloc;
3389a9fa9459Szrj 
3390a9fa9459Szrj       sreloc = elf_section_data (p->sec)->sreloc;
3391a9fa9459Szrj 
3392a9fa9459Szrj       BFD_ASSERT (sreloc != NULL);
3393a9fa9459Szrj 
3394a9fa9459Szrj       sreloc->size += p->count * bed->s->sizeof_rela;
3395a9fa9459Szrj     }
3396a9fa9459Szrj 
3397a9fa9459Szrj   return TRUE;
3398a9fa9459Szrj }
3399a9fa9459Szrj 
3400a9fa9459Szrj /* Allocate space in .plt, .got and associated reloc sections for
3401a9fa9459Szrj    local dynamic relocs.  */
3402a9fa9459Szrj 
3403a9fa9459Szrj static bfd_boolean
elf_x86_64_allocate_local_dynrelocs(void ** slot,void * inf)3404a9fa9459Szrj elf_x86_64_allocate_local_dynrelocs (void **slot, void *inf)
3405a9fa9459Szrj {
3406a9fa9459Szrj   struct elf_link_hash_entry *h
3407a9fa9459Szrj     = (struct elf_link_hash_entry *) *slot;
3408a9fa9459Szrj 
3409a9fa9459Szrj   if (h->type != STT_GNU_IFUNC
3410a9fa9459Szrj       || !h->def_regular
3411a9fa9459Szrj       || !h->ref_regular
3412a9fa9459Szrj       || !h->forced_local
3413a9fa9459Szrj       || h->root.type != bfd_link_hash_defined)
3414a9fa9459Szrj     abort ();
3415a9fa9459Szrj 
3416a9fa9459Szrj   return elf_x86_64_allocate_dynrelocs (h, inf);
3417a9fa9459Szrj }
3418a9fa9459Szrj 
3419a9fa9459Szrj /* Find any dynamic relocs that apply to read-only sections.  */
3420a9fa9459Szrj 
3421a9fa9459Szrj static bfd_boolean
elf_x86_64_readonly_dynrelocs(struct elf_link_hash_entry * h,void * inf)3422a9fa9459Szrj elf_x86_64_readonly_dynrelocs (struct elf_link_hash_entry *h,
3423a9fa9459Szrj 			       void * inf)
3424a9fa9459Szrj {
3425a9fa9459Szrj   struct elf_x86_64_link_hash_entry *eh;
3426a9fa9459Szrj   struct elf_dyn_relocs *p;
3427a9fa9459Szrj 
3428a9fa9459Szrj   /* Skip local IFUNC symbols. */
3429a9fa9459Szrj   if (h->forced_local && h->type == STT_GNU_IFUNC)
3430a9fa9459Szrj     return TRUE;
3431a9fa9459Szrj 
3432a9fa9459Szrj   eh = (struct elf_x86_64_link_hash_entry *) h;
3433a9fa9459Szrj   for (p = eh->dyn_relocs; p != NULL; p = p->next)
3434a9fa9459Szrj     {
3435a9fa9459Szrj       asection *s = p->sec->output_section;
3436a9fa9459Szrj 
3437a9fa9459Szrj       if (s != NULL && (s->flags & SEC_READONLY) != 0)
3438a9fa9459Szrj 	{
3439a9fa9459Szrj 	  struct bfd_link_info *info = (struct bfd_link_info *) inf;
3440a9fa9459Szrj 
3441a9fa9459Szrj 	  info->flags |= DF_TEXTREL;
3442a9fa9459Szrj 
3443a9fa9459Szrj 	  if ((info->warn_shared_textrel && bfd_link_pic (info))
3444a9fa9459Szrj 	      || info->error_textrel)
3445a9fa9459Szrj 	    info->callbacks->einfo (_("%P: %B: warning: relocation against `%s' in readonly section `%A'\n"),
3446a9fa9459Szrj 				    p->sec->owner, h->root.root.string,
3447a9fa9459Szrj 				    p->sec);
3448a9fa9459Szrj 
3449a9fa9459Szrj 	  /* Not an error, just cut short the traversal.  */
3450a9fa9459Szrj 	  return FALSE;
3451a9fa9459Szrj 	}
3452a9fa9459Szrj     }
3453a9fa9459Szrj   return TRUE;
3454a9fa9459Szrj }
3455a9fa9459Szrj 
3456a9fa9459Szrj /* Convert load via the GOT slot to load immediate.  */
3457a9fa9459Szrj 
3458a9fa9459Szrj static bfd_boolean
elf_x86_64_convert_load(bfd * abfd,asection * sec,struct bfd_link_info * link_info)3459a9fa9459Szrj elf_x86_64_convert_load (bfd *abfd, asection *sec,
3460a9fa9459Szrj 			 struct bfd_link_info *link_info)
3461a9fa9459Szrj {
3462a9fa9459Szrj   Elf_Internal_Shdr *symtab_hdr;
3463a9fa9459Szrj   Elf_Internal_Rela *internal_relocs;
3464a9fa9459Szrj   Elf_Internal_Rela *irel, *irelend;
3465a9fa9459Szrj   bfd_byte *contents;
3466a9fa9459Szrj   struct elf_x86_64_link_hash_table *htab;
3467a9fa9459Szrj   bfd_boolean changed;
3468a9fa9459Szrj   bfd_signed_vma *local_got_refcounts;
3469a9fa9459Szrj 
3470a9fa9459Szrj   /* Don't even try to convert non-ELF outputs.  */
3471a9fa9459Szrj   if (!is_elf_hash_table (link_info->hash))
3472a9fa9459Szrj     return FALSE;
3473a9fa9459Szrj 
3474a9fa9459Szrj   /* Nothing to do if there is no need or no output.  */
3475a9fa9459Szrj   if ((sec->flags & (SEC_CODE | SEC_RELOC)) != (SEC_CODE | SEC_RELOC)
3476a9fa9459Szrj       || sec->need_convert_load == 0
3477a9fa9459Szrj       || bfd_is_abs_section (sec->output_section))
3478a9fa9459Szrj     return TRUE;
3479a9fa9459Szrj 
3480a9fa9459Szrj   symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
3481a9fa9459Szrj 
3482a9fa9459Szrj   /* Load the relocations for this section.  */
3483a9fa9459Szrj   internal_relocs = (_bfd_elf_link_read_relocs
3484a9fa9459Szrj 		     (abfd, sec, NULL, (Elf_Internal_Rela *) NULL,
3485a9fa9459Szrj 		      link_info->keep_memory));
3486a9fa9459Szrj   if (internal_relocs == NULL)
3487a9fa9459Szrj     return FALSE;
3488a9fa9459Szrj 
3489a9fa9459Szrj   changed = FALSE;
3490a9fa9459Szrj   htab = elf_x86_64_hash_table (link_info);
3491a9fa9459Szrj   local_got_refcounts = elf_local_got_refcounts (abfd);
3492a9fa9459Szrj 
3493a9fa9459Szrj   /* Get the section contents.  */
3494a9fa9459Szrj   if (elf_section_data (sec)->this_hdr.contents != NULL)
3495a9fa9459Szrj     contents = elf_section_data (sec)->this_hdr.contents;
3496a9fa9459Szrj   else
3497a9fa9459Szrj     {
3498a9fa9459Szrj       if (!bfd_malloc_and_get_section (abfd, sec, &contents))
3499a9fa9459Szrj 	goto error_return;
3500a9fa9459Szrj     }
3501a9fa9459Szrj 
3502a9fa9459Szrj   irelend = internal_relocs + sec->reloc_count;
3503a9fa9459Szrj   for (irel = internal_relocs; irel < irelend; irel++)
3504a9fa9459Szrj     {
3505a9fa9459Szrj       unsigned int r_type = ELF32_R_TYPE (irel->r_info);
3506a9fa9459Szrj       unsigned int r_symndx;
3507a9fa9459Szrj       struct elf_link_hash_entry *h;
3508a9fa9459Szrj       bfd_boolean converted;
3509a9fa9459Szrj 
3510a9fa9459Szrj       if (r_type != R_X86_64_GOTPCRELX
3511a9fa9459Szrj 	  && r_type != R_X86_64_REX_GOTPCRELX
3512a9fa9459Szrj 	  && r_type != R_X86_64_GOTPCREL)
3513a9fa9459Szrj 	continue;
3514a9fa9459Szrj 
3515a9fa9459Szrj       r_symndx = htab->r_sym (irel->r_info);
3516a9fa9459Szrj       if (r_symndx < symtab_hdr->sh_info)
3517a9fa9459Szrj 	h = elf_x86_64_get_local_sym_hash (htab, sec->owner,
3518a9fa9459Szrj 					   (const Elf_Internal_Rela *) irel,
3519a9fa9459Szrj 					   FALSE);
3520a9fa9459Szrj       else
3521a9fa9459Szrj 	{
3522a9fa9459Szrj 	  h = elf_sym_hashes (abfd)[r_symndx - symtab_hdr->sh_info];
3523a9fa9459Szrj 	  while (h->root.type == bfd_link_hash_indirect
3524a9fa9459Szrj 		 || h->root.type == bfd_link_hash_warning)
3525a9fa9459Szrj 	    h = (struct elf_link_hash_entry *) h->root.u.i.link;
3526a9fa9459Szrj 	}
3527a9fa9459Szrj 
3528a9fa9459Szrj       /* STT_GNU_IFUNC must keep GOTPCREL relocations.  */
3529a9fa9459Szrj       if (h != NULL && h->type == STT_GNU_IFUNC)
3530a9fa9459Szrj 	continue;
3531a9fa9459Szrj 
3532a9fa9459Szrj       converted = FALSE;
3533a9fa9459Szrj       if (!elf_x86_64_convert_load_reloc (abfd, sec, contents, irel, h,
3534a9fa9459Szrj 					  &converted, link_info))
3535a9fa9459Szrj 	goto error_return;
3536a9fa9459Szrj 
3537a9fa9459Szrj       if (converted)
3538a9fa9459Szrj 	{
3539a9fa9459Szrj 	  changed = converted;
3540a9fa9459Szrj 	  if (h)
3541a9fa9459Szrj 	    {
3542a9fa9459Szrj 	      if (h->got.refcount > 0)
3543a9fa9459Szrj 		h->got.refcount -= 1;
3544a9fa9459Szrj 	    }
3545a9fa9459Szrj 	  else
3546a9fa9459Szrj 	    {
3547a9fa9459Szrj 	      if (local_got_refcounts != NULL
3548a9fa9459Szrj 		  && local_got_refcounts[r_symndx] > 0)
3549a9fa9459Szrj 		local_got_refcounts[r_symndx] -= 1;
3550a9fa9459Szrj 	    }
3551a9fa9459Szrj 	}
3552a9fa9459Szrj     }
3553a9fa9459Szrj 
3554a9fa9459Szrj   if (contents != NULL
3555a9fa9459Szrj       && elf_section_data (sec)->this_hdr.contents != contents)
3556a9fa9459Szrj     {
3557a9fa9459Szrj       if (!changed && !link_info->keep_memory)
3558a9fa9459Szrj 	free (contents);
3559a9fa9459Szrj       else
3560a9fa9459Szrj 	{
3561a9fa9459Szrj 	  /* Cache the section contents for elf_link_input_bfd.  */
3562a9fa9459Szrj 	  elf_section_data (sec)->this_hdr.contents = contents;
3563a9fa9459Szrj 	}
3564a9fa9459Szrj     }
3565a9fa9459Szrj 
3566a9fa9459Szrj   if (elf_section_data (sec)->relocs != internal_relocs)
3567a9fa9459Szrj     {
3568a9fa9459Szrj       if (!changed)
3569a9fa9459Szrj 	free (internal_relocs);
3570a9fa9459Szrj       else
3571a9fa9459Szrj 	elf_section_data (sec)->relocs = internal_relocs;
3572a9fa9459Szrj     }
3573a9fa9459Szrj 
3574a9fa9459Szrj   return TRUE;
3575a9fa9459Szrj 
3576a9fa9459Szrj  error_return:
3577a9fa9459Szrj   if (contents != NULL
3578a9fa9459Szrj       && elf_section_data (sec)->this_hdr.contents != contents)
3579a9fa9459Szrj     free (contents);
3580a9fa9459Szrj   if (internal_relocs != NULL
3581a9fa9459Szrj       && elf_section_data (sec)->relocs != internal_relocs)
3582a9fa9459Szrj     free (internal_relocs);
3583a9fa9459Szrj   return FALSE;
3584a9fa9459Szrj }
3585a9fa9459Szrj 
3586a9fa9459Szrj /* Set the sizes of the dynamic sections.  */
3587a9fa9459Szrj 
3588a9fa9459Szrj static bfd_boolean
elf_x86_64_size_dynamic_sections(bfd * output_bfd,struct bfd_link_info * info)3589a9fa9459Szrj elf_x86_64_size_dynamic_sections (bfd *output_bfd,
3590a9fa9459Szrj 				  struct bfd_link_info *info)
3591a9fa9459Szrj {
3592a9fa9459Szrj   struct elf_x86_64_link_hash_table *htab;
3593a9fa9459Szrj   bfd *dynobj;
3594a9fa9459Szrj   asection *s;
3595a9fa9459Szrj   bfd_boolean relocs;
3596a9fa9459Szrj   bfd *ibfd;
3597a9fa9459Szrj   const struct elf_backend_data *bed;
3598a9fa9459Szrj 
3599a9fa9459Szrj   htab = elf_x86_64_hash_table (info);
3600a9fa9459Szrj   if (htab == NULL)
3601a9fa9459Szrj     return FALSE;
3602a9fa9459Szrj   bed = get_elf_backend_data (output_bfd);
3603a9fa9459Szrj 
3604a9fa9459Szrj   dynobj = htab->elf.dynobj;
3605a9fa9459Szrj   if (dynobj == NULL)
3606a9fa9459Szrj     abort ();
3607a9fa9459Szrj 
3608a9fa9459Szrj   /* Set up .got offsets for local syms, and space for local dynamic
3609a9fa9459Szrj      relocs.  */
3610a9fa9459Szrj   for (ibfd = info->input_bfds; ibfd != NULL; ibfd = ibfd->link.next)
3611a9fa9459Szrj     {
3612a9fa9459Szrj       bfd_signed_vma *local_got;
3613a9fa9459Szrj       bfd_signed_vma *end_local_got;
3614a9fa9459Szrj       char *local_tls_type;
3615a9fa9459Szrj       bfd_vma *local_tlsdesc_gotent;
3616a9fa9459Szrj       bfd_size_type locsymcount;
3617a9fa9459Szrj       Elf_Internal_Shdr *symtab_hdr;
3618a9fa9459Szrj       asection *srel;
3619a9fa9459Szrj 
3620a9fa9459Szrj       if (! is_x86_64_elf (ibfd))
3621a9fa9459Szrj 	continue;
3622a9fa9459Szrj 
3623a9fa9459Szrj       for (s = ibfd->sections; s != NULL; s = s->next)
3624a9fa9459Szrj 	{
3625a9fa9459Szrj 	  struct elf_dyn_relocs *p;
3626a9fa9459Szrj 
3627a9fa9459Szrj 	  if (!elf_x86_64_convert_load (ibfd, s, info))
3628a9fa9459Szrj 	    return FALSE;
3629a9fa9459Szrj 
3630a9fa9459Szrj 	  for (p = (struct elf_dyn_relocs *)
3631a9fa9459Szrj 		    (elf_section_data (s)->local_dynrel);
3632a9fa9459Szrj 	       p != NULL;
3633a9fa9459Szrj 	       p = p->next)
3634a9fa9459Szrj 	    {
3635a9fa9459Szrj 	      if (!bfd_is_abs_section (p->sec)
3636a9fa9459Szrj 		  && bfd_is_abs_section (p->sec->output_section))
3637a9fa9459Szrj 		{
3638a9fa9459Szrj 		  /* Input section has been discarded, either because
3639a9fa9459Szrj 		     it is a copy of a linkonce section or due to
3640a9fa9459Szrj 		     linker script /DISCARD/, so we'll be discarding
3641a9fa9459Szrj 		     the relocs too.  */
3642a9fa9459Szrj 		}
3643a9fa9459Szrj 	      else if (p->count != 0)
3644a9fa9459Szrj 		{
3645a9fa9459Szrj 		  srel = elf_section_data (p->sec)->sreloc;
3646a9fa9459Szrj 		  srel->size += p->count * bed->s->sizeof_rela;
3647a9fa9459Szrj 		  if ((p->sec->output_section->flags & SEC_READONLY) != 0
3648a9fa9459Szrj 		      && (info->flags & DF_TEXTREL) == 0)
3649a9fa9459Szrj 		    {
3650a9fa9459Szrj 		      info->flags |= DF_TEXTREL;
3651a9fa9459Szrj 		      if ((info->warn_shared_textrel && bfd_link_pic (info))
3652a9fa9459Szrj 			  || info->error_textrel)
3653a9fa9459Szrj 			info->callbacks->einfo (_("%P: %B: warning: relocation in readonly section `%A'\n"),
3654a9fa9459Szrj 						p->sec->owner, p->sec);
3655a9fa9459Szrj 		    }
3656a9fa9459Szrj 		}
3657a9fa9459Szrj 	    }
3658a9fa9459Szrj 	}
3659a9fa9459Szrj 
3660a9fa9459Szrj       local_got = elf_local_got_refcounts (ibfd);
3661a9fa9459Szrj       if (!local_got)
3662a9fa9459Szrj 	continue;
3663a9fa9459Szrj 
3664a9fa9459Szrj       symtab_hdr = &elf_symtab_hdr (ibfd);
3665a9fa9459Szrj       locsymcount = symtab_hdr->sh_info;
3666a9fa9459Szrj       end_local_got = local_got + locsymcount;
3667a9fa9459Szrj       local_tls_type = elf_x86_64_local_got_tls_type (ibfd);
3668a9fa9459Szrj       local_tlsdesc_gotent = elf_x86_64_local_tlsdesc_gotent (ibfd);
3669a9fa9459Szrj       s = htab->elf.sgot;
3670a9fa9459Szrj       srel = htab->elf.srelgot;
3671a9fa9459Szrj       for (; local_got < end_local_got;
3672a9fa9459Szrj 	   ++local_got, ++local_tls_type, ++local_tlsdesc_gotent)
3673a9fa9459Szrj 	{
3674a9fa9459Szrj 	  *local_tlsdesc_gotent = (bfd_vma) -1;
3675a9fa9459Szrj 	  if (*local_got > 0)
3676a9fa9459Szrj 	    {
3677a9fa9459Szrj 	      if (GOT_TLS_GDESC_P (*local_tls_type))
3678a9fa9459Szrj 		{
3679a9fa9459Szrj 		  *local_tlsdesc_gotent = htab->elf.sgotplt->size
3680a9fa9459Szrj 		    - elf_x86_64_compute_jump_table_size (htab);
3681a9fa9459Szrj 		  htab->elf.sgotplt->size += 2 * GOT_ENTRY_SIZE;
3682a9fa9459Szrj 		  *local_got = (bfd_vma) -2;
3683a9fa9459Szrj 		}
3684a9fa9459Szrj 	      if (! GOT_TLS_GDESC_P (*local_tls_type)
3685a9fa9459Szrj 		  || GOT_TLS_GD_P (*local_tls_type))
3686a9fa9459Szrj 		{
3687a9fa9459Szrj 		  *local_got = s->size;
3688a9fa9459Szrj 		  s->size += GOT_ENTRY_SIZE;
3689a9fa9459Szrj 		  if (GOT_TLS_GD_P (*local_tls_type))
3690a9fa9459Szrj 		    s->size += GOT_ENTRY_SIZE;
3691a9fa9459Szrj 		}
3692a9fa9459Szrj 	      if (bfd_link_pic (info)
3693a9fa9459Szrj 		  || GOT_TLS_GD_ANY_P (*local_tls_type)
3694a9fa9459Szrj 		  || *local_tls_type == GOT_TLS_IE)
3695a9fa9459Szrj 		{
3696a9fa9459Szrj 		  if (GOT_TLS_GDESC_P (*local_tls_type))
3697a9fa9459Szrj 		    {
3698a9fa9459Szrj 		      htab->elf.srelplt->size
3699a9fa9459Szrj 			+= bed->s->sizeof_rela;
3700a9fa9459Szrj 		      htab->tlsdesc_plt = (bfd_vma) -1;
3701a9fa9459Szrj 		    }
3702a9fa9459Szrj 		  if (! GOT_TLS_GDESC_P (*local_tls_type)
3703a9fa9459Szrj 		      || GOT_TLS_GD_P (*local_tls_type))
3704a9fa9459Szrj 		    srel->size += bed->s->sizeof_rela;
3705a9fa9459Szrj 		}
3706a9fa9459Szrj 	    }
3707a9fa9459Szrj 	  else
3708a9fa9459Szrj 	    *local_got = (bfd_vma) -1;
3709a9fa9459Szrj 	}
3710a9fa9459Szrj     }
3711a9fa9459Szrj 
3712a9fa9459Szrj   if (htab->tls_ld_got.refcount > 0)
3713a9fa9459Szrj     {
3714a9fa9459Szrj       /* Allocate 2 got entries and 1 dynamic reloc for R_X86_64_TLSLD
3715a9fa9459Szrj 	 relocs.  */
3716a9fa9459Szrj       htab->tls_ld_got.offset = htab->elf.sgot->size;
3717a9fa9459Szrj       htab->elf.sgot->size += 2 * GOT_ENTRY_SIZE;
3718a9fa9459Szrj       htab->elf.srelgot->size += bed->s->sizeof_rela;
3719a9fa9459Szrj     }
3720a9fa9459Szrj   else
3721a9fa9459Szrj     htab->tls_ld_got.offset = -1;
3722a9fa9459Szrj 
3723a9fa9459Szrj   /* Allocate global sym .plt and .got entries, and space for global
3724a9fa9459Szrj      sym dynamic relocs.  */
3725a9fa9459Szrj   elf_link_hash_traverse (&htab->elf, elf_x86_64_allocate_dynrelocs,
3726a9fa9459Szrj 			  info);
3727a9fa9459Szrj 
3728a9fa9459Szrj   /* Allocate .plt and .got entries, and space for local symbols.  */
3729a9fa9459Szrj   htab_traverse (htab->loc_hash_table,
3730a9fa9459Szrj 		 elf_x86_64_allocate_local_dynrelocs,
3731a9fa9459Szrj 		 info);
3732a9fa9459Szrj 
3733a9fa9459Szrj   /* For every jump slot reserved in the sgotplt, reloc_count is
3734a9fa9459Szrj      incremented.  However, when we reserve space for TLS descriptors,
3735a9fa9459Szrj      it's not incremented, so in order to compute the space reserved
3736a9fa9459Szrj      for them, it suffices to multiply the reloc count by the jump
3737a9fa9459Szrj      slot size.
3738a9fa9459Szrj 
3739a9fa9459Szrj      PR ld/13302: We start next_irelative_index at the end of .rela.plt
3740a9fa9459Szrj      so that R_X86_64_IRELATIVE entries come last.  */
3741a9fa9459Szrj   if (htab->elf.srelplt)
3742a9fa9459Szrj     {
3743a9fa9459Szrj       htab->sgotplt_jump_table_size
3744a9fa9459Szrj 	= elf_x86_64_compute_jump_table_size (htab);
3745a9fa9459Szrj       htab->next_irelative_index = htab->elf.srelplt->reloc_count - 1;
3746a9fa9459Szrj     }
3747a9fa9459Szrj   else if (htab->elf.irelplt)
3748a9fa9459Szrj     htab->next_irelative_index = htab->elf.irelplt->reloc_count - 1;
3749a9fa9459Szrj 
3750a9fa9459Szrj   if (htab->tlsdesc_plt)
3751a9fa9459Szrj     {
3752a9fa9459Szrj       /* If we're not using lazy TLS relocations, don't generate the
3753a9fa9459Szrj 	 PLT and GOT entries they require.  */
3754a9fa9459Szrj       if ((info->flags & DF_BIND_NOW))
3755a9fa9459Szrj 	htab->tlsdesc_plt = 0;
3756a9fa9459Szrj       else
3757a9fa9459Szrj 	{
3758a9fa9459Szrj 	  htab->tlsdesc_got = htab->elf.sgot->size;
3759a9fa9459Szrj 	  htab->elf.sgot->size += GOT_ENTRY_SIZE;
3760a9fa9459Szrj 	  /* Reserve room for the initial entry.
3761a9fa9459Szrj 	     FIXME: we could probably do away with it in this case.  */
3762a9fa9459Szrj 	  if (htab->elf.splt->size == 0)
3763a9fa9459Szrj 	    htab->elf.splt->size += GET_PLT_ENTRY_SIZE (output_bfd);
3764a9fa9459Szrj 	  htab->tlsdesc_plt = htab->elf.splt->size;
3765a9fa9459Szrj 	  htab->elf.splt->size += GET_PLT_ENTRY_SIZE (output_bfd);
3766a9fa9459Szrj 	}
3767a9fa9459Szrj     }
3768a9fa9459Szrj 
3769a9fa9459Szrj   if (htab->elf.sgotplt)
3770a9fa9459Szrj     {
3771a9fa9459Szrj       /* Don't allocate .got.plt section if there are no GOT nor PLT
3772a9fa9459Szrj 	 entries and there is no refeence to _GLOBAL_OFFSET_TABLE_.  */
3773a9fa9459Szrj       if ((htab->elf.hgot == NULL
3774a9fa9459Szrj 	   || !htab->elf.hgot->ref_regular_nonweak)
3775a9fa9459Szrj 	  && (htab->elf.sgotplt->size
3776a9fa9459Szrj 	      == get_elf_backend_data (output_bfd)->got_header_size)
3777a9fa9459Szrj 	  && (htab->elf.splt == NULL
3778a9fa9459Szrj 	      || htab->elf.splt->size == 0)
3779a9fa9459Szrj 	  && (htab->elf.sgot == NULL
3780a9fa9459Szrj 	      || htab->elf.sgot->size == 0)
3781a9fa9459Szrj 	  && (htab->elf.iplt == NULL
3782a9fa9459Szrj 	      || htab->elf.iplt->size == 0)
3783a9fa9459Szrj 	  && (htab->elf.igotplt == NULL
3784a9fa9459Szrj 	      || htab->elf.igotplt->size == 0))
3785a9fa9459Szrj 	htab->elf.sgotplt->size = 0;
3786a9fa9459Szrj     }
3787a9fa9459Szrj 
3788a9fa9459Szrj   if (htab->plt_eh_frame != NULL
3789a9fa9459Szrj       && htab->elf.splt != NULL
3790a9fa9459Szrj       && htab->elf.splt->size != 0
3791a9fa9459Szrj       && !bfd_is_abs_section (htab->elf.splt->output_section)
3792a9fa9459Szrj       && _bfd_elf_eh_frame_present (info))
3793a9fa9459Szrj     {
3794a9fa9459Szrj       const struct elf_x86_64_backend_data *arch_data
3795a9fa9459Szrj 	= get_elf_x86_64_arch_data (bed);
3796a9fa9459Szrj       htab->plt_eh_frame->size = arch_data->eh_frame_plt_size;
3797a9fa9459Szrj     }
3798a9fa9459Szrj 
3799a9fa9459Szrj   /* We now have determined the sizes of the various dynamic sections.
3800a9fa9459Szrj      Allocate memory for them.  */
3801a9fa9459Szrj   relocs = FALSE;
3802a9fa9459Szrj   for (s = dynobj->sections; s != NULL; s = s->next)
3803a9fa9459Szrj     {
3804a9fa9459Szrj       if ((s->flags & SEC_LINKER_CREATED) == 0)
3805a9fa9459Szrj 	continue;
3806a9fa9459Szrj 
3807a9fa9459Szrj       if (s == htab->elf.splt
3808a9fa9459Szrj 	  || s == htab->elf.sgot
3809a9fa9459Szrj 	  || s == htab->elf.sgotplt
3810a9fa9459Szrj 	  || s == htab->elf.iplt
3811a9fa9459Szrj 	  || s == htab->elf.igotplt
3812a9fa9459Szrj 	  || s == htab->plt_bnd
3813a9fa9459Szrj 	  || s == htab->plt_got
3814a9fa9459Szrj 	  || s == htab->plt_eh_frame
3815a9fa9459Szrj 	  || s == htab->sdynbss)
3816a9fa9459Szrj 	{
3817a9fa9459Szrj 	  /* Strip this section if we don't need it; see the
3818a9fa9459Szrj 	     comment below.  */
3819a9fa9459Szrj 	}
3820a9fa9459Szrj       else if (CONST_STRNEQ (bfd_get_section_name (dynobj, s), ".rela"))
3821a9fa9459Szrj 	{
3822a9fa9459Szrj 	  if (s->size != 0 && s != htab->elf.srelplt)
3823a9fa9459Szrj 	    relocs = TRUE;
3824a9fa9459Szrj 
3825a9fa9459Szrj 	  /* We use the reloc_count field as a counter if we need
3826a9fa9459Szrj 	     to copy relocs into the output file.  */
3827a9fa9459Szrj 	  if (s != htab->elf.srelplt)
3828a9fa9459Szrj 	    s->reloc_count = 0;
3829a9fa9459Szrj 	}
3830a9fa9459Szrj       else
3831a9fa9459Szrj 	{
3832a9fa9459Szrj 	  /* It's not one of our sections, so don't allocate space.  */
3833a9fa9459Szrj 	  continue;
3834a9fa9459Szrj 	}
3835a9fa9459Szrj 
3836a9fa9459Szrj       if (s->size == 0)
3837a9fa9459Szrj 	{
3838a9fa9459Szrj 	  /* If we don't need this section, strip it from the
3839a9fa9459Szrj 	     output file.  This is mostly to handle .rela.bss and
3840a9fa9459Szrj 	     .rela.plt.  We must create both sections in
3841a9fa9459Szrj 	     create_dynamic_sections, because they must be created
3842a9fa9459Szrj 	     before the linker maps input sections to output
3843a9fa9459Szrj 	     sections.  The linker does that before
3844a9fa9459Szrj 	     adjust_dynamic_symbol is called, and it is that
3845a9fa9459Szrj 	     function which decides whether anything needs to go
3846a9fa9459Szrj 	     into these sections.  */
3847a9fa9459Szrj 
3848a9fa9459Szrj 	  s->flags |= SEC_EXCLUDE;
3849a9fa9459Szrj 	  continue;
3850a9fa9459Szrj 	}
3851a9fa9459Szrj 
3852a9fa9459Szrj       if ((s->flags & SEC_HAS_CONTENTS) == 0)
3853a9fa9459Szrj 	continue;
3854a9fa9459Szrj 
3855a9fa9459Szrj       /* Allocate memory for the section contents.  We use bfd_zalloc
3856a9fa9459Szrj 	 here in case unused entries are not reclaimed before the
3857a9fa9459Szrj 	 section's contents are written out.  This should not happen,
3858a9fa9459Szrj 	 but this way if it does, we get a R_X86_64_NONE reloc instead
3859a9fa9459Szrj 	 of garbage.  */
3860a9fa9459Szrj       s->contents = (bfd_byte *) bfd_zalloc (dynobj, s->size);
3861a9fa9459Szrj       if (s->contents == NULL)
3862a9fa9459Szrj 	return FALSE;
3863a9fa9459Szrj     }
3864a9fa9459Szrj 
3865a9fa9459Szrj   if (htab->plt_eh_frame != NULL
3866a9fa9459Szrj       && htab->plt_eh_frame->contents != NULL)
3867a9fa9459Szrj     {
3868a9fa9459Szrj       const struct elf_x86_64_backend_data *arch_data
3869a9fa9459Szrj 	= get_elf_x86_64_arch_data (bed);
3870a9fa9459Szrj 
3871a9fa9459Szrj       memcpy (htab->plt_eh_frame->contents,
3872a9fa9459Szrj 	      arch_data->eh_frame_plt, htab->plt_eh_frame->size);
3873a9fa9459Szrj       bfd_put_32 (dynobj, htab->elf.splt->size,
3874a9fa9459Szrj 		  htab->plt_eh_frame->contents + PLT_FDE_LEN_OFFSET);
3875a9fa9459Szrj     }
3876a9fa9459Szrj 
3877a9fa9459Szrj   if (htab->elf.dynamic_sections_created)
3878a9fa9459Szrj     {
3879a9fa9459Szrj       /* Add some entries to the .dynamic section.  We fill in the
3880a9fa9459Szrj 	 values later, in elf_x86_64_finish_dynamic_sections, but we
3881a9fa9459Szrj 	 must add the entries now so that we get the correct size for
3882a9fa9459Szrj 	 the .dynamic section.	The DT_DEBUG entry is filled in by the
3883a9fa9459Szrj 	 dynamic linker and used by the debugger.  */
3884a9fa9459Szrj #define add_dynamic_entry(TAG, VAL) \
3885a9fa9459Szrj   _bfd_elf_add_dynamic_entry (info, TAG, VAL)
3886a9fa9459Szrj 
3887a9fa9459Szrj       if (bfd_link_executable (info))
3888a9fa9459Szrj 	{
3889a9fa9459Szrj 	  if (!add_dynamic_entry (DT_DEBUG, 0))
3890a9fa9459Szrj 	    return FALSE;
3891a9fa9459Szrj 	}
3892a9fa9459Szrj 
3893a9fa9459Szrj       if (htab->elf.splt->size != 0)
3894a9fa9459Szrj 	{
3895a9fa9459Szrj 	  /* DT_PLTGOT is used by prelink even if there is no PLT
3896a9fa9459Szrj 	     relocation.  */
3897a9fa9459Szrj 	  if (!add_dynamic_entry (DT_PLTGOT, 0))
3898a9fa9459Szrj 	    return FALSE;
3899a9fa9459Szrj 
3900a9fa9459Szrj 	  if (htab->elf.srelplt->size != 0)
3901a9fa9459Szrj 	    {
3902a9fa9459Szrj 	      if (!add_dynamic_entry (DT_PLTRELSZ, 0)
3903a9fa9459Szrj 		  || !add_dynamic_entry (DT_PLTREL, DT_RELA)
3904a9fa9459Szrj 		  || !add_dynamic_entry (DT_JMPREL, 0))
3905a9fa9459Szrj 		return FALSE;
3906a9fa9459Szrj 	    }
3907a9fa9459Szrj 
3908a9fa9459Szrj 	  if (htab->tlsdesc_plt
3909a9fa9459Szrj 	      && (!add_dynamic_entry (DT_TLSDESC_PLT, 0)
3910a9fa9459Szrj 		  || !add_dynamic_entry (DT_TLSDESC_GOT, 0)))
3911a9fa9459Szrj 	    return FALSE;
3912a9fa9459Szrj 	}
3913a9fa9459Szrj 
3914a9fa9459Szrj       if (relocs)
3915a9fa9459Szrj 	{
3916a9fa9459Szrj 	  if (!add_dynamic_entry (DT_RELA, 0)
3917a9fa9459Szrj 	      || !add_dynamic_entry (DT_RELASZ, 0)
3918a9fa9459Szrj 	      || !add_dynamic_entry (DT_RELAENT, bed->s->sizeof_rela))
3919a9fa9459Szrj 	    return FALSE;
3920a9fa9459Szrj 
3921a9fa9459Szrj 	  /* If any dynamic relocs apply to a read-only section,
3922a9fa9459Szrj 	     then we need a DT_TEXTREL entry.  */
3923a9fa9459Szrj 	  if ((info->flags & DF_TEXTREL) == 0)
3924a9fa9459Szrj 	    elf_link_hash_traverse (&htab->elf,
3925a9fa9459Szrj 				    elf_x86_64_readonly_dynrelocs,
3926a9fa9459Szrj 				    info);
3927a9fa9459Szrj 
3928a9fa9459Szrj 	  if ((info->flags & DF_TEXTREL) != 0)
3929a9fa9459Szrj 	    {
3930a9fa9459Szrj 	      if (htab->readonly_dynrelocs_against_ifunc)
3931a9fa9459Szrj 		{
3932a9fa9459Szrj 		  info->callbacks->einfo
3933a9fa9459Szrj 		    (_("%P%X: read-only segment has dynamic IFUNC relocations; recompile with -fPIC\n"));
3934a9fa9459Szrj 		  bfd_set_error (bfd_error_bad_value);
3935a9fa9459Szrj 		  return FALSE;
3936a9fa9459Szrj 		}
3937a9fa9459Szrj 
3938a9fa9459Szrj 	      if (!add_dynamic_entry (DT_TEXTREL, 0))
3939a9fa9459Szrj 		return FALSE;
3940a9fa9459Szrj 	    }
3941a9fa9459Szrj 	}
3942a9fa9459Szrj     }
3943a9fa9459Szrj #undef add_dynamic_entry
3944a9fa9459Szrj 
3945a9fa9459Szrj   return TRUE;
3946a9fa9459Szrj }
3947a9fa9459Szrj 
3948a9fa9459Szrj static bfd_boolean
elf_x86_64_always_size_sections(bfd * output_bfd,struct bfd_link_info * info)3949a9fa9459Szrj elf_x86_64_always_size_sections (bfd *output_bfd,
3950a9fa9459Szrj 				 struct bfd_link_info *info)
3951a9fa9459Szrj {
3952a9fa9459Szrj   asection *tls_sec = elf_hash_table (info)->tls_sec;
3953a9fa9459Szrj 
3954a9fa9459Szrj   if (tls_sec)
3955a9fa9459Szrj     {
3956a9fa9459Szrj       struct elf_link_hash_entry *tlsbase;
3957a9fa9459Szrj 
3958a9fa9459Szrj       tlsbase = elf_link_hash_lookup (elf_hash_table (info),
3959a9fa9459Szrj 				      "_TLS_MODULE_BASE_",
3960a9fa9459Szrj 				      FALSE, FALSE, FALSE);
3961a9fa9459Szrj 
3962a9fa9459Szrj       if (tlsbase && tlsbase->type == STT_TLS)
3963a9fa9459Szrj 	{
3964a9fa9459Szrj 	  struct elf_x86_64_link_hash_table *htab;
3965a9fa9459Szrj 	  struct bfd_link_hash_entry *bh = NULL;
3966a9fa9459Szrj 	  const struct elf_backend_data *bed
3967a9fa9459Szrj 	    = get_elf_backend_data (output_bfd);
3968a9fa9459Szrj 
3969a9fa9459Szrj 	  htab = elf_x86_64_hash_table (info);
3970a9fa9459Szrj 	  if (htab == NULL)
3971a9fa9459Szrj 	    return FALSE;
3972a9fa9459Szrj 
3973a9fa9459Szrj 	  if (!(_bfd_generic_link_add_one_symbol
3974a9fa9459Szrj 		(info, output_bfd, "_TLS_MODULE_BASE_", BSF_LOCAL,
3975a9fa9459Szrj 		 tls_sec, 0, NULL, FALSE,
3976a9fa9459Szrj 		 bed->collect, &bh)))
3977a9fa9459Szrj 	    return FALSE;
3978a9fa9459Szrj 
3979a9fa9459Szrj 	  htab->tls_module_base = bh;
3980a9fa9459Szrj 
3981a9fa9459Szrj 	  tlsbase = (struct elf_link_hash_entry *)bh;
3982a9fa9459Szrj 	  tlsbase->def_regular = 1;
3983a9fa9459Szrj 	  tlsbase->other = STV_HIDDEN;
3984a9fa9459Szrj 	  tlsbase->root.linker_def = 1;
3985a9fa9459Szrj 	  (*bed->elf_backend_hide_symbol) (info, tlsbase, TRUE);
3986a9fa9459Szrj 	}
3987a9fa9459Szrj     }
3988a9fa9459Szrj 
3989a9fa9459Szrj   return TRUE;
3990a9fa9459Szrj }
3991a9fa9459Szrj 
3992a9fa9459Szrj /* _TLS_MODULE_BASE_ needs to be treated especially when linking
3993a9fa9459Szrj    executables.  Rather than setting it to the beginning of the TLS
3994a9fa9459Szrj    section, we have to set it to the end.  This function may be called
3995a9fa9459Szrj    multiple times, it is idempotent.  */
3996a9fa9459Szrj 
3997a9fa9459Szrj static void
elf_x86_64_set_tls_module_base(struct bfd_link_info * info)3998a9fa9459Szrj elf_x86_64_set_tls_module_base (struct bfd_link_info *info)
3999a9fa9459Szrj {
4000a9fa9459Szrj   struct elf_x86_64_link_hash_table *htab;
4001a9fa9459Szrj   struct bfd_link_hash_entry *base;
4002a9fa9459Szrj 
4003a9fa9459Szrj   if (!bfd_link_executable (info))
4004a9fa9459Szrj     return;
4005a9fa9459Szrj 
4006a9fa9459Szrj   htab = elf_x86_64_hash_table (info);
4007a9fa9459Szrj   if (htab == NULL)
4008a9fa9459Szrj     return;
4009a9fa9459Szrj 
4010a9fa9459Szrj   base = htab->tls_module_base;
4011a9fa9459Szrj   if (base == NULL)
4012a9fa9459Szrj     return;
4013a9fa9459Szrj 
4014a9fa9459Szrj   base->u.def.value = htab->elf.tls_size;
4015a9fa9459Szrj }
4016a9fa9459Szrj 
4017a9fa9459Szrj /* Return the base VMA address which should be subtracted from real addresses
4018a9fa9459Szrj    when resolving @dtpoff relocation.
4019a9fa9459Szrj    This is PT_TLS segment p_vaddr.  */
4020a9fa9459Szrj 
4021a9fa9459Szrj static bfd_vma
elf_x86_64_dtpoff_base(struct bfd_link_info * info)4022a9fa9459Szrj elf_x86_64_dtpoff_base (struct bfd_link_info *info)
4023a9fa9459Szrj {
4024a9fa9459Szrj   /* If tls_sec is NULL, we should have signalled an error already.  */
4025a9fa9459Szrj   if (elf_hash_table (info)->tls_sec == NULL)
4026a9fa9459Szrj     return 0;
4027a9fa9459Szrj   return elf_hash_table (info)->tls_sec->vma;
4028a9fa9459Szrj }
4029a9fa9459Szrj 
4030a9fa9459Szrj /* Return the relocation value for @tpoff relocation
4031a9fa9459Szrj    if STT_TLS virtual address is ADDRESS.  */
4032a9fa9459Szrj 
4033a9fa9459Szrj static bfd_vma
elf_x86_64_tpoff(struct bfd_link_info * info,bfd_vma address)4034a9fa9459Szrj elf_x86_64_tpoff (struct bfd_link_info *info, bfd_vma address)
4035a9fa9459Szrj {
4036a9fa9459Szrj   struct elf_link_hash_table *htab = elf_hash_table (info);
4037a9fa9459Szrj   const struct elf_backend_data *bed = get_elf_backend_data (info->output_bfd);
4038a9fa9459Szrj   bfd_vma static_tls_size;
4039a9fa9459Szrj 
4040a9fa9459Szrj   /* If tls_segment is NULL, we should have signalled an error already.  */
4041a9fa9459Szrj   if (htab->tls_sec == NULL)
4042a9fa9459Szrj     return 0;
4043a9fa9459Szrj 
4044a9fa9459Szrj   /* Consider special static TLS alignment requirements.  */
4045a9fa9459Szrj   static_tls_size = BFD_ALIGN (htab->tls_size, bed->static_tls_alignment);
4046a9fa9459Szrj   return address - static_tls_size - htab->tls_sec->vma;
4047a9fa9459Szrj }
4048a9fa9459Szrj 
4049a9fa9459Szrj /* Is the instruction before OFFSET in CONTENTS a 32bit relative
4050a9fa9459Szrj    branch?  */
4051a9fa9459Szrj 
4052a9fa9459Szrj static bfd_boolean
is_32bit_relative_branch(bfd_byte * contents,bfd_vma offset)4053a9fa9459Szrj is_32bit_relative_branch (bfd_byte *contents, bfd_vma offset)
4054a9fa9459Szrj {
4055a9fa9459Szrj   /* Opcode		Instruction
4056a9fa9459Szrj      0xe8		call
4057a9fa9459Szrj      0xe9		jump
4058a9fa9459Szrj      0x0f 0x8x		conditional jump */
4059a9fa9459Szrj   return ((offset > 0
4060a9fa9459Szrj 	   && (contents [offset - 1] == 0xe8
4061a9fa9459Szrj 	       || contents [offset - 1] == 0xe9))
4062a9fa9459Szrj 	  || (offset > 1
4063a9fa9459Szrj 	      && contents [offset - 2] == 0x0f
4064a9fa9459Szrj 	      && (contents [offset - 1] & 0xf0) == 0x80));
4065a9fa9459Szrj }
4066a9fa9459Szrj 
4067a9fa9459Szrj /* Relocate an x86_64 ELF section.  */
4068a9fa9459Szrj 
4069a9fa9459Szrj static bfd_boolean
elf_x86_64_relocate_section(bfd * output_bfd,struct bfd_link_info * info,bfd * input_bfd,asection * input_section,bfd_byte * contents,Elf_Internal_Rela * relocs,Elf_Internal_Sym * local_syms,asection ** local_sections)4070a9fa9459Szrj elf_x86_64_relocate_section (bfd *output_bfd,
4071a9fa9459Szrj 			     struct bfd_link_info *info,
4072a9fa9459Szrj 			     bfd *input_bfd,
4073a9fa9459Szrj 			     asection *input_section,
4074a9fa9459Szrj 			     bfd_byte *contents,
4075a9fa9459Szrj 			     Elf_Internal_Rela *relocs,
4076a9fa9459Szrj 			     Elf_Internal_Sym *local_syms,
4077a9fa9459Szrj 			     asection **local_sections)
4078a9fa9459Szrj {
4079a9fa9459Szrj   struct elf_x86_64_link_hash_table *htab;
4080a9fa9459Szrj   Elf_Internal_Shdr *symtab_hdr;
4081a9fa9459Szrj   struct elf_link_hash_entry **sym_hashes;
4082a9fa9459Szrj   bfd_vma *local_got_offsets;
4083a9fa9459Szrj   bfd_vma *local_tlsdesc_gotents;
4084a9fa9459Szrj   Elf_Internal_Rela *rel;
4085a9fa9459Szrj   Elf_Internal_Rela *wrel;
4086a9fa9459Szrj   Elf_Internal_Rela *relend;
4087a9fa9459Szrj   const unsigned int plt_entry_size = GET_PLT_ENTRY_SIZE (info->output_bfd);
4088a9fa9459Szrj 
4089a9fa9459Szrj   BFD_ASSERT (is_x86_64_elf (input_bfd));
4090a9fa9459Szrj 
4091a9fa9459Szrj   /* Skip if check_relocs failed.  */
4092a9fa9459Szrj   if (input_section->check_relocs_failed)
4093a9fa9459Szrj     return FALSE;
4094a9fa9459Szrj 
4095a9fa9459Szrj   htab = elf_x86_64_hash_table (info);
4096a9fa9459Szrj   if (htab == NULL)
4097a9fa9459Szrj     return FALSE;
4098a9fa9459Szrj   symtab_hdr = &elf_symtab_hdr (input_bfd);
4099a9fa9459Szrj   sym_hashes = elf_sym_hashes (input_bfd);
4100a9fa9459Szrj   local_got_offsets = elf_local_got_offsets (input_bfd);
4101a9fa9459Szrj   local_tlsdesc_gotents = elf_x86_64_local_tlsdesc_gotent (input_bfd);
4102a9fa9459Szrj 
4103a9fa9459Szrj   elf_x86_64_set_tls_module_base (info);
4104a9fa9459Szrj 
4105a9fa9459Szrj   rel = wrel = relocs;
4106a9fa9459Szrj   relend = relocs + input_section->reloc_count;
4107a9fa9459Szrj   for (; rel < relend; wrel++, rel++)
4108a9fa9459Szrj     {
4109a9fa9459Szrj       unsigned int r_type;
4110a9fa9459Szrj       reloc_howto_type *howto;
4111a9fa9459Szrj       unsigned long r_symndx;
4112a9fa9459Szrj       struct elf_link_hash_entry *h;
4113a9fa9459Szrj       struct elf_x86_64_link_hash_entry *eh;
4114a9fa9459Szrj       Elf_Internal_Sym *sym;
4115a9fa9459Szrj       asection *sec;
4116a9fa9459Szrj       bfd_vma off, offplt, plt_offset;
4117a9fa9459Szrj       bfd_vma relocation;
4118a9fa9459Szrj       bfd_boolean unresolved_reloc;
4119a9fa9459Szrj       bfd_reloc_status_type r;
4120a9fa9459Szrj       int tls_type;
4121a9fa9459Szrj       asection *base_got, *resolved_plt;
4122a9fa9459Szrj       bfd_vma st_size;
4123a9fa9459Szrj       bfd_boolean resolved_to_zero;
4124a9fa9459Szrj 
4125a9fa9459Szrj       r_type = ELF32_R_TYPE (rel->r_info);
4126a9fa9459Szrj       if (r_type == (int) R_X86_64_GNU_VTINHERIT
4127a9fa9459Szrj 	  || r_type == (int) R_X86_64_GNU_VTENTRY)
4128a9fa9459Szrj 	{
4129a9fa9459Szrj 	  if (wrel != rel)
4130a9fa9459Szrj 	    *wrel = *rel;
4131a9fa9459Szrj 	  continue;
4132a9fa9459Szrj 	}
4133a9fa9459Szrj 
4134a9fa9459Szrj       if (r_type >= (int) R_X86_64_standard)
4135a9fa9459Szrj 	{
4136a9fa9459Szrj 	  (*_bfd_error_handler)
4137a9fa9459Szrj 	    (_("%B: unrecognized relocation (0x%x) in section `%A'"),
4138a9fa9459Szrj 	     input_bfd, input_section, r_type);
4139a9fa9459Szrj 	  bfd_set_error (bfd_error_bad_value);
4140a9fa9459Szrj 	  return FALSE;
4141a9fa9459Szrj 	}
4142a9fa9459Szrj 
4143a9fa9459Szrj       if (r_type != (int) R_X86_64_32
4144a9fa9459Szrj 	  || ABI_64_P (output_bfd))
4145a9fa9459Szrj 	howto = x86_64_elf_howto_table + r_type;
4146a9fa9459Szrj       else
4147a9fa9459Szrj 	howto = (x86_64_elf_howto_table
4148a9fa9459Szrj 		 + ARRAY_SIZE (x86_64_elf_howto_table) - 1);
4149a9fa9459Szrj       r_symndx = htab->r_sym (rel->r_info);
4150a9fa9459Szrj       h = NULL;
4151a9fa9459Szrj       sym = NULL;
4152a9fa9459Szrj       sec = NULL;
4153a9fa9459Szrj       unresolved_reloc = FALSE;
4154a9fa9459Szrj       if (r_symndx < symtab_hdr->sh_info)
4155a9fa9459Szrj 	{
4156a9fa9459Szrj 	  sym = local_syms + r_symndx;
4157a9fa9459Szrj 	  sec = local_sections[r_symndx];
4158a9fa9459Szrj 
4159a9fa9459Szrj 	  relocation = _bfd_elf_rela_local_sym (output_bfd, sym,
4160a9fa9459Szrj 						&sec, rel);
4161a9fa9459Szrj 	  st_size = sym->st_size;
4162a9fa9459Szrj 
4163a9fa9459Szrj 	  /* Relocate against local STT_GNU_IFUNC symbol.  */
4164a9fa9459Szrj 	  if (!bfd_link_relocatable (info)
4165a9fa9459Szrj 	      && ELF_ST_TYPE (sym->st_info) == STT_GNU_IFUNC)
4166a9fa9459Szrj 	    {
4167a9fa9459Szrj 	      h = elf_x86_64_get_local_sym_hash (htab, input_bfd,
4168a9fa9459Szrj 						 rel, FALSE);
4169a9fa9459Szrj 	      if (h == NULL)
4170a9fa9459Szrj 		abort ();
4171a9fa9459Szrj 
4172a9fa9459Szrj 	      /* Set STT_GNU_IFUNC symbol value.  */
4173a9fa9459Szrj 	      h->root.u.def.value = sym->st_value;
4174a9fa9459Szrj 	      h->root.u.def.section = sec;
4175a9fa9459Szrj 	    }
4176a9fa9459Szrj 	}
4177a9fa9459Szrj       else
4178a9fa9459Szrj 	{
4179a9fa9459Szrj 	  bfd_boolean warned ATTRIBUTE_UNUSED;
4180a9fa9459Szrj 	  bfd_boolean ignored ATTRIBUTE_UNUSED;
4181a9fa9459Szrj 
4182a9fa9459Szrj 	  RELOC_FOR_GLOBAL_SYMBOL (info, input_bfd, input_section, rel,
4183a9fa9459Szrj 				   r_symndx, symtab_hdr, sym_hashes,
4184a9fa9459Szrj 				   h, sec, relocation,
4185a9fa9459Szrj 				   unresolved_reloc, warned, ignored);
4186a9fa9459Szrj 	  st_size = h->size;
4187a9fa9459Szrj 	}
4188a9fa9459Szrj 
4189a9fa9459Szrj       if (sec != NULL && discarded_section (sec))
4190a9fa9459Szrj 	{
4191a9fa9459Szrj 	  _bfd_clear_contents (howto, input_bfd, input_section,
4192a9fa9459Szrj 			       contents + rel->r_offset);
4193a9fa9459Szrj 	  wrel->r_offset = rel->r_offset;
4194a9fa9459Szrj 	  wrel->r_info = 0;
4195a9fa9459Szrj 	  wrel->r_addend = 0;
4196a9fa9459Szrj 
4197a9fa9459Szrj 	  /* For ld -r, remove relocations in debug sections against
4198a9fa9459Szrj 	     sections defined in discarded sections.  Not done for
4199a9fa9459Szrj 	     eh_frame editing code expects to be present.  */
4200a9fa9459Szrj 	   if (bfd_link_relocatable (info)
4201a9fa9459Szrj 	       && (input_section->flags & SEC_DEBUGGING))
4202a9fa9459Szrj 	     wrel--;
4203a9fa9459Szrj 
4204a9fa9459Szrj 	  continue;
4205a9fa9459Szrj 	}
4206a9fa9459Szrj 
4207a9fa9459Szrj       if (bfd_link_relocatable (info))
4208a9fa9459Szrj 	{
4209a9fa9459Szrj 	  if (wrel != rel)
4210a9fa9459Szrj 	    *wrel = *rel;
4211a9fa9459Szrj 	  continue;
4212a9fa9459Szrj 	}
4213a9fa9459Szrj 
4214a9fa9459Szrj       if (rel->r_addend == 0 && !ABI_64_P (output_bfd))
4215a9fa9459Szrj 	{
4216a9fa9459Szrj 	  if (r_type == R_X86_64_64)
4217a9fa9459Szrj 	    {
4218a9fa9459Szrj 	      /* For x32, treat R_X86_64_64 like R_X86_64_32 and
4219a9fa9459Szrj 		 zero-extend it to 64bit if addend is zero.  */
4220a9fa9459Szrj 	      r_type = R_X86_64_32;
4221a9fa9459Szrj 	      memset (contents + rel->r_offset + 4, 0, 4);
4222a9fa9459Szrj 	    }
4223a9fa9459Szrj 	  else if (r_type == R_X86_64_SIZE64)
4224a9fa9459Szrj 	    {
4225a9fa9459Szrj 	      /* For x32, treat R_X86_64_SIZE64 like R_X86_64_SIZE32 and
4226a9fa9459Szrj 		 zero-extend it to 64bit if addend is zero.  */
4227a9fa9459Szrj 	      r_type = R_X86_64_SIZE32;
4228a9fa9459Szrj 	      memset (contents + rel->r_offset + 4, 0, 4);
4229a9fa9459Szrj 	    }
4230a9fa9459Szrj 	}
4231a9fa9459Szrj 
4232a9fa9459Szrj       eh = (struct elf_x86_64_link_hash_entry *) h;
4233a9fa9459Szrj 
4234a9fa9459Szrj       /* Since STT_GNU_IFUNC symbol must go through PLT, we handle
4235a9fa9459Szrj 	 it here if it is defined in a non-shared object.  */
4236a9fa9459Szrj       if (h != NULL
4237a9fa9459Szrj 	  && h->type == STT_GNU_IFUNC
4238a9fa9459Szrj 	  && h->def_regular)
4239a9fa9459Szrj 	{
4240a9fa9459Szrj 	  bfd_vma plt_index;
4241a9fa9459Szrj 	  const char *name;
4242a9fa9459Szrj 
4243a9fa9459Szrj 	  if ((input_section->flags & SEC_ALLOC) == 0)
4244a9fa9459Szrj 	    {
4245a9fa9459Szrj 	      /* Dynamic relocs are not propagated for SEC_DEBUGGING
4246a9fa9459Szrj 		 sections because such sections are not SEC_ALLOC and
4247a9fa9459Szrj 		 thus ld.so will not process them.  */
4248a9fa9459Szrj 	      if ((input_section->flags & SEC_DEBUGGING) != 0)
4249a9fa9459Szrj 		continue;
4250a9fa9459Szrj 	      abort ();
4251a9fa9459Szrj 	    }
4252a9fa9459Szrj 
4253a9fa9459Szrj 	  switch (r_type)
4254a9fa9459Szrj 	    {
4255a9fa9459Szrj 	    default:
4256a9fa9459Szrj 	      break;
4257a9fa9459Szrj 
4258a9fa9459Szrj 	    case R_X86_64_GOTPCREL:
4259a9fa9459Szrj 	    case R_X86_64_GOTPCRELX:
4260a9fa9459Szrj 	    case R_X86_64_REX_GOTPCRELX:
4261a9fa9459Szrj 	    case R_X86_64_GOTPCREL64:
4262a9fa9459Szrj 	      base_got = htab->elf.sgot;
4263a9fa9459Szrj 	      off = h->got.offset;
4264a9fa9459Szrj 
4265a9fa9459Szrj 	      if (base_got == NULL)
4266a9fa9459Szrj 		abort ();
4267a9fa9459Szrj 
4268a9fa9459Szrj 	      if (off == (bfd_vma) -1)
4269a9fa9459Szrj 		{
4270a9fa9459Szrj 		  /* We can't use h->got.offset here to save state, or
4271a9fa9459Szrj 		     even just remember the offset, as finish_dynamic_symbol
4272a9fa9459Szrj 		     would use that as offset into .got.  */
4273a9fa9459Szrj 
4274a9fa9459Szrj 		  if (h->plt.offset == (bfd_vma) -1)
4275a9fa9459Szrj 		    abort ();
4276a9fa9459Szrj 
4277a9fa9459Szrj 		  if (htab->elf.splt != NULL)
4278a9fa9459Szrj 		    {
4279a9fa9459Szrj 		      plt_index = h->plt.offset / plt_entry_size - 1;
4280a9fa9459Szrj 		      off = (plt_index + 3) * GOT_ENTRY_SIZE;
4281a9fa9459Szrj 		      base_got = htab->elf.sgotplt;
4282a9fa9459Szrj 		    }
4283a9fa9459Szrj 		  else
4284a9fa9459Szrj 		    {
4285a9fa9459Szrj 		      plt_index = h->plt.offset / plt_entry_size;
4286a9fa9459Szrj 		      off = plt_index * GOT_ENTRY_SIZE;
4287a9fa9459Szrj 		      base_got = htab->elf.igotplt;
4288a9fa9459Szrj 		    }
4289a9fa9459Szrj 
4290a9fa9459Szrj 		  if (h->dynindx == -1
4291a9fa9459Szrj 		      || h->forced_local
4292a9fa9459Szrj 		      || info->symbolic)
4293a9fa9459Szrj 		    {
4294a9fa9459Szrj 		      /* This references the local defitionion.  We must
4295a9fa9459Szrj 			 initialize this entry in the global offset table.
4296a9fa9459Szrj 			 Since the offset must always be a multiple of 8,
4297a9fa9459Szrj 			 we use the least significant bit to record
4298a9fa9459Szrj 			 whether we have initialized it already.
4299a9fa9459Szrj 
4300a9fa9459Szrj 			 When doing a dynamic link, we create a .rela.got
4301a9fa9459Szrj 			 relocation entry to initialize the value.  This
4302a9fa9459Szrj 			 is done in the finish_dynamic_symbol routine.	 */
4303a9fa9459Szrj 		      if ((off & 1) != 0)
4304a9fa9459Szrj 			off &= ~1;
4305a9fa9459Szrj 		      else
4306a9fa9459Szrj 			{
4307a9fa9459Szrj 			  bfd_put_64 (output_bfd, relocation,
4308a9fa9459Szrj 				      base_got->contents + off);
4309a9fa9459Szrj 			  /* Note that this is harmless for the GOTPLT64
4310a9fa9459Szrj 			     case, as -1 | 1 still is -1.  */
4311a9fa9459Szrj 			  h->got.offset |= 1;
4312a9fa9459Szrj 			}
4313a9fa9459Szrj 		    }
4314a9fa9459Szrj 		}
4315a9fa9459Szrj 
4316a9fa9459Szrj 	      relocation = (base_got->output_section->vma
4317a9fa9459Szrj 			    + base_got->output_offset + off);
4318a9fa9459Szrj 
4319a9fa9459Szrj 	      goto do_relocation;
4320a9fa9459Szrj 	    }
4321a9fa9459Szrj 
4322a9fa9459Szrj 	  if (h->plt.offset == (bfd_vma) -1)
4323a9fa9459Szrj 	    {
4324a9fa9459Szrj 	      /* Handle static pointers of STT_GNU_IFUNC symbols.  */
4325a9fa9459Szrj 	      if (r_type == htab->pointer_r_type
4326a9fa9459Szrj 		  && (input_section->flags & SEC_CODE) == 0)
4327a9fa9459Szrj 		goto do_ifunc_pointer;
4328a9fa9459Szrj 	      goto bad_ifunc_reloc;
4329a9fa9459Szrj 	    }
4330a9fa9459Szrj 
4331a9fa9459Szrj 	  /* STT_GNU_IFUNC symbol must go through PLT.  */
4332a9fa9459Szrj 	  if (htab->elf.splt != NULL)
4333a9fa9459Szrj 	    {
4334a9fa9459Szrj 	      if (htab->plt_bnd != NULL)
4335a9fa9459Szrj 		{
4336a9fa9459Szrj 		  resolved_plt = htab->plt_bnd;
4337a9fa9459Szrj 		  plt_offset = eh->plt_bnd.offset;
4338a9fa9459Szrj 		}
4339a9fa9459Szrj 	      else
4340a9fa9459Szrj 		{
4341a9fa9459Szrj 		  resolved_plt = htab->elf.splt;
4342a9fa9459Szrj 		  plt_offset =  h->plt.offset;
4343a9fa9459Szrj 		}
4344a9fa9459Szrj 	    }
4345a9fa9459Szrj 	  else
4346a9fa9459Szrj 	    {
4347a9fa9459Szrj 	      resolved_plt = htab->elf.iplt;
4348a9fa9459Szrj 	      plt_offset =  h->plt.offset;
4349a9fa9459Szrj 	    }
4350a9fa9459Szrj 
4351a9fa9459Szrj 	  relocation = (resolved_plt->output_section->vma
4352a9fa9459Szrj 			+ resolved_plt->output_offset + plt_offset);
4353a9fa9459Szrj 
4354a9fa9459Szrj 	  switch (r_type)
4355a9fa9459Szrj 	    {
4356a9fa9459Szrj 	    default:
4357a9fa9459Szrj bad_ifunc_reloc:
4358a9fa9459Szrj 	      if (h->root.root.string)
4359a9fa9459Szrj 		name = h->root.root.string;
4360a9fa9459Szrj 	      else
4361a9fa9459Szrj 		name = bfd_elf_sym_name (input_bfd, symtab_hdr, sym,
4362a9fa9459Szrj 					 NULL);
4363a9fa9459Szrj 	      (*_bfd_error_handler)
4364a9fa9459Szrj 		(_("%B: relocation %s against STT_GNU_IFUNC "
4365a9fa9459Szrj 		   "symbol `%s' isn't supported"), input_bfd,
4366a9fa9459Szrj 		 howto->name, name);
4367a9fa9459Szrj 	      bfd_set_error (bfd_error_bad_value);
4368a9fa9459Szrj 	      return FALSE;
4369a9fa9459Szrj 
4370a9fa9459Szrj 	    case R_X86_64_32S:
4371a9fa9459Szrj 	      if (bfd_link_pic (info))
4372a9fa9459Szrj 		abort ();
4373a9fa9459Szrj 	      goto do_relocation;
4374a9fa9459Szrj 
4375a9fa9459Szrj 	    case R_X86_64_32:
4376a9fa9459Szrj 	      if (ABI_64_P (output_bfd))
4377a9fa9459Szrj 		goto do_relocation;
4378a9fa9459Szrj 	      /* FALLTHROUGH */
4379a9fa9459Szrj 	    case R_X86_64_64:
4380a9fa9459Szrj do_ifunc_pointer:
4381a9fa9459Szrj 	      if (rel->r_addend != 0)
4382a9fa9459Szrj 		{
4383a9fa9459Szrj 		  if (h->root.root.string)
4384a9fa9459Szrj 		    name = h->root.root.string;
4385a9fa9459Szrj 		  else
4386a9fa9459Szrj 		    name = bfd_elf_sym_name (input_bfd, symtab_hdr,
4387a9fa9459Szrj 					     sym, NULL);
4388a9fa9459Szrj 		  (*_bfd_error_handler)
4389a9fa9459Szrj 		    (_("%B: relocation %s against STT_GNU_IFUNC "
4390a9fa9459Szrj 		       "symbol `%s' has non-zero addend: %d"),
4391a9fa9459Szrj 		     input_bfd, howto->name, name, rel->r_addend);
4392a9fa9459Szrj 		  bfd_set_error (bfd_error_bad_value);
4393a9fa9459Szrj 		  return FALSE;
4394a9fa9459Szrj 		}
4395a9fa9459Szrj 
4396a9fa9459Szrj 	      /* Generate dynamic relcoation only when there is a
4397a9fa9459Szrj 		 non-GOT reference in a shared object or there is no
4398a9fa9459Szrj 		 PLT.  */
4399a9fa9459Szrj 	      if ((bfd_link_pic (info) && h->non_got_ref)
4400a9fa9459Szrj 		  || h->plt.offset == (bfd_vma) -1)
4401a9fa9459Szrj 		{
4402a9fa9459Szrj 		  Elf_Internal_Rela outrel;
4403a9fa9459Szrj 		  asection *sreloc;
4404a9fa9459Szrj 
4405a9fa9459Szrj 		  /* Need a dynamic relocation to get the real function
4406a9fa9459Szrj 		     address.  */
4407a9fa9459Szrj 		  outrel.r_offset = _bfd_elf_section_offset (output_bfd,
4408a9fa9459Szrj 							     info,
4409a9fa9459Szrj 							     input_section,
4410a9fa9459Szrj 							     rel->r_offset);
4411a9fa9459Szrj 		  if (outrel.r_offset == (bfd_vma) -1
4412a9fa9459Szrj 		      || outrel.r_offset == (bfd_vma) -2)
4413a9fa9459Szrj 		    abort ();
4414a9fa9459Szrj 
4415a9fa9459Szrj 		  outrel.r_offset += (input_section->output_section->vma
4416a9fa9459Szrj 				      + input_section->output_offset);
4417a9fa9459Szrj 
4418a9fa9459Szrj 		  if (h->dynindx == -1
4419a9fa9459Szrj 		      || h->forced_local
4420a9fa9459Szrj 		      || bfd_link_executable (info))
4421a9fa9459Szrj 		    {
4422a9fa9459Szrj 		      /* This symbol is resolved locally.  */
4423a9fa9459Szrj 		      outrel.r_info = htab->r_info (0, R_X86_64_IRELATIVE);
4424a9fa9459Szrj 		      outrel.r_addend = (h->root.u.def.value
4425a9fa9459Szrj 					 + h->root.u.def.section->output_section->vma
4426a9fa9459Szrj 					 + h->root.u.def.section->output_offset);
4427a9fa9459Szrj 		    }
4428a9fa9459Szrj 		  else
4429a9fa9459Szrj 		    {
4430a9fa9459Szrj 		      outrel.r_info = htab->r_info (h->dynindx, r_type);
4431a9fa9459Szrj 		      outrel.r_addend = 0;
4432a9fa9459Szrj 		    }
4433a9fa9459Szrj 
4434a9fa9459Szrj 		  /* Dynamic relocations are stored in
4435a9fa9459Szrj 		     1. .rela.ifunc section in PIC object.
4436a9fa9459Szrj 		     2. .rela.got section in dynamic executable.
4437a9fa9459Szrj 		     3. .rela.iplt section in static executable.  */
4438a9fa9459Szrj 		  if (bfd_link_pic (info))
4439a9fa9459Szrj 		    sreloc = htab->elf.irelifunc;
4440a9fa9459Szrj 		  else if (htab->elf.splt != NULL)
4441a9fa9459Szrj 		    sreloc = htab->elf.srelgot;
4442a9fa9459Szrj 		  else
4443a9fa9459Szrj 		    sreloc = htab->elf.irelplt;
4444a9fa9459Szrj 		  elf_append_rela (output_bfd, sreloc, &outrel);
4445a9fa9459Szrj 
4446a9fa9459Szrj 		  /* If this reloc is against an external symbol, we
4447a9fa9459Szrj 		     do not want to fiddle with the addend.  Otherwise,
4448a9fa9459Szrj 		     we need to include the symbol value so that it
4449a9fa9459Szrj 		     becomes an addend for the dynamic reloc.  For an
4450a9fa9459Szrj 		     internal symbol, we have updated addend.  */
4451a9fa9459Szrj 		  continue;
4452a9fa9459Szrj 		}
4453a9fa9459Szrj 	      /* FALLTHROUGH */
4454a9fa9459Szrj 	    case R_X86_64_PC32:
4455a9fa9459Szrj 	    case R_X86_64_PC32_BND:
4456a9fa9459Szrj 	    case R_X86_64_PC64:
4457a9fa9459Szrj 	    case R_X86_64_PLT32:
4458a9fa9459Szrj 	    case R_X86_64_PLT32_BND:
4459a9fa9459Szrj 	      goto do_relocation;
4460a9fa9459Szrj 	    }
4461a9fa9459Szrj 	}
4462a9fa9459Szrj 
4463a9fa9459Szrj       resolved_to_zero = (eh != NULL
4464a9fa9459Szrj 			  && UNDEFINED_WEAK_RESOLVED_TO_ZERO (info,
4465a9fa9459Szrj 							      eh->has_got_reloc,
4466a9fa9459Szrj 							      eh));
4467a9fa9459Szrj 
4468a9fa9459Szrj       /* When generating a shared object, the relocations handled here are
4469a9fa9459Szrj 	 copied into the output file to be resolved at run time.  */
4470a9fa9459Szrj       switch (r_type)
4471a9fa9459Szrj 	{
4472a9fa9459Szrj 	case R_X86_64_GOT32:
4473a9fa9459Szrj 	case R_X86_64_GOT64:
4474a9fa9459Szrj 	  /* Relocation is to the entry for this symbol in the global
4475a9fa9459Szrj 	     offset table.  */
4476a9fa9459Szrj 	case R_X86_64_GOTPCREL:
4477a9fa9459Szrj 	case R_X86_64_GOTPCRELX:
4478a9fa9459Szrj 	case R_X86_64_REX_GOTPCRELX:
4479a9fa9459Szrj 	case R_X86_64_GOTPCREL64:
4480a9fa9459Szrj 	  /* Use global offset table entry as symbol value.  */
4481a9fa9459Szrj 	case R_X86_64_GOTPLT64:
4482a9fa9459Szrj 	  /* This is obsolete and treated the the same as GOT64.  */
4483a9fa9459Szrj 	  base_got = htab->elf.sgot;
4484a9fa9459Szrj 
4485a9fa9459Szrj 	  if (htab->elf.sgot == NULL)
4486a9fa9459Szrj 	    abort ();
4487a9fa9459Szrj 
4488a9fa9459Szrj 	  if (h != NULL)
4489a9fa9459Szrj 	    {
4490a9fa9459Szrj 	      bfd_boolean dyn;
4491a9fa9459Szrj 
4492a9fa9459Szrj 	      off = h->got.offset;
4493a9fa9459Szrj 	      if (h->needs_plt
4494a9fa9459Szrj 		  && h->plt.offset != (bfd_vma)-1
4495a9fa9459Szrj 		  && off == (bfd_vma)-1)
4496a9fa9459Szrj 		{
4497a9fa9459Szrj 		  /* We can't use h->got.offset here to save
4498a9fa9459Szrj 		     state, or even just remember the offset, as
4499a9fa9459Szrj 		     finish_dynamic_symbol would use that as offset into
4500a9fa9459Szrj 		     .got.  */
4501a9fa9459Szrj 		  bfd_vma plt_index = h->plt.offset / plt_entry_size - 1;
4502a9fa9459Szrj 		  off = (plt_index + 3) * GOT_ENTRY_SIZE;
4503a9fa9459Szrj 		  base_got = htab->elf.sgotplt;
4504a9fa9459Szrj 		}
4505a9fa9459Szrj 
4506a9fa9459Szrj 	      dyn = htab->elf.dynamic_sections_created;
4507a9fa9459Szrj 
4508a9fa9459Szrj 	      if (! WILL_CALL_FINISH_DYNAMIC_SYMBOL (dyn, bfd_link_pic (info), h)
4509a9fa9459Szrj 		  || (bfd_link_pic (info)
4510a9fa9459Szrj 		      && SYMBOL_REFERENCES_LOCAL (info, h))
4511a9fa9459Szrj 		  || (ELF_ST_VISIBILITY (h->other)
4512a9fa9459Szrj 		      && h->root.type == bfd_link_hash_undefweak))
4513a9fa9459Szrj 		{
4514a9fa9459Szrj 		  /* This is actually a static link, or it is a -Bsymbolic
4515a9fa9459Szrj 		     link and the symbol is defined locally, or the symbol
4516a9fa9459Szrj 		     was forced to be local because of a version file.	We
4517a9fa9459Szrj 		     must initialize this entry in the global offset table.
4518a9fa9459Szrj 		     Since the offset must always be a multiple of 8, we
4519a9fa9459Szrj 		     use the least significant bit to record whether we
4520a9fa9459Szrj 		     have initialized it already.
4521a9fa9459Szrj 
4522a9fa9459Szrj 		     When doing a dynamic link, we create a .rela.got
4523a9fa9459Szrj 		     relocation entry to initialize the value.	This is
4524a9fa9459Szrj 		     done in the finish_dynamic_symbol routine.	 */
4525a9fa9459Szrj 		  if ((off & 1) != 0)
4526a9fa9459Szrj 		    off &= ~1;
4527a9fa9459Szrj 		  else
4528a9fa9459Szrj 		    {
4529a9fa9459Szrj 		      bfd_put_64 (output_bfd, relocation,
4530a9fa9459Szrj 				  base_got->contents + off);
4531a9fa9459Szrj 		      /* Note that this is harmless for the GOTPLT64 case,
4532a9fa9459Szrj 			 as -1 | 1 still is -1.  */
4533a9fa9459Szrj 		      h->got.offset |= 1;
4534a9fa9459Szrj 		    }
4535a9fa9459Szrj 		}
4536a9fa9459Szrj 	      else
4537a9fa9459Szrj 		unresolved_reloc = FALSE;
4538a9fa9459Szrj 	    }
4539a9fa9459Szrj 	  else
4540a9fa9459Szrj 	    {
4541a9fa9459Szrj 	      if (local_got_offsets == NULL)
4542a9fa9459Szrj 		abort ();
4543a9fa9459Szrj 
4544a9fa9459Szrj 	      off = local_got_offsets[r_symndx];
4545a9fa9459Szrj 
4546a9fa9459Szrj 	      /* The offset must always be a multiple of 8.  We use
4547a9fa9459Szrj 		 the least significant bit to record whether we have
4548a9fa9459Szrj 		 already generated the necessary reloc.	 */
4549a9fa9459Szrj 	      if ((off & 1) != 0)
4550a9fa9459Szrj 		off &= ~1;
4551a9fa9459Szrj 	      else
4552a9fa9459Szrj 		{
4553a9fa9459Szrj 		  bfd_put_64 (output_bfd, relocation,
4554a9fa9459Szrj 			      base_got->contents + off);
4555a9fa9459Szrj 
4556a9fa9459Szrj 		  if (bfd_link_pic (info))
4557a9fa9459Szrj 		    {
4558a9fa9459Szrj 		      asection *s;
4559a9fa9459Szrj 		      Elf_Internal_Rela outrel;
4560a9fa9459Szrj 
4561a9fa9459Szrj 		      /* We need to generate a R_X86_64_RELATIVE reloc
4562a9fa9459Szrj 			 for the dynamic linker.  */
4563a9fa9459Szrj 		      s = htab->elf.srelgot;
4564a9fa9459Szrj 		      if (s == NULL)
4565a9fa9459Szrj 			abort ();
4566a9fa9459Szrj 
4567a9fa9459Szrj 		      outrel.r_offset = (base_got->output_section->vma
4568a9fa9459Szrj 					 + base_got->output_offset
4569a9fa9459Szrj 					 + off);
4570a9fa9459Szrj 		      outrel.r_info = htab->r_info (0, R_X86_64_RELATIVE);
4571a9fa9459Szrj 		      outrel.r_addend = relocation;
4572a9fa9459Szrj 		      elf_append_rela (output_bfd, s, &outrel);
4573a9fa9459Szrj 		    }
4574a9fa9459Szrj 
4575a9fa9459Szrj 		  local_got_offsets[r_symndx] |= 1;
4576a9fa9459Szrj 		}
4577a9fa9459Szrj 	    }
4578a9fa9459Szrj 
4579a9fa9459Szrj 	  if (off >= (bfd_vma) -2)
4580a9fa9459Szrj 	    abort ();
4581a9fa9459Szrj 
4582a9fa9459Szrj 	  relocation = base_got->output_section->vma
4583a9fa9459Szrj 		       + base_got->output_offset + off;
4584a9fa9459Szrj 	  if (r_type != R_X86_64_GOTPCREL
4585a9fa9459Szrj 	      && r_type != R_X86_64_GOTPCRELX
4586a9fa9459Szrj 	      && r_type != R_X86_64_REX_GOTPCRELX
4587a9fa9459Szrj 	      && r_type != R_X86_64_GOTPCREL64)
4588a9fa9459Szrj 	    relocation -= htab->elf.sgotplt->output_section->vma
4589a9fa9459Szrj 			  - htab->elf.sgotplt->output_offset;
4590a9fa9459Szrj 
4591a9fa9459Szrj 	  break;
4592a9fa9459Szrj 
4593a9fa9459Szrj 	case R_X86_64_GOTOFF64:
4594a9fa9459Szrj 	  /* Relocation is relative to the start of the global offset
4595a9fa9459Szrj 	     table.  */
4596a9fa9459Szrj 
4597a9fa9459Szrj 	  /* Check to make sure it isn't a protected function or data
4598a9fa9459Szrj 	     symbol for shared library since it may not be local when
4599a9fa9459Szrj 	     used as function address or with copy relocation.  We also
4600a9fa9459Szrj 	     need to make sure that a symbol is referenced locally.  */
4601a9fa9459Szrj 	  if (bfd_link_pic (info) && h)
4602a9fa9459Szrj 	    {
4603a9fa9459Szrj 	      if (!h->def_regular)
4604a9fa9459Szrj 		{
4605a9fa9459Szrj 		  const char *v;
4606a9fa9459Szrj 
4607a9fa9459Szrj 		  switch (ELF_ST_VISIBILITY (h->other))
4608a9fa9459Szrj 		    {
4609a9fa9459Szrj 		    case STV_HIDDEN:
4610a9fa9459Szrj 		      v = _("hidden symbol");
4611a9fa9459Szrj 		      break;
4612a9fa9459Szrj 		    case STV_INTERNAL:
4613a9fa9459Szrj 		      v = _("internal symbol");
4614a9fa9459Szrj 		      break;
4615a9fa9459Szrj 		    case STV_PROTECTED:
4616a9fa9459Szrj 		      v = _("protected symbol");
4617a9fa9459Szrj 		      break;
4618a9fa9459Szrj 		    default:
4619a9fa9459Szrj 		      v = _("symbol");
4620a9fa9459Szrj 		      break;
4621a9fa9459Szrj 		    }
4622a9fa9459Szrj 
4623a9fa9459Szrj 		  (*_bfd_error_handler)
4624a9fa9459Szrj 		    (_("%B: relocation R_X86_64_GOTOFF64 against undefined %s `%s' can not be used when making a shared object"),
4625a9fa9459Szrj 		     input_bfd, v, h->root.root.string);
4626a9fa9459Szrj 		  bfd_set_error (bfd_error_bad_value);
4627a9fa9459Szrj 		  return FALSE;
4628a9fa9459Szrj 		}
4629a9fa9459Szrj 	      else if (!bfd_link_executable (info)
4630a9fa9459Szrj 		       && !SYMBOL_REFERENCES_LOCAL (info, h)
4631a9fa9459Szrj 		       && (h->type == STT_FUNC
4632a9fa9459Szrj 			   || h->type == STT_OBJECT)
4633a9fa9459Szrj 		       && ELF_ST_VISIBILITY (h->other) == STV_PROTECTED)
4634a9fa9459Szrj 		{
4635a9fa9459Szrj 		  (*_bfd_error_handler)
4636a9fa9459Szrj 		    (_("%B: relocation R_X86_64_GOTOFF64 against protected %s `%s' can not be used when making a shared object"),
4637a9fa9459Szrj 		     input_bfd,
4638a9fa9459Szrj 		     h->type == STT_FUNC ? "function" : "data",
4639a9fa9459Szrj 		     h->root.root.string);
4640a9fa9459Szrj 		  bfd_set_error (bfd_error_bad_value);
4641a9fa9459Szrj 	      return FALSE;
4642a9fa9459Szrj 		}
4643a9fa9459Szrj 	    }
4644a9fa9459Szrj 
4645a9fa9459Szrj 	  /* Note that sgot is not involved in this
4646a9fa9459Szrj 	     calculation.  We always want the start of .got.plt.  If we
4647a9fa9459Szrj 	     defined _GLOBAL_OFFSET_TABLE_ in a different way, as is
4648a9fa9459Szrj 	     permitted by the ABI, we might have to change this
4649a9fa9459Szrj 	     calculation.  */
4650a9fa9459Szrj 	  relocation -= htab->elf.sgotplt->output_section->vma
4651a9fa9459Szrj 			+ htab->elf.sgotplt->output_offset;
4652a9fa9459Szrj 	  break;
4653a9fa9459Szrj 
4654a9fa9459Szrj 	case R_X86_64_GOTPC32:
4655a9fa9459Szrj 	case R_X86_64_GOTPC64:
4656a9fa9459Szrj 	  /* Use global offset table as symbol value.  */
4657a9fa9459Szrj 	  relocation = htab->elf.sgotplt->output_section->vma
4658a9fa9459Szrj 		       + htab->elf.sgotplt->output_offset;
4659a9fa9459Szrj 	  unresolved_reloc = FALSE;
4660a9fa9459Szrj 	  break;
4661a9fa9459Szrj 
4662a9fa9459Szrj 	case R_X86_64_PLTOFF64:
4663a9fa9459Szrj 	  /* Relocation is PLT entry relative to GOT.  For local
4664a9fa9459Szrj 	     symbols it's the symbol itself relative to GOT.  */
4665a9fa9459Szrj 	  if (h != NULL
4666a9fa9459Szrj 	      /* See PLT32 handling.  */
4667a9fa9459Szrj 	      && h->plt.offset != (bfd_vma) -1
4668a9fa9459Szrj 	      && htab->elf.splt != NULL)
4669a9fa9459Szrj 	    {
4670a9fa9459Szrj 	      if (htab->plt_bnd != NULL)
4671a9fa9459Szrj 		{
4672a9fa9459Szrj 		  resolved_plt = htab->plt_bnd;
4673a9fa9459Szrj 		  plt_offset = eh->plt_bnd.offset;
4674a9fa9459Szrj 		}
4675a9fa9459Szrj 	      else
4676a9fa9459Szrj 		{
4677a9fa9459Szrj 		  resolved_plt = htab->elf.splt;
4678a9fa9459Szrj 		  plt_offset = h->plt.offset;
4679a9fa9459Szrj 		}
4680a9fa9459Szrj 
4681a9fa9459Szrj 	      relocation = (resolved_plt->output_section->vma
4682a9fa9459Szrj 			    + resolved_plt->output_offset
4683a9fa9459Szrj 			    + plt_offset);
4684a9fa9459Szrj 	      unresolved_reloc = FALSE;
4685a9fa9459Szrj 	    }
4686a9fa9459Szrj 
4687a9fa9459Szrj 	  relocation -= htab->elf.sgotplt->output_section->vma
4688a9fa9459Szrj 			+ htab->elf.sgotplt->output_offset;
4689a9fa9459Szrj 	  break;
4690a9fa9459Szrj 
4691a9fa9459Szrj 	case R_X86_64_PLT32:
4692a9fa9459Szrj 	case R_X86_64_PLT32_BND:
4693a9fa9459Szrj 	  /* Relocation is to the entry for this symbol in the
4694a9fa9459Szrj 	     procedure linkage table.  */
4695a9fa9459Szrj 
4696a9fa9459Szrj 	  /* Resolve a PLT32 reloc against a local symbol directly,
4697a9fa9459Szrj 	     without using the procedure linkage table.	 */
4698a9fa9459Szrj 	  if (h == NULL)
4699a9fa9459Szrj 	    break;
4700a9fa9459Szrj 
4701a9fa9459Szrj 	  if ((h->plt.offset == (bfd_vma) -1
4702a9fa9459Szrj 	       && eh->plt_got.offset == (bfd_vma) -1)
4703a9fa9459Szrj 	      || htab->elf.splt == NULL)
4704a9fa9459Szrj 	    {
4705a9fa9459Szrj 	      /* We didn't make a PLT entry for this symbol.  This
4706a9fa9459Szrj 		 happens when statically linking PIC code, or when
4707a9fa9459Szrj 		 using -Bsymbolic.  */
4708a9fa9459Szrj 	      break;
4709a9fa9459Szrj 	    }
4710a9fa9459Szrj 
4711a9fa9459Szrj 	  if (h->plt.offset != (bfd_vma) -1)
4712a9fa9459Szrj 	    {
4713a9fa9459Szrj 	      if (htab->plt_bnd != NULL)
4714a9fa9459Szrj 		{
4715a9fa9459Szrj 		  resolved_plt = htab->plt_bnd;
4716a9fa9459Szrj 		  plt_offset = eh->plt_bnd.offset;
4717a9fa9459Szrj 		}
4718a9fa9459Szrj 	      else
4719a9fa9459Szrj 		{
4720a9fa9459Szrj 		  resolved_plt = htab->elf.splt;
4721a9fa9459Szrj 		  plt_offset = h->plt.offset;
4722a9fa9459Szrj 		}
4723a9fa9459Szrj 	    }
4724a9fa9459Szrj 	  else
4725a9fa9459Szrj 	    {
4726a9fa9459Szrj 	      /* Use the GOT PLT.  */
4727a9fa9459Szrj 	      resolved_plt = htab->plt_got;
4728a9fa9459Szrj 	      plt_offset = eh->plt_got.offset;
4729a9fa9459Szrj 	    }
4730a9fa9459Szrj 
4731a9fa9459Szrj 	  relocation = (resolved_plt->output_section->vma
4732a9fa9459Szrj 			+ resolved_plt->output_offset
4733a9fa9459Szrj 			+ plt_offset);
4734a9fa9459Szrj 	  unresolved_reloc = FALSE;
4735a9fa9459Szrj 	  break;
4736a9fa9459Szrj 
4737a9fa9459Szrj 	case R_X86_64_SIZE32:
4738a9fa9459Szrj 	case R_X86_64_SIZE64:
4739a9fa9459Szrj 	  /* Set to symbol size.  */
4740a9fa9459Szrj 	  relocation = st_size;
4741a9fa9459Szrj 	  goto direct;
4742a9fa9459Szrj 
4743a9fa9459Szrj 	case R_X86_64_PC8:
4744a9fa9459Szrj 	case R_X86_64_PC16:
4745a9fa9459Szrj 	case R_X86_64_PC32:
4746a9fa9459Szrj 	case R_X86_64_PC32_BND:
4747a9fa9459Szrj 	  /* Don't complain about -fPIC if the symbol is undefined when
4748a9fa9459Szrj 	     building executable unless it is unresolved weak symbol.  */
4749a9fa9459Szrj           if ((input_section->flags & SEC_ALLOC) != 0
4750a9fa9459Szrj 	      && (input_section->flags & SEC_READONLY) != 0
4751a9fa9459Szrj 	      && h != NULL
4752a9fa9459Szrj 	      && ((bfd_link_executable (info)
4753a9fa9459Szrj 		  && h->root.type == bfd_link_hash_undefweak
4754a9fa9459Szrj 		  && !resolved_to_zero)
4755a9fa9459Szrj 		  || (bfd_link_pic (info)
4756a9fa9459Szrj 		      && !(bfd_link_pie (info)
4757a9fa9459Szrj 			   && h->root.type == bfd_link_hash_undefined))))
4758a9fa9459Szrj 	    {
4759a9fa9459Szrj 	      bfd_boolean fail = FALSE;
4760a9fa9459Szrj 	      bfd_boolean branch
4761a9fa9459Szrj 		= ((r_type == R_X86_64_PC32
4762a9fa9459Szrj 		    || r_type == R_X86_64_PC32_BND)
4763a9fa9459Szrj 		   && is_32bit_relative_branch (contents, rel->r_offset));
4764a9fa9459Szrj 
4765a9fa9459Szrj 	      if (SYMBOL_REFERENCES_LOCAL (info, h))
4766a9fa9459Szrj 		{
4767a9fa9459Szrj 		  /* Symbol is referenced locally.  Make sure it is
4768a9fa9459Szrj 		     defined locally or for a branch.  */
4769a9fa9459Szrj 		  fail = !h->def_regular && !branch;
4770a9fa9459Szrj 		}
4771a9fa9459Szrj 	      else if (!(bfd_link_pie (info)
4772a9fa9459Szrj 			 && (h->needs_copy || eh->needs_copy)))
4773a9fa9459Szrj 		{
4774a9fa9459Szrj 		  /* Symbol doesn't need copy reloc and isn't referenced
4775a9fa9459Szrj 		     locally.  We only allow branch to symbol with
4776a9fa9459Szrj 		     non-default visibility. */
4777a9fa9459Szrj 		  fail = (!branch
4778a9fa9459Szrj 			  || ELF_ST_VISIBILITY (h->other) == STV_DEFAULT);
4779a9fa9459Szrj 		}
4780a9fa9459Szrj 
4781a9fa9459Szrj 	      if (fail)
4782a9fa9459Szrj 		return elf_x86_64_need_pic (input_bfd, input_section,
4783a9fa9459Szrj 					    h, NULL, NULL, howto);
4784a9fa9459Szrj 	    }
4785a9fa9459Szrj 	  /* Fall through.  */
4786a9fa9459Szrj 
4787a9fa9459Szrj 	case R_X86_64_8:
4788a9fa9459Szrj 	case R_X86_64_16:
4789a9fa9459Szrj 	case R_X86_64_32:
4790a9fa9459Szrj 	case R_X86_64_PC64:
4791a9fa9459Szrj 	case R_X86_64_64:
4792a9fa9459Szrj 	  /* FIXME: The ABI says the linker should make sure the value is
4793a9fa9459Szrj 	     the same when it's zeroextended to 64 bit.	 */
4794a9fa9459Szrj 
4795a9fa9459Szrj direct:
4796a9fa9459Szrj 	  if ((input_section->flags & SEC_ALLOC) == 0)
4797a9fa9459Szrj 	    break;
4798a9fa9459Szrj 
4799a9fa9459Szrj 	   /* Don't copy a pc-relative relocation into the output file
4800a9fa9459Szrj 	      if the symbol needs copy reloc or the symbol is undefined
4801a9fa9459Szrj 	      when building executable.  Copy dynamic function pointer
4802a9fa9459Szrj 	      relocations.  Don't generate dynamic relocations against
4803a9fa9459Szrj 	      resolved undefined weak symbols in PIE.  */
4804a9fa9459Szrj 	  if ((bfd_link_pic (info)
4805a9fa9459Szrj 	       && !(bfd_link_pie (info)
4806a9fa9459Szrj 		    && h != NULL
4807a9fa9459Szrj 		    && (h->needs_copy
4808a9fa9459Szrj 			|| eh->needs_copy
4809a9fa9459Szrj 			|| h->root.type == bfd_link_hash_undefined)
4810a9fa9459Szrj 		    && IS_X86_64_PCREL_TYPE (r_type))
4811a9fa9459Szrj 	       && (h == NULL
4812a9fa9459Szrj 		   || ((ELF_ST_VISIBILITY (h->other) == STV_DEFAULT
4813a9fa9459Szrj 			&& !resolved_to_zero)
4814a9fa9459Szrj 		       || h->root.type != bfd_link_hash_undefweak))
4815a9fa9459Szrj 	       && ((! IS_X86_64_PCREL_TYPE (r_type)
4816a9fa9459Szrj 		      && r_type != R_X86_64_SIZE32
4817a9fa9459Szrj 		      && r_type != R_X86_64_SIZE64)
4818a9fa9459Szrj 		   || ! SYMBOL_CALLS_LOCAL (info, h)))
4819a9fa9459Szrj 	      || (ELIMINATE_COPY_RELOCS
4820a9fa9459Szrj 		  && !bfd_link_pic (info)
4821a9fa9459Szrj 		  && h != NULL
4822a9fa9459Szrj 		  && h->dynindx != -1
4823a9fa9459Szrj 		  && (!h->non_got_ref
4824a9fa9459Szrj 		      || eh->func_pointer_refcount > 0
4825a9fa9459Szrj 		      || (h->root.type == bfd_link_hash_undefweak
4826a9fa9459Szrj 			  && !resolved_to_zero))
4827a9fa9459Szrj 		  && ((h->def_dynamic && !h->def_regular)
4828a9fa9459Szrj 		      /* Undefined weak symbol is bound locally when
4829a9fa9459Szrj 			 PIC is false.  */
4830a9fa9459Szrj 		      || h->root.type == bfd_link_hash_undefined)))
4831a9fa9459Szrj 	    {
4832a9fa9459Szrj 	      Elf_Internal_Rela outrel;
4833a9fa9459Szrj 	      bfd_boolean skip, relocate;
4834a9fa9459Szrj 	      asection *sreloc;
4835a9fa9459Szrj 
4836a9fa9459Szrj 	      /* When generating a shared object, these relocations
4837a9fa9459Szrj 		 are copied into the output file to be resolved at run
4838a9fa9459Szrj 		 time.	*/
4839a9fa9459Szrj 	      skip = FALSE;
4840a9fa9459Szrj 	      relocate = FALSE;
4841a9fa9459Szrj 
4842a9fa9459Szrj 	      outrel.r_offset =
4843a9fa9459Szrj 		_bfd_elf_section_offset (output_bfd, info, input_section,
4844a9fa9459Szrj 					 rel->r_offset);
4845a9fa9459Szrj 	      if (outrel.r_offset == (bfd_vma) -1)
4846a9fa9459Szrj 		skip = TRUE;
4847a9fa9459Szrj 	      else if (outrel.r_offset == (bfd_vma) -2)
4848a9fa9459Szrj 		skip = TRUE, relocate = TRUE;
4849a9fa9459Szrj 
4850a9fa9459Szrj 	      outrel.r_offset += (input_section->output_section->vma
4851a9fa9459Szrj 				  + input_section->output_offset);
4852a9fa9459Szrj 
4853a9fa9459Szrj 	      if (skip)
4854a9fa9459Szrj 		memset (&outrel, 0, sizeof outrel);
4855a9fa9459Szrj 
4856a9fa9459Szrj 	      /* h->dynindx may be -1 if this symbol was marked to
4857a9fa9459Szrj 		 become local.  */
4858a9fa9459Szrj 	      else if (h != NULL
4859a9fa9459Szrj 		       && h->dynindx != -1
4860a9fa9459Szrj 		       && (IS_X86_64_PCREL_TYPE (r_type)
4861a9fa9459Szrj 			   || !(bfd_link_executable (info)
4862a9fa9459Szrj 				|| SYMBOLIC_BIND (info, h))
4863a9fa9459Szrj 			   || ! h->def_regular))
4864a9fa9459Szrj 		{
4865a9fa9459Szrj 		  outrel.r_info = htab->r_info (h->dynindx, r_type);
4866a9fa9459Szrj 		  outrel.r_addend = rel->r_addend;
4867a9fa9459Szrj 		}
4868a9fa9459Szrj 	      else
4869a9fa9459Szrj 		{
4870a9fa9459Szrj 		  /* This symbol is local, or marked to become local.
4871a9fa9459Szrj 		     When relocation overflow check is disabled, we
4872a9fa9459Szrj 		     convert R_X86_64_32 to dynamic R_X86_64_RELATIVE.  */
4873a9fa9459Szrj 		  if (r_type == htab->pointer_r_type
4874a9fa9459Szrj 		      || (r_type == R_X86_64_32
4875a9fa9459Szrj 			  && info->no_reloc_overflow_check))
4876a9fa9459Szrj 		    {
4877a9fa9459Szrj 		      relocate = TRUE;
4878a9fa9459Szrj 		      outrel.r_info = htab->r_info (0, R_X86_64_RELATIVE);
4879a9fa9459Szrj 		      outrel.r_addend = relocation + rel->r_addend;
4880a9fa9459Szrj 		    }
4881a9fa9459Szrj 		  else if (r_type == R_X86_64_64
4882a9fa9459Szrj 			   && !ABI_64_P (output_bfd))
4883a9fa9459Szrj 		    {
4884a9fa9459Szrj 		      relocate = TRUE;
4885a9fa9459Szrj 		      outrel.r_info = htab->r_info (0,
4886a9fa9459Szrj 						    R_X86_64_RELATIVE64);
4887a9fa9459Szrj 		      outrel.r_addend = relocation + rel->r_addend;
4888a9fa9459Szrj 		      /* Check addend overflow.  */
4889a9fa9459Szrj 		      if ((outrel.r_addend & 0x80000000)
4890a9fa9459Szrj 			  != (rel->r_addend & 0x80000000))
4891a9fa9459Szrj 			{
4892a9fa9459Szrj 			  const char *name;
4893a9fa9459Szrj 			  int addend = rel->r_addend;
4894a9fa9459Szrj 			  if (h && h->root.root.string)
4895a9fa9459Szrj 			    name = h->root.root.string;
4896a9fa9459Szrj 			  else
4897a9fa9459Szrj 			    name = bfd_elf_sym_name (input_bfd, symtab_hdr,
4898a9fa9459Szrj 						     sym, NULL);
4899a9fa9459Szrj 			  if (addend < 0)
4900a9fa9459Szrj 			    (*_bfd_error_handler)
4901a9fa9459Szrj 			      (_("%B: addend -0x%x in relocation %s against "
4902a9fa9459Szrj 				 "symbol `%s' at 0x%lx in section `%A' is "
4903a9fa9459Szrj 				 "out of range"),
4904a9fa9459Szrj 			       input_bfd, input_section, addend,
4905a9fa9459Szrj 			       howto->name, name,
4906a9fa9459Szrj 			       (unsigned long) rel->r_offset);
4907a9fa9459Szrj 			  else
4908a9fa9459Szrj 			    (*_bfd_error_handler)
4909a9fa9459Szrj 			      (_("%B: addend 0x%x in relocation %s against "
4910a9fa9459Szrj 				 "symbol `%s' at 0x%lx in section `%A' is "
4911a9fa9459Szrj 				 "out of range"),
4912a9fa9459Szrj 			       input_bfd, input_section, addend,
4913a9fa9459Szrj 			       howto->name, name,
4914a9fa9459Szrj 			       (unsigned long) rel->r_offset);
4915a9fa9459Szrj 			  bfd_set_error (bfd_error_bad_value);
4916a9fa9459Szrj 			  return FALSE;
4917a9fa9459Szrj 			}
4918a9fa9459Szrj 		    }
4919a9fa9459Szrj 		  else
4920a9fa9459Szrj 		    {
4921a9fa9459Szrj 		      long sindx;
4922a9fa9459Szrj 
4923a9fa9459Szrj 		      if (bfd_is_abs_section (sec))
4924a9fa9459Szrj 			sindx = 0;
4925a9fa9459Szrj 		      else if (sec == NULL || sec->owner == NULL)
4926a9fa9459Szrj 			{
4927a9fa9459Szrj 			  bfd_set_error (bfd_error_bad_value);
4928a9fa9459Szrj 			  return FALSE;
4929a9fa9459Szrj 			}
4930a9fa9459Szrj 		      else
4931a9fa9459Szrj 			{
4932a9fa9459Szrj 			  asection *osec;
4933a9fa9459Szrj 
4934a9fa9459Szrj 			  /* We are turning this relocation into one
4935a9fa9459Szrj 			     against a section symbol.  It would be
4936a9fa9459Szrj 			     proper to subtract the symbol's value,
4937a9fa9459Szrj 			     osec->vma, from the emitted reloc addend,
4938a9fa9459Szrj 			     but ld.so expects buggy relocs.  */
4939a9fa9459Szrj 			  osec = sec->output_section;
4940a9fa9459Szrj 			  sindx = elf_section_data (osec)->dynindx;
4941a9fa9459Szrj 			  if (sindx == 0)
4942a9fa9459Szrj 			    {
4943a9fa9459Szrj 			      asection *oi = htab->elf.text_index_section;
4944a9fa9459Szrj 			      sindx = elf_section_data (oi)->dynindx;
4945a9fa9459Szrj 			    }
4946a9fa9459Szrj 			  BFD_ASSERT (sindx != 0);
4947a9fa9459Szrj 			}
4948a9fa9459Szrj 
4949a9fa9459Szrj 		      outrel.r_info = htab->r_info (sindx, r_type);
4950a9fa9459Szrj 		      outrel.r_addend = relocation + rel->r_addend;
4951a9fa9459Szrj 		    }
4952a9fa9459Szrj 		}
4953a9fa9459Szrj 
4954a9fa9459Szrj 	      sreloc = elf_section_data (input_section)->sreloc;
4955a9fa9459Szrj 
4956a9fa9459Szrj 	      if (sreloc == NULL || sreloc->contents == NULL)
4957a9fa9459Szrj 		{
4958a9fa9459Szrj 		  r = bfd_reloc_notsupported;
4959a9fa9459Szrj 		  goto check_relocation_error;
4960a9fa9459Szrj 		}
4961a9fa9459Szrj 
4962a9fa9459Szrj 	      elf_append_rela (output_bfd, sreloc, &outrel);
4963a9fa9459Szrj 
4964a9fa9459Szrj 	      /* If this reloc is against an external symbol, we do
4965a9fa9459Szrj 		 not want to fiddle with the addend.  Otherwise, we
4966a9fa9459Szrj 		 need to include the symbol value so that it becomes
4967a9fa9459Szrj 		 an addend for the dynamic reloc.  */
4968a9fa9459Szrj 	      if (! relocate)
4969a9fa9459Szrj 		continue;
4970a9fa9459Szrj 	    }
4971a9fa9459Szrj 
4972a9fa9459Szrj 	  break;
4973a9fa9459Szrj 
4974a9fa9459Szrj 	case R_X86_64_TLSGD:
4975a9fa9459Szrj 	case R_X86_64_GOTPC32_TLSDESC:
4976a9fa9459Szrj 	case R_X86_64_TLSDESC_CALL:
4977a9fa9459Szrj 	case R_X86_64_GOTTPOFF:
4978a9fa9459Szrj 	  tls_type = GOT_UNKNOWN;
4979a9fa9459Szrj 	  if (h == NULL && local_got_offsets)
4980a9fa9459Szrj 	    tls_type = elf_x86_64_local_got_tls_type (input_bfd) [r_symndx];
4981a9fa9459Szrj 	  else if (h != NULL)
4982a9fa9459Szrj 	    tls_type = elf_x86_64_hash_entry (h)->tls_type;
4983a9fa9459Szrj 
4984a9fa9459Szrj 	  if (! elf_x86_64_tls_transition (info, input_bfd,
4985a9fa9459Szrj 					   input_section, contents,
4986a9fa9459Szrj 					   symtab_hdr, sym_hashes,
4987a9fa9459Szrj 					   &r_type, tls_type, rel,
4988a9fa9459Szrj 					   relend, h, r_symndx, TRUE))
4989a9fa9459Szrj 	    return FALSE;
4990a9fa9459Szrj 
4991a9fa9459Szrj 	  if (r_type == R_X86_64_TPOFF32)
4992a9fa9459Szrj 	    {
4993a9fa9459Szrj 	      bfd_vma roff = rel->r_offset;
4994a9fa9459Szrj 
4995a9fa9459Szrj 	      BFD_ASSERT (! unresolved_reloc);
4996a9fa9459Szrj 
4997a9fa9459Szrj 	      if (ELF32_R_TYPE (rel->r_info) == R_X86_64_TLSGD)
4998a9fa9459Szrj 		{
4999a9fa9459Szrj 		  /* GD->LE transition.  For 64bit, change
5000a9fa9459Szrj 			.byte 0x66; leaq foo@tlsgd(%rip), %rdi
5001a9fa9459Szrj 			.word 0x6666; rex64; call __tls_get_addr@PLT
5002a9fa9459Szrj 		     or
5003a9fa9459Szrj 			.byte 0x66; leaq foo@tlsgd(%rip), %rdi
5004a9fa9459Szrj 			.byte 0x66; rex64
5005a9fa9459Szrj 			call *__tls_get_addr@GOTPCREL(%rip)
5006a9fa9459Szrj 			which may be converted to
5007a9fa9459Szrj 			addr32 call __tls_get_addr
5008a9fa9459Szrj 		     into:
5009a9fa9459Szrj 			movq %fs:0, %rax
5010a9fa9459Szrj 			leaq foo@tpoff(%rax), %rax
5011a9fa9459Szrj 		     For 32bit, change
5012a9fa9459Szrj 			leaq foo@tlsgd(%rip), %rdi
5013a9fa9459Szrj 			.word 0x6666; rex64; call __tls_get_addr@PLT
5014a9fa9459Szrj 		     or
5015a9fa9459Szrj 			leaq foo@tlsgd(%rip), %rdi
5016a9fa9459Szrj 			.byte 0x66; rex64
5017a9fa9459Szrj 			call *__tls_get_addr@GOTPCREL(%rip)
5018a9fa9459Szrj 			which may be converted to
5019a9fa9459Szrj 			addr32 call __tls_get_addr
5020a9fa9459Szrj 		     into:
5021a9fa9459Szrj 			movl %fs:0, %eax
5022a9fa9459Szrj 			leaq foo@tpoff(%rax), %rax
5023a9fa9459Szrj 		     For largepic, change:
5024a9fa9459Szrj 			leaq foo@tlsgd(%rip), %rdi
5025a9fa9459Szrj 			movabsq $__tls_get_addr@pltoff, %rax
5026a9fa9459Szrj 			addq %r15, %rax
5027a9fa9459Szrj 			call *%rax
5028a9fa9459Szrj 		     into:
5029a9fa9459Szrj 			movq %fs:0, %rax
5030a9fa9459Szrj 			leaq foo@tpoff(%rax), %rax
5031a9fa9459Szrj 			nopw 0x0(%rax,%rax,1)  */
5032a9fa9459Szrj 		  int largepic = 0;
5033a9fa9459Szrj 		  if (ABI_64_P (output_bfd))
5034a9fa9459Szrj 		    {
5035a9fa9459Szrj 		      if (contents[roff + 5] == 0xb8)
5036a9fa9459Szrj 			{
5037a9fa9459Szrj 			  memcpy (contents + roff - 3,
5038a9fa9459Szrj 				  "\x64\x48\x8b\x04\x25\0\0\0\0\x48\x8d\x80"
5039a9fa9459Szrj 				  "\0\0\0\0\x66\x0f\x1f\x44\0", 22);
5040a9fa9459Szrj 			  largepic = 1;
5041a9fa9459Szrj 			}
5042a9fa9459Szrj 		      else
5043a9fa9459Szrj 			memcpy (contents + roff - 4,
5044a9fa9459Szrj 				"\x64\x48\x8b\x04\x25\0\0\0\0\x48\x8d\x80\0\0\0",
5045a9fa9459Szrj 				16);
5046a9fa9459Szrj 		    }
5047a9fa9459Szrj 		  else
5048a9fa9459Szrj 		    memcpy (contents + roff - 3,
5049a9fa9459Szrj 			    "\x64\x8b\x04\x25\0\0\0\0\x48\x8d\x80\0\0\0",
5050a9fa9459Szrj 			    15);
5051a9fa9459Szrj 		  bfd_put_32 (output_bfd,
5052a9fa9459Szrj 			      elf_x86_64_tpoff (info, relocation),
5053a9fa9459Szrj 			      contents + roff + 8 + largepic);
5054a9fa9459Szrj 		  /* Skip R_X86_64_PC32, R_X86_64_PLT32,
5055a9fa9459Szrj 		     R_X86_64_GOTPCRELX and R_X86_64_PLTOFF64.  */
5056a9fa9459Szrj 		  rel++;
5057a9fa9459Szrj 		  wrel++;
5058a9fa9459Szrj 		  continue;
5059a9fa9459Szrj 		}
5060a9fa9459Szrj 	      else if (ELF32_R_TYPE (rel->r_info) == R_X86_64_GOTPC32_TLSDESC)
5061a9fa9459Szrj 		{
5062a9fa9459Szrj 		  /* GDesc -> LE transition.
5063a9fa9459Szrj 		     It's originally something like:
5064a9fa9459Szrj 		     leaq x@tlsdesc(%rip), %rax
5065a9fa9459Szrj 
5066a9fa9459Szrj 		     Change it to:
5067a9fa9459Szrj 		     movl $x@tpoff, %rax.  */
5068a9fa9459Szrj 
5069a9fa9459Szrj 		  unsigned int val, type;
5070a9fa9459Szrj 
5071a9fa9459Szrj 		  type = bfd_get_8 (input_bfd, contents + roff - 3);
5072a9fa9459Szrj 		  val = bfd_get_8 (input_bfd, contents + roff - 1);
5073a9fa9459Szrj 		  bfd_put_8 (output_bfd, 0x48 | ((type >> 2) & 1),
5074a9fa9459Szrj 			     contents + roff - 3);
5075a9fa9459Szrj 		  bfd_put_8 (output_bfd, 0xc7, contents + roff - 2);
5076a9fa9459Szrj 		  bfd_put_8 (output_bfd, 0xc0 | ((val >> 3) & 7),
5077a9fa9459Szrj 			     contents + roff - 1);
5078a9fa9459Szrj 		  bfd_put_32 (output_bfd,
5079a9fa9459Szrj 			      elf_x86_64_tpoff (info, relocation),
5080a9fa9459Szrj 			      contents + roff);
5081a9fa9459Szrj 		  continue;
5082a9fa9459Szrj 		}
5083a9fa9459Szrj 	      else if (ELF32_R_TYPE (rel->r_info) == R_X86_64_TLSDESC_CALL)
5084a9fa9459Szrj 		{
5085a9fa9459Szrj 		  /* GDesc -> LE transition.
5086a9fa9459Szrj 		     It's originally:
5087a9fa9459Szrj 		     call *(%rax)
5088a9fa9459Szrj 		     Turn it into:
5089a9fa9459Szrj 		     xchg %ax,%ax.  */
5090a9fa9459Szrj 		  bfd_put_8 (output_bfd, 0x66, contents + roff);
5091a9fa9459Szrj 		  bfd_put_8 (output_bfd, 0x90, contents + roff + 1);
5092a9fa9459Szrj 		  continue;
5093a9fa9459Szrj 		}
5094a9fa9459Szrj 	      else if (ELF32_R_TYPE (rel->r_info) == R_X86_64_GOTTPOFF)
5095a9fa9459Szrj 		{
5096a9fa9459Szrj 		  /* IE->LE transition:
5097a9fa9459Szrj 		     For 64bit, originally it can be one of:
5098a9fa9459Szrj 		     movq foo@gottpoff(%rip), %reg
5099a9fa9459Szrj 		     addq foo@gottpoff(%rip), %reg
5100a9fa9459Szrj 		     We change it into:
5101a9fa9459Szrj 		     movq $foo, %reg
5102a9fa9459Szrj 		     leaq foo(%reg), %reg
5103a9fa9459Szrj 		     addq $foo, %reg.
5104a9fa9459Szrj 		     For 32bit, originally it can be one of:
5105a9fa9459Szrj 		     movq foo@gottpoff(%rip), %reg
5106a9fa9459Szrj 		     addl foo@gottpoff(%rip), %reg
5107a9fa9459Szrj 		     We change it into:
5108a9fa9459Szrj 		     movq $foo, %reg
5109a9fa9459Szrj 		     leal foo(%reg), %reg
5110a9fa9459Szrj 		     addl $foo, %reg. */
5111a9fa9459Szrj 
5112a9fa9459Szrj 		  unsigned int val, type, reg;
5113a9fa9459Szrj 
5114a9fa9459Szrj 		  if (roff >= 3)
5115a9fa9459Szrj 		    val = bfd_get_8 (input_bfd, contents + roff - 3);
5116a9fa9459Szrj 		  else
5117a9fa9459Szrj 		    val = 0;
5118a9fa9459Szrj 		  type = bfd_get_8 (input_bfd, contents + roff - 2);
5119a9fa9459Szrj 		  reg = bfd_get_8 (input_bfd, contents + roff - 1);
5120a9fa9459Szrj 		  reg >>= 3;
5121a9fa9459Szrj 		  if (type == 0x8b)
5122a9fa9459Szrj 		    {
5123a9fa9459Szrj 		      /* movq */
5124a9fa9459Szrj 		      if (val == 0x4c)
5125a9fa9459Szrj 			bfd_put_8 (output_bfd, 0x49,
5126a9fa9459Szrj 				   contents + roff - 3);
5127a9fa9459Szrj 		      else if (!ABI_64_P (output_bfd) && val == 0x44)
5128a9fa9459Szrj 			bfd_put_8 (output_bfd, 0x41,
5129a9fa9459Szrj 				   contents + roff - 3);
5130a9fa9459Szrj 		      bfd_put_8 (output_bfd, 0xc7,
5131a9fa9459Szrj 				 contents + roff - 2);
5132a9fa9459Szrj 		      bfd_put_8 (output_bfd, 0xc0 | reg,
5133a9fa9459Szrj 				 contents + roff - 1);
5134a9fa9459Szrj 		    }
5135a9fa9459Szrj 		  else if (reg == 4)
5136a9fa9459Szrj 		    {
5137a9fa9459Szrj 		      /* addq/addl -> addq/addl - addressing with %rsp/%r12
5138a9fa9459Szrj 			 is special  */
5139a9fa9459Szrj 		      if (val == 0x4c)
5140a9fa9459Szrj 			bfd_put_8 (output_bfd, 0x49,
5141a9fa9459Szrj 				   contents + roff - 3);
5142a9fa9459Szrj 		      else if (!ABI_64_P (output_bfd) && val == 0x44)
5143a9fa9459Szrj 			bfd_put_8 (output_bfd, 0x41,
5144a9fa9459Szrj 				   contents + roff - 3);
5145a9fa9459Szrj 		      bfd_put_8 (output_bfd, 0x81,
5146a9fa9459Szrj 				 contents + roff - 2);
5147a9fa9459Szrj 		      bfd_put_8 (output_bfd, 0xc0 | reg,
5148a9fa9459Szrj 				 contents + roff - 1);
5149a9fa9459Szrj 		    }
5150a9fa9459Szrj 		  else
5151a9fa9459Szrj 		    {
5152a9fa9459Szrj 		      /* addq/addl -> leaq/leal */
5153a9fa9459Szrj 		      if (val == 0x4c)
5154a9fa9459Szrj 			bfd_put_8 (output_bfd, 0x4d,
5155a9fa9459Szrj 				   contents + roff - 3);
5156a9fa9459Szrj 		      else if (!ABI_64_P (output_bfd) && val == 0x44)
5157a9fa9459Szrj 			bfd_put_8 (output_bfd, 0x45,
5158a9fa9459Szrj 				   contents + roff - 3);
5159a9fa9459Szrj 		      bfd_put_8 (output_bfd, 0x8d,
5160a9fa9459Szrj 				 contents + roff - 2);
5161a9fa9459Szrj 		      bfd_put_8 (output_bfd, 0x80 | reg | (reg << 3),
5162a9fa9459Szrj 				 contents + roff - 1);
5163a9fa9459Szrj 		    }
5164a9fa9459Szrj 		  bfd_put_32 (output_bfd,
5165a9fa9459Szrj 			      elf_x86_64_tpoff (info, relocation),
5166a9fa9459Szrj 			      contents + roff);
5167a9fa9459Szrj 		  continue;
5168a9fa9459Szrj 		}
5169a9fa9459Szrj 	      else
5170a9fa9459Szrj 		BFD_ASSERT (FALSE);
5171a9fa9459Szrj 	    }
5172a9fa9459Szrj 
5173a9fa9459Szrj 	  if (htab->elf.sgot == NULL)
5174a9fa9459Szrj 	    abort ();
5175a9fa9459Szrj 
5176a9fa9459Szrj 	  if (h != NULL)
5177a9fa9459Szrj 	    {
5178a9fa9459Szrj 	      off = h->got.offset;
5179a9fa9459Szrj 	      offplt = elf_x86_64_hash_entry (h)->tlsdesc_got;
5180a9fa9459Szrj 	    }
5181a9fa9459Szrj 	  else
5182a9fa9459Szrj 	    {
5183a9fa9459Szrj 	      if (local_got_offsets == NULL)
5184a9fa9459Szrj 		abort ();
5185a9fa9459Szrj 
5186a9fa9459Szrj 	      off = local_got_offsets[r_symndx];
5187a9fa9459Szrj 	      offplt = local_tlsdesc_gotents[r_symndx];
5188a9fa9459Szrj 	    }
5189a9fa9459Szrj 
5190a9fa9459Szrj 	  if ((off & 1) != 0)
5191a9fa9459Szrj 	    off &= ~1;
5192a9fa9459Szrj 	  else
5193a9fa9459Szrj 	    {
5194a9fa9459Szrj 	      Elf_Internal_Rela outrel;
5195a9fa9459Szrj 	      int dr_type, indx;
5196a9fa9459Szrj 	      asection *sreloc;
5197a9fa9459Szrj 
5198a9fa9459Szrj 	      if (htab->elf.srelgot == NULL)
5199a9fa9459Szrj 		abort ();
5200a9fa9459Szrj 
5201a9fa9459Szrj 	      indx = h && h->dynindx != -1 ? h->dynindx : 0;
5202a9fa9459Szrj 
5203a9fa9459Szrj 	      if (GOT_TLS_GDESC_P (tls_type))
5204a9fa9459Szrj 		{
5205a9fa9459Szrj 		  outrel.r_info = htab->r_info (indx, R_X86_64_TLSDESC);
5206a9fa9459Szrj 		  BFD_ASSERT (htab->sgotplt_jump_table_size + offplt
5207a9fa9459Szrj 			      + 2 * GOT_ENTRY_SIZE <= htab->elf.sgotplt->size);
5208a9fa9459Szrj 		  outrel.r_offset = (htab->elf.sgotplt->output_section->vma
5209a9fa9459Szrj 				     + htab->elf.sgotplt->output_offset
5210a9fa9459Szrj 				     + offplt
5211a9fa9459Szrj 				     + htab->sgotplt_jump_table_size);
5212a9fa9459Szrj 		  sreloc = htab->elf.srelplt;
5213a9fa9459Szrj 		  if (indx == 0)
5214a9fa9459Szrj 		    outrel.r_addend = relocation - elf_x86_64_dtpoff_base (info);
5215a9fa9459Szrj 		  else
5216a9fa9459Szrj 		    outrel.r_addend = 0;
5217a9fa9459Szrj 		  elf_append_rela (output_bfd, sreloc, &outrel);
5218a9fa9459Szrj 		}
5219a9fa9459Szrj 
5220a9fa9459Szrj 	      sreloc = htab->elf.srelgot;
5221a9fa9459Szrj 
5222a9fa9459Szrj 	      outrel.r_offset = (htab->elf.sgot->output_section->vma
5223a9fa9459Szrj 				 + htab->elf.sgot->output_offset + off);
5224a9fa9459Szrj 
5225a9fa9459Szrj 	      if (GOT_TLS_GD_P (tls_type))
5226a9fa9459Szrj 		dr_type = R_X86_64_DTPMOD64;
5227a9fa9459Szrj 	      else if (GOT_TLS_GDESC_P (tls_type))
5228a9fa9459Szrj 		goto dr_done;
5229a9fa9459Szrj 	      else
5230a9fa9459Szrj 		dr_type = R_X86_64_TPOFF64;
5231a9fa9459Szrj 
5232a9fa9459Szrj 	      bfd_put_64 (output_bfd, 0, htab->elf.sgot->contents + off);
5233a9fa9459Szrj 	      outrel.r_addend = 0;
5234a9fa9459Szrj 	      if ((dr_type == R_X86_64_TPOFF64
5235a9fa9459Szrj 		   || dr_type == R_X86_64_TLSDESC) && indx == 0)
5236a9fa9459Szrj 		outrel.r_addend = relocation - elf_x86_64_dtpoff_base (info);
5237a9fa9459Szrj 	      outrel.r_info = htab->r_info (indx, dr_type);
5238a9fa9459Szrj 
5239a9fa9459Szrj 	      elf_append_rela (output_bfd, sreloc, &outrel);
5240a9fa9459Szrj 
5241a9fa9459Szrj 	      if (GOT_TLS_GD_P (tls_type))
5242a9fa9459Szrj 		{
5243a9fa9459Szrj 		  if (indx == 0)
5244a9fa9459Szrj 		    {
5245a9fa9459Szrj 		      BFD_ASSERT (! unresolved_reloc);
5246a9fa9459Szrj 		      bfd_put_64 (output_bfd,
5247a9fa9459Szrj 				  relocation - elf_x86_64_dtpoff_base (info),
5248a9fa9459Szrj 				  htab->elf.sgot->contents + off + GOT_ENTRY_SIZE);
5249a9fa9459Szrj 		    }
5250a9fa9459Szrj 		  else
5251a9fa9459Szrj 		    {
5252a9fa9459Szrj 		      bfd_put_64 (output_bfd, 0,
5253a9fa9459Szrj 				  htab->elf.sgot->contents + off + GOT_ENTRY_SIZE);
5254a9fa9459Szrj 		      outrel.r_info = htab->r_info (indx,
5255a9fa9459Szrj 						    R_X86_64_DTPOFF64);
5256a9fa9459Szrj 		      outrel.r_offset += GOT_ENTRY_SIZE;
5257a9fa9459Szrj 		      elf_append_rela (output_bfd, sreloc,
5258a9fa9459Szrj 						&outrel);
5259a9fa9459Szrj 		    }
5260a9fa9459Szrj 		}
5261a9fa9459Szrj 
5262a9fa9459Szrj 	    dr_done:
5263a9fa9459Szrj 	      if (h != NULL)
5264a9fa9459Szrj 		h->got.offset |= 1;
5265a9fa9459Szrj 	      else
5266a9fa9459Szrj 		local_got_offsets[r_symndx] |= 1;
5267a9fa9459Szrj 	    }
5268a9fa9459Szrj 
5269a9fa9459Szrj 	  if (off >= (bfd_vma) -2
5270a9fa9459Szrj 	      && ! GOT_TLS_GDESC_P (tls_type))
5271a9fa9459Szrj 	    abort ();
5272a9fa9459Szrj 	  if (r_type == ELF32_R_TYPE (rel->r_info))
5273a9fa9459Szrj 	    {
5274a9fa9459Szrj 	      if (r_type == R_X86_64_GOTPC32_TLSDESC
5275a9fa9459Szrj 		  || r_type == R_X86_64_TLSDESC_CALL)
5276a9fa9459Szrj 		relocation = htab->elf.sgotplt->output_section->vma
5277a9fa9459Szrj 		  + htab->elf.sgotplt->output_offset
5278a9fa9459Szrj 		  + offplt + htab->sgotplt_jump_table_size;
5279a9fa9459Szrj 	      else
5280a9fa9459Szrj 		relocation = htab->elf.sgot->output_section->vma
5281a9fa9459Szrj 		  + htab->elf.sgot->output_offset + off;
5282a9fa9459Szrj 	      unresolved_reloc = FALSE;
5283a9fa9459Szrj 	    }
5284a9fa9459Szrj 	  else
5285a9fa9459Szrj 	    {
5286a9fa9459Szrj 	      bfd_vma roff = rel->r_offset;
5287a9fa9459Szrj 
5288a9fa9459Szrj 	      if (ELF32_R_TYPE (rel->r_info) == R_X86_64_TLSGD)
5289a9fa9459Szrj 		{
5290a9fa9459Szrj 		  /* GD->IE transition.  For 64bit, change
5291a9fa9459Szrj 			.byte 0x66; leaq foo@tlsgd(%rip), %rdi
5292a9fa9459Szrj 			.word 0x6666; rex64; call __tls_get_addr@PLT
5293a9fa9459Szrj 		     or
5294a9fa9459Szrj 			.byte 0x66; leaq foo@tlsgd(%rip), %rdi
5295a9fa9459Szrj 			.byte 0x66; rex64
5296a9fa9459Szrj 			call *__tls_get_addr@GOTPCREL(%rip
5297a9fa9459Szrj 			which may be converted to
5298a9fa9459Szrj 			addr32 call __tls_get_addr
5299a9fa9459Szrj 		     into:
5300a9fa9459Szrj 			movq %fs:0, %rax
5301a9fa9459Szrj 			addq foo@gottpoff(%rip), %rax
5302a9fa9459Szrj 		     For 32bit, change
5303a9fa9459Szrj 			leaq foo@tlsgd(%rip), %rdi
5304a9fa9459Szrj 			.word 0x6666; rex64; call __tls_get_addr@PLT
5305a9fa9459Szrj 		     or
5306a9fa9459Szrj 			leaq foo@tlsgd(%rip), %rdi
5307a9fa9459Szrj 			.byte 0x66; rex64;
5308a9fa9459Szrj 			call *__tls_get_addr@GOTPCREL(%rip)
5309a9fa9459Szrj 			which may be converted to
5310a9fa9459Szrj 			addr32 call __tls_get_addr
5311a9fa9459Szrj 		     into:
5312a9fa9459Szrj 			movl %fs:0, %eax
5313a9fa9459Szrj 			addq foo@gottpoff(%rip), %rax
5314a9fa9459Szrj 		     For largepic, change:
5315a9fa9459Szrj 			leaq foo@tlsgd(%rip), %rdi
5316a9fa9459Szrj 			movabsq $__tls_get_addr@pltoff, %rax
5317a9fa9459Szrj 			addq %r15, %rax
5318a9fa9459Szrj 			call *%rax
5319a9fa9459Szrj 		     into:
5320a9fa9459Szrj 			movq %fs:0, %rax
5321a9fa9459Szrj 			addq foo@gottpoff(%rax), %rax
5322a9fa9459Szrj 			nopw 0x0(%rax,%rax,1)  */
5323a9fa9459Szrj 		  int largepic = 0;
5324a9fa9459Szrj 		  if (ABI_64_P (output_bfd))
5325a9fa9459Szrj 		    {
5326a9fa9459Szrj 		      if (contents[roff + 5] == 0xb8)
5327a9fa9459Szrj 			{
5328a9fa9459Szrj 			  memcpy (contents + roff - 3,
5329a9fa9459Szrj 				  "\x64\x48\x8b\x04\x25\0\0\0\0\x48\x03\x05"
5330a9fa9459Szrj 				  "\0\0\0\0\x66\x0f\x1f\x44\0", 22);
5331a9fa9459Szrj 			  largepic = 1;
5332a9fa9459Szrj 			}
5333a9fa9459Szrj 		      else
5334a9fa9459Szrj 			memcpy (contents + roff - 4,
5335a9fa9459Szrj 				"\x64\x48\x8b\x04\x25\0\0\0\0\x48\x03\x05\0\0\0",
5336a9fa9459Szrj 				16);
5337a9fa9459Szrj 		    }
5338a9fa9459Szrj 		  else
5339a9fa9459Szrj 		    memcpy (contents + roff - 3,
5340a9fa9459Szrj 			    "\x64\x8b\x04\x25\0\0\0\0\x48\x03\x05\0\0\0",
5341a9fa9459Szrj 			    15);
5342a9fa9459Szrj 
5343a9fa9459Szrj 		  relocation = (htab->elf.sgot->output_section->vma
5344a9fa9459Szrj 				+ htab->elf.sgot->output_offset + off
5345a9fa9459Szrj 				- roff
5346a9fa9459Szrj 				- largepic
5347a9fa9459Szrj 				- input_section->output_section->vma
5348a9fa9459Szrj 				- input_section->output_offset
5349a9fa9459Szrj 				- 12);
5350a9fa9459Szrj 		  bfd_put_32 (output_bfd, relocation,
5351a9fa9459Szrj 			      contents + roff + 8 + largepic);
5352a9fa9459Szrj 		  /* Skip R_X86_64_PLT32/R_X86_64_PLTOFF64.  */
5353a9fa9459Szrj 		  rel++;
5354a9fa9459Szrj 		  wrel++;
5355a9fa9459Szrj 		  continue;
5356a9fa9459Szrj 		}
5357a9fa9459Szrj 	      else if (ELF32_R_TYPE (rel->r_info) == R_X86_64_GOTPC32_TLSDESC)
5358a9fa9459Szrj 		{
5359a9fa9459Szrj 		  /* GDesc -> IE transition.
5360a9fa9459Szrj 		     It's originally something like:
5361a9fa9459Szrj 		     leaq x@tlsdesc(%rip), %rax
5362a9fa9459Szrj 
5363a9fa9459Szrj 		     Change it to:
5364a9fa9459Szrj 		     movq x@gottpoff(%rip), %rax # before xchg %ax,%ax.  */
5365a9fa9459Szrj 
5366a9fa9459Szrj 		  /* Now modify the instruction as appropriate. To
5367a9fa9459Szrj 		     turn a leaq into a movq in the form we use it, it
5368a9fa9459Szrj 		     suffices to change the second byte from 0x8d to
5369a9fa9459Szrj 		     0x8b.  */
5370a9fa9459Szrj 		  bfd_put_8 (output_bfd, 0x8b, contents + roff - 2);
5371a9fa9459Szrj 
5372a9fa9459Szrj 		  bfd_put_32 (output_bfd,
5373a9fa9459Szrj 			      htab->elf.sgot->output_section->vma
5374a9fa9459Szrj 			      + htab->elf.sgot->output_offset + off
5375a9fa9459Szrj 			      - rel->r_offset
5376a9fa9459Szrj 			      - input_section->output_section->vma
5377a9fa9459Szrj 			      - input_section->output_offset
5378a9fa9459Szrj 			      - 4,
5379a9fa9459Szrj 			      contents + roff);
5380a9fa9459Szrj 		  continue;
5381a9fa9459Szrj 		}
5382a9fa9459Szrj 	      else if (ELF32_R_TYPE (rel->r_info) == R_X86_64_TLSDESC_CALL)
5383a9fa9459Szrj 		{
5384a9fa9459Szrj 		  /* GDesc -> IE transition.
5385a9fa9459Szrj 		     It's originally:
5386a9fa9459Szrj 		     call *(%rax)
5387a9fa9459Szrj 
5388a9fa9459Szrj 		     Change it to:
5389a9fa9459Szrj 		     xchg %ax, %ax.  */
5390a9fa9459Szrj 
5391a9fa9459Szrj 		  bfd_put_8 (output_bfd, 0x66, contents + roff);
5392a9fa9459Szrj 		  bfd_put_8 (output_bfd, 0x90, contents + roff + 1);
5393a9fa9459Szrj 		  continue;
5394a9fa9459Szrj 		}
5395a9fa9459Szrj 	      else
5396a9fa9459Szrj 		BFD_ASSERT (FALSE);
5397a9fa9459Szrj 	    }
5398a9fa9459Szrj 	  break;
5399a9fa9459Szrj 
5400a9fa9459Szrj 	case R_X86_64_TLSLD:
5401a9fa9459Szrj 	  if (! elf_x86_64_tls_transition (info, input_bfd,
5402a9fa9459Szrj 					   input_section, contents,
5403a9fa9459Szrj 					   symtab_hdr, sym_hashes,
5404a9fa9459Szrj 					   &r_type, GOT_UNKNOWN, rel,
5405a9fa9459Szrj 					   relend, h, r_symndx, TRUE))
5406a9fa9459Szrj 	    return FALSE;
5407a9fa9459Szrj 
5408a9fa9459Szrj 	  if (r_type != R_X86_64_TLSLD)
5409a9fa9459Szrj 	    {
5410a9fa9459Szrj 	      /* LD->LE transition:
5411a9fa9459Szrj 			leaq foo@tlsld(%rip), %rdi
5412a9fa9459Szrj 			call __tls_get_addr@PLT
5413a9fa9459Szrj 		 For 64bit, we change it into:
5414a9fa9459Szrj 			.word 0x6666; .byte 0x66; movq %fs:0, %rax
5415a9fa9459Szrj 		 For 32bit, we change it into:
5416a9fa9459Szrj 			nopl 0x0(%rax); movl %fs:0, %eax
5417a9fa9459Szrj 		 Or
5418a9fa9459Szrj 			leaq foo@tlsld(%rip), %rdi;
5419a9fa9459Szrj 			call *__tls_get_addr@GOTPCREL(%rip)
5420a9fa9459Szrj 			which may be converted to
5421a9fa9459Szrj 			addr32 call __tls_get_addr
5422a9fa9459Szrj 		 For 64bit, we change it into:
5423a9fa9459Szrj 			.word 0x6666; .word 0x6666; movq %fs:0, %rax
5424a9fa9459Szrj 		 For 32bit, we change it into:
5425a9fa9459Szrj 			nopw 0x0(%rax); movl %fs:0, %eax
5426a9fa9459Szrj 		 For largepic, change:
5427a9fa9459Szrj 			leaq foo@tlsgd(%rip), %rdi
5428a9fa9459Szrj 			movabsq $__tls_get_addr@pltoff, %rax
5429a9fa9459Szrj 			addq %rbx, %rax
5430a9fa9459Szrj 			call *%rax
5431a9fa9459Szrj 		 into
5432a9fa9459Szrj 			data16 data16 data16 nopw %cs:0x0(%rax,%rax,1)
5433a9fa9459Szrj 			movq %fs:0, %eax  */
5434a9fa9459Szrj 
5435a9fa9459Szrj 	      BFD_ASSERT (r_type == R_X86_64_TPOFF32);
5436a9fa9459Szrj 	      if (ABI_64_P (output_bfd))
5437a9fa9459Szrj 		{
5438a9fa9459Szrj 		  if (contents[rel->r_offset + 5] == 0xb8)
5439a9fa9459Szrj 		    memcpy (contents + rel->r_offset - 3,
5440a9fa9459Szrj 			    "\x66\x66\x66\x66\x2e\x0f\x1f\x84\0\0\0\0\0"
5441a9fa9459Szrj 			    "\x64\x48\x8b\x04\x25\0\0\0", 22);
5442a9fa9459Szrj 		  else if (contents[rel->r_offset + 4] == 0xff
5443a9fa9459Szrj 			   || contents[rel->r_offset + 4] == 0x67)
5444a9fa9459Szrj 		    memcpy (contents + rel->r_offset - 3,
5445a9fa9459Szrj 			    "\x66\x66\x66\x66\x64\x48\x8b\x04\x25\0\0\0",
5446a9fa9459Szrj 			    13);
5447a9fa9459Szrj 		  else
5448a9fa9459Szrj 		    memcpy (contents + rel->r_offset - 3,
5449a9fa9459Szrj 			    "\x66\x66\x66\x64\x48\x8b\x04\x25\0\0\0", 12);
5450a9fa9459Szrj 		}
5451a9fa9459Szrj 	      else
5452a9fa9459Szrj 		{
5453a9fa9459Szrj 		  if (contents[rel->r_offset + 4] == 0xff)
5454a9fa9459Szrj 		    memcpy (contents + rel->r_offset - 3,
5455a9fa9459Szrj 			    "\x66\x0f\x1f\x40\x00\x64\x8b\x04\x25\0\0\0",
5456a9fa9459Szrj 			    13);
5457a9fa9459Szrj 		  else
5458a9fa9459Szrj 		    memcpy (contents + rel->r_offset - 3,
5459a9fa9459Szrj 			    "\x0f\x1f\x40\x00\x64\x8b\x04\x25\0\0\0", 12);
5460a9fa9459Szrj 		}
5461a9fa9459Szrj 	      /* Skip R_X86_64_PC32, R_X86_64_PLT32, R_X86_64_GOTPCRELX
5462a9fa9459Szrj 		 and R_X86_64_PLTOFF64.  */
5463a9fa9459Szrj 	      rel++;
5464a9fa9459Szrj 	      wrel++;
5465a9fa9459Szrj 	      continue;
5466a9fa9459Szrj 	    }
5467a9fa9459Szrj 
5468a9fa9459Szrj 	  if (htab->elf.sgot == NULL)
5469a9fa9459Szrj 	    abort ();
5470a9fa9459Szrj 
5471a9fa9459Szrj 	  off = htab->tls_ld_got.offset;
5472a9fa9459Szrj 	  if (off & 1)
5473a9fa9459Szrj 	    off &= ~1;
5474a9fa9459Szrj 	  else
5475a9fa9459Szrj 	    {
5476a9fa9459Szrj 	      Elf_Internal_Rela outrel;
5477a9fa9459Szrj 
5478a9fa9459Szrj 	      if (htab->elf.srelgot == NULL)
5479a9fa9459Szrj 		abort ();
5480a9fa9459Szrj 
5481a9fa9459Szrj 	      outrel.r_offset = (htab->elf.sgot->output_section->vma
5482a9fa9459Szrj 				 + htab->elf.sgot->output_offset + off);
5483a9fa9459Szrj 
5484a9fa9459Szrj 	      bfd_put_64 (output_bfd, 0,
5485a9fa9459Szrj 			  htab->elf.sgot->contents + off);
5486a9fa9459Szrj 	      bfd_put_64 (output_bfd, 0,
5487a9fa9459Szrj 			  htab->elf.sgot->contents + off + GOT_ENTRY_SIZE);
5488a9fa9459Szrj 	      outrel.r_info = htab->r_info (0, R_X86_64_DTPMOD64);
5489a9fa9459Szrj 	      outrel.r_addend = 0;
5490a9fa9459Szrj 	      elf_append_rela (output_bfd, htab->elf.srelgot,
5491a9fa9459Szrj 					&outrel);
5492a9fa9459Szrj 	      htab->tls_ld_got.offset |= 1;
5493a9fa9459Szrj 	    }
5494a9fa9459Szrj 	  relocation = htab->elf.sgot->output_section->vma
5495a9fa9459Szrj 		       + htab->elf.sgot->output_offset + off;
5496a9fa9459Szrj 	  unresolved_reloc = FALSE;
5497a9fa9459Szrj 	  break;
5498a9fa9459Szrj 
5499a9fa9459Szrj 	case R_X86_64_DTPOFF32:
5500a9fa9459Szrj 	  if (!bfd_link_executable (info)
5501a9fa9459Szrj 	      || (input_section->flags & SEC_CODE) == 0)
5502a9fa9459Szrj 	    relocation -= elf_x86_64_dtpoff_base (info);
5503a9fa9459Szrj 	  else
5504a9fa9459Szrj 	    relocation = elf_x86_64_tpoff (info, relocation);
5505a9fa9459Szrj 	  break;
5506a9fa9459Szrj 
5507a9fa9459Szrj 	case R_X86_64_TPOFF32:
5508a9fa9459Szrj 	case R_X86_64_TPOFF64:
5509a9fa9459Szrj 	  BFD_ASSERT (bfd_link_executable (info));
5510a9fa9459Szrj 	  relocation = elf_x86_64_tpoff (info, relocation);
5511a9fa9459Szrj 	  break;
5512a9fa9459Szrj 
5513a9fa9459Szrj 	case R_X86_64_DTPOFF64:
5514a9fa9459Szrj 	  BFD_ASSERT ((input_section->flags & SEC_CODE) == 0);
5515a9fa9459Szrj 	  relocation -= elf_x86_64_dtpoff_base (info);
5516a9fa9459Szrj 	  break;
5517a9fa9459Szrj 
5518a9fa9459Szrj 	default:
5519a9fa9459Szrj 	  break;
5520a9fa9459Szrj 	}
5521a9fa9459Szrj 
5522a9fa9459Szrj       /* Dynamic relocs are not propagated for SEC_DEBUGGING sections
5523a9fa9459Szrj 	 because such sections are not SEC_ALLOC and thus ld.so will
5524a9fa9459Szrj 	 not process them.  */
5525a9fa9459Szrj       if (unresolved_reloc
5526a9fa9459Szrj 	  && !((input_section->flags & SEC_DEBUGGING) != 0
5527a9fa9459Szrj 	       && h->def_dynamic)
5528a9fa9459Szrj 	  && _bfd_elf_section_offset (output_bfd, info, input_section,
5529a9fa9459Szrj 				      rel->r_offset) != (bfd_vma) -1)
5530a9fa9459Szrj 	{
5531a9fa9459Szrj 	  (*_bfd_error_handler)
5532a9fa9459Szrj 	    (_("%B(%A+0x%lx): unresolvable %s relocation against symbol `%s'"),
5533a9fa9459Szrj 	     input_bfd,
5534a9fa9459Szrj 	     input_section,
5535a9fa9459Szrj 	     (long) rel->r_offset,
5536a9fa9459Szrj 	     howto->name,
5537a9fa9459Szrj 	     h->root.root.string);
5538a9fa9459Szrj 	  return FALSE;
5539a9fa9459Szrj 	}
5540a9fa9459Szrj 
5541a9fa9459Szrj do_relocation:
5542a9fa9459Szrj       r = _bfd_final_link_relocate (howto, input_bfd, input_section,
5543a9fa9459Szrj 				    contents, rel->r_offset,
5544a9fa9459Szrj 				    relocation, rel->r_addend);
5545a9fa9459Szrj 
5546a9fa9459Szrj check_relocation_error:
5547a9fa9459Szrj       if (r != bfd_reloc_ok)
5548a9fa9459Szrj 	{
5549a9fa9459Szrj 	  const char *name;
5550a9fa9459Szrj 
5551a9fa9459Szrj 	  if (h != NULL)
5552a9fa9459Szrj 	    name = h->root.root.string;
5553a9fa9459Szrj 	  else
5554a9fa9459Szrj 	    {
5555a9fa9459Szrj 	      name = bfd_elf_string_from_elf_section (input_bfd,
5556a9fa9459Szrj 						      symtab_hdr->sh_link,
5557a9fa9459Szrj 						      sym->st_name);
5558a9fa9459Szrj 	      if (name == NULL)
5559a9fa9459Szrj 		return FALSE;
5560a9fa9459Szrj 	      if (*name == '\0')
5561a9fa9459Szrj 		name = bfd_section_name (input_bfd, sec);
5562a9fa9459Szrj 	    }
5563a9fa9459Szrj 
5564a9fa9459Szrj 	  if (r == bfd_reloc_overflow)
5565a9fa9459Szrj 	    (*info->callbacks->reloc_overflow)
5566a9fa9459Szrj 	      (info, (h ? &h->root : NULL), name, howto->name,
5567a9fa9459Szrj 	       (bfd_vma) 0, input_bfd, input_section, rel->r_offset);
5568a9fa9459Szrj 	  else
5569a9fa9459Szrj 	    {
5570a9fa9459Szrj 	      (*_bfd_error_handler)
5571a9fa9459Szrj 		(_("%B(%A+0x%lx): reloc against `%s': error %d"),
5572a9fa9459Szrj 		 input_bfd, input_section,
5573a9fa9459Szrj 		 (long) rel->r_offset, name, (int) r);
5574a9fa9459Szrj 	      return FALSE;
5575a9fa9459Szrj 	    }
5576a9fa9459Szrj 	}
5577a9fa9459Szrj 
5578a9fa9459Szrj       if (wrel != rel)
5579a9fa9459Szrj 	*wrel = *rel;
5580a9fa9459Szrj     }
5581a9fa9459Szrj 
5582a9fa9459Szrj   if (wrel != rel)
5583a9fa9459Szrj     {
5584a9fa9459Szrj       Elf_Internal_Shdr *rel_hdr;
5585a9fa9459Szrj       size_t deleted = rel - wrel;
5586a9fa9459Szrj 
5587a9fa9459Szrj       rel_hdr = _bfd_elf_single_rel_hdr (input_section->output_section);
5588a9fa9459Szrj       rel_hdr->sh_size -= rel_hdr->sh_entsize * deleted;
5589a9fa9459Szrj       if (rel_hdr->sh_size == 0)
5590a9fa9459Szrj 	{
5591a9fa9459Szrj 	  /* It is too late to remove an empty reloc section.  Leave
5592a9fa9459Szrj 	     one NONE reloc.
5593a9fa9459Szrj 	     ??? What is wrong with an empty section???  */
5594a9fa9459Szrj 	  rel_hdr->sh_size = rel_hdr->sh_entsize;
5595a9fa9459Szrj 	  deleted -= 1;
5596a9fa9459Szrj 	}
5597a9fa9459Szrj       rel_hdr = _bfd_elf_single_rel_hdr (input_section);
5598a9fa9459Szrj       rel_hdr->sh_size -= rel_hdr->sh_entsize * deleted;
5599a9fa9459Szrj       input_section->reloc_count -= deleted;
5600a9fa9459Szrj     }
5601a9fa9459Szrj 
5602a9fa9459Szrj   return TRUE;
5603a9fa9459Szrj }
5604a9fa9459Szrj 
5605a9fa9459Szrj /* Finish up dynamic symbol handling.  We set the contents of various
5606a9fa9459Szrj    dynamic sections here.  */
5607a9fa9459Szrj 
5608a9fa9459Szrj static bfd_boolean
elf_x86_64_finish_dynamic_symbol(bfd * output_bfd,struct bfd_link_info * info,struct elf_link_hash_entry * h,Elf_Internal_Sym * sym)5609a9fa9459Szrj elf_x86_64_finish_dynamic_symbol (bfd *output_bfd,
5610a9fa9459Szrj 				  struct bfd_link_info *info,
5611a9fa9459Szrj 				  struct elf_link_hash_entry *h,
5612a9fa9459Szrj 				  Elf_Internal_Sym *sym)
5613a9fa9459Szrj {
5614a9fa9459Szrj   struct elf_x86_64_link_hash_table *htab;
5615a9fa9459Szrj   const struct elf_x86_64_backend_data *abed;
5616a9fa9459Szrj   bfd_boolean use_plt_bnd;
5617a9fa9459Szrj   struct elf_x86_64_link_hash_entry *eh;
5618a9fa9459Szrj   bfd_boolean local_undefweak;
5619a9fa9459Szrj 
5620a9fa9459Szrj   htab = elf_x86_64_hash_table (info);
5621a9fa9459Szrj   if (htab == NULL)
5622a9fa9459Szrj     return FALSE;
5623a9fa9459Szrj 
5624a9fa9459Szrj   /* Use MPX backend data in case of BND relocation.  Use .plt_bnd
5625a9fa9459Szrj      section only if there is .plt section.  */
5626a9fa9459Szrj   use_plt_bnd = htab->elf.splt != NULL && htab->plt_bnd != NULL;
5627a9fa9459Szrj   abed = (use_plt_bnd
5628a9fa9459Szrj 	  ? &elf_x86_64_bnd_arch_bed
5629a9fa9459Szrj 	  : get_elf_x86_64_backend_data (output_bfd));
5630a9fa9459Szrj 
5631a9fa9459Szrj   eh = (struct elf_x86_64_link_hash_entry *) h;
5632a9fa9459Szrj 
5633a9fa9459Szrj   /* We keep PLT/GOT entries without dynamic PLT/GOT relocations for
5634a9fa9459Szrj      resolved undefined weak symbols in executable so that their
5635a9fa9459Szrj      references have value 0 at run-time.  */
5636a9fa9459Szrj   local_undefweak = UNDEFINED_WEAK_RESOLVED_TO_ZERO (info,
5637a9fa9459Szrj 						     eh->has_got_reloc,
5638a9fa9459Szrj 						     eh);
5639a9fa9459Szrj 
5640a9fa9459Szrj   if (h->plt.offset != (bfd_vma) -1)
5641a9fa9459Szrj     {
5642a9fa9459Szrj       bfd_vma plt_index;
5643a9fa9459Szrj       bfd_vma got_offset, plt_offset, plt_plt_offset, plt_got_offset;
5644a9fa9459Szrj       bfd_vma plt_plt_insn_end, plt_got_insn_size;
5645a9fa9459Szrj       Elf_Internal_Rela rela;
5646a9fa9459Szrj       bfd_byte *loc;
5647a9fa9459Szrj       asection *plt, *gotplt, *relplt, *resolved_plt;
5648a9fa9459Szrj       const struct elf_backend_data *bed;
5649a9fa9459Szrj       bfd_vma plt_got_pcrel_offset;
5650a9fa9459Szrj 
5651a9fa9459Szrj       /* When building a static executable, use .iplt, .igot.plt and
5652a9fa9459Szrj 	 .rela.iplt sections for STT_GNU_IFUNC symbols.  */
5653a9fa9459Szrj       if (htab->elf.splt != NULL)
5654a9fa9459Szrj 	{
5655a9fa9459Szrj 	  plt = htab->elf.splt;
5656a9fa9459Szrj 	  gotplt = htab->elf.sgotplt;
5657a9fa9459Szrj 	  relplt = htab->elf.srelplt;
5658a9fa9459Szrj 	}
5659a9fa9459Szrj       else
5660a9fa9459Szrj 	{
5661a9fa9459Szrj 	  plt = htab->elf.iplt;
5662a9fa9459Szrj 	  gotplt = htab->elf.igotplt;
5663a9fa9459Szrj 	  relplt = htab->elf.irelplt;
5664a9fa9459Szrj 	}
5665a9fa9459Szrj 
5666a9fa9459Szrj       /* This symbol has an entry in the procedure linkage table.  Set
5667a9fa9459Szrj 	 it up.	 */
5668a9fa9459Szrj       if ((h->dynindx == -1
5669a9fa9459Szrj 	   && !local_undefweak
5670a9fa9459Szrj 	   && !((h->forced_local || bfd_link_executable (info))
5671a9fa9459Szrj 		&& h->def_regular
5672a9fa9459Szrj 		&& h->type == STT_GNU_IFUNC))
5673a9fa9459Szrj 	  || plt == NULL
5674a9fa9459Szrj 	  || gotplt == NULL
5675a9fa9459Szrj 	  || relplt == NULL)
5676a9fa9459Szrj 	abort ();
5677a9fa9459Szrj 
5678a9fa9459Szrj       /* Get the index in the procedure linkage table which
5679a9fa9459Szrj 	 corresponds to this symbol.  This is the index of this symbol
5680a9fa9459Szrj 	 in all the symbols for which we are making plt entries.  The
5681a9fa9459Szrj 	 first entry in the procedure linkage table is reserved.
5682a9fa9459Szrj 
5683a9fa9459Szrj 	 Get the offset into the .got table of the entry that
5684a9fa9459Szrj 	 corresponds to this function.	Each .got entry is GOT_ENTRY_SIZE
5685a9fa9459Szrj 	 bytes. The first three are reserved for the dynamic linker.
5686a9fa9459Szrj 
5687a9fa9459Szrj 	 For static executables, we don't reserve anything.  */
5688a9fa9459Szrj 
5689a9fa9459Szrj       if (plt == htab->elf.splt)
5690a9fa9459Szrj 	{
5691a9fa9459Szrj 	  got_offset = h->plt.offset / abed->plt_entry_size - 1;
5692a9fa9459Szrj 	  got_offset = (got_offset + 3) * GOT_ENTRY_SIZE;
5693a9fa9459Szrj 	}
5694a9fa9459Szrj       else
5695a9fa9459Szrj 	{
5696a9fa9459Szrj 	  got_offset = h->plt.offset / abed->plt_entry_size;
5697a9fa9459Szrj 	  got_offset = got_offset * GOT_ENTRY_SIZE;
5698a9fa9459Szrj 	}
5699a9fa9459Szrj 
5700a9fa9459Szrj       plt_plt_insn_end = abed->plt_plt_insn_end;
5701a9fa9459Szrj       plt_plt_offset = abed->plt_plt_offset;
5702a9fa9459Szrj       plt_got_insn_size = abed->plt_got_insn_size;
5703a9fa9459Szrj       plt_got_offset = abed->plt_got_offset;
5704a9fa9459Szrj       if (use_plt_bnd)
5705a9fa9459Szrj 	{
5706a9fa9459Szrj 	  /* Use the second PLT with BND relocations.  */
5707a9fa9459Szrj 	  const bfd_byte *plt_entry, *plt2_entry;
5708a9fa9459Szrj 
5709a9fa9459Szrj 	  if (eh->has_bnd_reloc)
5710a9fa9459Szrj 	    {
5711a9fa9459Szrj 	      plt_entry = elf_x86_64_bnd_plt_entry;
5712a9fa9459Szrj 	      plt2_entry = elf_x86_64_bnd_plt2_entry;
5713a9fa9459Szrj 	    }
5714a9fa9459Szrj 	  else
5715a9fa9459Szrj 	    {
5716a9fa9459Szrj 	      plt_entry = elf_x86_64_legacy_plt_entry;
5717a9fa9459Szrj 	      plt2_entry = elf_x86_64_legacy_plt2_entry;
5718a9fa9459Szrj 
5719a9fa9459Szrj 	      /* Subtract 1 since there is no BND prefix.  */
5720a9fa9459Szrj 	      plt_plt_insn_end -= 1;
5721a9fa9459Szrj 	      plt_plt_offset -= 1;
5722a9fa9459Szrj 	      plt_got_insn_size -= 1;
5723a9fa9459Szrj 	      plt_got_offset -= 1;
5724a9fa9459Szrj 	    }
5725a9fa9459Szrj 
5726a9fa9459Szrj 	  BFD_ASSERT (sizeof (elf_x86_64_bnd_plt_entry)
5727a9fa9459Szrj 		      == sizeof (elf_x86_64_legacy_plt_entry));
5728a9fa9459Szrj 
5729a9fa9459Szrj 	  /* Fill in the entry in the procedure linkage table.  */
5730a9fa9459Szrj 	  memcpy (plt->contents + h->plt.offset,
5731a9fa9459Szrj 		  plt_entry, sizeof (elf_x86_64_legacy_plt_entry));
5732a9fa9459Szrj 	  /* Fill in the entry in the second PLT.  */
5733a9fa9459Szrj 	  memcpy (htab->plt_bnd->contents + eh->plt_bnd.offset,
5734a9fa9459Szrj 		  plt2_entry, sizeof (elf_x86_64_legacy_plt2_entry));
5735a9fa9459Szrj 
5736a9fa9459Szrj 	  resolved_plt = htab->plt_bnd;
5737a9fa9459Szrj 	  plt_offset = eh->plt_bnd.offset;
5738a9fa9459Szrj 	}
5739a9fa9459Szrj       else
5740a9fa9459Szrj 	{
5741a9fa9459Szrj 	  /* Fill in the entry in the procedure linkage table.  */
5742a9fa9459Szrj 	  memcpy (plt->contents + h->plt.offset, abed->plt_entry,
5743a9fa9459Szrj 		  abed->plt_entry_size);
5744a9fa9459Szrj 
5745a9fa9459Szrj 	  resolved_plt = plt;
5746a9fa9459Szrj 	  plt_offset = h->plt.offset;
5747a9fa9459Szrj 	}
5748a9fa9459Szrj 
5749a9fa9459Szrj       /* Insert the relocation positions of the plt section.  */
5750a9fa9459Szrj 
5751a9fa9459Szrj       /* Put offset the PC-relative instruction referring to the GOT entry,
5752a9fa9459Szrj 	 subtracting the size of that instruction.  */
5753a9fa9459Szrj       plt_got_pcrel_offset = (gotplt->output_section->vma
5754a9fa9459Szrj 			      + gotplt->output_offset
5755a9fa9459Szrj 			      + got_offset
5756a9fa9459Szrj 			      - resolved_plt->output_section->vma
5757a9fa9459Szrj 			      - resolved_plt->output_offset
5758a9fa9459Szrj 			      - plt_offset
5759a9fa9459Szrj 			      - plt_got_insn_size);
5760a9fa9459Szrj 
5761a9fa9459Szrj       /* Check PC-relative offset overflow in PLT entry.  */
5762a9fa9459Szrj       if ((plt_got_pcrel_offset + 0x80000000) > 0xffffffff)
5763a9fa9459Szrj 	info->callbacks->einfo (_("%F%B: PC-relative offset overflow in PLT entry for `%s'\n"),
5764a9fa9459Szrj 				output_bfd, h->root.root.string);
5765a9fa9459Szrj 
5766a9fa9459Szrj       bfd_put_32 (output_bfd, plt_got_pcrel_offset,
5767a9fa9459Szrj 		  resolved_plt->contents + plt_offset + plt_got_offset);
5768a9fa9459Szrj 
5769a9fa9459Szrj       /* Fill in the entry in the global offset table, initially this
5770a9fa9459Szrj 	 points to the second part of the PLT entry.  Leave the entry
5771a9fa9459Szrj 	 as zero for undefined weak symbol in PIE.  No PLT relocation
5772a9fa9459Szrj 	 against undefined weak symbol in PIE.  */
5773a9fa9459Szrj       if (!local_undefweak)
5774a9fa9459Szrj 	{
5775a9fa9459Szrj 	  bfd_put_64 (output_bfd, (plt->output_section->vma
5776a9fa9459Szrj 				   + plt->output_offset
5777a9fa9459Szrj 				   + h->plt.offset
5778a9fa9459Szrj 				   + abed->plt_lazy_offset),
5779a9fa9459Szrj 		      gotplt->contents + got_offset);
5780a9fa9459Szrj 
5781a9fa9459Szrj 	  /* Fill in the entry in the .rela.plt section.  */
5782a9fa9459Szrj 	  rela.r_offset = (gotplt->output_section->vma
5783a9fa9459Szrj 			   + gotplt->output_offset
5784a9fa9459Szrj 			   + got_offset);
5785a9fa9459Szrj 	  if (h->dynindx == -1
5786a9fa9459Szrj 	      || ((bfd_link_executable (info)
5787a9fa9459Szrj 		   || ELF_ST_VISIBILITY (h->other) != STV_DEFAULT)
5788a9fa9459Szrj 		  && h->def_regular
5789a9fa9459Szrj 		  && h->type == STT_GNU_IFUNC))
5790a9fa9459Szrj 	    {
5791a9fa9459Szrj 	      /* If an STT_GNU_IFUNC symbol is locally defined, generate
5792a9fa9459Szrj 		 R_X86_64_IRELATIVE instead of R_X86_64_JUMP_SLOT.  */
5793a9fa9459Szrj 	      rela.r_info = htab->r_info (0, R_X86_64_IRELATIVE);
5794a9fa9459Szrj 	      rela.r_addend = (h->root.u.def.value
5795a9fa9459Szrj 			       + h->root.u.def.section->output_section->vma
5796a9fa9459Szrj 			       + h->root.u.def.section->output_offset);
5797a9fa9459Szrj 	      /* R_X86_64_IRELATIVE comes last.  */
5798a9fa9459Szrj 	      plt_index = htab->next_irelative_index--;
5799a9fa9459Szrj 	    }
5800a9fa9459Szrj 	  else
5801a9fa9459Szrj 	    {
5802a9fa9459Szrj 	      rela.r_info = htab->r_info (h->dynindx, R_X86_64_JUMP_SLOT);
5803a9fa9459Szrj 	      rela.r_addend = 0;
5804a9fa9459Szrj 	      plt_index = htab->next_jump_slot_index++;
5805a9fa9459Szrj 	    }
5806a9fa9459Szrj 
5807a9fa9459Szrj 	  /* Don't fill PLT entry for static executables.  */
5808a9fa9459Szrj 	  if (plt == htab->elf.splt)
5809a9fa9459Szrj 	    {
5810a9fa9459Szrj 	      bfd_vma plt0_offset = h->plt.offset + plt_plt_insn_end;
5811a9fa9459Szrj 
5812a9fa9459Szrj 	      /* Put relocation index.  */
5813a9fa9459Szrj 	      bfd_put_32 (output_bfd, plt_index,
5814a9fa9459Szrj 			  (plt->contents + h->plt.offset
5815a9fa9459Szrj 			   + abed->plt_reloc_offset));
5816a9fa9459Szrj 
5817a9fa9459Szrj 	      /* Put offset for jmp .PLT0 and check for overflow.  We don't
5818a9fa9459Szrj 		 check relocation index for overflow since branch displacement
5819a9fa9459Szrj 		 will overflow first.  */
5820a9fa9459Szrj 	      if (plt0_offset > 0x80000000)
5821a9fa9459Szrj 		info->callbacks->einfo (_("%F%B: branch displacement overflow in PLT entry for `%s'\n"),
5822a9fa9459Szrj 					output_bfd, h->root.root.string);
5823a9fa9459Szrj 	      bfd_put_32 (output_bfd, - plt0_offset,
5824a9fa9459Szrj 			  plt->contents + h->plt.offset + plt_plt_offset);
5825a9fa9459Szrj 	    }
5826a9fa9459Szrj 
5827a9fa9459Szrj 	  bed = get_elf_backend_data (output_bfd);
5828a9fa9459Szrj 	  loc = relplt->contents + plt_index * bed->s->sizeof_rela;
5829a9fa9459Szrj 	  bed->s->swap_reloca_out (output_bfd, &rela, loc);
5830a9fa9459Szrj 	}
5831a9fa9459Szrj     }
5832a9fa9459Szrj   else if (eh->plt_got.offset != (bfd_vma) -1)
5833a9fa9459Szrj     {
5834a9fa9459Szrj       bfd_vma got_offset, plt_offset, plt_got_offset, plt_got_insn_size;
5835a9fa9459Szrj       asection *plt, *got;
5836a9fa9459Szrj       bfd_boolean got_after_plt;
5837a9fa9459Szrj       int32_t got_pcrel_offset;
5838a9fa9459Szrj       const bfd_byte *got_plt_entry;
5839a9fa9459Szrj 
5840a9fa9459Szrj       /* Set the entry in the GOT procedure linkage table.  */
5841a9fa9459Szrj       plt = htab->plt_got;
5842a9fa9459Szrj       got = htab->elf.sgot;
5843a9fa9459Szrj       got_offset = h->got.offset;
5844a9fa9459Szrj 
5845a9fa9459Szrj       if (got_offset == (bfd_vma) -1
5846a9fa9459Szrj 	  || h->type == STT_GNU_IFUNC
5847a9fa9459Szrj 	  || plt == NULL
5848a9fa9459Szrj 	  || got == NULL)
5849a9fa9459Szrj 	abort ();
5850a9fa9459Szrj 
5851a9fa9459Szrj       /* Use the second PLT entry template for the GOT PLT since they
5852a9fa9459Szrj 	 are the identical.  */
5853a9fa9459Szrj       plt_got_insn_size = elf_x86_64_bnd_arch_bed.plt_got_insn_size;
5854a9fa9459Szrj       plt_got_offset = elf_x86_64_bnd_arch_bed.plt_got_offset;
5855a9fa9459Szrj       if (eh->has_bnd_reloc)
5856a9fa9459Szrj 	got_plt_entry = elf_x86_64_bnd_plt2_entry;
5857a9fa9459Szrj       else
5858a9fa9459Szrj 	{
5859a9fa9459Szrj 	  got_plt_entry = elf_x86_64_legacy_plt2_entry;
5860a9fa9459Szrj 
5861a9fa9459Szrj 	  /* Subtract 1 since there is no BND prefix.  */
5862a9fa9459Szrj 	  plt_got_insn_size -= 1;
5863a9fa9459Szrj 	  plt_got_offset -= 1;
5864a9fa9459Szrj 	}
5865a9fa9459Szrj 
5866a9fa9459Szrj       /* Fill in the entry in the GOT procedure linkage table.  */
5867a9fa9459Szrj       plt_offset = eh->plt_got.offset;
5868a9fa9459Szrj       memcpy (plt->contents + plt_offset,
5869a9fa9459Szrj 	      got_plt_entry, sizeof (elf_x86_64_legacy_plt2_entry));
5870a9fa9459Szrj 
5871a9fa9459Szrj       /* Put offset the PC-relative instruction referring to the GOT
5872a9fa9459Szrj 	 entry, subtracting the size of that instruction.  */
5873a9fa9459Szrj       got_pcrel_offset = (got->output_section->vma
5874a9fa9459Szrj 			  + got->output_offset
5875a9fa9459Szrj 			  + got_offset
5876a9fa9459Szrj 			  - plt->output_section->vma
5877a9fa9459Szrj 			  - plt->output_offset
5878a9fa9459Szrj 			  - plt_offset
5879a9fa9459Szrj 			  - plt_got_insn_size);
5880a9fa9459Szrj 
5881a9fa9459Szrj       /* Check PC-relative offset overflow in GOT PLT entry.  */
5882a9fa9459Szrj       got_after_plt = got->output_section->vma > plt->output_section->vma;
5883a9fa9459Szrj       if ((got_after_plt && got_pcrel_offset < 0)
5884a9fa9459Szrj 	  || (!got_after_plt && got_pcrel_offset > 0))
5885a9fa9459Szrj 	info->callbacks->einfo (_("%F%B: PC-relative offset overflow in GOT PLT entry for `%s'\n"),
5886a9fa9459Szrj 				output_bfd, h->root.root.string);
5887a9fa9459Szrj 
5888a9fa9459Szrj       bfd_put_32 (output_bfd, got_pcrel_offset,
5889a9fa9459Szrj 		  plt->contents + plt_offset + plt_got_offset);
5890a9fa9459Szrj     }
5891a9fa9459Szrj 
5892a9fa9459Szrj   if (!local_undefweak
5893a9fa9459Szrj       && !h->def_regular
5894a9fa9459Szrj       && (h->plt.offset != (bfd_vma) -1
5895a9fa9459Szrj 	  || eh->plt_got.offset != (bfd_vma) -1))
5896a9fa9459Szrj     {
5897a9fa9459Szrj       /* Mark the symbol as undefined, rather than as defined in
5898a9fa9459Szrj 	 the .plt section.  Leave the value if there were any
5899a9fa9459Szrj 	 relocations where pointer equality matters (this is a clue
5900a9fa9459Szrj 	 for the dynamic linker, to make function pointer
5901a9fa9459Szrj 	 comparisons work between an application and shared
5902a9fa9459Szrj 	 library), otherwise set it to zero.  If a function is only
5903a9fa9459Szrj 	 called from a binary, there is no need to slow down
5904a9fa9459Szrj 	 shared libraries because of that.  */
5905a9fa9459Szrj       sym->st_shndx = SHN_UNDEF;
5906a9fa9459Szrj       if (!h->pointer_equality_needed)
5907a9fa9459Szrj 	sym->st_value = 0;
5908a9fa9459Szrj     }
5909a9fa9459Szrj 
5910a9fa9459Szrj   /* Don't generate dynamic GOT relocation against undefined weak
5911a9fa9459Szrj      symbol in executable.  */
5912a9fa9459Szrj   if (h->got.offset != (bfd_vma) -1
5913a9fa9459Szrj       && ! GOT_TLS_GD_ANY_P (elf_x86_64_hash_entry (h)->tls_type)
5914a9fa9459Szrj       && elf_x86_64_hash_entry (h)->tls_type != GOT_TLS_IE
5915a9fa9459Szrj       && !local_undefweak)
5916a9fa9459Szrj     {
5917a9fa9459Szrj       Elf_Internal_Rela rela;
5918a9fa9459Szrj       asection *relgot = htab->elf.srelgot;
5919a9fa9459Szrj 
5920a9fa9459Szrj       /* This symbol has an entry in the global offset table.  Set it
5921a9fa9459Szrj 	 up.  */
5922a9fa9459Szrj       if (htab->elf.sgot == NULL || htab->elf.srelgot == NULL)
5923a9fa9459Szrj 	abort ();
5924a9fa9459Szrj 
5925a9fa9459Szrj       rela.r_offset = (htab->elf.sgot->output_section->vma
5926a9fa9459Szrj 		       + htab->elf.sgot->output_offset
5927a9fa9459Szrj 		       + (h->got.offset &~ (bfd_vma) 1));
5928a9fa9459Szrj 
5929a9fa9459Szrj       /* If this is a static link, or it is a -Bsymbolic link and the
5930a9fa9459Szrj 	 symbol is defined locally or was forced to be local because
5931a9fa9459Szrj 	 of a version file, we just want to emit a RELATIVE reloc.
5932a9fa9459Szrj 	 The entry in the global offset table will already have been
5933a9fa9459Szrj 	 initialized in the relocate_section function.  */
5934a9fa9459Szrj       if (h->def_regular
5935a9fa9459Szrj 	  && h->type == STT_GNU_IFUNC)
5936a9fa9459Szrj 	{
5937a9fa9459Szrj 	  if (h->plt.offset == (bfd_vma) -1)
5938a9fa9459Szrj 	    {
5939a9fa9459Szrj 	      /* STT_GNU_IFUNC is referenced without PLT.  */
5940a9fa9459Szrj 	      if (htab->elf.splt == NULL)
5941a9fa9459Szrj 		{
5942a9fa9459Szrj 		  /* use .rel[a].iplt section to store .got relocations
5943a9fa9459Szrj 		     in static executable.  */
5944a9fa9459Szrj 		  relgot = htab->elf.irelplt;
5945a9fa9459Szrj 		}
5946a9fa9459Szrj 	      if (SYMBOL_REFERENCES_LOCAL (info, h))
5947a9fa9459Szrj 		{
5948a9fa9459Szrj 		  rela.r_info = htab->r_info (0,
5949a9fa9459Szrj 					      R_X86_64_IRELATIVE);
5950a9fa9459Szrj 		  rela.r_addend = (h->root.u.def.value
5951a9fa9459Szrj 				   + h->root.u.def.section->output_section->vma
5952a9fa9459Szrj 				   + h->root.u.def.section->output_offset);
5953a9fa9459Szrj 		}
5954a9fa9459Szrj 	      else
5955a9fa9459Szrj 		goto do_glob_dat;
5956a9fa9459Szrj 	    }
5957a9fa9459Szrj 	  else if (bfd_link_pic (info))
5958a9fa9459Szrj 	    {
5959a9fa9459Szrj 	      /* Generate R_X86_64_GLOB_DAT.  */
5960a9fa9459Szrj 	      goto do_glob_dat;
5961a9fa9459Szrj 	    }
5962a9fa9459Szrj 	  else
5963a9fa9459Szrj 	    {
5964a9fa9459Szrj 	      asection *plt;
5965a9fa9459Szrj 
5966a9fa9459Szrj 	      if (!h->pointer_equality_needed)
5967a9fa9459Szrj 		abort ();
5968a9fa9459Szrj 
5969a9fa9459Szrj 	      /* For non-shared object, we can't use .got.plt, which
5970a9fa9459Szrj 		 contains the real function addres if we need pointer
5971a9fa9459Szrj 		 equality.  We load the GOT entry with the PLT entry.  */
5972a9fa9459Szrj 	      plt = htab->elf.splt ? htab->elf.splt : htab->elf.iplt;
5973a9fa9459Szrj 	      bfd_put_64 (output_bfd, (plt->output_section->vma
5974a9fa9459Szrj 				       + plt->output_offset
5975a9fa9459Szrj 				       + h->plt.offset),
5976a9fa9459Szrj 			  htab->elf.sgot->contents + h->got.offset);
5977a9fa9459Szrj 	      return TRUE;
5978a9fa9459Szrj 	    }
5979a9fa9459Szrj 	}
5980a9fa9459Szrj       else if (bfd_link_pic (info)
5981a9fa9459Szrj 	       && SYMBOL_REFERENCES_LOCAL (info, h))
5982a9fa9459Szrj 	{
5983a9fa9459Szrj 	  if (!h->def_regular)
5984a9fa9459Szrj 	    return FALSE;
5985a9fa9459Szrj 	  BFD_ASSERT((h->got.offset & 1) != 0);
5986a9fa9459Szrj 	  rela.r_info = htab->r_info (0, R_X86_64_RELATIVE);
5987a9fa9459Szrj 	  rela.r_addend = (h->root.u.def.value
5988a9fa9459Szrj 			   + h->root.u.def.section->output_section->vma
5989a9fa9459Szrj 			   + h->root.u.def.section->output_offset);
5990a9fa9459Szrj 	}
5991a9fa9459Szrj       else
5992a9fa9459Szrj 	{
5993a9fa9459Szrj 	  BFD_ASSERT((h->got.offset & 1) == 0);
5994a9fa9459Szrj do_glob_dat:
5995a9fa9459Szrj 	  bfd_put_64 (output_bfd, (bfd_vma) 0,
5996a9fa9459Szrj 		      htab->elf.sgot->contents + h->got.offset);
5997a9fa9459Szrj 	  rela.r_info = htab->r_info (h->dynindx, R_X86_64_GLOB_DAT);
5998a9fa9459Szrj 	  rela.r_addend = 0;
5999a9fa9459Szrj 	}
6000a9fa9459Szrj 
6001a9fa9459Szrj       elf_append_rela (output_bfd, relgot, &rela);
6002a9fa9459Szrj     }
6003a9fa9459Szrj 
6004a9fa9459Szrj   if (h->needs_copy)
6005a9fa9459Szrj     {
6006a9fa9459Szrj       Elf_Internal_Rela rela;
6007a9fa9459Szrj 
6008a9fa9459Szrj       /* This symbol needs a copy reloc.  Set it up.  */
6009a9fa9459Szrj 
6010a9fa9459Szrj       if (h->dynindx == -1
6011a9fa9459Szrj 	  || (h->root.type != bfd_link_hash_defined
6012a9fa9459Szrj 	      && h->root.type != bfd_link_hash_defweak)
6013a9fa9459Szrj 	  || htab->srelbss == NULL)
6014a9fa9459Szrj 	abort ();
6015a9fa9459Szrj 
6016a9fa9459Szrj       rela.r_offset = (h->root.u.def.value
6017a9fa9459Szrj 		       + h->root.u.def.section->output_section->vma
6018a9fa9459Szrj 		       + h->root.u.def.section->output_offset);
6019a9fa9459Szrj       rela.r_info = htab->r_info (h->dynindx, R_X86_64_COPY);
6020a9fa9459Szrj       rela.r_addend = 0;
6021a9fa9459Szrj       elf_append_rela (output_bfd, htab->srelbss, &rela);
6022a9fa9459Szrj     }
6023a9fa9459Szrj 
6024a9fa9459Szrj   return TRUE;
6025a9fa9459Szrj }
6026a9fa9459Szrj 
6027a9fa9459Szrj /* Finish up local dynamic symbol handling.  We set the contents of
6028a9fa9459Szrj    various dynamic sections here.  */
6029a9fa9459Szrj 
6030a9fa9459Szrj static bfd_boolean
elf_x86_64_finish_local_dynamic_symbol(void ** slot,void * inf)6031a9fa9459Szrj elf_x86_64_finish_local_dynamic_symbol (void **slot, void *inf)
6032a9fa9459Szrj {
6033a9fa9459Szrj   struct elf_link_hash_entry *h
6034a9fa9459Szrj     = (struct elf_link_hash_entry *) *slot;
6035a9fa9459Szrj   struct bfd_link_info *info
6036a9fa9459Szrj     = (struct bfd_link_info *) inf;
6037a9fa9459Szrj 
6038a9fa9459Szrj   return elf_x86_64_finish_dynamic_symbol (info->output_bfd,
6039a9fa9459Szrj 					     info, h, NULL);
6040a9fa9459Szrj }
6041a9fa9459Szrj 
6042a9fa9459Szrj /* Finish up undefined weak symbol handling in PIE.  Fill its PLT entry
6043a9fa9459Szrj    here since undefined weak symbol may not be dynamic and may not be
6044a9fa9459Szrj    called for elf_x86_64_finish_dynamic_symbol.  */
6045a9fa9459Szrj 
6046a9fa9459Szrj static bfd_boolean
elf_x86_64_pie_finish_undefweak_symbol(struct bfd_hash_entry * bh,void * inf)6047a9fa9459Szrj elf_x86_64_pie_finish_undefweak_symbol (struct bfd_hash_entry *bh,
6048a9fa9459Szrj 					void *inf)
6049a9fa9459Szrj {
6050a9fa9459Szrj   struct elf_link_hash_entry *h = (struct elf_link_hash_entry *) bh;
6051a9fa9459Szrj   struct bfd_link_info *info = (struct bfd_link_info *) inf;
6052a9fa9459Szrj 
6053a9fa9459Szrj   if (h->root.type != bfd_link_hash_undefweak
6054a9fa9459Szrj       || h->dynindx != -1)
6055a9fa9459Szrj     return TRUE;
6056a9fa9459Szrj 
6057a9fa9459Szrj   return elf_x86_64_finish_dynamic_symbol (info->output_bfd,
6058a9fa9459Szrj 					     info, h, NULL);
6059a9fa9459Szrj }
6060a9fa9459Szrj 
6061a9fa9459Szrj /* Used to decide how to sort relocs in an optimal manner for the
6062a9fa9459Szrj    dynamic linker, before writing them out.  */
6063a9fa9459Szrj 
6064a9fa9459Szrj static enum elf_reloc_type_class
elf_x86_64_reloc_type_class(const struct bfd_link_info * info,const asection * rel_sec ATTRIBUTE_UNUSED,const Elf_Internal_Rela * rela)6065a9fa9459Szrj elf_x86_64_reloc_type_class (const struct bfd_link_info *info,
6066a9fa9459Szrj 			     const asection *rel_sec ATTRIBUTE_UNUSED,
6067a9fa9459Szrj 			     const Elf_Internal_Rela *rela)
6068a9fa9459Szrj {
6069a9fa9459Szrj   bfd *abfd = info->output_bfd;
6070a9fa9459Szrj   const struct elf_backend_data *bed = get_elf_backend_data (abfd);
6071a9fa9459Szrj   struct elf_x86_64_link_hash_table *htab = elf_x86_64_hash_table (info);
6072a9fa9459Szrj 
6073a9fa9459Szrj   if (htab->elf.dynsym != NULL
6074a9fa9459Szrj       && htab->elf.dynsym->contents != NULL)
6075a9fa9459Szrj     {
6076a9fa9459Szrj       /* Check relocation against STT_GNU_IFUNC symbol if there are
6077a9fa9459Szrj          dynamic symbols.  */
6078a9fa9459Szrj       unsigned long r_symndx = htab->r_sym (rela->r_info);
6079a9fa9459Szrj       if (r_symndx != STN_UNDEF)
6080a9fa9459Szrj 	{
6081a9fa9459Szrj 	  Elf_Internal_Sym sym;
6082a9fa9459Szrj 	  if (!bed->s->swap_symbol_in (abfd,
6083a9fa9459Szrj 				       (htab->elf.dynsym->contents
6084a9fa9459Szrj 					+ r_symndx * bed->s->sizeof_sym),
6085a9fa9459Szrj 				       0, &sym))
6086a9fa9459Szrj 	    abort ();
6087a9fa9459Szrj 
6088a9fa9459Szrj 	  if (ELF_ST_TYPE (sym.st_info) == STT_GNU_IFUNC)
6089a9fa9459Szrj 	    return reloc_class_ifunc;
6090a9fa9459Szrj 	}
6091a9fa9459Szrj     }
6092a9fa9459Szrj 
6093a9fa9459Szrj   switch ((int) ELF32_R_TYPE (rela->r_info))
6094a9fa9459Szrj     {
6095a9fa9459Szrj     case R_X86_64_IRELATIVE:
6096a9fa9459Szrj       return reloc_class_ifunc;
6097a9fa9459Szrj     case R_X86_64_RELATIVE:
6098a9fa9459Szrj     case R_X86_64_RELATIVE64:
6099a9fa9459Szrj       return reloc_class_relative;
6100a9fa9459Szrj     case R_X86_64_JUMP_SLOT:
6101a9fa9459Szrj       return reloc_class_plt;
6102a9fa9459Szrj     case R_X86_64_COPY:
6103a9fa9459Szrj       return reloc_class_copy;
6104a9fa9459Szrj     default:
6105a9fa9459Szrj       return reloc_class_normal;
6106a9fa9459Szrj     }
6107a9fa9459Szrj }
6108a9fa9459Szrj 
6109a9fa9459Szrj /* Finish up the dynamic sections.  */
6110a9fa9459Szrj 
6111a9fa9459Szrj static bfd_boolean
elf_x86_64_finish_dynamic_sections(bfd * output_bfd,struct bfd_link_info * info)6112a9fa9459Szrj elf_x86_64_finish_dynamic_sections (bfd *output_bfd,
6113a9fa9459Szrj 				    struct bfd_link_info *info)
6114a9fa9459Szrj {
6115a9fa9459Szrj   struct elf_x86_64_link_hash_table *htab;
6116a9fa9459Szrj   bfd *dynobj;
6117a9fa9459Szrj   asection *sdyn;
6118a9fa9459Szrj   const struct elf_x86_64_backend_data *abed;
6119a9fa9459Szrj 
6120a9fa9459Szrj   htab = elf_x86_64_hash_table (info);
6121a9fa9459Szrj   if (htab == NULL)
6122a9fa9459Szrj     return FALSE;
6123a9fa9459Szrj 
6124a9fa9459Szrj   /* Use MPX backend data in case of BND relocation.  Use .plt_bnd
6125a9fa9459Szrj      section only if there is .plt section.  */
6126a9fa9459Szrj   abed = (htab->elf.splt != NULL && htab->plt_bnd != NULL
6127a9fa9459Szrj 	  ? &elf_x86_64_bnd_arch_bed
6128a9fa9459Szrj 	  : get_elf_x86_64_backend_data (output_bfd));
6129a9fa9459Szrj 
6130a9fa9459Szrj   dynobj = htab->elf.dynobj;
6131a9fa9459Szrj   sdyn = bfd_get_linker_section (dynobj, ".dynamic");
6132a9fa9459Szrj 
6133a9fa9459Szrj   if (htab->elf.dynamic_sections_created)
6134a9fa9459Szrj     {
6135a9fa9459Szrj       bfd_byte *dyncon, *dynconend;
6136a9fa9459Szrj       const struct elf_backend_data *bed;
6137a9fa9459Szrj       bfd_size_type sizeof_dyn;
6138a9fa9459Szrj 
6139a9fa9459Szrj       if (sdyn == NULL || htab->elf.sgot == NULL)
6140a9fa9459Szrj 	abort ();
6141a9fa9459Szrj 
6142a9fa9459Szrj       bed = get_elf_backend_data (dynobj);
6143a9fa9459Szrj       sizeof_dyn = bed->s->sizeof_dyn;
6144a9fa9459Szrj       dyncon = sdyn->contents;
6145a9fa9459Szrj       dynconend = sdyn->contents + sdyn->size;
6146a9fa9459Szrj       for (; dyncon < dynconend; dyncon += sizeof_dyn)
6147a9fa9459Szrj 	{
6148a9fa9459Szrj 	  Elf_Internal_Dyn dyn;
6149a9fa9459Szrj 	  asection *s;
6150a9fa9459Szrj 
6151a9fa9459Szrj 	  (*bed->s->swap_dyn_in) (dynobj, dyncon, &dyn);
6152a9fa9459Szrj 
6153a9fa9459Szrj 	  switch (dyn.d_tag)
6154a9fa9459Szrj 	    {
6155a9fa9459Szrj 	    default:
6156a9fa9459Szrj 	      continue;
6157a9fa9459Szrj 
6158a9fa9459Szrj 	    case DT_PLTGOT:
6159a9fa9459Szrj 	      s = htab->elf.sgotplt;
6160a9fa9459Szrj 	      dyn.d_un.d_ptr = s->output_section->vma + s->output_offset;
6161a9fa9459Szrj 	      break;
6162a9fa9459Szrj 
6163a9fa9459Szrj 	    case DT_JMPREL:
6164a9fa9459Szrj 	      dyn.d_un.d_ptr = htab->elf.srelplt->output_section->vma;
6165a9fa9459Szrj 	      break;
6166a9fa9459Szrj 
6167a9fa9459Szrj 	    case DT_PLTRELSZ:
6168a9fa9459Szrj 	      s = htab->elf.srelplt->output_section;
6169a9fa9459Szrj 	      dyn.d_un.d_val = s->size;
6170a9fa9459Szrj 	      break;
6171a9fa9459Szrj 
6172a9fa9459Szrj 	    case DT_RELASZ:
6173a9fa9459Szrj 	      /* The procedure linkage table relocs (DT_JMPREL) should
6174a9fa9459Szrj 		 not be included in the overall relocs (DT_RELA).
6175a9fa9459Szrj 		 Therefore, we override the DT_RELASZ entry here to
6176a9fa9459Szrj 		 make it not include the JMPREL relocs.  Since the
6177a9fa9459Szrj 		 linker script arranges for .rela.plt to follow all
6178a9fa9459Szrj 		 other relocation sections, we don't have to worry
6179a9fa9459Szrj 		 about changing the DT_RELA entry.  */
6180a9fa9459Szrj 	      if (htab->elf.srelplt != NULL)
6181a9fa9459Szrj 		{
6182a9fa9459Szrj 		  s = htab->elf.srelplt->output_section;
6183a9fa9459Szrj 		  dyn.d_un.d_val -= s->size;
6184a9fa9459Szrj 		}
6185a9fa9459Szrj 	      break;
6186a9fa9459Szrj 
6187a9fa9459Szrj 	    case DT_TLSDESC_PLT:
6188a9fa9459Szrj 	      s = htab->elf.splt;
6189a9fa9459Szrj 	      dyn.d_un.d_ptr = s->output_section->vma + s->output_offset
6190a9fa9459Szrj 		+ htab->tlsdesc_plt;
6191a9fa9459Szrj 	      break;
6192a9fa9459Szrj 
6193a9fa9459Szrj 	    case DT_TLSDESC_GOT:
6194a9fa9459Szrj 	      s = htab->elf.sgot;
6195a9fa9459Szrj 	      dyn.d_un.d_ptr = s->output_section->vma + s->output_offset
6196a9fa9459Szrj 		+ htab->tlsdesc_got;
6197a9fa9459Szrj 	      break;
6198a9fa9459Szrj 	    }
6199a9fa9459Szrj 
6200a9fa9459Szrj 	  (*bed->s->swap_dyn_out) (output_bfd, &dyn, dyncon);
6201a9fa9459Szrj 	}
6202a9fa9459Szrj 
6203a9fa9459Szrj       /* Fill in the special first entry in the procedure linkage table.  */
6204a9fa9459Szrj       if (htab->elf.splt && htab->elf.splt->size > 0)
6205a9fa9459Szrj 	{
6206a9fa9459Szrj 	  /* Fill in the first entry in the procedure linkage table.  */
6207a9fa9459Szrj 	  memcpy (htab->elf.splt->contents,
6208a9fa9459Szrj 		  abed->plt0_entry, abed->plt_entry_size);
6209a9fa9459Szrj 	  /* Add offset for pushq GOT+8(%rip), since the instruction
6210a9fa9459Szrj 	     uses 6 bytes subtract this value.  */
6211a9fa9459Szrj 	  bfd_put_32 (output_bfd,
6212a9fa9459Szrj 		      (htab->elf.sgotplt->output_section->vma
6213a9fa9459Szrj 		       + htab->elf.sgotplt->output_offset
6214a9fa9459Szrj 		       + 8
6215a9fa9459Szrj 		       - htab->elf.splt->output_section->vma
6216a9fa9459Szrj 		       - htab->elf.splt->output_offset
6217a9fa9459Szrj 		       - 6),
6218a9fa9459Szrj 		      htab->elf.splt->contents + abed->plt0_got1_offset);
6219a9fa9459Szrj 	  /* Add offset for the PC-relative instruction accessing GOT+16,
6220a9fa9459Szrj 	     subtracting the offset to the end of that instruction.  */
6221a9fa9459Szrj 	  bfd_put_32 (output_bfd,
6222a9fa9459Szrj 		      (htab->elf.sgotplt->output_section->vma
6223a9fa9459Szrj 		       + htab->elf.sgotplt->output_offset
6224a9fa9459Szrj 		       + 16
6225a9fa9459Szrj 		       - htab->elf.splt->output_section->vma
6226a9fa9459Szrj 		       - htab->elf.splt->output_offset
6227a9fa9459Szrj 		       - abed->plt0_got2_insn_end),
6228a9fa9459Szrj 		      htab->elf.splt->contents + abed->plt0_got2_offset);
6229a9fa9459Szrj 
6230a9fa9459Szrj 	  elf_section_data (htab->elf.splt->output_section)
6231a9fa9459Szrj 	    ->this_hdr.sh_entsize = abed->plt_entry_size;
6232a9fa9459Szrj 
6233a9fa9459Szrj 	  if (htab->tlsdesc_plt)
6234a9fa9459Szrj 	    {
6235a9fa9459Szrj 	      bfd_put_64 (output_bfd, (bfd_vma) 0,
6236a9fa9459Szrj 			  htab->elf.sgot->contents + htab->tlsdesc_got);
6237a9fa9459Szrj 
6238a9fa9459Szrj 	      memcpy (htab->elf.splt->contents + htab->tlsdesc_plt,
6239a9fa9459Szrj 		      abed->plt0_entry, abed->plt_entry_size);
6240a9fa9459Szrj 
6241a9fa9459Szrj 	      /* Add offset for pushq GOT+8(%rip), since the
6242a9fa9459Szrj 		 instruction uses 6 bytes subtract this value.  */
6243a9fa9459Szrj 	      bfd_put_32 (output_bfd,
6244a9fa9459Szrj 			  (htab->elf.sgotplt->output_section->vma
6245a9fa9459Szrj 			   + htab->elf.sgotplt->output_offset
6246a9fa9459Szrj 			   + 8
6247a9fa9459Szrj 			   - htab->elf.splt->output_section->vma
6248a9fa9459Szrj 			   - htab->elf.splt->output_offset
6249a9fa9459Szrj 			   - htab->tlsdesc_plt
6250a9fa9459Szrj 			   - 6),
6251a9fa9459Szrj 			  htab->elf.splt->contents
6252a9fa9459Szrj 			  + htab->tlsdesc_plt + abed->plt0_got1_offset);
6253a9fa9459Szrj 	  /* Add offset for the PC-relative instruction accessing GOT+TDG,
6254a9fa9459Szrj 	     where TGD stands for htab->tlsdesc_got, subtracting the offset
6255a9fa9459Szrj 	     to the end of that instruction.  */
6256a9fa9459Szrj 	      bfd_put_32 (output_bfd,
6257a9fa9459Szrj 			  (htab->elf.sgot->output_section->vma
6258a9fa9459Szrj 			   + htab->elf.sgot->output_offset
6259a9fa9459Szrj 			   + htab->tlsdesc_got
6260a9fa9459Szrj 			   - htab->elf.splt->output_section->vma
6261a9fa9459Szrj 			   - htab->elf.splt->output_offset
6262a9fa9459Szrj 			   - htab->tlsdesc_plt
6263a9fa9459Szrj 			   - abed->plt0_got2_insn_end),
6264a9fa9459Szrj 			  htab->elf.splt->contents
6265a9fa9459Szrj 			  + htab->tlsdesc_plt + abed->plt0_got2_offset);
6266a9fa9459Szrj 	    }
6267a9fa9459Szrj 	}
6268a9fa9459Szrj     }
6269a9fa9459Szrj 
6270a9fa9459Szrj   if (htab->plt_bnd != NULL)
6271a9fa9459Szrj     elf_section_data (htab->plt_bnd->output_section)
6272a9fa9459Szrj       ->this_hdr.sh_entsize = sizeof (elf_x86_64_bnd_plt2_entry);
6273a9fa9459Szrj 
6274a9fa9459Szrj   if (htab->elf.sgotplt)
6275a9fa9459Szrj     {
6276a9fa9459Szrj       if (bfd_is_abs_section (htab->elf.sgotplt->output_section))
6277a9fa9459Szrj 	{
6278a9fa9459Szrj 	  (*_bfd_error_handler)
6279a9fa9459Szrj 	    (_("discarded output section: `%A'"), htab->elf.sgotplt);
6280a9fa9459Szrj 	  return FALSE;
6281a9fa9459Szrj 	}
6282a9fa9459Szrj 
6283a9fa9459Szrj       /* Fill in the first three entries in the global offset table.  */
6284a9fa9459Szrj       if (htab->elf.sgotplt->size > 0)
6285a9fa9459Szrj 	{
6286a9fa9459Szrj 	  /* Set the first entry in the global offset table to the address of
6287a9fa9459Szrj 	     the dynamic section.  */
6288a9fa9459Szrj 	  if (sdyn == NULL)
6289a9fa9459Szrj 	    bfd_put_64 (output_bfd, (bfd_vma) 0, htab->elf.sgotplt->contents);
6290a9fa9459Szrj 	  else
6291a9fa9459Szrj 	    bfd_put_64 (output_bfd,
6292a9fa9459Szrj 			sdyn->output_section->vma + sdyn->output_offset,
6293a9fa9459Szrj 			htab->elf.sgotplt->contents);
6294a9fa9459Szrj 	  /* Write GOT[1] and GOT[2], needed for the dynamic linker.  */
6295a9fa9459Szrj 	  bfd_put_64 (output_bfd, (bfd_vma) 0, htab->elf.sgotplt->contents + GOT_ENTRY_SIZE);
6296a9fa9459Szrj 	  bfd_put_64 (output_bfd, (bfd_vma) 0, htab->elf.sgotplt->contents + GOT_ENTRY_SIZE*2);
6297a9fa9459Szrj 	}
6298a9fa9459Szrj 
6299a9fa9459Szrj       elf_section_data (htab->elf.sgotplt->output_section)->this_hdr.sh_entsize =
6300a9fa9459Szrj 	GOT_ENTRY_SIZE;
6301a9fa9459Szrj     }
6302a9fa9459Szrj 
6303a9fa9459Szrj   /* Adjust .eh_frame for .plt section.  */
6304a9fa9459Szrj   if (htab->plt_eh_frame != NULL
6305a9fa9459Szrj       && htab->plt_eh_frame->contents != NULL)
6306a9fa9459Szrj     {
6307a9fa9459Szrj       if (htab->elf.splt != NULL
6308a9fa9459Szrj 	  && htab->elf.splt->size != 0
6309a9fa9459Szrj 	  && (htab->elf.splt->flags & SEC_EXCLUDE) == 0
6310a9fa9459Szrj 	  && htab->elf.splt->output_section != NULL
6311a9fa9459Szrj 	  && htab->plt_eh_frame->output_section != NULL)
6312a9fa9459Szrj 	{
6313a9fa9459Szrj 	  bfd_vma plt_start = htab->elf.splt->output_section->vma;
6314a9fa9459Szrj 	  bfd_vma eh_frame_start = htab->plt_eh_frame->output_section->vma
6315a9fa9459Szrj 				   + htab->plt_eh_frame->output_offset
6316a9fa9459Szrj 				   + PLT_FDE_START_OFFSET;
6317a9fa9459Szrj 	  bfd_put_signed_32 (dynobj, plt_start - eh_frame_start,
6318a9fa9459Szrj 			     htab->plt_eh_frame->contents
6319a9fa9459Szrj 			     + PLT_FDE_START_OFFSET);
6320a9fa9459Szrj 	}
6321a9fa9459Szrj       if (htab->plt_eh_frame->sec_info_type == SEC_INFO_TYPE_EH_FRAME)
6322a9fa9459Szrj 	{
6323a9fa9459Szrj 	  if (! _bfd_elf_write_section_eh_frame (output_bfd, info,
6324a9fa9459Szrj 						 htab->plt_eh_frame,
6325a9fa9459Szrj 						 htab->plt_eh_frame->contents))
6326a9fa9459Szrj 	    return FALSE;
6327a9fa9459Szrj 	}
6328a9fa9459Szrj     }
6329a9fa9459Szrj 
6330a9fa9459Szrj   if (htab->elf.sgot && htab->elf.sgot->size > 0)
6331a9fa9459Szrj     elf_section_data (htab->elf.sgot->output_section)->this_hdr.sh_entsize
6332a9fa9459Szrj       = GOT_ENTRY_SIZE;
6333a9fa9459Szrj 
6334a9fa9459Szrj   /* Fill PLT entries for undefined weak symbols in PIE.  */
6335a9fa9459Szrj   if (bfd_link_pie (info))
6336a9fa9459Szrj     bfd_hash_traverse (&info->hash->table,
6337a9fa9459Szrj 		       elf_x86_64_pie_finish_undefweak_symbol,
6338a9fa9459Szrj 		       info);
6339a9fa9459Szrj 
6340a9fa9459Szrj   return TRUE;
6341a9fa9459Szrj }
6342a9fa9459Szrj 
6343a9fa9459Szrj /* Fill PLT/GOT entries and allocate dynamic relocations for local
6344a9fa9459Szrj    STT_GNU_IFUNC symbols, which aren't in the ELF linker hash table.
6345a9fa9459Szrj    It has to be done before elf_link_sort_relocs is called so that
6346a9fa9459Szrj    dynamic relocations are properly sorted.  */
6347a9fa9459Szrj 
6348a9fa9459Szrj static bfd_boolean
elf_x86_64_output_arch_local_syms(bfd * output_bfd ATTRIBUTE_UNUSED,struct bfd_link_info * info,void * flaginfo ATTRIBUTE_UNUSED,int (* func)(void *,const char *,Elf_Internal_Sym *,asection *,struct elf_link_hash_entry *)ATTRIBUTE_UNUSED)6349a9fa9459Szrj elf_x86_64_output_arch_local_syms
6350a9fa9459Szrj   (bfd *output_bfd ATTRIBUTE_UNUSED,
6351a9fa9459Szrj    struct bfd_link_info *info,
6352a9fa9459Szrj    void *flaginfo ATTRIBUTE_UNUSED,
6353a9fa9459Szrj    int (*func) (void *, const char *,
6354a9fa9459Szrj 		Elf_Internal_Sym *,
6355a9fa9459Szrj 		asection *,
6356a9fa9459Szrj 		struct elf_link_hash_entry *) ATTRIBUTE_UNUSED)
6357a9fa9459Szrj {
6358a9fa9459Szrj   struct elf_x86_64_link_hash_table *htab = elf_x86_64_hash_table (info);
6359a9fa9459Szrj   if (htab == NULL)
6360a9fa9459Szrj     return FALSE;
6361a9fa9459Szrj 
6362a9fa9459Szrj   /* Fill PLT and GOT entries for local STT_GNU_IFUNC symbols.  */
6363a9fa9459Szrj   htab_traverse (htab->loc_hash_table,
6364a9fa9459Szrj 		 elf_x86_64_finish_local_dynamic_symbol,
6365a9fa9459Szrj 		 info);
6366a9fa9459Szrj 
6367a9fa9459Szrj   return TRUE;
6368a9fa9459Szrj }
6369a9fa9459Szrj 
6370a9fa9459Szrj /* Return an array of PLT entry symbol values.  */
6371a9fa9459Szrj 
6372a9fa9459Szrj static bfd_vma *
elf_x86_64_get_plt_sym_val(bfd * abfd,asymbol ** dynsyms,asection * plt,asection * relplt)6373a9fa9459Szrj elf_x86_64_get_plt_sym_val (bfd *abfd, asymbol **dynsyms, asection *plt,
6374a9fa9459Szrj 			    asection *relplt)
6375a9fa9459Szrj {
6376a9fa9459Szrj   bfd_boolean (*slurp_relocs) (bfd *, asection *, asymbol **, bfd_boolean);
6377a9fa9459Szrj   arelent *p;
6378a9fa9459Szrj   long count, i;
6379a9fa9459Szrj   bfd_vma *plt_sym_val;
6380a9fa9459Szrj   bfd_vma plt_offset;
6381a9fa9459Szrj   bfd_byte *plt_contents;
6382a9fa9459Szrj   const struct elf_x86_64_backend_data *bed;
6383a9fa9459Szrj   Elf_Internal_Shdr *hdr;
6384a9fa9459Szrj   asection *plt_bnd;
6385a9fa9459Szrj 
6386a9fa9459Szrj   /* Get the .plt section contents.  PLT passed down may point to the
6387a9fa9459Szrj      .plt.bnd section.  Make sure that PLT always points to the .plt
6388a9fa9459Szrj      section.  */
6389a9fa9459Szrj   plt_bnd = bfd_get_section_by_name (abfd, ".plt.bnd");
6390a9fa9459Szrj   if (plt_bnd)
6391a9fa9459Szrj     {
6392a9fa9459Szrj       if (plt != plt_bnd)
6393a9fa9459Szrj 	abort ();
6394a9fa9459Szrj       plt = bfd_get_section_by_name (abfd, ".plt");
6395a9fa9459Szrj       if (plt == NULL)
6396a9fa9459Szrj 	abort ();
6397a9fa9459Szrj       bed = &elf_x86_64_bnd_arch_bed;
6398a9fa9459Szrj     }
6399a9fa9459Szrj   else
6400a9fa9459Szrj     bed = get_elf_x86_64_backend_data (abfd);
6401a9fa9459Szrj 
6402a9fa9459Szrj   plt_contents = (bfd_byte *) bfd_malloc (plt->size);
6403a9fa9459Szrj   if (plt_contents == NULL)
6404a9fa9459Szrj     return NULL;
6405a9fa9459Szrj   if (!bfd_get_section_contents (abfd, (asection *) plt,
6406a9fa9459Szrj 				 plt_contents, 0, plt->size))
6407a9fa9459Szrj     {
6408a9fa9459Szrj bad_return:
6409a9fa9459Szrj       free (plt_contents);
6410a9fa9459Szrj       return NULL;
6411a9fa9459Szrj     }
6412a9fa9459Szrj 
6413a9fa9459Szrj   slurp_relocs = get_elf_backend_data (abfd)->s->slurp_reloc_table;
6414a9fa9459Szrj   if (! (*slurp_relocs) (abfd, relplt, dynsyms, TRUE))
6415a9fa9459Szrj     goto bad_return;
6416a9fa9459Szrj 
6417a9fa9459Szrj   hdr = &elf_section_data (relplt)->this_hdr;
6418a9fa9459Szrj   count = relplt->size / hdr->sh_entsize;
6419a9fa9459Szrj 
6420a9fa9459Szrj   plt_sym_val = (bfd_vma *) bfd_malloc (sizeof (bfd_vma) * count);
6421a9fa9459Szrj   if (plt_sym_val == NULL)
6422a9fa9459Szrj     goto bad_return;
6423a9fa9459Szrj 
6424a9fa9459Szrj   for (i = 0; i < count; i++)
6425a9fa9459Szrj     plt_sym_val[i] = -1;
6426a9fa9459Szrj 
6427a9fa9459Szrj   plt_offset = bed->plt_entry_size;
6428a9fa9459Szrj   p = relplt->relocation;
6429a9fa9459Szrj   for (i = 0; i < count; i++, p++)
6430a9fa9459Szrj     {
6431a9fa9459Szrj       long reloc_index;
6432a9fa9459Szrj 
6433a9fa9459Szrj       /* Skip unknown relocation.  */
6434a9fa9459Szrj       if (p->howto == NULL)
6435a9fa9459Szrj 	continue;
6436a9fa9459Szrj 
6437a9fa9459Szrj       if (p->howto->type != R_X86_64_JUMP_SLOT
6438a9fa9459Szrj 	  && p->howto->type != R_X86_64_IRELATIVE)
6439a9fa9459Szrj 	continue;
6440a9fa9459Szrj 
6441a9fa9459Szrj       reloc_index = H_GET_32 (abfd, (plt_contents + plt_offset
6442a9fa9459Szrj 				     + bed->plt_reloc_offset));
6443a9fa9459Szrj       if (reloc_index < count)
6444a9fa9459Szrj 	{
6445a9fa9459Szrj 	  if (plt_bnd)
6446a9fa9459Szrj 	    {
6447a9fa9459Szrj 	      /* This is the index in .plt section.  */
6448a9fa9459Szrj 	      long plt_index = plt_offset / bed->plt_entry_size;
6449a9fa9459Szrj 	      /* Store VMA + the offset in .plt.bnd section.  */
6450a9fa9459Szrj 	      plt_sym_val[reloc_index] =
6451a9fa9459Szrj 		(plt_bnd->vma
6452a9fa9459Szrj 		 + (plt_index - 1) * sizeof (elf_x86_64_legacy_plt2_entry));
6453a9fa9459Szrj 	    }
6454a9fa9459Szrj 	  else
6455a9fa9459Szrj 	    plt_sym_val[reloc_index] = plt->vma + plt_offset;
6456a9fa9459Szrj 	}
6457a9fa9459Szrj       plt_offset += bed->plt_entry_size;
6458a9fa9459Szrj 
6459a9fa9459Szrj       /* PR binutils/18437: Skip extra relocations in the .rela.plt
6460a9fa9459Szrj 	 section.  */
6461a9fa9459Szrj       if (plt_offset >= plt->size)
6462a9fa9459Szrj 	break;
6463a9fa9459Szrj     }
6464a9fa9459Szrj 
6465a9fa9459Szrj   free (plt_contents);
6466a9fa9459Szrj 
6467a9fa9459Szrj   return plt_sym_val;
6468a9fa9459Szrj }
6469a9fa9459Szrj 
6470a9fa9459Szrj /* Similar to _bfd_elf_get_synthetic_symtab, with .plt.bnd section
6471a9fa9459Szrj    support.  */
6472a9fa9459Szrj 
6473a9fa9459Szrj static long
elf_x86_64_get_synthetic_symtab(bfd * abfd,long symcount,asymbol ** syms,long dynsymcount,asymbol ** dynsyms,asymbol ** ret)6474a9fa9459Szrj elf_x86_64_get_synthetic_symtab (bfd *abfd,
6475a9fa9459Szrj 				 long symcount,
6476a9fa9459Szrj 				 asymbol **syms,
6477a9fa9459Szrj 				 long dynsymcount,
6478a9fa9459Szrj 				 asymbol **dynsyms,
6479a9fa9459Szrj 				 asymbol **ret)
6480a9fa9459Szrj {
6481a9fa9459Szrj   /* Pass the .plt.bnd section to _bfd_elf_ifunc_get_synthetic_symtab
6482a9fa9459Szrj      as PLT if it exists.  */
6483a9fa9459Szrj   asection *plt = bfd_get_section_by_name (abfd, ".plt.bnd");
6484a9fa9459Szrj   if (plt == NULL)
6485a9fa9459Szrj     plt = bfd_get_section_by_name (abfd, ".plt");
6486a9fa9459Szrj   return _bfd_elf_ifunc_get_synthetic_symtab (abfd, symcount, syms,
6487a9fa9459Szrj 					      dynsymcount, dynsyms, ret,
6488a9fa9459Szrj 					      plt,
6489a9fa9459Szrj 					      elf_x86_64_get_plt_sym_val);
6490a9fa9459Szrj }
6491a9fa9459Szrj 
6492a9fa9459Szrj /* Handle an x86-64 specific section when reading an object file.  This
6493a9fa9459Szrj    is called when elfcode.h finds a section with an unknown type.  */
6494a9fa9459Szrj 
6495a9fa9459Szrj static bfd_boolean
elf_x86_64_section_from_shdr(bfd * abfd,Elf_Internal_Shdr * hdr,const char * name,int shindex)6496a9fa9459Szrj elf_x86_64_section_from_shdr (bfd *abfd, Elf_Internal_Shdr *hdr,
6497a9fa9459Szrj 			      const char *name, int shindex)
6498a9fa9459Szrj {
6499a9fa9459Szrj   if (hdr->sh_type != SHT_X86_64_UNWIND)
6500a9fa9459Szrj     return FALSE;
6501a9fa9459Szrj 
6502a9fa9459Szrj   if (! _bfd_elf_make_section_from_shdr (abfd, hdr, name, shindex))
6503a9fa9459Szrj     return FALSE;
6504a9fa9459Szrj 
6505a9fa9459Szrj   return TRUE;
6506a9fa9459Szrj }
6507a9fa9459Szrj 
6508a9fa9459Szrj /* Hook called by the linker routine which adds symbols from an object
6509a9fa9459Szrj    file.  We use it to put SHN_X86_64_LCOMMON items in .lbss, instead
6510a9fa9459Szrj    of .bss.  */
6511a9fa9459Szrj 
6512a9fa9459Szrj static bfd_boolean
elf_x86_64_add_symbol_hook(bfd * abfd,struct bfd_link_info * info ATTRIBUTE_UNUSED,Elf_Internal_Sym * sym,const char ** namep ATTRIBUTE_UNUSED,flagword * flagsp ATTRIBUTE_UNUSED,asection ** secp,bfd_vma * valp)6513a9fa9459Szrj elf_x86_64_add_symbol_hook (bfd *abfd,
6514a9fa9459Szrj 			    struct bfd_link_info *info ATTRIBUTE_UNUSED,
6515a9fa9459Szrj 			    Elf_Internal_Sym *sym,
6516a9fa9459Szrj 			    const char **namep ATTRIBUTE_UNUSED,
6517a9fa9459Szrj 			    flagword *flagsp ATTRIBUTE_UNUSED,
6518a9fa9459Szrj 			    asection **secp,
6519a9fa9459Szrj 			    bfd_vma *valp)
6520a9fa9459Szrj {
6521a9fa9459Szrj   asection *lcomm;
6522a9fa9459Szrj 
6523a9fa9459Szrj   switch (sym->st_shndx)
6524a9fa9459Szrj     {
6525a9fa9459Szrj     case SHN_X86_64_LCOMMON:
6526a9fa9459Szrj       lcomm = bfd_get_section_by_name (abfd, "LARGE_COMMON");
6527a9fa9459Szrj       if (lcomm == NULL)
6528a9fa9459Szrj 	{
6529a9fa9459Szrj 	  lcomm = bfd_make_section_with_flags (abfd,
6530a9fa9459Szrj 					       "LARGE_COMMON",
6531a9fa9459Szrj 					       (SEC_ALLOC
6532a9fa9459Szrj 						| SEC_IS_COMMON
6533a9fa9459Szrj 						| SEC_LINKER_CREATED));
6534a9fa9459Szrj 	  if (lcomm == NULL)
6535a9fa9459Szrj 	    return FALSE;
6536a9fa9459Szrj 	  elf_section_flags (lcomm) |= SHF_X86_64_LARGE;
6537a9fa9459Szrj 	}
6538a9fa9459Szrj       *secp = lcomm;
6539a9fa9459Szrj       *valp = sym->st_size;
6540a9fa9459Szrj       return TRUE;
6541a9fa9459Szrj     }
6542a9fa9459Szrj 
6543a9fa9459Szrj   return TRUE;
6544a9fa9459Szrj }
6545a9fa9459Szrj 
6546a9fa9459Szrj 
6547a9fa9459Szrj /* Given a BFD section, try to locate the corresponding ELF section
6548a9fa9459Szrj    index.  */
6549a9fa9459Szrj 
6550a9fa9459Szrj static bfd_boolean
elf_x86_64_elf_section_from_bfd_section(bfd * abfd ATTRIBUTE_UNUSED,asection * sec,int * index_return)6551a9fa9459Szrj elf_x86_64_elf_section_from_bfd_section (bfd *abfd ATTRIBUTE_UNUSED,
6552a9fa9459Szrj 					 asection *sec, int *index_return)
6553a9fa9459Szrj {
6554a9fa9459Szrj   if (sec == &_bfd_elf_large_com_section)
6555a9fa9459Szrj     {
6556a9fa9459Szrj       *index_return = SHN_X86_64_LCOMMON;
6557a9fa9459Szrj       return TRUE;
6558a9fa9459Szrj     }
6559a9fa9459Szrj   return FALSE;
6560a9fa9459Szrj }
6561a9fa9459Szrj 
6562a9fa9459Szrj /* Process a symbol.  */
6563a9fa9459Szrj 
6564a9fa9459Szrj static void
elf_x86_64_symbol_processing(bfd * abfd ATTRIBUTE_UNUSED,asymbol * asym)6565a9fa9459Szrj elf_x86_64_symbol_processing (bfd *abfd ATTRIBUTE_UNUSED,
6566a9fa9459Szrj 			      asymbol *asym)
6567a9fa9459Szrj {
6568a9fa9459Szrj   elf_symbol_type *elfsym = (elf_symbol_type *) asym;
6569a9fa9459Szrj 
6570a9fa9459Szrj   switch (elfsym->internal_elf_sym.st_shndx)
6571a9fa9459Szrj     {
6572a9fa9459Szrj     case SHN_X86_64_LCOMMON:
6573a9fa9459Szrj       asym->section = &_bfd_elf_large_com_section;
6574a9fa9459Szrj       asym->value = elfsym->internal_elf_sym.st_size;
6575a9fa9459Szrj       /* Common symbol doesn't set BSF_GLOBAL.  */
6576a9fa9459Szrj       asym->flags &= ~BSF_GLOBAL;
6577a9fa9459Szrj       break;
6578a9fa9459Szrj     }
6579a9fa9459Szrj }
6580a9fa9459Szrj 
6581a9fa9459Szrj static bfd_boolean
elf_x86_64_common_definition(Elf_Internal_Sym * sym)6582a9fa9459Szrj elf_x86_64_common_definition (Elf_Internal_Sym *sym)
6583a9fa9459Szrj {
6584a9fa9459Szrj   return (sym->st_shndx == SHN_COMMON
6585a9fa9459Szrj 	  || sym->st_shndx == SHN_X86_64_LCOMMON);
6586a9fa9459Szrj }
6587a9fa9459Szrj 
6588a9fa9459Szrj static unsigned int
elf_x86_64_common_section_index(asection * sec)6589a9fa9459Szrj elf_x86_64_common_section_index (asection *sec)
6590a9fa9459Szrj {
6591a9fa9459Szrj   if ((elf_section_flags (sec) & SHF_X86_64_LARGE) == 0)
6592a9fa9459Szrj     return SHN_COMMON;
6593a9fa9459Szrj   else
6594a9fa9459Szrj     return SHN_X86_64_LCOMMON;
6595a9fa9459Szrj }
6596a9fa9459Szrj 
6597a9fa9459Szrj static asection *
elf_x86_64_common_section(asection * sec)6598a9fa9459Szrj elf_x86_64_common_section (asection *sec)
6599a9fa9459Szrj {
6600a9fa9459Szrj   if ((elf_section_flags (sec) & SHF_X86_64_LARGE) == 0)
6601a9fa9459Szrj     return bfd_com_section_ptr;
6602a9fa9459Szrj   else
6603a9fa9459Szrj     return &_bfd_elf_large_com_section;
6604a9fa9459Szrj }
6605a9fa9459Szrj 
6606a9fa9459Szrj static bfd_boolean
elf_x86_64_merge_symbol(struct elf_link_hash_entry * h,const Elf_Internal_Sym * sym,asection ** psec,bfd_boolean newdef,bfd_boolean olddef,bfd * oldbfd,const asection * oldsec)6607a9fa9459Szrj elf_x86_64_merge_symbol (struct elf_link_hash_entry *h,
6608a9fa9459Szrj 			 const Elf_Internal_Sym *sym,
6609a9fa9459Szrj 			 asection **psec,
6610a9fa9459Szrj 			 bfd_boolean newdef,
6611a9fa9459Szrj 			 bfd_boolean olddef,
6612a9fa9459Szrj 			 bfd *oldbfd,
6613a9fa9459Szrj 			 const asection *oldsec)
6614a9fa9459Szrj {
6615a9fa9459Szrj   /* A normal common symbol and a large common symbol result in a
6616a9fa9459Szrj      normal common symbol.  We turn the large common symbol into a
6617a9fa9459Szrj      normal one.  */
6618a9fa9459Szrj   if (!olddef
6619a9fa9459Szrj       && h->root.type == bfd_link_hash_common
6620a9fa9459Szrj       && !newdef
6621a9fa9459Szrj       && bfd_is_com_section (*psec)
6622a9fa9459Szrj       && oldsec != *psec)
6623a9fa9459Szrj     {
6624a9fa9459Szrj       if (sym->st_shndx == SHN_COMMON
6625a9fa9459Szrj 	  && (elf_section_flags (oldsec) & SHF_X86_64_LARGE) != 0)
6626a9fa9459Szrj 	{
6627a9fa9459Szrj 	  h->root.u.c.p->section
6628a9fa9459Szrj 	    = bfd_make_section_old_way (oldbfd, "COMMON");
6629a9fa9459Szrj 	  h->root.u.c.p->section->flags = SEC_ALLOC;
6630a9fa9459Szrj 	}
6631a9fa9459Szrj       else if (sym->st_shndx == SHN_X86_64_LCOMMON
6632a9fa9459Szrj 	       && (elf_section_flags (oldsec) & SHF_X86_64_LARGE) == 0)
6633a9fa9459Szrj 	*psec = bfd_com_section_ptr;
6634a9fa9459Szrj     }
6635a9fa9459Szrj 
6636a9fa9459Szrj   return TRUE;
6637a9fa9459Szrj }
6638a9fa9459Szrj 
6639a9fa9459Szrj static int
elf_x86_64_additional_program_headers(bfd * abfd,struct bfd_link_info * info ATTRIBUTE_UNUSED)6640a9fa9459Szrj elf_x86_64_additional_program_headers (bfd *abfd,
6641a9fa9459Szrj 				       struct bfd_link_info *info ATTRIBUTE_UNUSED)
6642a9fa9459Szrj {
6643a9fa9459Szrj   asection *s;
6644a9fa9459Szrj   int count = 0;
6645a9fa9459Szrj 
6646a9fa9459Szrj   /* Check to see if we need a large readonly segment.  */
6647a9fa9459Szrj   s = bfd_get_section_by_name (abfd, ".lrodata");
6648a9fa9459Szrj   if (s && (s->flags & SEC_LOAD))
6649a9fa9459Szrj     count++;
6650a9fa9459Szrj 
6651a9fa9459Szrj   /* Check to see if we need a large data segment.  Since .lbss sections
6652a9fa9459Szrj      is placed right after the .bss section, there should be no need for
6653a9fa9459Szrj      a large data segment just because of .lbss.  */
6654a9fa9459Szrj   s = bfd_get_section_by_name (abfd, ".ldata");
6655a9fa9459Szrj   if (s && (s->flags & SEC_LOAD))
6656a9fa9459Szrj     count++;
6657a9fa9459Szrj 
6658a9fa9459Szrj   return count;
6659a9fa9459Szrj }
6660a9fa9459Szrj 
6661a9fa9459Szrj /* Return TRUE if symbol should be hashed in the `.gnu.hash' section.  */
6662a9fa9459Szrj 
6663a9fa9459Szrj static bfd_boolean
elf_x86_64_hash_symbol(struct elf_link_hash_entry * h)6664a9fa9459Szrj elf_x86_64_hash_symbol (struct elf_link_hash_entry *h)
6665a9fa9459Szrj {
6666a9fa9459Szrj   if (h->plt.offset != (bfd_vma) -1
6667a9fa9459Szrj       && !h->def_regular
6668a9fa9459Szrj       && !h->pointer_equality_needed)
6669a9fa9459Szrj     return FALSE;
6670a9fa9459Szrj 
6671a9fa9459Szrj   return _bfd_elf_hash_symbol (h);
6672a9fa9459Szrj }
6673a9fa9459Szrj 
6674a9fa9459Szrj /* Return TRUE iff relocations for INPUT are compatible with OUTPUT. */
6675a9fa9459Szrj 
6676a9fa9459Szrj static bfd_boolean
elf_x86_64_relocs_compatible(const bfd_target * input,const bfd_target * output)6677a9fa9459Szrj elf_x86_64_relocs_compatible (const bfd_target *input,
6678a9fa9459Szrj 			      const bfd_target *output)
6679a9fa9459Szrj {
6680a9fa9459Szrj   return ((xvec_get_elf_backend_data (input)->s->elfclass
6681a9fa9459Szrj 	   == xvec_get_elf_backend_data (output)->s->elfclass)
6682a9fa9459Szrj 	  && _bfd_elf_relocs_compatible (input, output));
6683a9fa9459Szrj }
6684a9fa9459Szrj 
6685a9fa9459Szrj static const struct bfd_elf_special_section
6686a9fa9459Szrj   elf_x86_64_special_sections[]=
6687a9fa9459Szrj {
6688a9fa9459Szrj   { STRING_COMMA_LEN (".gnu.linkonce.lb"), -2, SHT_NOBITS,   SHF_ALLOC + SHF_WRITE + SHF_X86_64_LARGE},
6689a9fa9459Szrj   { STRING_COMMA_LEN (".gnu.linkonce.lr"), -2, SHT_PROGBITS, SHF_ALLOC + SHF_X86_64_LARGE},
6690a9fa9459Szrj   { STRING_COMMA_LEN (".gnu.linkonce.lt"), -2, SHT_PROGBITS, SHF_ALLOC + SHF_EXECINSTR + SHF_X86_64_LARGE},
6691a9fa9459Szrj   { STRING_COMMA_LEN (".lbss"),	           -2, SHT_NOBITS,   SHF_ALLOC + SHF_WRITE + SHF_X86_64_LARGE},
6692a9fa9459Szrj   { STRING_COMMA_LEN (".ldata"),	   -2, SHT_PROGBITS, SHF_ALLOC + SHF_WRITE + SHF_X86_64_LARGE},
6693a9fa9459Szrj   { STRING_COMMA_LEN (".lrodata"),	   -2, SHT_PROGBITS, SHF_ALLOC + SHF_X86_64_LARGE},
6694a9fa9459Szrj   { NULL,	                0,          0, 0,            0 }
6695a9fa9459Szrj };
6696a9fa9459Szrj 
6697a9fa9459Szrj #define TARGET_LITTLE_SYM		    x86_64_elf64_vec
6698a9fa9459Szrj #define TARGET_LITTLE_NAME		    "elf64-x86-64"
6699a9fa9459Szrj #define ELF_ARCH			    bfd_arch_i386
6700a9fa9459Szrj #define ELF_TARGET_ID			    X86_64_ELF_DATA
6701a9fa9459Szrj #define ELF_MACHINE_CODE		    EM_X86_64
6702a9fa9459Szrj #define ELF_MAXPAGESIZE			    0x200000
6703a9fa9459Szrj #define ELF_MINPAGESIZE			    0x1000
6704a9fa9459Szrj #define ELF_COMMONPAGESIZE		    0x1000
6705a9fa9459Szrj 
6706a9fa9459Szrj #define elf_backend_can_gc_sections	    1
6707a9fa9459Szrj #define elf_backend_can_refcount	    1
6708a9fa9459Szrj #define elf_backend_want_got_plt	    1
6709a9fa9459Szrj #define elf_backend_plt_readonly	    1
6710a9fa9459Szrj #define elf_backend_want_plt_sym	    0
6711a9fa9459Szrj #define elf_backend_got_header_size	    (GOT_ENTRY_SIZE*3)
6712a9fa9459Szrj #define elf_backend_rela_normal		    1
6713a9fa9459Szrj #define elf_backend_plt_alignment           4
6714a9fa9459Szrj #define elf_backend_extern_protected_data   1
6715a9fa9459Szrj #define elf_backend_caches_rawsize	    1
6716a9fa9459Szrj 
6717a9fa9459Szrj #define elf_info_to_howto		    elf_x86_64_info_to_howto
6718a9fa9459Szrj 
6719a9fa9459Szrj #define bfd_elf64_bfd_link_hash_table_create \
6720a9fa9459Szrj   elf_x86_64_link_hash_table_create
6721a9fa9459Szrj #define bfd_elf64_bfd_reloc_type_lookup	    elf_x86_64_reloc_type_lookup
6722a9fa9459Szrj #define bfd_elf64_bfd_reloc_name_lookup \
6723a9fa9459Szrj   elf_x86_64_reloc_name_lookup
6724a9fa9459Szrj 
6725a9fa9459Szrj #define elf_backend_adjust_dynamic_symbol   elf_x86_64_adjust_dynamic_symbol
6726a9fa9459Szrj #define elf_backend_relocs_compatible	    elf_x86_64_relocs_compatible
6727a9fa9459Szrj #define elf_backend_check_relocs	    elf_x86_64_check_relocs
6728a9fa9459Szrj #define elf_backend_copy_indirect_symbol    elf_x86_64_copy_indirect_symbol
6729a9fa9459Szrj #define elf_backend_create_dynamic_sections elf_x86_64_create_dynamic_sections
6730a9fa9459Szrj #define elf_backend_finish_dynamic_sections elf_x86_64_finish_dynamic_sections
6731a9fa9459Szrj #define elf_backend_finish_dynamic_symbol   elf_x86_64_finish_dynamic_symbol
6732a9fa9459Szrj #define elf_backend_output_arch_local_syms  elf_x86_64_output_arch_local_syms
6733a9fa9459Szrj #define elf_backend_gc_mark_hook	    elf_x86_64_gc_mark_hook
6734a9fa9459Szrj #define elf_backend_grok_prstatus	    elf_x86_64_grok_prstatus
6735a9fa9459Szrj #define elf_backend_grok_psinfo		    elf_x86_64_grok_psinfo
6736a9fa9459Szrj #ifdef CORE_HEADER
6737a9fa9459Szrj #define elf_backend_write_core_note	    elf_x86_64_write_core_note
6738a9fa9459Szrj #endif
6739a9fa9459Szrj #define elf_backend_reloc_type_class	    elf_x86_64_reloc_type_class
6740a9fa9459Szrj #define elf_backend_relocate_section	    elf_x86_64_relocate_section
6741a9fa9459Szrj #define elf_backend_size_dynamic_sections   elf_x86_64_size_dynamic_sections
6742a9fa9459Szrj #define elf_backend_always_size_sections    elf_x86_64_always_size_sections
6743a9fa9459Szrj #define elf_backend_init_index_section	    _bfd_elf_init_1_index_section
6744a9fa9459Szrj #define elf_backend_object_p		    elf64_x86_64_elf_object_p
6745a9fa9459Szrj #define bfd_elf64_mkobject		    elf_x86_64_mkobject
6746a9fa9459Szrj #define bfd_elf64_get_synthetic_symtab	    elf_x86_64_get_synthetic_symtab
6747a9fa9459Szrj 
6748a9fa9459Szrj #define elf_backend_section_from_shdr \
6749a9fa9459Szrj 	elf_x86_64_section_from_shdr
6750a9fa9459Szrj 
6751a9fa9459Szrj #define elf_backend_section_from_bfd_section \
6752a9fa9459Szrj   elf_x86_64_elf_section_from_bfd_section
6753a9fa9459Szrj #define elf_backend_add_symbol_hook \
6754a9fa9459Szrj   elf_x86_64_add_symbol_hook
6755a9fa9459Szrj #define elf_backend_symbol_processing \
6756a9fa9459Szrj   elf_x86_64_symbol_processing
6757a9fa9459Szrj #define elf_backend_common_section_index \
6758a9fa9459Szrj   elf_x86_64_common_section_index
6759a9fa9459Szrj #define elf_backend_common_section \
6760a9fa9459Szrj   elf_x86_64_common_section
6761a9fa9459Szrj #define elf_backend_common_definition \
6762a9fa9459Szrj   elf_x86_64_common_definition
6763a9fa9459Szrj #define elf_backend_merge_symbol \
6764a9fa9459Szrj   elf_x86_64_merge_symbol
6765a9fa9459Szrj #define elf_backend_special_sections \
6766a9fa9459Szrj   elf_x86_64_special_sections
6767a9fa9459Szrj #define elf_backend_additional_program_headers \
6768a9fa9459Szrj   elf_x86_64_additional_program_headers
6769a9fa9459Szrj #define elf_backend_hash_symbol \
6770a9fa9459Szrj   elf_x86_64_hash_symbol
6771a9fa9459Szrj #define elf_backend_omit_section_dynsym \
6772a9fa9459Szrj   ((bfd_boolean (*) (bfd *, struct bfd_link_info *, asection *)) bfd_true)
6773a9fa9459Szrj #define elf_backend_fixup_symbol \
6774a9fa9459Szrj   elf_x86_64_fixup_symbol
6775a9fa9459Szrj 
6776a9fa9459Szrj #include "elf64-target.h"
6777a9fa9459Szrj 
6778a9fa9459Szrj /* CloudABI support.  */
6779a9fa9459Szrj 
6780a9fa9459Szrj #undef  TARGET_LITTLE_SYM
6781a9fa9459Szrj #define TARGET_LITTLE_SYM		    x86_64_elf64_cloudabi_vec
6782a9fa9459Szrj #undef  TARGET_LITTLE_NAME
6783a9fa9459Szrj #define TARGET_LITTLE_NAME		    "elf64-x86-64-cloudabi"
6784a9fa9459Szrj 
6785a9fa9459Szrj #undef	ELF_OSABI
6786a9fa9459Szrj #define	ELF_OSABI			    ELFOSABI_CLOUDABI
6787a9fa9459Szrj 
6788a9fa9459Szrj #undef  elf64_bed
6789a9fa9459Szrj #define elf64_bed elf64_x86_64_cloudabi_bed
6790a9fa9459Szrj 
6791a9fa9459Szrj #include "elf64-target.h"
6792a9fa9459Szrj 
6793a9fa9459Szrj /* FreeBSD support.  */
6794a9fa9459Szrj 
6795a9fa9459Szrj #undef  TARGET_LITTLE_SYM
6796a9fa9459Szrj #define TARGET_LITTLE_SYM		    x86_64_elf64_fbsd_vec
6797a9fa9459Szrj #undef  TARGET_LITTLE_NAME
6798a9fa9459Szrj #define TARGET_LITTLE_NAME		    "elf64-x86-64-freebsd"
6799a9fa9459Szrj 
6800a9fa9459Szrj #undef	ELF_OSABI
6801a9fa9459Szrj #define	ELF_OSABI			    ELFOSABI_FREEBSD
6802a9fa9459Szrj 
6803a9fa9459Szrj #undef  elf64_bed
6804a9fa9459Szrj #define elf64_bed elf64_x86_64_fbsd_bed
6805a9fa9459Szrj 
6806a9fa9459Szrj #include "elf64-target.h"
6807a9fa9459Szrj 
6808a9fa9459Szrj /* Solaris 2 support.  */
6809a9fa9459Szrj 
6810a9fa9459Szrj #undef  TARGET_LITTLE_SYM
6811a9fa9459Szrj #define TARGET_LITTLE_SYM		    x86_64_elf64_sol2_vec
6812a9fa9459Szrj #undef  TARGET_LITTLE_NAME
6813a9fa9459Szrj #define TARGET_LITTLE_NAME		    "elf64-x86-64-sol2"
6814a9fa9459Szrj 
6815a9fa9459Szrj /* Restore default: we cannot use ELFOSABI_SOLARIS, otherwise ELFOSABI_NONE
6816a9fa9459Szrj    objects won't be recognized.  */
6817a9fa9459Szrj #undef ELF_OSABI
6818a9fa9459Szrj 
6819a9fa9459Szrj #undef  elf64_bed
6820a9fa9459Szrj #define elf64_bed			    elf64_x86_64_sol2_bed
6821a9fa9459Szrj 
6822a9fa9459Szrj /* The 64-bit static TLS arena size is rounded to the nearest 16-byte
6823a9fa9459Szrj    boundary.  */
6824a9fa9459Szrj #undef  elf_backend_static_tls_alignment
6825a9fa9459Szrj #define elf_backend_static_tls_alignment    16
6826a9fa9459Szrj 
6827a9fa9459Szrj /* The Solaris 2 ABI requires a plt symbol on all platforms.
6828a9fa9459Szrj 
6829a9fa9459Szrj    Cf. Linker and Libraries Guide, Ch. 2, Link-Editor, Generating the Output
6830a9fa9459Szrj    File, p.63.  */
6831a9fa9459Szrj #undef  elf_backend_want_plt_sym
6832a9fa9459Szrj #define elf_backend_want_plt_sym	    1
6833a9fa9459Szrj 
6834a9fa9459Szrj #undef  elf_backend_strtab_flags
6835a9fa9459Szrj #define elf_backend_strtab_flags	SHF_STRINGS
6836a9fa9459Szrj 
6837a9fa9459Szrj static bfd_boolean
elf64_x86_64_copy_solaris_special_section_fields(const bfd * ibfd ATTRIBUTE_UNUSED,bfd * obfd ATTRIBUTE_UNUSED,const Elf_Internal_Shdr * isection ATTRIBUTE_UNUSED,Elf_Internal_Shdr * osection ATTRIBUTE_UNUSED)6838a9fa9459Szrj elf64_x86_64_copy_solaris_special_section_fields (const bfd *ibfd ATTRIBUTE_UNUSED,
6839a9fa9459Szrj 						  bfd *obfd ATTRIBUTE_UNUSED,
6840a9fa9459Szrj 						  const Elf_Internal_Shdr *isection ATTRIBUTE_UNUSED,
6841a9fa9459Szrj 						  Elf_Internal_Shdr *osection ATTRIBUTE_UNUSED)
6842a9fa9459Szrj {
6843a9fa9459Szrj   /* PR 19938: FIXME: Need to add code for setting the sh_info
6844a9fa9459Szrj      and sh_link fields of Solaris specific section types.  */
6845a9fa9459Szrj   return FALSE;
6846a9fa9459Szrj }
6847a9fa9459Szrj 
6848a9fa9459Szrj #undef  elf_backend_copy_special_section_fields
6849a9fa9459Szrj #define elf_backend_copy_special_section_fields elf64_x86_64_copy_solaris_special_section_fields
6850a9fa9459Szrj 
6851a9fa9459Szrj #include "elf64-target.h"
6852a9fa9459Szrj 
6853a9fa9459Szrj /* Native Client support.  */
6854a9fa9459Szrj 
6855a9fa9459Szrj static bfd_boolean
elf64_x86_64_nacl_elf_object_p(bfd * abfd)6856a9fa9459Szrj elf64_x86_64_nacl_elf_object_p (bfd *abfd)
6857a9fa9459Szrj {
6858a9fa9459Szrj   /* Set the right machine number for a NaCl x86-64 ELF64 file.  */
6859a9fa9459Szrj   bfd_default_set_arch_mach (abfd, bfd_arch_i386, bfd_mach_x86_64_nacl);
6860a9fa9459Szrj   return TRUE;
6861a9fa9459Szrj }
6862a9fa9459Szrj 
6863a9fa9459Szrj #undef	TARGET_LITTLE_SYM
6864a9fa9459Szrj #define	TARGET_LITTLE_SYM		x86_64_elf64_nacl_vec
6865a9fa9459Szrj #undef	TARGET_LITTLE_NAME
6866a9fa9459Szrj #define	TARGET_LITTLE_NAME		"elf64-x86-64-nacl"
6867a9fa9459Szrj #undef	elf64_bed
6868a9fa9459Szrj #define	elf64_bed			elf64_x86_64_nacl_bed
6869a9fa9459Szrj 
6870a9fa9459Szrj #undef	ELF_MAXPAGESIZE
6871a9fa9459Szrj #undef	ELF_MINPAGESIZE
6872a9fa9459Szrj #undef	ELF_COMMONPAGESIZE
6873a9fa9459Szrj #define ELF_MAXPAGESIZE			0x10000
6874a9fa9459Szrj #define ELF_MINPAGESIZE			0x10000
6875a9fa9459Szrj #define ELF_COMMONPAGESIZE		0x10000
6876a9fa9459Szrj 
6877a9fa9459Szrj /* Restore defaults.  */
6878a9fa9459Szrj #undef	ELF_OSABI
6879a9fa9459Szrj #undef	elf_backend_static_tls_alignment
6880a9fa9459Szrj #undef	elf_backend_want_plt_sym
6881a9fa9459Szrj #define elf_backend_want_plt_sym	0
6882a9fa9459Szrj #undef  elf_backend_strtab_flags
6883a9fa9459Szrj #undef  elf_backend_copy_special_section_fields
6884a9fa9459Szrj 
6885a9fa9459Szrj /* NaCl uses substantially different PLT entries for the same effects.  */
6886a9fa9459Szrj 
6887a9fa9459Szrj #undef	elf_backend_plt_alignment
6888a9fa9459Szrj #define elf_backend_plt_alignment	5
6889a9fa9459Szrj #define NACL_PLT_ENTRY_SIZE		64
6890a9fa9459Szrj #define	NACLMASK			0xe0 /* 32-byte alignment mask.  */
6891a9fa9459Szrj 
6892a9fa9459Szrj static const bfd_byte elf_x86_64_nacl_plt0_entry[NACL_PLT_ENTRY_SIZE] =
6893a9fa9459Szrj   {
6894a9fa9459Szrj     0xff, 0x35, 8, 0, 0, 0,             /* pushq GOT+8(%rip) 		*/
6895a9fa9459Szrj     0x4c, 0x8b, 0x1d, 16, 0, 0, 0,	/* mov GOT+16(%rip), %r11	*/
6896a9fa9459Szrj     0x41, 0x83, 0xe3, NACLMASK,         /* and $-32, %r11d		*/
6897a9fa9459Szrj     0x4d, 0x01, 0xfb,             	/* add %r15, %r11		*/
6898a9fa9459Szrj     0x41, 0xff, 0xe3,             	/* jmpq *%r11			*/
6899a9fa9459Szrj 
6900a9fa9459Szrj     /* 9-byte nop sequence to pad out to the next 32-byte boundary.  */
6901a9fa9459Szrj     0x66, 0x0f, 0x1f, 0x84, 0, 0, 0, 0, 0, /* nopw 0x0(%rax,%rax,1)	*/
6902a9fa9459Szrj 
6903a9fa9459Szrj     /* 32 bytes of nop to pad out to the standard size.  */
6904a9fa9459Szrj     0x66, 0x66, 0x66, 0x66, 0x66, 0x66,    /* excess data16 prefixes	*/
6905a9fa9459Szrj     0x2e, 0x0f, 0x1f, 0x84, 0, 0, 0, 0, 0, /* nopw %cs:0x0(%rax,%rax,1)	*/
6906a9fa9459Szrj     0x66, 0x66, 0x66, 0x66, 0x66, 0x66,    /* excess data16 prefixes	*/
6907a9fa9459Szrj     0x2e, 0x0f, 0x1f, 0x84, 0, 0, 0, 0, 0, /* nopw %cs:0x0(%rax,%rax,1)	*/
6908a9fa9459Szrj     0x66,                                  /* excess data16 prefix	*/
6909a9fa9459Szrj     0x90                                   /* nop */
6910a9fa9459Szrj   };
6911a9fa9459Szrj 
6912a9fa9459Szrj static const bfd_byte elf_x86_64_nacl_plt_entry[NACL_PLT_ENTRY_SIZE] =
6913a9fa9459Szrj   {
6914a9fa9459Szrj     0x4c, 0x8b, 0x1d, 0, 0, 0, 0,	/* mov name@GOTPCREL(%rip),%r11	*/
6915a9fa9459Szrj     0x41, 0x83, 0xe3, NACLMASK,         /* and $-32, %r11d		*/
6916a9fa9459Szrj     0x4d, 0x01, 0xfb,             	/* add %r15, %r11		*/
6917a9fa9459Szrj     0x41, 0xff, 0xe3,             	/* jmpq *%r11			*/
6918a9fa9459Szrj 
6919a9fa9459Szrj     /* 15-byte nop sequence to pad out to the next 32-byte boundary.  */
6920a9fa9459Szrj     0x66, 0x66, 0x66, 0x66, 0x66, 0x66,    /* excess data16 prefixes	*/
6921a9fa9459Szrj     0x2e, 0x0f, 0x1f, 0x84, 0, 0, 0, 0, 0, /* nopw %cs:0x0(%rax,%rax,1)	*/
6922a9fa9459Szrj 
6923a9fa9459Szrj     /* Lazy GOT entries point here (32-byte aligned).  */
6924a9fa9459Szrj     0x68,                 /* pushq immediate */
6925a9fa9459Szrj     0, 0, 0, 0,           /* replaced with index into relocation table.  */
6926a9fa9459Szrj     0xe9,                 /* jmp relative */
6927a9fa9459Szrj     0, 0, 0, 0,           /* replaced with offset to start of .plt0.  */
6928a9fa9459Szrj 
6929a9fa9459Szrj     /* 22 bytes of nop to pad out to the standard size.  */
6930a9fa9459Szrj     0x66, 0x66, 0x66, 0x66, 0x66, 0x66,    /* excess data16 prefixes	*/
6931a9fa9459Szrj     0x2e, 0x0f, 0x1f, 0x84, 0, 0, 0, 0, 0, /* nopw %cs:0x0(%rax,%rax,1)	*/
6932a9fa9459Szrj     0x0f, 0x1f, 0x80, 0, 0, 0, 0,          /* nopl 0x0(%rax)		*/
6933a9fa9459Szrj   };
6934a9fa9459Szrj 
6935a9fa9459Szrj /* .eh_frame covering the .plt section.  */
6936a9fa9459Szrj 
6937a9fa9459Szrj static const bfd_byte elf_x86_64_nacl_eh_frame_plt[] =
6938a9fa9459Szrj   {
6939a9fa9459Szrj #if (PLT_CIE_LENGTH != 20                               \
6940a9fa9459Szrj      || PLT_FDE_LENGTH != 36                            \
6941a9fa9459Szrj      || PLT_FDE_START_OFFSET != 4 + PLT_CIE_LENGTH + 8  \
6942a9fa9459Szrj      || PLT_FDE_LEN_OFFSET != 4 + PLT_CIE_LENGTH + 12)
6943a9fa9459Szrj # error "Need elf_x86_64_backend_data parameters for eh_frame_plt offsets!"
6944a9fa9459Szrj #endif
6945a9fa9459Szrj     PLT_CIE_LENGTH, 0, 0, 0,	/* CIE length */
6946a9fa9459Szrj     0, 0, 0, 0,			/* CIE ID */
6947a9fa9459Szrj     1,				/* CIE version */
6948a9fa9459Szrj     'z', 'R', 0,                /* Augmentation string */
6949a9fa9459Szrj     1,				/* Code alignment factor */
6950a9fa9459Szrj     0x78,                       /* Data alignment factor */
6951a9fa9459Szrj     16,				/* Return address column */
6952a9fa9459Szrj     1,				/* Augmentation size */
6953a9fa9459Szrj     DW_EH_PE_pcrel | DW_EH_PE_sdata4, /* FDE encoding */
6954a9fa9459Szrj     DW_CFA_def_cfa, 7, 8,	/* DW_CFA_def_cfa: r7 (rsp) ofs 8 */
6955a9fa9459Szrj     DW_CFA_offset + 16, 1,	/* DW_CFA_offset: r16 (rip) at cfa-8 */
6956a9fa9459Szrj     DW_CFA_nop, DW_CFA_nop,
6957a9fa9459Szrj 
6958a9fa9459Szrj     PLT_FDE_LENGTH, 0, 0, 0,	/* FDE length */
6959a9fa9459Szrj     PLT_CIE_LENGTH + 8, 0, 0, 0,/* CIE pointer */
6960a9fa9459Szrj     0, 0, 0, 0,			/* R_X86_64_PC32 .plt goes here */
6961a9fa9459Szrj     0, 0, 0, 0,			/* .plt size goes here */
6962a9fa9459Szrj     0,				/* Augmentation size */
6963a9fa9459Szrj     DW_CFA_def_cfa_offset, 16,	/* DW_CFA_def_cfa_offset: 16 */
6964a9fa9459Szrj     DW_CFA_advance_loc + 6,	/* DW_CFA_advance_loc: 6 to __PLT__+6 */
6965a9fa9459Szrj     DW_CFA_def_cfa_offset, 24,	/* DW_CFA_def_cfa_offset: 24 */
6966a9fa9459Szrj     DW_CFA_advance_loc + 58,	/* DW_CFA_advance_loc: 58 to __PLT__+64 */
6967a9fa9459Szrj     DW_CFA_def_cfa_expression,	/* DW_CFA_def_cfa_expression */
6968a9fa9459Szrj     13,				/* Block length */
6969a9fa9459Szrj     DW_OP_breg7, 8,		/* DW_OP_breg7 (rsp): 8 */
6970a9fa9459Szrj     DW_OP_breg16, 0,		/* DW_OP_breg16 (rip): 0 */
6971a9fa9459Szrj     DW_OP_const1u, 63, DW_OP_and, DW_OP_const1u, 37, DW_OP_ge,
6972a9fa9459Szrj     DW_OP_lit3, DW_OP_shl, DW_OP_plus,
6973a9fa9459Szrj     DW_CFA_nop, DW_CFA_nop
6974a9fa9459Szrj   };
6975a9fa9459Szrj 
6976a9fa9459Szrj static const struct elf_x86_64_backend_data elf_x86_64_nacl_arch_bed =
6977a9fa9459Szrj   {
6978a9fa9459Szrj     elf_x86_64_nacl_plt0_entry,              /* plt0_entry */
6979a9fa9459Szrj     elf_x86_64_nacl_plt_entry,               /* plt_entry */
6980a9fa9459Szrj     NACL_PLT_ENTRY_SIZE,                     /* plt_entry_size */
6981a9fa9459Szrj     2,                                       /* plt0_got1_offset */
6982a9fa9459Szrj     9,                                       /* plt0_got2_offset */
6983a9fa9459Szrj     13,                                      /* plt0_got2_insn_end */
6984a9fa9459Szrj     3,                                       /* plt_got_offset */
6985a9fa9459Szrj     33,                                      /* plt_reloc_offset */
6986a9fa9459Szrj     38,                                      /* plt_plt_offset */
6987a9fa9459Szrj     7,                                       /* plt_got_insn_size */
6988a9fa9459Szrj     42,                                      /* plt_plt_insn_end */
6989a9fa9459Szrj     32,                                      /* plt_lazy_offset */
6990a9fa9459Szrj     elf_x86_64_nacl_eh_frame_plt,            /* eh_frame_plt */
6991a9fa9459Szrj     sizeof (elf_x86_64_nacl_eh_frame_plt),   /* eh_frame_plt_size */
6992a9fa9459Szrj   };
6993a9fa9459Szrj 
6994a9fa9459Szrj #undef	elf_backend_arch_data
6995a9fa9459Szrj #define	elf_backend_arch_data	&elf_x86_64_nacl_arch_bed
6996a9fa9459Szrj 
6997a9fa9459Szrj #undef	elf_backend_object_p
6998a9fa9459Szrj #define elf_backend_object_p			elf64_x86_64_nacl_elf_object_p
6999a9fa9459Szrj #undef	elf_backend_modify_segment_map
7000a9fa9459Szrj #define	elf_backend_modify_segment_map		nacl_modify_segment_map
7001a9fa9459Szrj #undef	elf_backend_modify_program_headers
7002a9fa9459Szrj #define	elf_backend_modify_program_headers	nacl_modify_program_headers
7003a9fa9459Szrj #undef	elf_backend_final_write_processing
7004a9fa9459Szrj #define elf_backend_final_write_processing	nacl_final_write_processing
7005a9fa9459Szrj 
7006a9fa9459Szrj #include "elf64-target.h"
7007a9fa9459Szrj 
7008a9fa9459Szrj /* Native Client x32 support.  */
7009a9fa9459Szrj 
7010a9fa9459Szrj static bfd_boolean
elf32_x86_64_nacl_elf_object_p(bfd * abfd)7011a9fa9459Szrj elf32_x86_64_nacl_elf_object_p (bfd *abfd)
7012a9fa9459Szrj {
7013a9fa9459Szrj   /* Set the right machine number for a NaCl x86-64 ELF32 file.  */
7014a9fa9459Szrj   bfd_default_set_arch_mach (abfd, bfd_arch_i386, bfd_mach_x64_32_nacl);
7015a9fa9459Szrj   return TRUE;
7016a9fa9459Szrj }
7017a9fa9459Szrj 
7018a9fa9459Szrj #undef  TARGET_LITTLE_SYM
7019a9fa9459Szrj #define TARGET_LITTLE_SYM		x86_64_elf32_nacl_vec
7020a9fa9459Szrj #undef  TARGET_LITTLE_NAME
7021a9fa9459Szrj #define TARGET_LITTLE_NAME		"elf32-x86-64-nacl"
7022a9fa9459Szrj #undef	elf32_bed
7023a9fa9459Szrj #define	elf32_bed			elf32_x86_64_nacl_bed
7024a9fa9459Szrj 
7025a9fa9459Szrj #define bfd_elf32_bfd_link_hash_table_create \
7026a9fa9459Szrj   elf_x86_64_link_hash_table_create
7027a9fa9459Szrj #define bfd_elf32_bfd_reloc_type_lookup	\
7028a9fa9459Szrj   elf_x86_64_reloc_type_lookup
7029a9fa9459Szrj #define bfd_elf32_bfd_reloc_name_lookup \
7030a9fa9459Szrj   elf_x86_64_reloc_name_lookup
7031a9fa9459Szrj #define bfd_elf32_mkobject \
7032a9fa9459Szrj   elf_x86_64_mkobject
7033a9fa9459Szrj #define bfd_elf32_get_synthetic_symtab \
7034a9fa9459Szrj   elf_x86_64_get_synthetic_symtab
7035a9fa9459Szrj 
7036a9fa9459Szrj #undef elf_backend_object_p
7037a9fa9459Szrj #define elf_backend_object_p \
7038a9fa9459Szrj   elf32_x86_64_nacl_elf_object_p
7039a9fa9459Szrj 
7040a9fa9459Szrj #undef elf_backend_bfd_from_remote_memory
7041a9fa9459Szrj #define elf_backend_bfd_from_remote_memory \
7042a9fa9459Szrj   _bfd_elf32_bfd_from_remote_memory
7043a9fa9459Szrj 
7044a9fa9459Szrj #undef elf_backend_size_info
7045a9fa9459Szrj #define elf_backend_size_info \
7046a9fa9459Szrj   _bfd_elf32_size_info
7047a9fa9459Szrj 
7048a9fa9459Szrj #include "elf32-target.h"
7049a9fa9459Szrj 
7050a9fa9459Szrj /* Restore defaults.  */
7051a9fa9459Szrj #undef	elf_backend_object_p
7052a9fa9459Szrj #define elf_backend_object_p		    elf64_x86_64_elf_object_p
7053a9fa9459Szrj #undef	elf_backend_bfd_from_remote_memory
7054a9fa9459Szrj #undef	elf_backend_size_info
7055a9fa9459Szrj #undef	elf_backend_modify_segment_map
7056a9fa9459Szrj #undef	elf_backend_modify_program_headers
7057a9fa9459Szrj #undef	elf_backend_final_write_processing
7058a9fa9459Szrj 
7059a9fa9459Szrj /* Intel L1OM support.  */
7060a9fa9459Szrj 
7061a9fa9459Szrj static bfd_boolean
elf64_l1om_elf_object_p(bfd * abfd)7062a9fa9459Szrj elf64_l1om_elf_object_p (bfd *abfd)
7063a9fa9459Szrj {
7064a9fa9459Szrj   /* Set the right machine number for an L1OM elf64 file.  */
7065a9fa9459Szrj   bfd_default_set_arch_mach (abfd, bfd_arch_l1om, bfd_mach_l1om);
7066a9fa9459Szrj   return TRUE;
7067a9fa9459Szrj }
7068a9fa9459Szrj 
7069a9fa9459Szrj #undef  TARGET_LITTLE_SYM
7070a9fa9459Szrj #define TARGET_LITTLE_SYM		    l1om_elf64_vec
7071a9fa9459Szrj #undef  TARGET_LITTLE_NAME
7072a9fa9459Szrj #define TARGET_LITTLE_NAME		    "elf64-l1om"
7073a9fa9459Szrj #undef ELF_ARCH
7074a9fa9459Szrj #define ELF_ARCH			    bfd_arch_l1om
7075a9fa9459Szrj 
7076a9fa9459Szrj #undef	ELF_MACHINE_CODE
7077a9fa9459Szrj #define ELF_MACHINE_CODE		    EM_L1OM
7078a9fa9459Szrj 
7079a9fa9459Szrj #undef	ELF_OSABI
7080a9fa9459Szrj 
7081a9fa9459Szrj #undef  elf64_bed
7082a9fa9459Szrj #define elf64_bed elf64_l1om_bed
7083a9fa9459Szrj 
7084a9fa9459Szrj #undef elf_backend_object_p
7085a9fa9459Szrj #define elf_backend_object_p		    elf64_l1om_elf_object_p
7086a9fa9459Szrj 
7087a9fa9459Szrj /* Restore defaults.  */
7088a9fa9459Szrj #undef	ELF_MAXPAGESIZE
7089a9fa9459Szrj #undef	ELF_MINPAGESIZE
7090a9fa9459Szrj #undef	ELF_COMMONPAGESIZE
7091a9fa9459Szrj #define ELF_MAXPAGESIZE			0x200000
7092a9fa9459Szrj #define ELF_MINPAGESIZE			0x1000
7093a9fa9459Szrj #define ELF_COMMONPAGESIZE		0x1000
7094a9fa9459Szrj #undef	elf_backend_plt_alignment
7095a9fa9459Szrj #define elf_backend_plt_alignment	4
7096a9fa9459Szrj #undef	elf_backend_arch_data
7097a9fa9459Szrj #define	elf_backend_arch_data	&elf_x86_64_arch_bed
7098a9fa9459Szrj 
7099a9fa9459Szrj #include "elf64-target.h"
7100a9fa9459Szrj 
7101a9fa9459Szrj /* FreeBSD L1OM support.  */
7102a9fa9459Szrj 
7103a9fa9459Szrj #undef  TARGET_LITTLE_SYM
7104a9fa9459Szrj #define TARGET_LITTLE_SYM		    l1om_elf64_fbsd_vec
7105a9fa9459Szrj #undef  TARGET_LITTLE_NAME
7106a9fa9459Szrj #define TARGET_LITTLE_NAME		    "elf64-l1om-freebsd"
7107a9fa9459Szrj 
7108a9fa9459Szrj #undef	ELF_OSABI
7109a9fa9459Szrj #define	ELF_OSABI			    ELFOSABI_FREEBSD
7110a9fa9459Szrj 
7111a9fa9459Szrj #undef  elf64_bed
7112a9fa9459Szrj #define elf64_bed elf64_l1om_fbsd_bed
7113a9fa9459Szrj 
7114a9fa9459Szrj #include "elf64-target.h"
7115a9fa9459Szrj 
7116a9fa9459Szrj /* Intel K1OM support.  */
7117a9fa9459Szrj 
7118a9fa9459Szrj static bfd_boolean
elf64_k1om_elf_object_p(bfd * abfd)7119a9fa9459Szrj elf64_k1om_elf_object_p (bfd *abfd)
7120a9fa9459Szrj {
7121a9fa9459Szrj   /* Set the right machine number for an K1OM elf64 file.  */
7122a9fa9459Szrj   bfd_default_set_arch_mach (abfd, bfd_arch_k1om, bfd_mach_k1om);
7123a9fa9459Szrj   return TRUE;
7124a9fa9459Szrj }
7125a9fa9459Szrj 
7126a9fa9459Szrj #undef  TARGET_LITTLE_SYM
7127a9fa9459Szrj #define TARGET_LITTLE_SYM		    k1om_elf64_vec
7128a9fa9459Szrj #undef  TARGET_LITTLE_NAME
7129a9fa9459Szrj #define TARGET_LITTLE_NAME		    "elf64-k1om"
7130a9fa9459Szrj #undef ELF_ARCH
7131a9fa9459Szrj #define ELF_ARCH			    bfd_arch_k1om
7132a9fa9459Szrj 
7133a9fa9459Szrj #undef	ELF_MACHINE_CODE
7134a9fa9459Szrj #define ELF_MACHINE_CODE		    EM_K1OM
7135a9fa9459Szrj 
7136a9fa9459Szrj #undef	ELF_OSABI
7137a9fa9459Szrj 
7138a9fa9459Szrj #undef  elf64_bed
7139a9fa9459Szrj #define elf64_bed elf64_k1om_bed
7140a9fa9459Szrj 
7141a9fa9459Szrj #undef elf_backend_object_p
7142a9fa9459Szrj #define elf_backend_object_p		    elf64_k1om_elf_object_p
7143a9fa9459Szrj 
7144a9fa9459Szrj #undef  elf_backend_static_tls_alignment
7145a9fa9459Szrj 
7146a9fa9459Szrj #undef elf_backend_want_plt_sym
7147a9fa9459Szrj #define elf_backend_want_plt_sym	    0
7148a9fa9459Szrj 
7149a9fa9459Szrj #include "elf64-target.h"
7150a9fa9459Szrj 
7151a9fa9459Szrj /* FreeBSD K1OM support.  */
7152a9fa9459Szrj 
7153a9fa9459Szrj #undef  TARGET_LITTLE_SYM
7154a9fa9459Szrj #define TARGET_LITTLE_SYM		    k1om_elf64_fbsd_vec
7155a9fa9459Szrj #undef  TARGET_LITTLE_NAME
7156a9fa9459Szrj #define TARGET_LITTLE_NAME		    "elf64-k1om-freebsd"
7157a9fa9459Szrj 
7158a9fa9459Szrj #undef	ELF_OSABI
7159a9fa9459Szrj #define	ELF_OSABI			    ELFOSABI_FREEBSD
7160a9fa9459Szrj 
7161a9fa9459Szrj #undef  elf64_bed
7162a9fa9459Szrj #define elf64_bed elf64_k1om_fbsd_bed
7163a9fa9459Szrj 
7164a9fa9459Szrj #include "elf64-target.h"
7165a9fa9459Szrj 
7166a9fa9459Szrj /* 32bit x86-64 support.  */
7167a9fa9459Szrj 
7168a9fa9459Szrj #undef  TARGET_LITTLE_SYM
7169a9fa9459Szrj #define TARGET_LITTLE_SYM		    x86_64_elf32_vec
7170a9fa9459Szrj #undef  TARGET_LITTLE_NAME
7171a9fa9459Szrj #define TARGET_LITTLE_NAME		    "elf32-x86-64"
7172a9fa9459Szrj #undef	elf32_bed
7173a9fa9459Szrj 
7174a9fa9459Szrj #undef ELF_ARCH
7175a9fa9459Szrj #define ELF_ARCH			    bfd_arch_i386
7176a9fa9459Szrj 
7177a9fa9459Szrj #undef	ELF_MACHINE_CODE
7178a9fa9459Szrj #define ELF_MACHINE_CODE		    EM_X86_64
7179a9fa9459Szrj 
7180a9fa9459Szrj #undef	ELF_OSABI
7181a9fa9459Szrj 
7182a9fa9459Szrj #undef elf_backend_object_p
7183a9fa9459Szrj #define elf_backend_object_p \
7184a9fa9459Szrj   elf32_x86_64_elf_object_p
7185a9fa9459Szrj 
7186a9fa9459Szrj #undef elf_backend_bfd_from_remote_memory
7187a9fa9459Szrj #define elf_backend_bfd_from_remote_memory \
7188a9fa9459Szrj   _bfd_elf32_bfd_from_remote_memory
7189a9fa9459Szrj 
7190a9fa9459Szrj #undef elf_backend_size_info
7191a9fa9459Szrj #define elf_backend_size_info \
7192a9fa9459Szrj   _bfd_elf32_size_info
7193a9fa9459Szrj 
7194a9fa9459Szrj #include "elf32-target.h"
7195