1 /* X86-64 specific support for ELF
2 Copyright (C) 2000-2017 Free Software Foundation, Inc.
3 Contributed by Jan Hubicka <jh@suse.cz>.
5 This file is part of BFD, the Binary File Descriptor library.
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 3 of the License, or
10 (at your option) any later version.
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with this program; if not, write to the Free Software
19 Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
20 MA 02110-1301, USA. */
22 #include "elfxx-x86.h"
25 #include "libiberty.h"
27 #include "opcode/i386.h"
28 #include "elf/x86-64.h"
35 /* In case we're on a 32-bit machine, construct a 64-bit "-1" value. */
36 #define MINUS_ONE (~ (bfd_vma) 0)
38 /* Since both 32-bit and 64-bit x86-64 encode relocation type in the
39 identical manner, we use ELF32_R_TYPE instead of ELF64_R_TYPE to get
40 relocation type. We also use ELF_ST_TYPE instead of ELF64_ST_TYPE
41 since they are the same. */
43 /* The relocation "howto" table. Order of fields:
44 type, rightshift, size, bitsize, pc_relative, bitpos, complain_on_overflow,
45 special_function, name, partial_inplace, src_mask, dst_mask, pcrel_offset. */
46 static reloc_howto_type x86_64_elf_howto_table
[] =
48 HOWTO(R_X86_64_NONE
, 0, 3, 0, FALSE
, 0, complain_overflow_dont
,
49 bfd_elf_generic_reloc
, "R_X86_64_NONE", FALSE
, 0x00000000, 0x00000000,
51 HOWTO(R_X86_64_64
, 0, 4, 64, FALSE
, 0, complain_overflow_bitfield
,
52 bfd_elf_generic_reloc
, "R_X86_64_64", FALSE
, MINUS_ONE
, MINUS_ONE
,
54 HOWTO(R_X86_64_PC32
, 0, 2, 32, TRUE
, 0, complain_overflow_signed
,
55 bfd_elf_generic_reloc
, "R_X86_64_PC32", FALSE
, 0xffffffff, 0xffffffff,
57 HOWTO(R_X86_64_GOT32
, 0, 2, 32, FALSE
, 0, complain_overflow_signed
,
58 bfd_elf_generic_reloc
, "R_X86_64_GOT32", FALSE
, 0xffffffff, 0xffffffff,
60 HOWTO(R_X86_64_PLT32
, 0, 2, 32, TRUE
, 0, complain_overflow_signed
,
61 bfd_elf_generic_reloc
, "R_X86_64_PLT32", FALSE
, 0xffffffff, 0xffffffff,
63 HOWTO(R_X86_64_COPY
, 0, 2, 32, FALSE
, 0, complain_overflow_bitfield
,
64 bfd_elf_generic_reloc
, "R_X86_64_COPY", FALSE
, 0xffffffff, 0xffffffff,
66 HOWTO(R_X86_64_GLOB_DAT
, 0, 4, 64, FALSE
, 0, complain_overflow_bitfield
,
67 bfd_elf_generic_reloc
, "R_X86_64_GLOB_DAT", FALSE
, MINUS_ONE
,
69 HOWTO(R_X86_64_JUMP_SLOT
, 0, 4, 64, FALSE
, 0, complain_overflow_bitfield
,
70 bfd_elf_generic_reloc
, "R_X86_64_JUMP_SLOT", FALSE
, MINUS_ONE
,
72 HOWTO(R_X86_64_RELATIVE
, 0, 4, 64, FALSE
, 0, complain_overflow_bitfield
,
73 bfd_elf_generic_reloc
, "R_X86_64_RELATIVE", FALSE
, MINUS_ONE
,
75 HOWTO(R_X86_64_GOTPCREL
, 0, 2, 32, TRUE
, 0, complain_overflow_signed
,
76 bfd_elf_generic_reloc
, "R_X86_64_GOTPCREL", FALSE
, 0xffffffff,
78 HOWTO(R_X86_64_32
, 0, 2, 32, FALSE
, 0, complain_overflow_unsigned
,
79 bfd_elf_generic_reloc
, "R_X86_64_32", FALSE
, 0xffffffff, 0xffffffff,
81 HOWTO(R_X86_64_32S
, 0, 2, 32, FALSE
, 0, complain_overflow_signed
,
82 bfd_elf_generic_reloc
, "R_X86_64_32S", FALSE
, 0xffffffff, 0xffffffff,
84 HOWTO(R_X86_64_16
, 0, 1, 16, FALSE
, 0, complain_overflow_bitfield
,
85 bfd_elf_generic_reloc
, "R_X86_64_16", FALSE
, 0xffff, 0xffff, FALSE
),
86 HOWTO(R_X86_64_PC16
,0, 1, 16, TRUE
, 0, complain_overflow_bitfield
,
87 bfd_elf_generic_reloc
, "R_X86_64_PC16", FALSE
, 0xffff, 0xffff, TRUE
),
88 HOWTO(R_X86_64_8
, 0, 0, 8, FALSE
, 0, complain_overflow_bitfield
,
89 bfd_elf_generic_reloc
, "R_X86_64_8", FALSE
, 0xff, 0xff, FALSE
),
90 HOWTO(R_X86_64_PC8
, 0, 0, 8, TRUE
, 0, complain_overflow_signed
,
91 bfd_elf_generic_reloc
, "R_X86_64_PC8", FALSE
, 0xff, 0xff, TRUE
),
92 HOWTO(R_X86_64_DTPMOD64
, 0, 4, 64, FALSE
, 0, complain_overflow_bitfield
,
93 bfd_elf_generic_reloc
, "R_X86_64_DTPMOD64", FALSE
, MINUS_ONE
,
95 HOWTO(R_X86_64_DTPOFF64
, 0, 4, 64, FALSE
, 0, complain_overflow_bitfield
,
96 bfd_elf_generic_reloc
, "R_X86_64_DTPOFF64", FALSE
, MINUS_ONE
,
98 HOWTO(R_X86_64_TPOFF64
, 0, 4, 64, FALSE
, 0, complain_overflow_bitfield
,
99 bfd_elf_generic_reloc
, "R_X86_64_TPOFF64", FALSE
, MINUS_ONE
,
101 HOWTO(R_X86_64_TLSGD
, 0, 2, 32, TRUE
, 0, complain_overflow_signed
,
102 bfd_elf_generic_reloc
, "R_X86_64_TLSGD", FALSE
, 0xffffffff,
104 HOWTO(R_X86_64_TLSLD
, 0, 2, 32, TRUE
, 0, complain_overflow_signed
,
105 bfd_elf_generic_reloc
, "R_X86_64_TLSLD", FALSE
, 0xffffffff,
107 HOWTO(R_X86_64_DTPOFF32
, 0, 2, 32, FALSE
, 0, complain_overflow_signed
,
108 bfd_elf_generic_reloc
, "R_X86_64_DTPOFF32", FALSE
, 0xffffffff,
110 HOWTO(R_X86_64_GOTTPOFF
, 0, 2, 32, TRUE
, 0, complain_overflow_signed
,
111 bfd_elf_generic_reloc
, "R_X86_64_GOTTPOFF", FALSE
, 0xffffffff,
113 HOWTO(R_X86_64_TPOFF32
, 0, 2, 32, FALSE
, 0, complain_overflow_signed
,
114 bfd_elf_generic_reloc
, "R_X86_64_TPOFF32", FALSE
, 0xffffffff,
116 HOWTO(R_X86_64_PC64
, 0, 4, 64, TRUE
, 0, complain_overflow_bitfield
,
117 bfd_elf_generic_reloc
, "R_X86_64_PC64", FALSE
, MINUS_ONE
, MINUS_ONE
,
119 HOWTO(R_X86_64_GOTOFF64
, 0, 4, 64, FALSE
, 0, complain_overflow_bitfield
,
120 bfd_elf_generic_reloc
, "R_X86_64_GOTOFF64",
121 FALSE
, MINUS_ONE
, MINUS_ONE
, FALSE
),
122 HOWTO(R_X86_64_GOTPC32
, 0, 2, 32, TRUE
, 0, complain_overflow_signed
,
123 bfd_elf_generic_reloc
, "R_X86_64_GOTPC32",
124 FALSE
, 0xffffffff, 0xffffffff, TRUE
),
125 HOWTO(R_X86_64_GOT64
, 0, 4, 64, FALSE
, 0, complain_overflow_signed
,
126 bfd_elf_generic_reloc
, "R_X86_64_GOT64", FALSE
, MINUS_ONE
, MINUS_ONE
,
128 HOWTO(R_X86_64_GOTPCREL64
, 0, 4, 64, TRUE
, 0, complain_overflow_signed
,
129 bfd_elf_generic_reloc
, "R_X86_64_GOTPCREL64", FALSE
, MINUS_ONE
,
131 HOWTO(R_X86_64_GOTPC64
, 0, 4, 64, TRUE
, 0, complain_overflow_signed
,
132 bfd_elf_generic_reloc
, "R_X86_64_GOTPC64",
133 FALSE
, MINUS_ONE
, MINUS_ONE
, TRUE
),
134 HOWTO(R_X86_64_GOTPLT64
, 0, 4, 64, FALSE
, 0, complain_overflow_signed
,
135 bfd_elf_generic_reloc
, "R_X86_64_GOTPLT64", FALSE
, MINUS_ONE
,
137 HOWTO(R_X86_64_PLTOFF64
, 0, 4, 64, FALSE
, 0, complain_overflow_signed
,
138 bfd_elf_generic_reloc
, "R_X86_64_PLTOFF64", FALSE
, MINUS_ONE
,
140 HOWTO(R_X86_64_SIZE32
, 0, 2, 32, FALSE
, 0, complain_overflow_unsigned
,
141 bfd_elf_generic_reloc
, "R_X86_64_SIZE32", FALSE
, 0xffffffff, 0xffffffff,
143 HOWTO(R_X86_64_SIZE64
, 0, 4, 64, FALSE
, 0, complain_overflow_unsigned
,
144 bfd_elf_generic_reloc
, "R_X86_64_SIZE64", FALSE
, MINUS_ONE
, MINUS_ONE
,
146 HOWTO(R_X86_64_GOTPC32_TLSDESC
, 0, 2, 32, TRUE
, 0,
147 complain_overflow_bitfield
, bfd_elf_generic_reloc
,
148 "R_X86_64_GOTPC32_TLSDESC",
149 FALSE
, 0xffffffff, 0xffffffff, TRUE
),
150 HOWTO(R_X86_64_TLSDESC_CALL
, 0, 0, 0, FALSE
, 0,
151 complain_overflow_dont
, bfd_elf_generic_reloc
,
152 "R_X86_64_TLSDESC_CALL",
154 HOWTO(R_X86_64_TLSDESC
, 0, 4, 64, FALSE
, 0,
155 complain_overflow_bitfield
, bfd_elf_generic_reloc
,
157 FALSE
, MINUS_ONE
, MINUS_ONE
, FALSE
),
158 HOWTO(R_X86_64_IRELATIVE
, 0, 4, 64, FALSE
, 0, complain_overflow_bitfield
,
159 bfd_elf_generic_reloc
, "R_X86_64_IRELATIVE", FALSE
, MINUS_ONE
,
161 HOWTO(R_X86_64_RELATIVE64
, 0, 4, 64, FALSE
, 0, complain_overflow_bitfield
,
162 bfd_elf_generic_reloc
, "R_X86_64_RELATIVE64", FALSE
, MINUS_ONE
,
164 HOWTO(R_X86_64_PC32_BND
, 0, 2, 32, TRUE
, 0, complain_overflow_signed
,
165 bfd_elf_generic_reloc
, "R_X86_64_PC32_BND", FALSE
, 0xffffffff, 0xffffffff,
167 HOWTO(R_X86_64_PLT32_BND
, 0, 2, 32, TRUE
, 0, complain_overflow_signed
,
168 bfd_elf_generic_reloc
, "R_X86_64_PLT32_BND", FALSE
, 0xffffffff, 0xffffffff,
170 HOWTO(R_X86_64_GOTPCRELX
, 0, 2, 32, TRUE
, 0, complain_overflow_signed
,
171 bfd_elf_generic_reloc
, "R_X86_64_GOTPCRELX", FALSE
, 0xffffffff,
173 HOWTO(R_X86_64_REX_GOTPCRELX
, 0, 2, 32, TRUE
, 0, complain_overflow_signed
,
174 bfd_elf_generic_reloc
, "R_X86_64_REX_GOTPCRELX", FALSE
, 0xffffffff,
177 /* We have a gap in the reloc numbers here.
178 R_X86_64_standard counts the number up to this point, and
179 R_X86_64_vt_offset is the value to subtract from a reloc type of
180 R_X86_64_GNU_VT* to form an index into this table. */
181 #define R_X86_64_standard (R_X86_64_REX_GOTPCRELX + 1)
182 #define R_X86_64_vt_offset (R_X86_64_GNU_VTINHERIT - R_X86_64_standard)
184 /* GNU extension to record C++ vtable hierarchy. */
185 HOWTO (R_X86_64_GNU_VTINHERIT
, 0, 4, 0, FALSE
, 0, complain_overflow_dont
,
186 NULL
, "R_X86_64_GNU_VTINHERIT", FALSE
, 0, 0, FALSE
),
188 /* GNU extension to record C++ vtable member usage. */
189 HOWTO (R_X86_64_GNU_VTENTRY
, 0, 4, 0, FALSE
, 0, complain_overflow_dont
,
190 _bfd_elf_rel_vtable_reloc_fn
, "R_X86_64_GNU_VTENTRY", FALSE
, 0, 0,
193 /* Use complain_overflow_bitfield on R_X86_64_32 for x32. */
194 HOWTO(R_X86_64_32
, 0, 2, 32, FALSE
, 0, complain_overflow_bitfield
,
195 bfd_elf_generic_reloc
, "R_X86_64_32", FALSE
, 0xffffffff, 0xffffffff,
199 #define IS_X86_64_PCREL_TYPE(TYPE) \
200 ( ((TYPE) == R_X86_64_PC8) \
201 || ((TYPE) == R_X86_64_PC16) \
202 || ((TYPE) == R_X86_64_PC32) \
203 || ((TYPE) == R_X86_64_PC32_BND) \
204 || ((TYPE) == R_X86_64_PC64))
206 /* Map BFD relocs to the x86_64 elf relocs. */
209 bfd_reloc_code_real_type bfd_reloc_val
;
210 unsigned char elf_reloc_val
;
213 static const struct elf_reloc_map x86_64_reloc_map
[] =
215 { BFD_RELOC_NONE
, R_X86_64_NONE
, },
216 { BFD_RELOC_64
, R_X86_64_64
, },
217 { BFD_RELOC_32_PCREL
, R_X86_64_PC32
, },
218 { BFD_RELOC_X86_64_GOT32
, R_X86_64_GOT32
,},
219 { BFD_RELOC_X86_64_PLT32
, R_X86_64_PLT32
,},
220 { BFD_RELOC_X86_64_COPY
, R_X86_64_COPY
, },
221 { BFD_RELOC_X86_64_GLOB_DAT
, R_X86_64_GLOB_DAT
, },
222 { BFD_RELOC_X86_64_JUMP_SLOT
, R_X86_64_JUMP_SLOT
, },
223 { BFD_RELOC_X86_64_RELATIVE
, R_X86_64_RELATIVE
, },
224 { BFD_RELOC_X86_64_GOTPCREL
, R_X86_64_GOTPCREL
, },
225 { BFD_RELOC_32
, R_X86_64_32
, },
226 { BFD_RELOC_X86_64_32S
, R_X86_64_32S
, },
227 { BFD_RELOC_16
, R_X86_64_16
, },
228 { BFD_RELOC_16_PCREL
, R_X86_64_PC16
, },
229 { BFD_RELOC_8
, R_X86_64_8
, },
230 { BFD_RELOC_8_PCREL
, R_X86_64_PC8
, },
231 { BFD_RELOC_X86_64_DTPMOD64
, R_X86_64_DTPMOD64
, },
232 { BFD_RELOC_X86_64_DTPOFF64
, R_X86_64_DTPOFF64
, },
233 { BFD_RELOC_X86_64_TPOFF64
, R_X86_64_TPOFF64
, },
234 { BFD_RELOC_X86_64_TLSGD
, R_X86_64_TLSGD
, },
235 { BFD_RELOC_X86_64_TLSLD
, R_X86_64_TLSLD
, },
236 { BFD_RELOC_X86_64_DTPOFF32
, R_X86_64_DTPOFF32
, },
237 { BFD_RELOC_X86_64_GOTTPOFF
, R_X86_64_GOTTPOFF
, },
238 { BFD_RELOC_X86_64_TPOFF32
, R_X86_64_TPOFF32
, },
239 { BFD_RELOC_64_PCREL
, R_X86_64_PC64
, },
240 { BFD_RELOC_X86_64_GOTOFF64
, R_X86_64_GOTOFF64
, },
241 { BFD_RELOC_X86_64_GOTPC32
, R_X86_64_GOTPC32
, },
242 { BFD_RELOC_X86_64_GOT64
, R_X86_64_GOT64
, },
243 { BFD_RELOC_X86_64_GOTPCREL64
,R_X86_64_GOTPCREL64
, },
244 { BFD_RELOC_X86_64_GOTPC64
, R_X86_64_GOTPC64
, },
245 { BFD_RELOC_X86_64_GOTPLT64
, R_X86_64_GOTPLT64
, },
246 { BFD_RELOC_X86_64_PLTOFF64
, R_X86_64_PLTOFF64
, },
247 { BFD_RELOC_SIZE32
, R_X86_64_SIZE32
, },
248 { BFD_RELOC_SIZE64
, R_X86_64_SIZE64
, },
249 { BFD_RELOC_X86_64_GOTPC32_TLSDESC
, R_X86_64_GOTPC32_TLSDESC
, },
250 { BFD_RELOC_X86_64_TLSDESC_CALL
, R_X86_64_TLSDESC_CALL
, },
251 { BFD_RELOC_X86_64_TLSDESC
, R_X86_64_TLSDESC
, },
252 { BFD_RELOC_X86_64_IRELATIVE
, R_X86_64_IRELATIVE
, },
253 { BFD_RELOC_X86_64_PC32_BND
, R_X86_64_PC32_BND
, },
254 { BFD_RELOC_X86_64_PLT32_BND
, R_X86_64_PLT32_BND
, },
255 { BFD_RELOC_X86_64_GOTPCRELX
, R_X86_64_GOTPCRELX
, },
256 { BFD_RELOC_X86_64_REX_GOTPCRELX
, R_X86_64_REX_GOTPCRELX
, },
257 { BFD_RELOC_VTABLE_INHERIT
, R_X86_64_GNU_VTINHERIT
, },
258 { BFD_RELOC_VTABLE_ENTRY
, R_X86_64_GNU_VTENTRY
, },
261 static reloc_howto_type
*
262 elf_x86_64_rtype_to_howto (bfd
*abfd
, unsigned r_type
)
266 if (r_type
== (unsigned int) R_X86_64_32
)
271 i
= ARRAY_SIZE (x86_64_elf_howto_table
) - 1;
273 else if (r_type
< (unsigned int) R_X86_64_GNU_VTINHERIT
274 || r_type
>= (unsigned int) R_X86_64_max
)
276 if (r_type
>= (unsigned int) R_X86_64_standard
)
278 /* xgettext:c-format */
279 _bfd_error_handler (_("%B: invalid relocation type %d"),
281 r_type
= R_X86_64_NONE
;
286 i
= r_type
- (unsigned int) R_X86_64_vt_offset
;
287 BFD_ASSERT (x86_64_elf_howto_table
[i
].type
== r_type
);
288 return &x86_64_elf_howto_table
[i
];
291 /* Given a BFD reloc type, return a HOWTO structure. */
292 static reloc_howto_type
*
293 elf_x86_64_reloc_type_lookup (bfd
*abfd
,
294 bfd_reloc_code_real_type code
)
298 for (i
= 0; i
< sizeof (x86_64_reloc_map
) / sizeof (struct elf_reloc_map
);
301 if (x86_64_reloc_map
[i
].bfd_reloc_val
== code
)
302 return elf_x86_64_rtype_to_howto (abfd
,
303 x86_64_reloc_map
[i
].elf_reloc_val
);
308 static reloc_howto_type
*
309 elf_x86_64_reloc_name_lookup (bfd
*abfd
,
314 if (!ABI_64_P (abfd
) && strcasecmp (r_name
, "R_X86_64_32") == 0)
316 /* Get x32 R_X86_64_32. */
317 reloc_howto_type
*reloc
318 = &x86_64_elf_howto_table
[ARRAY_SIZE (x86_64_elf_howto_table
) - 1];
319 BFD_ASSERT (reloc
->type
== (unsigned int) R_X86_64_32
);
323 for (i
= 0; i
< ARRAY_SIZE (x86_64_elf_howto_table
); i
++)
324 if (x86_64_elf_howto_table
[i
].name
!= NULL
325 && strcasecmp (x86_64_elf_howto_table
[i
].name
, r_name
) == 0)
326 return &x86_64_elf_howto_table
[i
];
331 /* Given an x86_64 ELF reloc type, fill in an arelent structure. */
334 elf_x86_64_info_to_howto (bfd
*abfd ATTRIBUTE_UNUSED
, arelent
*cache_ptr
,
335 Elf_Internal_Rela
*dst
)
339 r_type
= ELF32_R_TYPE (dst
->r_info
);
340 cache_ptr
->howto
= elf_x86_64_rtype_to_howto (abfd
, r_type
);
341 BFD_ASSERT (r_type
== cache_ptr
->howto
->type
);
344 /* Support for core dump NOTE sections. */
346 elf_x86_64_grok_prstatus (bfd
*abfd
, Elf_Internal_Note
*note
)
351 switch (note
->descsz
)
356 case 296: /* sizeof(istruct elf_prstatus) on Linux/x32 */
358 elf_tdata (abfd
)->core
->signal
= bfd_get_16 (abfd
, note
->descdata
+ 12);
361 elf_tdata (abfd
)->core
->lwpid
= bfd_get_32 (abfd
, note
->descdata
+ 24);
369 case 336: /* sizeof(istruct elf_prstatus) on Linux/x86_64 */
371 elf_tdata (abfd
)->core
->signal
372 = bfd_get_16 (abfd
, note
->descdata
+ 12);
375 elf_tdata (abfd
)->core
->lwpid
376 = bfd_get_32 (abfd
, note
->descdata
+ 32);
385 /* Make a ".reg/999" section. */
386 return _bfd_elfcore_make_pseudosection (abfd
, ".reg",
387 size
, note
->descpos
+ offset
);
391 elf_x86_64_grok_psinfo (bfd
*abfd
, Elf_Internal_Note
*note
)
393 switch (note
->descsz
)
398 case 124: /* sizeof(struct elf_prpsinfo) on Linux/x32 */
399 elf_tdata (abfd
)->core
->pid
400 = bfd_get_32 (abfd
, note
->descdata
+ 12);
401 elf_tdata (abfd
)->core
->program
402 = _bfd_elfcore_strndup (abfd
, note
->descdata
+ 28, 16);
403 elf_tdata (abfd
)->core
->command
404 = _bfd_elfcore_strndup (abfd
, note
->descdata
+ 44, 80);
407 case 136: /* sizeof(struct elf_prpsinfo) on Linux/x86_64 */
408 elf_tdata (abfd
)->core
->pid
409 = bfd_get_32 (abfd
, note
->descdata
+ 24);
410 elf_tdata (abfd
)->core
->program
411 = _bfd_elfcore_strndup (abfd
, note
->descdata
+ 40, 16);
412 elf_tdata (abfd
)->core
->command
413 = _bfd_elfcore_strndup (abfd
, note
->descdata
+ 56, 80);
416 /* Note that for some reason, a spurious space is tacked
417 onto the end of the args in some (at least one anyway)
418 implementations, so strip it off if it exists. */
421 char *command
= elf_tdata (abfd
)->core
->command
;
422 int n
= strlen (command
);
424 if (0 < n
&& command
[n
- 1] == ' ')
425 command
[n
- 1] = '\0';
433 elf_x86_64_write_core_note (bfd
*abfd
, char *buf
, int *bufsiz
,
436 const struct elf_backend_data
*bed
= get_elf_backend_data (abfd
);
438 const char *fname
, *psargs
;
449 va_start (ap
, note_type
);
450 fname
= va_arg (ap
, const char *);
451 psargs
= va_arg (ap
, const char *);
454 if (bed
->s
->elfclass
== ELFCLASS32
)
457 memset (&data
, 0, sizeof (data
));
458 strncpy (data
.pr_fname
, fname
, sizeof (data
.pr_fname
));
459 strncpy (data
.pr_psargs
, psargs
, sizeof (data
.pr_psargs
));
460 return elfcore_write_note (abfd
, buf
, bufsiz
, "CORE", note_type
,
461 &data
, sizeof (data
));
466 memset (&data
, 0, sizeof (data
));
467 strncpy (data
.pr_fname
, fname
, sizeof (data
.pr_fname
));
468 strncpy (data
.pr_psargs
, psargs
, sizeof (data
.pr_psargs
));
469 return elfcore_write_note (abfd
, buf
, bufsiz
, "CORE", note_type
,
470 &data
, sizeof (data
));
475 va_start (ap
, note_type
);
476 pid
= va_arg (ap
, long);
477 cursig
= va_arg (ap
, int);
478 gregs
= va_arg (ap
, const void *);
481 if (bed
->s
->elfclass
== ELFCLASS32
)
483 if (bed
->elf_machine_code
== EM_X86_64
)
485 prstatusx32_t prstat
;
486 memset (&prstat
, 0, sizeof (prstat
));
488 prstat
.pr_cursig
= cursig
;
489 memcpy (&prstat
.pr_reg
, gregs
, sizeof (prstat
.pr_reg
));
490 return elfcore_write_note (abfd
, buf
, bufsiz
, "CORE", note_type
,
491 &prstat
, sizeof (prstat
));
496 memset (&prstat
, 0, sizeof (prstat
));
498 prstat
.pr_cursig
= cursig
;
499 memcpy (&prstat
.pr_reg
, gregs
, sizeof (prstat
.pr_reg
));
500 return elfcore_write_note (abfd
, buf
, bufsiz
, "CORE", note_type
,
501 &prstat
, sizeof (prstat
));
507 memset (&prstat
, 0, sizeof (prstat
));
509 prstat
.pr_cursig
= cursig
;
510 memcpy (&prstat
.pr_reg
, gregs
, sizeof (prstat
.pr_reg
));
511 return elfcore_write_note (abfd
, buf
, bufsiz
, "CORE", note_type
,
512 &prstat
, sizeof (prstat
));
519 /* Functions for the x86-64 ELF linker. */
521 /* The size in bytes of an entry in the global offset table. */
523 #define GOT_ENTRY_SIZE 8
525 /* The size in bytes of an entry in the lazy procedure linkage table. */
527 #define LAZY_PLT_ENTRY_SIZE 16
529 /* The size in bytes of an entry in the non-lazy procedure linkage
532 #define NON_LAZY_PLT_ENTRY_SIZE 8
534 /* The first entry in a lazy procedure linkage table looks like this.
535 See the SVR4 ABI i386 supplement and the x86-64 ABI to see how this
538 static const bfd_byte elf_x86_64_lazy_plt0_entry
[LAZY_PLT_ENTRY_SIZE
] =
540 0xff, 0x35, 8, 0, 0, 0, /* pushq GOT+8(%rip) */
541 0xff, 0x25, 16, 0, 0, 0, /* jmpq *GOT+16(%rip) */
542 0x0f, 0x1f, 0x40, 0x00 /* nopl 0(%rax) */
545 /* Subsequent entries in a lazy procedure linkage table look like this. */
547 static const bfd_byte elf_x86_64_lazy_plt_entry
[LAZY_PLT_ENTRY_SIZE
] =
549 0xff, 0x25, /* jmpq *name@GOTPC(%rip) */
550 0, 0, 0, 0, /* replaced with offset to this symbol in .got. */
551 0x68, /* pushq immediate */
552 0, 0, 0, 0, /* replaced with index into relocation table. */
553 0xe9, /* jmp relative */
554 0, 0, 0, 0 /* replaced with offset to start of .plt0. */
557 /* The first entry in a lazy procedure linkage table with BND prefix
560 static const bfd_byte elf_x86_64_lazy_bnd_plt0_entry
[LAZY_PLT_ENTRY_SIZE
] =
562 0xff, 0x35, 8, 0, 0, 0, /* pushq GOT+8(%rip) */
563 0xf2, 0xff, 0x25, 16, 0, 0, 0, /* bnd jmpq *GOT+16(%rip) */
564 0x0f, 0x1f, 0 /* nopl (%rax) */
567 /* Subsequent entries for branches with BND prefx in a lazy procedure
568 linkage table look like this. */
570 static const bfd_byte elf_x86_64_lazy_bnd_plt_entry
[LAZY_PLT_ENTRY_SIZE
] =
572 0x68, 0, 0, 0, 0, /* pushq immediate */
573 0xf2, 0xe9, 0, 0, 0, 0, /* bnd jmpq relative */
574 0x0f, 0x1f, 0x44, 0, 0 /* nopl 0(%rax,%rax,1) */
577 /* The first entry in the IBT-enabled lazy procedure linkage table is the
578 the same as the lazy PLT with BND prefix so that bound registers are
579 preserved when control is passed to dynamic linker. Subsequent
580 entries for a IBT-enabled lazy procedure linkage table look like
583 static const bfd_byte elf_x86_64_lazy_ibt_plt_entry
[LAZY_PLT_ENTRY_SIZE
] =
585 0xf3, 0x0f, 0x1e, 0xfa, /* endbr64 */
586 0x68, 0, 0, 0, 0, /* pushq immediate */
587 0xf2, 0xe9, 0, 0, 0, 0, /* bnd jmpq relative */
591 /* The first entry in the x32 IBT-enabled lazy procedure linkage table
592 is the same as the normal lazy PLT. Subsequent entries for an
593 x32 IBT-enabled lazy procedure linkage table look like this. */
595 static const bfd_byte elf_x32_lazy_ibt_plt_entry
[LAZY_PLT_ENTRY_SIZE
] =
597 0xf3, 0x0f, 0x1e, 0xfa, /* endbr64 */
598 0x68, 0, 0, 0, 0, /* pushq immediate */
599 0xe9, 0, 0, 0, 0, /* jmpq relative */
600 0x66, 0x90 /* xchg %ax,%ax */
603 /* Entries in the non-lazey procedure linkage table look like this. */
605 static const bfd_byte elf_x86_64_non_lazy_plt_entry
[NON_LAZY_PLT_ENTRY_SIZE
] =
607 0xff, 0x25, /* jmpq *name@GOTPC(%rip) */
608 0, 0, 0, 0, /* replaced with offset to this symbol in .got. */
609 0x66, 0x90 /* xchg %ax,%ax */
612 /* Entries for branches with BND prefix in the non-lazey procedure
613 linkage table look like this. */
615 static const bfd_byte elf_x86_64_non_lazy_bnd_plt_entry
[NON_LAZY_PLT_ENTRY_SIZE
] =
617 0xf2, 0xff, 0x25, /* bnd jmpq *name@GOTPC(%rip) */
618 0, 0, 0, 0, /* replaced with offset to this symbol in .got. */
622 /* Entries for branches with IBT-enabled in the non-lazey procedure
623 linkage table look like this. They have the same size as the lazy
626 static const bfd_byte elf_x86_64_non_lazy_ibt_plt_entry
[LAZY_PLT_ENTRY_SIZE
] =
628 0xf3, 0x0f, 0x1e, 0xfa, /* endbr64 */
629 0xf2, 0xff, 0x25, /* bnd jmpq *name@GOTPC(%rip) */
630 0, 0, 0, 0, /* replaced with offset to this symbol in .got. */
631 0x0f, 0x1f, 0x44, 0x00, 0x00 /* nopl 0x0(%rax,%rax,1) */
634 /* Entries for branches with IBT-enabled in the x32 non-lazey procedure
635 linkage table look like this. They have the same size as the lazy
638 static const bfd_byte elf_x32_non_lazy_ibt_plt_entry
[LAZY_PLT_ENTRY_SIZE
] =
640 0xf3, 0x0f, 0x1e, 0xfa, /* endbr64 */
641 0xff, 0x25, /* jmpq *name@GOTPC(%rip) */
642 0, 0, 0, 0, /* replaced with offset to this symbol in .got. */
643 0x66, 0x0f, 0x1f, 0x44, 0x00, 0x00 /* nopw 0x0(%rax,%rax,1) */
646 /* .eh_frame covering the lazy .plt section. */
648 static const bfd_byte elf_x86_64_eh_frame_lazy_plt
[] =
650 PLT_CIE_LENGTH
, 0, 0, 0, /* CIE length */
651 0, 0, 0, 0, /* CIE ID */
653 'z', 'R', 0, /* Augmentation string */
654 1, /* Code alignment factor */
655 0x78, /* Data alignment factor */
656 16, /* Return address column */
657 1, /* Augmentation size */
658 DW_EH_PE_pcrel
| DW_EH_PE_sdata4
, /* FDE encoding */
659 DW_CFA_def_cfa
, 7, 8, /* DW_CFA_def_cfa: r7 (rsp) ofs 8 */
660 DW_CFA_offset
+ 16, 1, /* DW_CFA_offset: r16 (rip) at cfa-8 */
661 DW_CFA_nop
, DW_CFA_nop
,
663 PLT_FDE_LENGTH
, 0, 0, 0, /* FDE length */
664 PLT_CIE_LENGTH
+ 8, 0, 0, 0, /* CIE pointer */
665 0, 0, 0, 0, /* R_X86_64_PC32 .plt goes here */
666 0, 0, 0, 0, /* .plt size goes here */
667 0, /* Augmentation size */
668 DW_CFA_def_cfa_offset
, 16, /* DW_CFA_def_cfa_offset: 16 */
669 DW_CFA_advance_loc
+ 6, /* DW_CFA_advance_loc: 6 to __PLT__+6 */
670 DW_CFA_def_cfa_offset
, 24, /* DW_CFA_def_cfa_offset: 24 */
671 DW_CFA_advance_loc
+ 10, /* DW_CFA_advance_loc: 10 to __PLT__+16 */
672 DW_CFA_def_cfa_expression
, /* DW_CFA_def_cfa_expression */
673 11, /* Block length */
674 DW_OP_breg7
, 8, /* DW_OP_breg7 (rsp): 8 */
675 DW_OP_breg16
, 0, /* DW_OP_breg16 (rip): 0 */
676 DW_OP_lit15
, DW_OP_and
, DW_OP_lit11
, DW_OP_ge
,
677 DW_OP_lit3
, DW_OP_shl
, DW_OP_plus
,
678 DW_CFA_nop
, DW_CFA_nop
, DW_CFA_nop
, DW_CFA_nop
681 /* .eh_frame covering the lazy BND .plt section. */
683 static const bfd_byte elf_x86_64_eh_frame_lazy_bnd_plt
[] =
685 PLT_CIE_LENGTH
, 0, 0, 0, /* CIE length */
686 0, 0, 0, 0, /* CIE ID */
688 'z', 'R', 0, /* Augmentation string */
689 1, /* Code alignment factor */
690 0x78, /* Data alignment factor */
691 16, /* Return address column */
692 1, /* Augmentation size */
693 DW_EH_PE_pcrel
| DW_EH_PE_sdata4
, /* FDE encoding */
694 DW_CFA_def_cfa
, 7, 8, /* DW_CFA_def_cfa: r7 (rsp) ofs 8 */
695 DW_CFA_offset
+ 16, 1, /* DW_CFA_offset: r16 (rip) at cfa-8 */
696 DW_CFA_nop
, DW_CFA_nop
,
698 PLT_FDE_LENGTH
, 0, 0, 0, /* FDE length */
699 PLT_CIE_LENGTH
+ 8, 0, 0, 0, /* CIE pointer */
700 0, 0, 0, 0, /* R_X86_64_PC32 .plt goes here */
701 0, 0, 0, 0, /* .plt size goes here */
702 0, /* Augmentation size */
703 DW_CFA_def_cfa_offset
, 16, /* DW_CFA_def_cfa_offset: 16 */
704 DW_CFA_advance_loc
+ 6, /* DW_CFA_advance_loc: 6 to __PLT__+6 */
705 DW_CFA_def_cfa_offset
, 24, /* DW_CFA_def_cfa_offset: 24 */
706 DW_CFA_advance_loc
+ 10, /* DW_CFA_advance_loc: 10 to __PLT__+16 */
707 DW_CFA_def_cfa_expression
, /* DW_CFA_def_cfa_expression */
708 11, /* Block length */
709 DW_OP_breg7
, 8, /* DW_OP_breg7 (rsp): 8 */
710 DW_OP_breg16
, 0, /* DW_OP_breg16 (rip): 0 */
711 DW_OP_lit15
, DW_OP_and
, DW_OP_lit5
, DW_OP_ge
,
712 DW_OP_lit3
, DW_OP_shl
, DW_OP_plus
,
713 DW_CFA_nop
, DW_CFA_nop
, DW_CFA_nop
, DW_CFA_nop
716 /* .eh_frame covering the lazy .plt section with IBT-enabled. */
718 static const bfd_byte elf_x86_64_eh_frame_lazy_ibt_plt
[] =
720 PLT_CIE_LENGTH
, 0, 0, 0, /* CIE length */
721 0, 0, 0, 0, /* CIE ID */
723 'z', 'R', 0, /* Augmentation string */
724 1, /* Code alignment factor */
725 0x78, /* Data alignment factor */
726 16, /* Return address column */
727 1, /* Augmentation size */
728 DW_EH_PE_pcrel
| DW_EH_PE_sdata4
, /* FDE encoding */
729 DW_CFA_def_cfa
, 7, 8, /* DW_CFA_def_cfa: r7 (rsp) ofs 8 */
730 DW_CFA_offset
+ 16, 1, /* DW_CFA_offset: r16 (rip) at cfa-8 */
731 DW_CFA_nop
, DW_CFA_nop
,
733 PLT_FDE_LENGTH
, 0, 0, 0, /* FDE length */
734 PLT_CIE_LENGTH
+ 8, 0, 0, 0, /* CIE pointer */
735 0, 0, 0, 0, /* R_X86_64_PC32 .plt goes here */
736 0, 0, 0, 0, /* .plt size goes here */
737 0, /* Augmentation size */
738 DW_CFA_def_cfa_offset
, 16, /* DW_CFA_def_cfa_offset: 16 */
739 DW_CFA_advance_loc
+ 6, /* DW_CFA_advance_loc: 6 to __PLT__+6 */
740 DW_CFA_def_cfa_offset
, 24, /* DW_CFA_def_cfa_offset: 24 */
741 DW_CFA_advance_loc
+ 10, /* DW_CFA_advance_loc: 10 to __PLT__+16 */
742 DW_CFA_def_cfa_expression
, /* DW_CFA_def_cfa_expression */
743 11, /* Block length */
744 DW_OP_breg7
, 8, /* DW_OP_breg7 (rsp): 8 */
745 DW_OP_breg16
, 0, /* DW_OP_breg16 (rip): 0 */
746 DW_OP_lit15
, DW_OP_and
, DW_OP_lit10
, DW_OP_ge
,
747 DW_OP_lit3
, DW_OP_shl
, DW_OP_plus
,
748 DW_CFA_nop
, DW_CFA_nop
, DW_CFA_nop
, DW_CFA_nop
751 /* .eh_frame covering the x32 lazy .plt section with IBT-enabled. */
753 static const bfd_byte elf_x32_eh_frame_lazy_ibt_plt
[] =
755 PLT_CIE_LENGTH
, 0, 0, 0, /* CIE length */
756 0, 0, 0, 0, /* CIE ID */
758 'z', 'R', 0, /* Augmentation string */
759 1, /* Code alignment factor */
760 0x78, /* Data alignment factor */
761 16, /* Return address column */
762 1, /* Augmentation size */
763 DW_EH_PE_pcrel
| DW_EH_PE_sdata4
, /* FDE encoding */
764 DW_CFA_def_cfa
, 7, 8, /* DW_CFA_def_cfa: r7 (rsp) ofs 8 */
765 DW_CFA_offset
+ 16, 1, /* DW_CFA_offset: r16 (rip) at cfa-8 */
766 DW_CFA_nop
, DW_CFA_nop
,
768 PLT_FDE_LENGTH
, 0, 0, 0, /* FDE length */
769 PLT_CIE_LENGTH
+ 8, 0, 0, 0, /* CIE pointer */
770 0, 0, 0, 0, /* R_X86_64_PC32 .plt goes here */
771 0, 0, 0, 0, /* .plt size goes here */
772 0, /* Augmentation size */
773 DW_CFA_def_cfa_offset
, 16, /* DW_CFA_def_cfa_offset: 16 */
774 DW_CFA_advance_loc
+ 6, /* DW_CFA_advance_loc: 6 to __PLT__+6 */
775 DW_CFA_def_cfa_offset
, 24, /* DW_CFA_def_cfa_offset: 24 */
776 DW_CFA_advance_loc
+ 10, /* DW_CFA_advance_loc: 10 to __PLT__+16 */
777 DW_CFA_def_cfa_expression
, /* DW_CFA_def_cfa_expression */
778 11, /* Block length */
779 DW_OP_breg7
, 8, /* DW_OP_breg7 (rsp): 8 */
780 DW_OP_breg16
, 0, /* DW_OP_breg16 (rip): 0 */
781 DW_OP_lit15
, DW_OP_and
, DW_OP_lit9
, DW_OP_ge
,
782 DW_OP_lit3
, DW_OP_shl
, DW_OP_plus
,
783 DW_CFA_nop
, DW_CFA_nop
, DW_CFA_nop
, DW_CFA_nop
786 /* .eh_frame covering the non-lazy .plt section. */
788 static const bfd_byte elf_x86_64_eh_frame_non_lazy_plt
[] =
790 #define PLT_GOT_FDE_LENGTH 20
791 PLT_CIE_LENGTH
, 0, 0, 0, /* CIE length */
792 0, 0, 0, 0, /* CIE ID */
794 'z', 'R', 0, /* Augmentation string */
795 1, /* Code alignment factor */
796 0x78, /* Data alignment factor */
797 16, /* Return address column */
798 1, /* Augmentation size */
799 DW_EH_PE_pcrel
| DW_EH_PE_sdata4
, /* FDE encoding */
800 DW_CFA_def_cfa
, 7, 8, /* DW_CFA_def_cfa: r7 (rsp) ofs 8 */
801 DW_CFA_offset
+ 16, 1, /* DW_CFA_offset: r16 (rip) at cfa-8 */
802 DW_CFA_nop
, DW_CFA_nop
,
804 PLT_GOT_FDE_LENGTH
, 0, 0, 0, /* FDE length */
805 PLT_CIE_LENGTH
+ 8, 0, 0, 0, /* CIE pointer */
806 0, 0, 0, 0, /* the start of non-lazy .plt goes here */
807 0, 0, 0, 0, /* non-lazy .plt size goes here */
808 0, /* Augmentation size */
809 DW_CFA_nop
, DW_CFA_nop
, DW_CFA_nop
, DW_CFA_nop
,
810 DW_CFA_nop
, DW_CFA_nop
, DW_CFA_nop
813 /* Architecture-specific backend data for x86-64. */
815 struct elf_x86_64_backend_data
825 #define get_elf_x86_64_arch_data(bed) \
826 ((const struct elf_x86_64_backend_data *) (bed)->arch_data)
828 #define get_elf_x86_64_backend_data(abfd) \
829 get_elf_x86_64_arch_data (get_elf_backend_data (abfd))
831 /* These are the standard parameters. */
832 static const struct elf_x86_lazy_plt_layout elf_x86_64_lazy_plt
=
834 elf_x86_64_lazy_plt0_entry
, /* plt0_entry */
835 LAZY_PLT_ENTRY_SIZE
, /* plt0_entry_size */
836 elf_x86_64_lazy_plt_entry
, /* plt_entry */
837 LAZY_PLT_ENTRY_SIZE
, /* plt_entry_size */
838 2, /* plt0_got1_offset */
839 8, /* plt0_got2_offset */
840 12, /* plt0_got2_insn_end */
841 2, /* plt_got_offset */
842 7, /* plt_reloc_offset */
843 12, /* plt_plt_offset */
844 6, /* plt_got_insn_size */
845 LAZY_PLT_ENTRY_SIZE
, /* plt_plt_insn_end */
846 6, /* plt_lazy_offset */
847 elf_x86_64_lazy_plt0_entry
, /* pic_plt0_entry */
848 elf_x86_64_lazy_plt_entry
, /* pic_plt_entry */
849 elf_x86_64_eh_frame_lazy_plt
, /* eh_frame_plt */
850 sizeof (elf_x86_64_eh_frame_lazy_plt
) /* eh_frame_plt_size */
853 static const struct elf_x86_non_lazy_plt_layout elf_x86_64_non_lazy_plt
=
855 elf_x86_64_non_lazy_plt_entry
, /* plt_entry */
856 elf_x86_64_non_lazy_plt_entry
, /* pic_plt_entry */
857 NON_LAZY_PLT_ENTRY_SIZE
, /* plt_entry_size */
858 2, /* plt_got_offset */
859 6, /* plt_got_insn_size */
860 elf_x86_64_eh_frame_non_lazy_plt
, /* eh_frame_plt */
861 sizeof (elf_x86_64_eh_frame_non_lazy_plt
) /* eh_frame_plt_size */
864 static const struct elf_x86_lazy_plt_layout elf_x86_64_lazy_bnd_plt
=
866 elf_x86_64_lazy_bnd_plt0_entry
, /* plt0_entry */
867 LAZY_PLT_ENTRY_SIZE
, /* plt0_entry_size */
868 elf_x86_64_lazy_bnd_plt_entry
, /* plt_entry */
869 LAZY_PLT_ENTRY_SIZE
, /* plt_entry_size */
870 2, /* plt0_got1_offset */
871 1+8, /* plt0_got2_offset */
872 1+12, /* plt0_got2_insn_end */
873 1+2, /* plt_got_offset */
874 1, /* plt_reloc_offset */
875 7, /* plt_plt_offset */
876 1+6, /* plt_got_insn_size */
877 11, /* plt_plt_insn_end */
878 0, /* plt_lazy_offset */
879 elf_x86_64_lazy_bnd_plt0_entry
, /* pic_plt0_entry */
880 elf_x86_64_lazy_bnd_plt_entry
, /* pic_plt_entry */
881 elf_x86_64_eh_frame_lazy_bnd_plt
, /* eh_frame_plt */
882 sizeof (elf_x86_64_eh_frame_lazy_bnd_plt
) /* eh_frame_plt_size */
885 static const struct elf_x86_non_lazy_plt_layout elf_x86_64_non_lazy_bnd_plt
=
887 elf_x86_64_non_lazy_bnd_plt_entry
, /* plt_entry */
888 elf_x86_64_non_lazy_bnd_plt_entry
, /* pic_plt_entry */
889 NON_LAZY_PLT_ENTRY_SIZE
, /* plt_entry_size */
890 1+2, /* plt_got_offset */
891 1+6, /* plt_got_insn_size */
892 elf_x86_64_eh_frame_non_lazy_plt
, /* eh_frame_plt */
893 sizeof (elf_x86_64_eh_frame_non_lazy_plt
) /* eh_frame_plt_size */
896 static const struct elf_x86_lazy_plt_layout elf_x86_64_lazy_ibt_plt
=
898 elf_x86_64_lazy_bnd_plt0_entry
, /* plt0_entry */
899 LAZY_PLT_ENTRY_SIZE
, /* plt0_entry_size */
900 elf_x86_64_lazy_ibt_plt_entry
, /* plt_entry */
901 LAZY_PLT_ENTRY_SIZE
, /* plt_entry_size */
902 2, /* plt0_got1_offset */
903 1+8, /* plt0_got2_offset */
904 1+12, /* plt0_got2_insn_end */
905 4+1+2, /* plt_got_offset */
906 4+1, /* plt_reloc_offset */
907 4+1+6, /* plt_plt_offset */
908 4+1+6, /* plt_got_insn_size */
909 4+1+5+5, /* plt_plt_insn_end */
910 0, /* plt_lazy_offset */
911 elf_x86_64_lazy_bnd_plt0_entry
, /* pic_plt0_entry */
912 elf_x86_64_lazy_ibt_plt_entry
, /* pic_plt_entry */
913 elf_x86_64_eh_frame_lazy_ibt_plt
, /* eh_frame_plt */
914 sizeof (elf_x86_64_eh_frame_lazy_ibt_plt
) /* eh_frame_plt_size */
917 static const struct elf_x86_lazy_plt_layout elf_x32_lazy_ibt_plt
=
919 elf_x86_64_lazy_plt0_entry
, /* plt0_entry */
920 LAZY_PLT_ENTRY_SIZE
, /* plt0_entry_size */
921 elf_x32_lazy_ibt_plt_entry
, /* plt_entry */
922 LAZY_PLT_ENTRY_SIZE
, /* plt_entry_size */
923 2, /* plt0_got1_offset */
924 8, /* plt0_got2_offset */
925 12, /* plt0_got2_insn_end */
926 4+2, /* plt_got_offset */
927 4+1, /* plt_reloc_offset */
928 4+6, /* plt_plt_offset */
929 4+6, /* plt_got_insn_size */
930 4+5+5, /* plt_plt_insn_end */
931 0, /* plt_lazy_offset */
932 elf_x86_64_lazy_plt0_entry
, /* pic_plt0_entry */
933 elf_x32_lazy_ibt_plt_entry
, /* pic_plt_entry */
934 elf_x32_eh_frame_lazy_ibt_plt
, /* eh_frame_plt */
935 sizeof (elf_x32_eh_frame_lazy_ibt_plt
) /* eh_frame_plt_size */
938 static const struct elf_x86_non_lazy_plt_layout elf_x86_64_non_lazy_ibt_plt
=
940 elf_x86_64_non_lazy_ibt_plt_entry
, /* plt_entry */
941 elf_x86_64_non_lazy_ibt_plt_entry
, /* pic_plt_entry */
942 LAZY_PLT_ENTRY_SIZE
, /* plt_entry_size */
943 4+1+2, /* plt_got_offset */
944 4+1+6, /* plt_got_insn_size */
945 elf_x86_64_eh_frame_non_lazy_plt
, /* eh_frame_plt */
946 sizeof (elf_x86_64_eh_frame_non_lazy_plt
) /* eh_frame_plt_size */
949 static const struct elf_x86_non_lazy_plt_layout elf_x32_non_lazy_ibt_plt
=
951 elf_x32_non_lazy_ibt_plt_entry
, /* plt_entry */
952 elf_x32_non_lazy_ibt_plt_entry
, /* pic_plt_entry */
953 LAZY_PLT_ENTRY_SIZE
, /* plt_entry_size */
954 4+2, /* plt_got_offset */
955 4+6, /* plt_got_insn_size */
956 elf_x86_64_eh_frame_non_lazy_plt
, /* eh_frame_plt */
957 sizeof (elf_x86_64_eh_frame_non_lazy_plt
) /* eh_frame_plt_size */
960 static const struct elf_x86_64_backend_data elf_x86_64_arch_bed
=
965 #define elf_backend_arch_data &elf_x86_64_arch_bed
968 elf64_x86_64_elf_object_p (bfd
*abfd
)
970 /* Set the right machine number for an x86-64 elf64 file. */
971 bfd_default_set_arch_mach (abfd
, bfd_arch_i386
, bfd_mach_x86_64
);
976 elf32_x86_64_elf_object_p (bfd
*abfd
)
978 /* Set the right machine number for an x86-64 elf32 file. */
979 bfd_default_set_arch_mach (abfd
, bfd_arch_i386
, bfd_mach_x64_32
);
983 /* Return TRUE if the TLS access code sequence support transition
987 elf_x86_64_check_tls_transition (bfd
*abfd
,
988 struct bfd_link_info
*info
,
991 Elf_Internal_Shdr
*symtab_hdr
,
992 struct elf_link_hash_entry
**sym_hashes
,
994 const Elf_Internal_Rela
*rel
,
995 const Elf_Internal_Rela
*relend
)
998 unsigned long r_symndx
;
999 bfd_boolean largepic
= FALSE
;
1000 struct elf_link_hash_entry
*h
;
1002 struct elf_x86_link_hash_table
*htab
;
1004 bfd_boolean indirect_call
;
1006 htab
= elf_x86_hash_table (info
, X86_64_ELF_DATA
);
1007 offset
= rel
->r_offset
;
1010 case R_X86_64_TLSGD
:
1011 case R_X86_64_TLSLD
:
1012 if ((rel
+ 1) >= relend
)
1015 if (r_type
== R_X86_64_TLSGD
)
1017 /* Check transition from GD access model. For 64bit, only
1018 .byte 0x66; leaq foo@tlsgd(%rip), %rdi
1019 .word 0x6666; rex64; call __tls_get_addr@PLT
1021 .byte 0x66; leaq foo@tlsgd(%rip), %rdi
1023 call *__tls_get_addr@GOTPCREL(%rip)
1024 which may be converted to
1025 addr32 call __tls_get_addr
1026 can transit to different access model. For 32bit, only
1027 leaq foo@tlsgd(%rip), %rdi
1028 .word 0x6666; rex64; call __tls_get_addr@PLT
1030 leaq foo@tlsgd(%rip), %rdi
1032 call *__tls_get_addr@GOTPCREL(%rip)
1033 which may be converted to
1034 addr32 call __tls_get_addr
1035 can transit to different access model. For largepic,
1037 leaq foo@tlsgd(%rip), %rdi
1038 movabsq $__tls_get_addr@pltoff, %rax
1042 leaq foo@tlsgd(%rip), %rdi
1043 movabsq $__tls_get_addr@pltoff, %rax
1047 static const unsigned char leaq
[] = { 0x66, 0x48, 0x8d, 0x3d };
1049 if ((offset
+ 12) > sec
->size
)
1052 call
= contents
+ offset
+ 4;
1054 || !((call
[1] == 0x48
1062 && call
[3] == 0xe8)))
1064 if (!ABI_64_P (abfd
)
1065 || (offset
+ 19) > sec
->size
1067 || memcmp (call
- 7, leaq
+ 1, 3) != 0
1068 || memcmp (call
, "\x48\xb8", 2) != 0
1072 || !((call
[10] == 0x48 && call
[12] == 0xd8)
1073 || (call
[10] == 0x4c && call
[12] == 0xf8)))
1077 else if (ABI_64_P (abfd
))
1080 || memcmp (contents
+ offset
- 4, leaq
, 4) != 0)
1086 || memcmp (contents
+ offset
- 3, leaq
+ 1, 3) != 0)
1089 indirect_call
= call
[2] == 0xff;
1093 /* Check transition from LD access model. Only
1094 leaq foo@tlsld(%rip), %rdi;
1095 call __tls_get_addr@PLT
1097 leaq foo@tlsld(%rip), %rdi;
1098 call *__tls_get_addr@GOTPCREL(%rip)
1099 which may be converted to
1100 addr32 call __tls_get_addr
1101 can transit to different access model. For largepic
1103 leaq foo@tlsld(%rip), %rdi
1104 movabsq $__tls_get_addr@pltoff, %rax
1108 leaq foo@tlsld(%rip), %rdi
1109 movabsq $__tls_get_addr@pltoff, %rax
1113 static const unsigned char lea
[] = { 0x48, 0x8d, 0x3d };
1115 if (offset
< 3 || (offset
+ 9) > sec
->size
)
1118 if (memcmp (contents
+ offset
- 3, lea
, 3) != 0)
1121 call
= contents
+ offset
+ 4;
1122 if (!(call
[0] == 0xe8
1123 || (call
[0] == 0xff && call
[1] == 0x15)
1124 || (call
[0] == 0x67 && call
[1] == 0xe8)))
1126 if (!ABI_64_P (abfd
)
1127 || (offset
+ 19) > sec
->size
1128 || memcmp (call
, "\x48\xb8", 2) != 0
1132 || !((call
[10] == 0x48 && call
[12] == 0xd8)
1133 || (call
[10] == 0x4c && call
[12] == 0xf8)))
1137 indirect_call
= call
[0] == 0xff;
1140 r_symndx
= htab
->r_sym (rel
[1].r_info
);
1141 if (r_symndx
< symtab_hdr
->sh_info
)
1144 h
= sym_hashes
[r_symndx
- symtab_hdr
->sh_info
];
1146 || !((struct elf_x86_link_hash_entry
*) h
)->tls_get_addr
)
1149 return ELF32_R_TYPE (rel
[1].r_info
) == R_X86_64_PLTOFF64
;
1150 else if (indirect_call
)
1151 return ELF32_R_TYPE (rel
[1].r_info
) == R_X86_64_GOTPCRELX
;
1153 return (ELF32_R_TYPE (rel
[1].r_info
) == R_X86_64_PC32
1154 || ELF32_R_TYPE (rel
[1].r_info
) == R_X86_64_PLT32
);
1156 case R_X86_64_GOTTPOFF
:
1157 /* Check transition from IE access model:
1158 mov foo@gottpoff(%rip), %reg
1159 add foo@gottpoff(%rip), %reg
1162 /* Check REX prefix first. */
1163 if (offset
>= 3 && (offset
+ 4) <= sec
->size
)
1165 val
= bfd_get_8 (abfd
, contents
+ offset
- 3);
1166 if (val
!= 0x48 && val
!= 0x4c)
1168 /* X32 may have 0x44 REX prefix or no REX prefix. */
1169 if (ABI_64_P (abfd
))
1175 /* X32 may not have any REX prefix. */
1176 if (ABI_64_P (abfd
))
1178 if (offset
< 2 || (offset
+ 3) > sec
->size
)
1182 val
= bfd_get_8 (abfd
, contents
+ offset
- 2);
1183 if (val
!= 0x8b && val
!= 0x03)
1186 val
= bfd_get_8 (abfd
, contents
+ offset
- 1);
1187 return (val
& 0xc7) == 5;
1189 case R_X86_64_GOTPC32_TLSDESC
:
1190 /* Check transition from GDesc access model:
1191 leaq x@tlsdesc(%rip), %rax
1193 Make sure it's a leaq adding rip to a 32-bit offset
1194 into any register, although it's probably almost always
1197 if (offset
< 3 || (offset
+ 4) > sec
->size
)
1200 val
= bfd_get_8 (abfd
, contents
+ offset
- 3);
1201 if ((val
& 0xfb) != 0x48)
1204 if (bfd_get_8 (abfd
, contents
+ offset
- 2) != 0x8d)
1207 val
= bfd_get_8 (abfd
, contents
+ offset
- 1);
1208 return (val
& 0xc7) == 0x05;
1210 case R_X86_64_TLSDESC_CALL
:
1211 /* Check transition from GDesc access model:
1212 call *x@tlsdesc(%rax)
1214 if (offset
+ 2 <= sec
->size
)
1216 /* Make sure that it's a call *x@tlsdesc(%rax). */
1217 call
= contents
+ offset
;
1218 return call
[0] == 0xff && call
[1] == 0x10;
1228 /* Return TRUE if the TLS access transition is OK or no transition
1229 will be performed. Update R_TYPE if there is a transition. */
1232 elf_x86_64_tls_transition (struct bfd_link_info
*info
, bfd
*abfd
,
1233 asection
*sec
, bfd_byte
*contents
,
1234 Elf_Internal_Shdr
*symtab_hdr
,
1235 struct elf_link_hash_entry
**sym_hashes
,
1236 unsigned int *r_type
, int tls_type
,
1237 const Elf_Internal_Rela
*rel
,
1238 const Elf_Internal_Rela
*relend
,
1239 struct elf_link_hash_entry
*h
,
1240 unsigned long r_symndx
,
1241 bfd_boolean from_relocate_section
)
1243 unsigned int from_type
= *r_type
;
1244 unsigned int to_type
= from_type
;
1245 bfd_boolean check
= TRUE
;
1247 /* Skip TLS transition for functions. */
1249 && (h
->type
== STT_FUNC
1250 || h
->type
== STT_GNU_IFUNC
))
1255 case R_X86_64_TLSGD
:
1256 case R_X86_64_GOTPC32_TLSDESC
:
1257 case R_X86_64_TLSDESC_CALL
:
1258 case R_X86_64_GOTTPOFF
:
1259 if (bfd_link_executable (info
))
1262 to_type
= R_X86_64_TPOFF32
;
1264 to_type
= R_X86_64_GOTTPOFF
;
1267 /* When we are called from elf_x86_64_relocate_section, there may
1268 be additional transitions based on TLS_TYPE. */
1269 if (from_relocate_section
)
1271 unsigned int new_to_type
= to_type
;
1273 if (bfd_link_executable (info
)
1276 && tls_type
== GOT_TLS_IE
)
1277 new_to_type
= R_X86_64_TPOFF32
;
1279 if (to_type
== R_X86_64_TLSGD
1280 || to_type
== R_X86_64_GOTPC32_TLSDESC
1281 || to_type
== R_X86_64_TLSDESC_CALL
)
1283 if (tls_type
== GOT_TLS_IE
)
1284 new_to_type
= R_X86_64_GOTTPOFF
;
1287 /* We checked the transition before when we were called from
1288 elf_x86_64_check_relocs. We only want to check the new
1289 transition which hasn't been checked before. */
1290 check
= new_to_type
!= to_type
&& from_type
== to_type
;
1291 to_type
= new_to_type
;
1296 case R_X86_64_TLSLD
:
1297 if (bfd_link_executable (info
))
1298 to_type
= R_X86_64_TPOFF32
;
1305 /* Return TRUE if there is no transition. */
1306 if (from_type
== to_type
)
1309 /* Check if the transition can be performed. */
1311 && ! elf_x86_64_check_tls_transition (abfd
, info
, sec
, contents
,
1312 symtab_hdr
, sym_hashes
,
1313 from_type
, rel
, relend
))
1315 reloc_howto_type
*from
, *to
;
1318 from
= elf_x86_64_rtype_to_howto (abfd
, from_type
);
1319 to
= elf_x86_64_rtype_to_howto (abfd
, to_type
);
1322 name
= h
->root
.root
.string
;
1325 struct elf_x86_link_hash_table
*htab
;
1327 htab
= elf_x86_hash_table (info
, X86_64_ELF_DATA
);
1332 Elf_Internal_Sym
*isym
;
1334 isym
= bfd_sym_from_r_symndx (&htab
->sym_cache
,
1336 name
= bfd_elf_sym_name (abfd
, symtab_hdr
, isym
, NULL
);
1341 /* xgettext:c-format */
1342 (_("%B: TLS transition from %s to %s against `%s' at %#Lx "
1343 "in section `%A' failed"),
1344 abfd
, from
->name
, to
->name
, name
, rel
->r_offset
, sec
);
1345 bfd_set_error (bfd_error_bad_value
);
1353 /* Rename some of the generic section flags to better document how they
1355 #define need_convert_load sec_flg0
1356 #define check_relocs_failed sec_flg1
1359 elf_x86_64_need_pic (struct bfd_link_info
*info
,
1360 bfd
*input_bfd
, asection
*sec
,
1361 struct elf_link_hash_entry
*h
,
1362 Elf_Internal_Shdr
*symtab_hdr
,
1363 Elf_Internal_Sym
*isym
,
1364 reloc_howto_type
*howto
)
1367 const char *und
= "";
1368 const char *pic
= "";
1374 name
= h
->root
.root
.string
;
1375 switch (ELF_ST_VISIBILITY (h
->other
))
1378 v
= _("hidden symbol ");
1381 v
= _("internal symbol ");
1384 v
= _("protected symbol ");
1387 if (((struct elf_x86_link_hash_entry
*) h
)->def_protected
)
1388 v
= _("protected symbol ");
1391 pic
= _("; recompile with -fPIC");
1395 if (!h
->def_regular
&& !h
->def_dynamic
)
1396 und
= _("undefined ");
1400 name
= bfd_elf_sym_name (input_bfd
, symtab_hdr
, isym
, NULL
);
1401 pic
= _("; recompile with -fPIC");
1404 if (bfd_link_dll (info
))
1405 object
= _("a shared object");
1406 else if (bfd_link_pie (info
))
1407 object
= _("a PIE object");
1409 object
= _("a PDE object");
1411 /* xgettext:c-format */
1412 _bfd_error_handler (_("%B: relocation %s against %s%s`%s' can "
1413 "not be used when making %s%s"),
1414 input_bfd
, howto
->name
, und
, v
, name
,
1416 bfd_set_error (bfd_error_bad_value
);
1417 sec
->check_relocs_failed
= 1;
1421 /* With the local symbol, foo, we convert
1422 mov foo@GOTPCREL(%rip), %reg
1426 call/jmp *foo@GOTPCREL(%rip)
1428 nop call foo/jmp foo nop
1429 When PIC is false, convert
1430 test %reg, foo@GOTPCREL(%rip)
1434 binop foo@GOTPCREL(%rip), %reg
1437 where binop is one of adc, add, and, cmp, or, sbb, sub, xor
1441 elf_x86_64_convert_load_reloc (bfd
*abfd
,
1443 Elf_Internal_Rela
*irel
,
1444 struct elf_link_hash_entry
*h
,
1445 bfd_boolean
*converted
,
1446 struct bfd_link_info
*link_info
)
1448 struct elf_x86_link_hash_table
*htab
;
1450 bfd_boolean no_overflow
;
1452 bfd_boolean to_reloc_pc32
;
1454 bfd_signed_vma raddend
;
1455 unsigned int opcode
;
1457 unsigned int r_type
= ELF32_R_TYPE (irel
->r_info
);
1458 unsigned int r_symndx
;
1459 bfd_vma roff
= irel
->r_offset
;
1461 if (roff
< (r_type
== R_X86_64_REX_GOTPCRELX
? 3 : 2))
1464 raddend
= irel
->r_addend
;
1465 /* Addend for 32-bit PC-relative relocation must be -4. */
1469 htab
= elf_x86_hash_table (link_info
, X86_64_ELF_DATA
);
1470 is_pic
= bfd_link_pic (link_info
);
1472 relocx
= (r_type
== R_X86_64_GOTPCRELX
1473 || r_type
== R_X86_64_REX_GOTPCRELX
);
1475 /* TRUE if --no-relax is used. */
1476 no_overflow
= link_info
->disable_target_specific_optimizations
> 1;
1478 r_symndx
= htab
->r_sym (irel
->r_info
);
1480 opcode
= bfd_get_8 (abfd
, contents
+ roff
- 2);
1482 /* Convert mov to lea since it has been done for a while. */
1485 /* Only convert R_X86_64_GOTPCRELX and R_X86_64_REX_GOTPCRELX
1486 for call, jmp or one of adc, add, and, cmp, or, sbb, sub,
1487 test, xor instructions. */
1492 /* We convert only to R_X86_64_PC32:
1494 2. R_X86_64_GOTPCREL since we can't modify REX byte.
1495 3. no_overflow is true.
1498 to_reloc_pc32
= (opcode
== 0xff
1503 /* Get the symbol referred to by the reloc. */
1506 Elf_Internal_Sym
*isym
1507 = bfd_sym_from_r_symndx (&htab
->sym_cache
, abfd
, r_symndx
);
1509 /* Skip relocation against undefined symbols. */
1510 if (isym
->st_shndx
== SHN_UNDEF
)
1513 if (isym
->st_shndx
== SHN_ABS
)
1514 tsec
= bfd_abs_section_ptr
;
1515 else if (isym
->st_shndx
== SHN_COMMON
)
1516 tsec
= bfd_com_section_ptr
;
1517 else if (isym
->st_shndx
== SHN_X86_64_LCOMMON
)
1518 tsec
= &_bfd_elf_large_com_section
;
1520 tsec
= bfd_section_from_elf_index (abfd
, isym
->st_shndx
);
1524 /* Undefined weak symbol is only bound locally in executable
1525 and its reference is resolved as 0 without relocation
1526 overflow. We can only perform this optimization for
1527 GOTPCRELX relocations since we need to modify REX byte.
1528 It is OK convert mov with R_X86_64_GOTPCREL to
1530 if ((relocx
|| opcode
== 0x8b)
1531 && UNDEFINED_WEAK_RESOLVED_TO_ZERO (link_info
,
1534 elf_x86_hash_entry (h
)))
1538 /* Skip for branch instructions since R_X86_64_PC32
1545 /* For non-branch instructions, we can convert to
1546 R_X86_64_32/R_X86_64_32S since we know if there
1548 to_reloc_pc32
= FALSE
;
1551 /* Since we don't know the current PC when PIC is true,
1552 we can't convert to R_X86_64_PC32. */
1553 if (to_reloc_pc32
&& is_pic
)
1558 /* Avoid optimizing GOTPCREL relocations againt _DYNAMIC since
1559 ld.so may use its link-time address. */
1560 else if (h
->start_stop
1562 || h
->root
.type
== bfd_link_hash_defined
1563 || h
->root
.type
== bfd_link_hash_defweak
)
1564 && h
!= htab
->elf
.hdynamic
1565 && SYMBOL_REFERENCES_LOCAL (link_info
, h
)))
1567 /* bfd_link_hash_new or bfd_link_hash_undefined is
1568 set by an assignment in a linker script in
1569 bfd_elf_record_link_assignment. start_stop is set
1570 on __start_SECNAME/__stop_SECNAME which mark section
1574 && (h
->root
.type
== bfd_link_hash_new
1575 || h
->root
.type
== bfd_link_hash_undefined
1576 || ((h
->root
.type
== bfd_link_hash_defined
1577 || h
->root
.type
== bfd_link_hash_defweak
)
1578 && h
->root
.u
.def
.section
== bfd_und_section_ptr
))))
1580 /* Skip since R_X86_64_32/R_X86_64_32S may overflow. */
1585 tsec
= h
->root
.u
.def
.section
;
1591 /* Don't convert GOTPCREL relocation against large section. */
1592 if (elf_section_data (tsec
) != NULL
1593 && (elf_section_flags (tsec
) & SHF_X86_64_LARGE
) != 0)
1596 /* Skip since R_X86_64_PC32/R_X86_64_32/R_X86_64_32S may overflow. */
1602 ((struct elf_x86_link_hash_entry
*) h
)->converted_reloc
= 1;
1606 /* We have "call/jmp *foo@GOTPCREL(%rip)". */
1611 /* Convert R_X86_64_GOTPCRELX and R_X86_64_REX_GOTPCRELX to
1613 modrm
= bfd_get_8 (abfd
, contents
+ roff
- 1);
1616 /* Convert to "jmp foo nop". */
1619 nop_offset
= irel
->r_offset
+ 3;
1620 disp
= bfd_get_32 (abfd
, contents
+ irel
->r_offset
);
1621 irel
->r_offset
-= 1;
1622 bfd_put_32 (abfd
, disp
, contents
+ irel
->r_offset
);
1626 struct elf_x86_link_hash_entry
*eh
1627 = (struct elf_x86_link_hash_entry
*) h
;
1629 /* Convert to "nop call foo". ADDR_PREFIX_OPCODE
1632 /* To support TLS optimization, always use addr32 prefix for
1633 "call *__tls_get_addr@GOTPCREL(%rip)". */
1634 if (eh
&& eh
->tls_get_addr
)
1637 nop_offset
= irel
->r_offset
- 2;
1641 nop
= link_info
->call_nop_byte
;
1642 if (link_info
->call_nop_as_suffix
)
1644 nop_offset
= irel
->r_offset
+ 3;
1645 disp
= bfd_get_32 (abfd
, contents
+ irel
->r_offset
);
1646 irel
->r_offset
-= 1;
1647 bfd_put_32 (abfd
, disp
, contents
+ irel
->r_offset
);
1650 nop_offset
= irel
->r_offset
- 2;
1653 bfd_put_8 (abfd
, nop
, contents
+ nop_offset
);
1654 bfd_put_8 (abfd
, modrm
, contents
+ irel
->r_offset
- 1);
1655 r_type
= R_X86_64_PC32
;
1660 unsigned int rex_mask
= REX_R
;
1662 if (r_type
== R_X86_64_REX_GOTPCRELX
)
1663 rex
= bfd_get_8 (abfd
, contents
+ roff
- 3);
1671 /* Convert "mov foo@GOTPCREL(%rip), %reg" to
1672 "lea foo(%rip), %reg". */
1674 r_type
= R_X86_64_PC32
;
1678 /* Convert "mov foo@GOTPCREL(%rip), %reg" to
1679 "mov $foo, %reg". */
1681 modrm
= bfd_get_8 (abfd
, contents
+ roff
- 1);
1682 modrm
= 0xc0 | (modrm
& 0x38) >> 3;
1683 if ((rex
& REX_W
) != 0
1684 && ABI_64_P (link_info
->output_bfd
))
1686 /* Keep the REX_W bit in REX byte for LP64. */
1687 r_type
= R_X86_64_32S
;
1688 goto rewrite_modrm_rex
;
1692 /* If the REX_W bit in REX byte isn't needed,
1693 use R_X86_64_32 and clear the W bit to avoid
1694 sign-extend imm32 to imm64. */
1695 r_type
= R_X86_64_32
;
1696 /* Clear the W bit in REX byte. */
1698 goto rewrite_modrm_rex
;
1704 /* R_X86_64_PC32 isn't supported. */
1708 modrm
= bfd_get_8 (abfd
, contents
+ roff
- 1);
1711 /* Convert "test %reg, foo@GOTPCREL(%rip)" to
1712 "test $foo, %reg". */
1713 modrm
= 0xc0 | (modrm
& 0x38) >> 3;
1718 /* Convert "binop foo@GOTPCREL(%rip), %reg" to
1719 "binop $foo, %reg". */
1720 modrm
= 0xc0 | (modrm
& 0x38) >> 3 | (opcode
& 0x3c);
1724 /* Use R_X86_64_32 with 32-bit operand to avoid relocation
1725 overflow when sign-extending imm32 to imm64. */
1726 r_type
= (rex
& REX_W
) != 0 ? R_X86_64_32S
: R_X86_64_32
;
1729 bfd_put_8 (abfd
, modrm
, contents
+ roff
- 1);
1733 /* Move the R bit to the B bit in REX byte. */
1734 rex
= (rex
& ~rex_mask
) | (rex
& REX_R
) >> 2;
1735 bfd_put_8 (abfd
, rex
, contents
+ roff
- 3);
1738 /* No addend for R_X86_64_32/R_X86_64_32S relocations. */
1742 bfd_put_8 (abfd
, opcode
, contents
+ roff
- 2);
1745 irel
->r_info
= htab
->r_info (r_symndx
, r_type
);
1752 /* Look through the relocs for a section during the first phase, and
1753 calculate needed space in the global offset table, procedure
1754 linkage table, and dynamic reloc sections. */
1757 elf_x86_64_check_relocs (bfd
*abfd
, struct bfd_link_info
*info
,
1759 const Elf_Internal_Rela
*relocs
)
1761 struct elf_x86_link_hash_table
*htab
;
1762 Elf_Internal_Shdr
*symtab_hdr
;
1763 struct elf_link_hash_entry
**sym_hashes
;
1764 const Elf_Internal_Rela
*rel
;
1765 const Elf_Internal_Rela
*rel_end
;
1769 if (bfd_link_relocatable (info
))
1772 /* Don't do anything special with non-loaded, non-alloced sections.
1773 In particular, any relocs in such sections should not affect GOT
1774 and PLT reference counting (ie. we don't allow them to create GOT
1775 or PLT entries), there's no possibility or desire to optimize TLS
1776 relocs, and there's not much point in propagating relocs to shared
1777 libs that the dynamic linker won't relocate. */
1778 if ((sec
->flags
& SEC_ALLOC
) == 0)
1781 htab
= elf_x86_hash_table (info
, X86_64_ELF_DATA
);
1784 sec
->check_relocs_failed
= 1;
1788 BFD_ASSERT (is_x86_elf (abfd
, htab
));
1790 /* Get the section contents. */
1791 if (elf_section_data (sec
)->this_hdr
.contents
!= NULL
)
1792 contents
= elf_section_data (sec
)->this_hdr
.contents
;
1793 else if (!bfd_malloc_and_get_section (abfd
, sec
, &contents
))
1795 sec
->check_relocs_failed
= 1;
1799 symtab_hdr
= &elf_symtab_hdr (abfd
);
1800 sym_hashes
= elf_sym_hashes (abfd
);
1804 rel_end
= relocs
+ sec
->reloc_count
;
1805 for (rel
= relocs
; rel
< rel_end
; rel
++)
1807 unsigned int r_type
;
1808 unsigned int r_symndx
;
1809 struct elf_link_hash_entry
*h
;
1810 struct elf_x86_link_hash_entry
*eh
;
1811 Elf_Internal_Sym
*isym
;
1813 bfd_boolean size_reloc
;
1815 r_symndx
= htab
->r_sym (rel
->r_info
);
1816 r_type
= ELF32_R_TYPE (rel
->r_info
);
1818 if (r_symndx
>= NUM_SHDR_ENTRIES (symtab_hdr
))
1820 /* xgettext:c-format */
1821 _bfd_error_handler (_("%B: bad symbol index: %d"),
1826 if (r_symndx
< symtab_hdr
->sh_info
)
1828 /* A local symbol. */
1829 isym
= bfd_sym_from_r_symndx (&htab
->sym_cache
,
1834 /* Check relocation against local STT_GNU_IFUNC symbol. */
1835 if (ELF_ST_TYPE (isym
->st_info
) == STT_GNU_IFUNC
)
1837 h
= _bfd_elf_x86_get_local_sym_hash (htab
, abfd
, rel
,
1842 /* Fake a STT_GNU_IFUNC symbol. */
1843 h
->root
.root
.string
= bfd_elf_sym_name (abfd
, symtab_hdr
,
1845 h
->type
= STT_GNU_IFUNC
;
1848 h
->forced_local
= 1;
1849 h
->root
.type
= bfd_link_hash_defined
;
1857 h
= sym_hashes
[r_symndx
- symtab_hdr
->sh_info
];
1858 while (h
->root
.type
== bfd_link_hash_indirect
1859 || h
->root
.type
== bfd_link_hash_warning
)
1860 h
= (struct elf_link_hash_entry
*) h
->root
.u
.i
.link
;
1863 /* Check invalid x32 relocations. */
1864 if (!ABI_64_P (abfd
))
1870 case R_X86_64_DTPOFF64
:
1871 case R_X86_64_TPOFF64
:
1873 case R_X86_64_GOTOFF64
:
1874 case R_X86_64_GOT64
:
1875 case R_X86_64_GOTPCREL64
:
1876 case R_X86_64_GOTPC64
:
1877 case R_X86_64_GOTPLT64
:
1878 case R_X86_64_PLTOFF64
:
1881 name
= h
->root
.root
.string
;
1883 name
= bfd_elf_sym_name (abfd
, symtab_hdr
, isym
,
1886 /* xgettext:c-format */
1887 (_("%B: relocation %s against symbol `%s' isn't "
1888 "supported in x32 mode"), abfd
,
1889 x86_64_elf_howto_table
[r_type
].name
, name
);
1890 bfd_set_error (bfd_error_bad_value
);
1898 /* It is referenced by a non-shared object. */
1900 h
->root
.non_ir_ref_regular
= 1;
1902 if (h
->type
== STT_GNU_IFUNC
)
1903 elf_tdata (info
->output_bfd
)->has_gnu_symbols
1904 |= elf_gnu_symbol_ifunc
;
1907 if (! elf_x86_64_tls_transition (info
, abfd
, sec
, contents
,
1908 symtab_hdr
, sym_hashes
,
1909 &r_type
, GOT_UNKNOWN
,
1910 rel
, rel_end
, h
, r_symndx
, FALSE
))
1913 eh
= (struct elf_x86_link_hash_entry
*) h
;
1916 case R_X86_64_TLSLD
:
1917 htab
->tls_ld_or_ldm_got
.refcount
+= 1;
1920 case R_X86_64_TPOFF32
:
1921 if (!bfd_link_executable (info
) && ABI_64_P (abfd
))
1922 return elf_x86_64_need_pic (info
, abfd
, sec
, h
, symtab_hdr
, isym
,
1923 &x86_64_elf_howto_table
[r_type
]);
1925 eh
->has_got_reloc
= 1;
1928 case R_X86_64_GOTTPOFF
:
1929 if (!bfd_link_executable (info
))
1930 info
->flags
|= DF_STATIC_TLS
;
1933 case R_X86_64_GOT32
:
1934 case R_X86_64_GOTPCREL
:
1935 case R_X86_64_GOTPCRELX
:
1936 case R_X86_64_REX_GOTPCRELX
:
1937 case R_X86_64_TLSGD
:
1938 case R_X86_64_GOT64
:
1939 case R_X86_64_GOTPCREL64
:
1940 case R_X86_64_GOTPLT64
:
1941 case R_X86_64_GOTPC32_TLSDESC
:
1942 case R_X86_64_TLSDESC_CALL
:
1943 /* This symbol requires a global offset table entry. */
1945 int tls_type
, old_tls_type
;
1949 default: tls_type
= GOT_NORMAL
; break;
1950 case R_X86_64_TLSGD
: tls_type
= GOT_TLS_GD
; break;
1951 case R_X86_64_GOTTPOFF
: tls_type
= GOT_TLS_IE
; break;
1952 case R_X86_64_GOTPC32_TLSDESC
:
1953 case R_X86_64_TLSDESC_CALL
:
1954 tls_type
= GOT_TLS_GDESC
; break;
1959 h
->got
.refcount
+= 1;
1960 old_tls_type
= eh
->tls_type
;
1964 bfd_signed_vma
*local_got_refcounts
;
1966 /* This is a global offset table entry for a local symbol. */
1967 local_got_refcounts
= elf_local_got_refcounts (abfd
);
1968 if (local_got_refcounts
== NULL
)
1972 size
= symtab_hdr
->sh_info
;
1973 size
*= sizeof (bfd_signed_vma
)
1974 + sizeof (bfd_vma
) + sizeof (char);
1975 local_got_refcounts
= ((bfd_signed_vma
*)
1976 bfd_zalloc (abfd
, size
));
1977 if (local_got_refcounts
== NULL
)
1979 elf_local_got_refcounts (abfd
) = local_got_refcounts
;
1980 elf_x86_local_tlsdesc_gotent (abfd
)
1981 = (bfd_vma
*) (local_got_refcounts
+ symtab_hdr
->sh_info
);
1982 elf_x86_local_got_tls_type (abfd
)
1983 = (char *) (local_got_refcounts
+ 2 * symtab_hdr
->sh_info
);
1985 local_got_refcounts
[r_symndx
] += 1;
1987 = elf_x86_local_got_tls_type (abfd
) [r_symndx
];
1990 /* If a TLS symbol is accessed using IE at least once,
1991 there is no point to use dynamic model for it. */
1992 if (old_tls_type
!= tls_type
&& old_tls_type
!= GOT_UNKNOWN
1993 && (! GOT_TLS_GD_ANY_P (old_tls_type
)
1994 || tls_type
!= GOT_TLS_IE
))
1996 if (old_tls_type
== GOT_TLS_IE
&& GOT_TLS_GD_ANY_P (tls_type
))
1997 tls_type
= old_tls_type
;
1998 else if (GOT_TLS_GD_ANY_P (old_tls_type
)
1999 && GOT_TLS_GD_ANY_P (tls_type
))
2000 tls_type
|= old_tls_type
;
2004 name
= h
->root
.root
.string
;
2006 name
= bfd_elf_sym_name (abfd
, symtab_hdr
,
2009 /* xgettext:c-format */
2010 (_("%B: '%s' accessed both as normal and"
2011 " thread local symbol"),
2013 bfd_set_error (bfd_error_bad_value
);
2018 if (old_tls_type
!= tls_type
)
2021 eh
->tls_type
= tls_type
;
2023 elf_x86_local_got_tls_type (abfd
) [r_symndx
] = tls_type
;
2028 case R_X86_64_GOTOFF64
:
2029 case R_X86_64_GOTPC32
:
2030 case R_X86_64_GOTPC64
:
2033 eh
->has_got_reloc
= 1;
2036 case R_X86_64_PLT32
:
2037 case R_X86_64_PLT32_BND
:
2038 /* This symbol requires a procedure linkage table entry. We
2039 actually build the entry in adjust_dynamic_symbol,
2040 because this might be a case of linking PIC code which is
2041 never referenced by a dynamic object, in which case we
2042 don't need to generate a procedure linkage table entry
2045 /* If this is a local symbol, we resolve it directly without
2046 creating a procedure linkage table entry. */
2050 eh
->has_got_reloc
= 1;
2052 h
->plt
.refcount
+= 1;
2055 case R_X86_64_PLTOFF64
:
2056 /* This tries to form the 'address' of a function relative
2057 to GOT. For global symbols we need a PLT entry. */
2061 h
->plt
.refcount
+= 1;
2065 case R_X86_64_SIZE32
:
2066 case R_X86_64_SIZE64
:
2071 if (!ABI_64_P (abfd
))
2077 /* Check relocation overflow as these relocs may lead to
2078 run-time relocation overflow. Don't error out for
2079 sections we don't care about, such as debug sections or
2080 when relocation overflow check is disabled. */
2081 if (!info
->no_reloc_overflow_check
2082 && (bfd_link_pic (info
)
2083 || (bfd_link_executable (info
)
2087 && (sec
->flags
& SEC_READONLY
) == 0)))
2088 return elf_x86_64_need_pic (info
, abfd
, sec
, h
, symtab_hdr
, isym
,
2089 &x86_64_elf_howto_table
[r_type
]);
2095 case R_X86_64_PC32_BND
:
2099 if (eh
!= NULL
&& (sec
->flags
& SEC_CODE
) != 0)
2100 eh
->has_non_got_reloc
= 1;
2101 /* We are called after all symbols have been resolved. Only
2102 relocation against STT_GNU_IFUNC symbol must go through
2105 && (bfd_link_executable (info
)
2106 || h
->type
== STT_GNU_IFUNC
))
2108 /* If this reloc is in a read-only section, we might
2109 need a copy reloc. We can't check reliably at this
2110 stage whether the section is read-only, as input
2111 sections have not yet been mapped to output sections.
2112 Tentatively set the flag for now, and correct in
2113 adjust_dynamic_symbol. */
2116 /* We may need a .plt entry if the symbol is a function
2117 defined in a shared lib or is a STT_GNU_IFUNC function
2118 referenced from the code or read-only section. */
2120 || (sec
->flags
& (SEC_CODE
| SEC_READONLY
)) != 0)
2121 h
->plt
.refcount
+= 1;
2123 if (r_type
== R_X86_64_PC32
)
2125 /* Since something like ".long foo - ." may be used
2126 as pointer, make sure that PLT is used if foo is
2127 a function defined in a shared library. */
2128 if ((sec
->flags
& SEC_CODE
) == 0)
2129 h
->pointer_equality_needed
= 1;
2131 else if (r_type
!= R_X86_64_PC32_BND
2132 && r_type
!= R_X86_64_PC64
)
2134 h
->pointer_equality_needed
= 1;
2135 /* At run-time, R_X86_64_64 can be resolved for both
2136 x86-64 and x32. But R_X86_64_32 and R_X86_64_32S
2137 can only be resolved for x32. */
2138 if ((sec
->flags
& SEC_READONLY
) == 0
2139 && (r_type
== R_X86_64_64
2140 || (!ABI_64_P (abfd
)
2141 && (r_type
== R_X86_64_32
2142 || r_type
== R_X86_64_32S
))))
2143 eh
->func_pointer_refcount
+= 1;
2149 /* If we are creating a shared library, and this is a reloc
2150 against a global symbol, or a non PC relative reloc
2151 against a local symbol, then we need to copy the reloc
2152 into the shared library. However, if we are linking with
2153 -Bsymbolic, we do not need to copy a reloc against a
2154 global symbol which is defined in an object we are
2155 including in the link (i.e., DEF_REGULAR is set). At
2156 this point we have not seen all the input files, so it is
2157 possible that DEF_REGULAR is not set now but will be set
2158 later (it is never cleared). In case of a weak definition,
2159 DEF_REGULAR may be cleared later by a strong definition in
2160 a shared library. We account for that possibility below by
2161 storing information in the relocs_copied field of the hash
2162 table entry. A similar situation occurs when creating
2163 shared libraries and symbol visibility changes render the
2166 If on the other hand, we are creating an executable, we
2167 may need to keep relocations for symbols satisfied by a
2168 dynamic library if we manage to avoid copy relocs for the
2171 Generate dynamic pointer relocation against STT_GNU_IFUNC
2172 symbol in the non-code section. */
2173 if ((bfd_link_pic (info
)
2174 && (! IS_X86_64_PCREL_TYPE (r_type
)
2176 && (! (bfd_link_pie (info
)
2177 || SYMBOLIC_BIND (info
, h
))
2178 || h
->root
.type
== bfd_link_hash_defweak
2179 || !h
->def_regular
))))
2181 && h
->type
== STT_GNU_IFUNC
2182 && r_type
== htab
->pointer_r_type
2183 && (sec
->flags
& SEC_CODE
) == 0)
2184 || (ELIMINATE_COPY_RELOCS
2185 && !bfd_link_pic (info
)
2187 && (h
->root
.type
== bfd_link_hash_defweak
2188 || !h
->def_regular
)))
2190 struct elf_dyn_relocs
*p
;
2191 struct elf_dyn_relocs
**head
;
2193 /* We must copy these reloc types into the output file.
2194 Create a reloc section in dynobj and make room for
2198 sreloc
= _bfd_elf_make_dynamic_reloc_section
2199 (sec
, htab
->elf
.dynobj
, ABI_64_P (abfd
) ? 3 : 2,
2200 abfd
, /*rela?*/ TRUE
);
2206 /* If this is a global symbol, we count the number of
2207 relocations we need for this symbol. */
2209 head
= &eh
->dyn_relocs
;
2212 /* Track dynamic relocs needed for local syms too.
2213 We really need local syms available to do this
2218 isym
= bfd_sym_from_r_symndx (&htab
->sym_cache
,
2223 s
= bfd_section_from_elf_index (abfd
, isym
->st_shndx
);
2227 /* Beware of type punned pointers vs strict aliasing
2229 vpp
= &(elf_section_data (s
)->local_dynrel
);
2230 head
= (struct elf_dyn_relocs
**)vpp
;
2234 if (p
== NULL
|| p
->sec
!= sec
)
2236 bfd_size_type amt
= sizeof *p
;
2238 p
= ((struct elf_dyn_relocs
*)
2239 bfd_alloc (htab
->elf
.dynobj
, amt
));
2250 /* Count size relocation as PC-relative relocation. */
2251 if (IS_X86_64_PCREL_TYPE (r_type
) || size_reloc
)
2256 /* This relocation describes the C++ object vtable hierarchy.
2257 Reconstruct it for later use during GC. */
2258 case R_X86_64_GNU_VTINHERIT
:
2259 if (!bfd_elf_gc_record_vtinherit (abfd
, sec
, h
, rel
->r_offset
))
2263 /* This relocation describes which C++ vtable entries are actually
2264 used. Record for later use during GC. */
2265 case R_X86_64_GNU_VTENTRY
:
2266 BFD_ASSERT (h
!= NULL
);
2268 && !bfd_elf_gc_record_vtentry (abfd
, sec
, h
, rel
->r_addend
))
2276 if ((r_type
== R_X86_64_GOTPCREL
2277 || r_type
== R_X86_64_GOTPCRELX
2278 || r_type
== R_X86_64_REX_GOTPCRELX
)
2279 && (h
== NULL
|| h
->type
!= STT_GNU_IFUNC
))
2280 sec
->need_convert_load
= 1;
2283 if (elf_section_data (sec
)->this_hdr
.contents
!= contents
)
2285 if (!info
->keep_memory
)
2289 /* Cache the section contents for elf_link_input_bfd. */
2290 elf_section_data (sec
)->this_hdr
.contents
= contents
;
2297 if (elf_section_data (sec
)->this_hdr
.contents
!= contents
)
2299 sec
->check_relocs_failed
= 1;
2303 /* Convert load via the GOT slot to load immediate. */
2306 _bfd_x86_64_elf_convert_load (bfd
*abfd
, asection
*sec
,
2307 struct bfd_link_info
*link_info
)
2309 Elf_Internal_Shdr
*symtab_hdr
;
2310 Elf_Internal_Rela
*internal_relocs
;
2311 Elf_Internal_Rela
*irel
, *irelend
;
2313 struct elf_x86_link_hash_table
*htab
;
2314 bfd_boolean changed
;
2315 bfd_signed_vma
*local_got_refcounts
;
2317 /* Don't even try to convert non-ELF outputs. */
2318 if (!is_elf_hash_table (link_info
->hash
))
2321 /* Nothing to do if there is no need or no output. */
2322 if ((sec
->flags
& (SEC_CODE
| SEC_RELOC
)) != (SEC_CODE
| SEC_RELOC
)
2323 || sec
->need_convert_load
== 0
2324 || bfd_is_abs_section (sec
->output_section
))
2327 symtab_hdr
= &elf_tdata (abfd
)->symtab_hdr
;
2329 /* Load the relocations for this section. */
2330 internal_relocs
= (_bfd_elf_link_read_relocs
2331 (abfd
, sec
, NULL
, (Elf_Internal_Rela
*) NULL
,
2332 link_info
->keep_memory
));
2333 if (internal_relocs
== NULL
)
2337 htab
= elf_x86_hash_table (link_info
, X86_64_ELF_DATA
);
2338 local_got_refcounts
= elf_local_got_refcounts (abfd
);
2340 /* Get the section contents. */
2341 if (elf_section_data (sec
)->this_hdr
.contents
!= NULL
)
2342 contents
= elf_section_data (sec
)->this_hdr
.contents
;
2345 if (!bfd_malloc_and_get_section (abfd
, sec
, &contents
))
2349 irelend
= internal_relocs
+ sec
->reloc_count
;
2350 for (irel
= internal_relocs
; irel
< irelend
; irel
++)
2352 unsigned int r_type
= ELF32_R_TYPE (irel
->r_info
);
2353 unsigned int r_symndx
;
2354 struct elf_link_hash_entry
*h
;
2355 bfd_boolean converted
;
2357 if (r_type
!= R_X86_64_GOTPCRELX
2358 && r_type
!= R_X86_64_REX_GOTPCRELX
2359 && r_type
!= R_X86_64_GOTPCREL
)
2362 r_symndx
= htab
->r_sym (irel
->r_info
);
2363 if (r_symndx
< symtab_hdr
->sh_info
)
2364 h
= _bfd_elf_x86_get_local_sym_hash (htab
, sec
->owner
,
2365 (const Elf_Internal_Rela
*) irel
,
2369 h
= elf_sym_hashes (abfd
)[r_symndx
- symtab_hdr
->sh_info
];
2370 while (h
->root
.type
== bfd_link_hash_indirect
2371 || h
->root
.type
== bfd_link_hash_warning
)
2372 h
= (struct elf_link_hash_entry
*) h
->root
.u
.i
.link
;
2375 /* STT_GNU_IFUNC must keep GOTPCREL relocations. */
2376 if (h
!= NULL
&& h
->type
== STT_GNU_IFUNC
)
2380 if (!elf_x86_64_convert_load_reloc (abfd
, contents
, irel
, h
,
2381 &converted
, link_info
))
2386 changed
= converted
;
2389 if (h
->got
.refcount
> 0)
2390 h
->got
.refcount
-= 1;
2394 if (local_got_refcounts
!= NULL
2395 && local_got_refcounts
[r_symndx
] > 0)
2396 local_got_refcounts
[r_symndx
] -= 1;
2401 if (contents
!= NULL
2402 && elf_section_data (sec
)->this_hdr
.contents
!= contents
)
2404 if (!changed
&& !link_info
->keep_memory
)
2408 /* Cache the section contents for elf_link_input_bfd. */
2409 elf_section_data (sec
)->this_hdr
.contents
= contents
;
2413 if (elf_section_data (sec
)->relocs
!= internal_relocs
)
2416 free (internal_relocs
);
2418 elf_section_data (sec
)->relocs
= internal_relocs
;
2424 if (contents
!= NULL
2425 && elf_section_data (sec
)->this_hdr
.contents
!= contents
)
2427 if (internal_relocs
!= NULL
2428 && elf_section_data (sec
)->relocs
!= internal_relocs
)
2429 free (internal_relocs
);
2433 /* Return the relocation value for @tpoff relocation
2434 if STT_TLS virtual address is ADDRESS. */
2437 elf_x86_64_tpoff (struct bfd_link_info
*info
, bfd_vma address
)
2439 struct elf_link_hash_table
*htab
= elf_hash_table (info
);
2440 const struct elf_backend_data
*bed
= get_elf_backend_data (info
->output_bfd
);
2441 bfd_vma static_tls_size
;
2443 /* If tls_segment is NULL, we should have signalled an error already. */
2444 if (htab
->tls_sec
== NULL
)
2447 /* Consider special static TLS alignment requirements. */
2448 static_tls_size
= BFD_ALIGN (htab
->tls_size
, bed
->static_tls_alignment
);
2449 return address
- static_tls_size
- htab
->tls_sec
->vma
;
2452 /* Is the instruction before OFFSET in CONTENTS a 32bit relative
2456 is_32bit_relative_branch (bfd_byte
*contents
, bfd_vma offset
)
2458 /* Opcode Instruction
2461 0x0f 0x8x conditional jump */
2463 && (contents
[offset
- 1] == 0xe8
2464 || contents
[offset
- 1] == 0xe9))
2466 && contents
[offset
- 2] == 0x0f
2467 && (contents
[offset
- 1] & 0xf0) == 0x80));
2470 /* Relocate an x86_64 ELF section. */
2473 elf_x86_64_relocate_section (bfd
*output_bfd
,
2474 struct bfd_link_info
*info
,
2476 asection
*input_section
,
2478 Elf_Internal_Rela
*relocs
,
2479 Elf_Internal_Sym
*local_syms
,
2480 asection
**local_sections
)
2482 struct elf_x86_link_hash_table
*htab
;
2483 Elf_Internal_Shdr
*symtab_hdr
;
2484 struct elf_link_hash_entry
**sym_hashes
;
2485 bfd_vma
*local_got_offsets
;
2486 bfd_vma
*local_tlsdesc_gotents
;
2487 Elf_Internal_Rela
*rel
;
2488 Elf_Internal_Rela
*wrel
;
2489 Elf_Internal_Rela
*relend
;
2490 unsigned int plt_entry_size
;
2492 /* Skip if check_relocs failed. */
2493 if (input_section
->check_relocs_failed
)
2496 htab
= elf_x86_hash_table (info
, X86_64_ELF_DATA
);
2500 BFD_ASSERT (is_x86_elf (input_bfd
, htab
));
2502 plt_entry_size
= htab
->plt
.plt_entry_size
;
2503 symtab_hdr
= &elf_symtab_hdr (input_bfd
);
2504 sym_hashes
= elf_sym_hashes (input_bfd
);
2505 local_got_offsets
= elf_local_got_offsets (input_bfd
);
2506 local_tlsdesc_gotents
= elf_x86_local_tlsdesc_gotent (input_bfd
);
2508 _bfd_x86_elf_set_tls_module_base (info
);
2510 rel
= wrel
= relocs
;
2511 relend
= relocs
+ input_section
->reloc_count
;
2512 for (; rel
< relend
; wrel
++, rel
++)
2514 unsigned int r_type
;
2515 reloc_howto_type
*howto
;
2516 unsigned long r_symndx
;
2517 struct elf_link_hash_entry
*h
;
2518 struct elf_x86_link_hash_entry
*eh
;
2519 Elf_Internal_Sym
*sym
;
2521 bfd_vma off
, offplt
, plt_offset
;
2523 bfd_boolean unresolved_reloc
;
2524 bfd_reloc_status_type r
;
2526 asection
*base_got
, *resolved_plt
;
2528 bfd_boolean resolved_to_zero
;
2529 bfd_boolean relative_reloc
;
2531 r_type
= ELF32_R_TYPE (rel
->r_info
);
2532 if (r_type
== (int) R_X86_64_GNU_VTINHERIT
2533 || r_type
== (int) R_X86_64_GNU_VTENTRY
)
2540 if (r_type
>= (int) R_X86_64_standard
)
2541 return _bfd_unrecognized_reloc (input_bfd
, input_section
, r_type
);
2543 if (r_type
!= (int) R_X86_64_32
2544 || ABI_64_P (output_bfd
))
2545 howto
= x86_64_elf_howto_table
+ r_type
;
2547 howto
= (x86_64_elf_howto_table
2548 + ARRAY_SIZE (x86_64_elf_howto_table
) - 1);
2549 r_symndx
= htab
->r_sym (rel
->r_info
);
2553 unresolved_reloc
= FALSE
;
2554 if (r_symndx
< symtab_hdr
->sh_info
)
2556 sym
= local_syms
+ r_symndx
;
2557 sec
= local_sections
[r_symndx
];
2559 relocation
= _bfd_elf_rela_local_sym (output_bfd
, sym
,
2561 st_size
= sym
->st_size
;
2563 /* Relocate against local STT_GNU_IFUNC symbol. */
2564 if (!bfd_link_relocatable (info
)
2565 && ELF_ST_TYPE (sym
->st_info
) == STT_GNU_IFUNC
)
2567 h
= _bfd_elf_x86_get_local_sym_hash (htab
, input_bfd
,
2572 /* Set STT_GNU_IFUNC symbol value. */
2573 h
->root
.u
.def
.value
= sym
->st_value
;
2574 h
->root
.u
.def
.section
= sec
;
2579 bfd_boolean warned ATTRIBUTE_UNUSED
;
2580 bfd_boolean ignored ATTRIBUTE_UNUSED
;
2582 RELOC_FOR_GLOBAL_SYMBOL (info
, input_bfd
, input_section
, rel
,
2583 r_symndx
, symtab_hdr
, sym_hashes
,
2585 unresolved_reloc
, warned
, ignored
);
2589 if (sec
!= NULL
&& discarded_section (sec
))
2591 _bfd_clear_contents (howto
, input_bfd
, input_section
,
2592 contents
+ rel
->r_offset
);
2593 wrel
->r_offset
= rel
->r_offset
;
2597 /* For ld -r, remove relocations in debug sections against
2598 sections defined in discarded sections. Not done for
2599 eh_frame editing code expects to be present. */
2600 if (bfd_link_relocatable (info
)
2601 && (input_section
->flags
& SEC_DEBUGGING
))
2607 if (bfd_link_relocatable (info
))
2614 if (rel
->r_addend
== 0 && !ABI_64_P (output_bfd
))
2616 if (r_type
== R_X86_64_64
)
2618 /* For x32, treat R_X86_64_64 like R_X86_64_32 and
2619 zero-extend it to 64bit if addend is zero. */
2620 r_type
= R_X86_64_32
;
2621 memset (contents
+ rel
->r_offset
+ 4, 0, 4);
2623 else if (r_type
== R_X86_64_SIZE64
)
2625 /* For x32, treat R_X86_64_SIZE64 like R_X86_64_SIZE32 and
2626 zero-extend it to 64bit if addend is zero. */
2627 r_type
= R_X86_64_SIZE32
;
2628 memset (contents
+ rel
->r_offset
+ 4, 0, 4);
2632 eh
= (struct elf_x86_link_hash_entry
*) h
;
2634 /* Since STT_GNU_IFUNC symbol must go through PLT, we handle
2635 it here if it is defined in a non-shared object. */
2637 && h
->type
== STT_GNU_IFUNC
2643 if ((input_section
->flags
& SEC_ALLOC
) == 0)
2645 /* Dynamic relocs are not propagated for SEC_DEBUGGING
2646 sections because such sections are not SEC_ALLOC and
2647 thus ld.so will not process them. */
2648 if ((input_section
->flags
& SEC_DEBUGGING
) != 0)
2658 case R_X86_64_GOTPCREL
:
2659 case R_X86_64_GOTPCRELX
:
2660 case R_X86_64_REX_GOTPCRELX
:
2661 case R_X86_64_GOTPCREL64
:
2662 base_got
= htab
->elf
.sgot
;
2663 off
= h
->got
.offset
;
2665 if (base_got
== NULL
)
2668 if (off
== (bfd_vma
) -1)
2670 /* We can't use h->got.offset here to save state, or
2671 even just remember the offset, as finish_dynamic_symbol
2672 would use that as offset into .got. */
2674 if (h
->plt
.offset
== (bfd_vma
) -1)
2677 if (htab
->elf
.splt
!= NULL
)
2679 plt_index
= (h
->plt
.offset
/ plt_entry_size
2680 - htab
->plt
.has_plt0
);
2681 off
= (plt_index
+ 3) * GOT_ENTRY_SIZE
;
2682 base_got
= htab
->elf
.sgotplt
;
2686 plt_index
= h
->plt
.offset
/ plt_entry_size
;
2687 off
= plt_index
* GOT_ENTRY_SIZE
;
2688 base_got
= htab
->elf
.igotplt
;
2691 if (h
->dynindx
== -1
2695 /* This references the local defitionion. We must
2696 initialize this entry in the global offset table.
2697 Since the offset must always be a multiple of 8,
2698 we use the least significant bit to record
2699 whether we have initialized it already.
2701 When doing a dynamic link, we create a .rela.got
2702 relocation entry to initialize the value. This
2703 is done in the finish_dynamic_symbol routine. */
2708 bfd_put_64 (output_bfd
, relocation
,
2709 base_got
->contents
+ off
);
2710 /* Note that this is harmless for the GOTPLT64
2711 case, as -1 | 1 still is -1. */
2717 relocation
= (base_got
->output_section
->vma
2718 + base_got
->output_offset
+ off
);
2723 if (h
->plt
.offset
== (bfd_vma
) -1)
2725 /* Handle static pointers of STT_GNU_IFUNC symbols. */
2726 if (r_type
== htab
->pointer_r_type
2727 && (input_section
->flags
& SEC_CODE
) == 0)
2728 goto do_ifunc_pointer
;
2729 goto bad_ifunc_reloc
;
2732 /* STT_GNU_IFUNC symbol must go through PLT. */
2733 if (htab
->elf
.splt
!= NULL
)
2735 if (htab
->plt_second
!= NULL
)
2737 resolved_plt
= htab
->plt_second
;
2738 plt_offset
= eh
->plt_second
.offset
;
2742 resolved_plt
= htab
->elf
.splt
;
2743 plt_offset
= h
->plt
.offset
;
2748 resolved_plt
= htab
->elf
.iplt
;
2749 plt_offset
= h
->plt
.offset
;
2752 relocation
= (resolved_plt
->output_section
->vma
2753 + resolved_plt
->output_offset
+ plt_offset
);
2759 if (h
->root
.root
.string
)
2760 name
= h
->root
.root
.string
;
2762 name
= bfd_elf_sym_name (input_bfd
, symtab_hdr
, sym
,
2765 /* xgettext:c-format */
2766 (_("%B: relocation %s against STT_GNU_IFUNC "
2767 "symbol `%s' isn't supported"), input_bfd
,
2769 bfd_set_error (bfd_error_bad_value
);
2773 if (bfd_link_pic (info
))
2778 if (ABI_64_P (output_bfd
))
2783 if (rel
->r_addend
!= 0)
2785 if (h
->root
.root
.string
)
2786 name
= h
->root
.root
.string
;
2788 name
= bfd_elf_sym_name (input_bfd
, symtab_hdr
,
2791 /* xgettext:c-format */
2792 (_("%B: relocation %s against STT_GNU_IFUNC "
2793 "symbol `%s' has non-zero addend: %Ld"),
2794 input_bfd
, howto
->name
, name
, rel
->r_addend
);
2795 bfd_set_error (bfd_error_bad_value
);
2799 /* Generate dynamic relcoation only when there is a
2800 non-GOT reference in a shared object or there is no
2802 if ((bfd_link_pic (info
) && h
->non_got_ref
)
2803 || h
->plt
.offset
== (bfd_vma
) -1)
2805 Elf_Internal_Rela outrel
;
2808 /* Need a dynamic relocation to get the real function
2810 outrel
.r_offset
= _bfd_elf_section_offset (output_bfd
,
2814 if (outrel
.r_offset
== (bfd_vma
) -1
2815 || outrel
.r_offset
== (bfd_vma
) -2)
2818 outrel
.r_offset
+= (input_section
->output_section
->vma
2819 + input_section
->output_offset
);
2821 if (h
->dynindx
== -1
2823 || bfd_link_executable (info
))
2825 info
->callbacks
->minfo (_("Local IFUNC function `%s' in %B\n"),
2826 h
->root
.root
.string
,
2827 h
->root
.u
.def
.section
->owner
);
2829 /* This symbol is resolved locally. */
2830 outrel
.r_info
= htab
->r_info (0, R_X86_64_IRELATIVE
);
2831 outrel
.r_addend
= (h
->root
.u
.def
.value
2832 + h
->root
.u
.def
.section
->output_section
->vma
2833 + h
->root
.u
.def
.section
->output_offset
);
2837 outrel
.r_info
= htab
->r_info (h
->dynindx
, r_type
);
2838 outrel
.r_addend
= 0;
2841 /* Dynamic relocations are stored in
2842 1. .rela.ifunc section in PIC object.
2843 2. .rela.got section in dynamic executable.
2844 3. .rela.iplt section in static executable. */
2845 if (bfd_link_pic (info
))
2846 sreloc
= htab
->elf
.irelifunc
;
2847 else if (htab
->elf
.splt
!= NULL
)
2848 sreloc
= htab
->elf
.srelgot
;
2850 sreloc
= htab
->elf
.irelplt
;
2851 elf_append_rela (output_bfd
, sreloc
, &outrel
);
2853 /* If this reloc is against an external symbol, we
2854 do not want to fiddle with the addend. Otherwise,
2855 we need to include the symbol value so that it
2856 becomes an addend for the dynamic reloc. For an
2857 internal symbol, we have updated addend. */
2862 case R_X86_64_PC32_BND
:
2864 case R_X86_64_PLT32
:
2865 case R_X86_64_PLT32_BND
:
2870 resolved_to_zero
= (eh
!= NULL
2871 && UNDEFINED_WEAK_RESOLVED_TO_ZERO (info
,
2876 /* When generating a shared object, the relocations handled here are
2877 copied into the output file to be resolved at run time. */
2880 case R_X86_64_GOT32
:
2881 case R_X86_64_GOT64
:
2882 /* Relocation is to the entry for this symbol in the global
2884 case R_X86_64_GOTPCREL
:
2885 case R_X86_64_GOTPCRELX
:
2886 case R_X86_64_REX_GOTPCRELX
:
2887 case R_X86_64_GOTPCREL64
:
2888 /* Use global offset table entry as symbol value. */
2889 case R_X86_64_GOTPLT64
:
2890 /* This is obsolete and treated the same as GOT64. */
2891 base_got
= htab
->elf
.sgot
;
2893 if (htab
->elf
.sgot
== NULL
)
2896 relative_reloc
= FALSE
;
2901 off
= h
->got
.offset
;
2903 && h
->plt
.offset
!= (bfd_vma
)-1
2904 && off
== (bfd_vma
)-1)
2906 /* We can't use h->got.offset here to save
2907 state, or even just remember the offset, as
2908 finish_dynamic_symbol would use that as offset into
2910 bfd_vma plt_index
= (h
->plt
.offset
/ plt_entry_size
2911 - htab
->plt
.has_plt0
);
2912 off
= (plt_index
+ 3) * GOT_ENTRY_SIZE
;
2913 base_got
= htab
->elf
.sgotplt
;
2916 dyn
= htab
->elf
.dynamic_sections_created
;
2918 if (! WILL_CALL_FINISH_DYNAMIC_SYMBOL (dyn
, bfd_link_pic (info
), h
)
2919 || (bfd_link_pic (info
)
2920 && SYMBOL_REFERENCES_LOCAL (info
, h
))
2921 || (ELF_ST_VISIBILITY (h
->other
)
2922 && h
->root
.type
== bfd_link_hash_undefweak
))
2924 /* This is actually a static link, or it is a -Bsymbolic
2925 link and the symbol is defined locally, or the symbol
2926 was forced to be local because of a version file. We
2927 must initialize this entry in the global offset table.
2928 Since the offset must always be a multiple of 8, we
2929 use the least significant bit to record whether we
2930 have initialized it already.
2932 When doing a dynamic link, we create a .rela.got
2933 relocation entry to initialize the value. This is
2934 done in the finish_dynamic_symbol routine. */
2939 bfd_put_64 (output_bfd
, relocation
,
2940 base_got
->contents
+ off
);
2941 /* Note that this is harmless for the GOTPLT64 case,
2942 as -1 | 1 still is -1. */
2945 if (h
->dynindx
== -1
2947 && h
->root
.type
!= bfd_link_hash_undefweak
2948 && bfd_link_pic (info
))
2950 /* If this symbol isn't dynamic in PIC,
2951 generate R_X86_64_RELATIVE here. */
2952 eh
->no_finish_dynamic_symbol
= 1;
2953 relative_reloc
= TRUE
;
2958 unresolved_reloc
= FALSE
;
2962 if (local_got_offsets
== NULL
)
2965 off
= local_got_offsets
[r_symndx
];
2967 /* The offset must always be a multiple of 8. We use
2968 the least significant bit to record whether we have
2969 already generated the necessary reloc. */
2974 bfd_put_64 (output_bfd
, relocation
,
2975 base_got
->contents
+ off
);
2976 local_got_offsets
[r_symndx
] |= 1;
2978 if (bfd_link_pic (info
))
2979 relative_reloc
= TRUE
;
2986 Elf_Internal_Rela outrel
;
2988 /* We need to generate a R_X86_64_RELATIVE reloc
2989 for the dynamic linker. */
2990 s
= htab
->elf
.srelgot
;
2994 outrel
.r_offset
= (base_got
->output_section
->vma
2995 + base_got
->output_offset
2997 outrel
.r_info
= htab
->r_info (0, R_X86_64_RELATIVE
);
2998 outrel
.r_addend
= relocation
;
2999 elf_append_rela (output_bfd
, s
, &outrel
);
3002 if (off
>= (bfd_vma
) -2)
3005 relocation
= base_got
->output_section
->vma
3006 + base_got
->output_offset
+ off
;
3007 if (r_type
!= R_X86_64_GOTPCREL
3008 && r_type
!= R_X86_64_GOTPCRELX
3009 && r_type
!= R_X86_64_REX_GOTPCRELX
3010 && r_type
!= R_X86_64_GOTPCREL64
)
3011 relocation
-= htab
->elf
.sgotplt
->output_section
->vma
3012 - htab
->elf
.sgotplt
->output_offset
;
3016 case R_X86_64_GOTOFF64
:
3017 /* Relocation is relative to the start of the global offset
3020 /* Check to make sure it isn't a protected function or data
3021 symbol for shared library since it may not be local when
3022 used as function address or with copy relocation. We also
3023 need to make sure that a symbol is referenced locally. */
3024 if (bfd_link_pic (info
) && h
)
3026 if (!h
->def_regular
)
3030 switch (ELF_ST_VISIBILITY (h
->other
))
3033 v
= _("hidden symbol");
3036 v
= _("internal symbol");
3039 v
= _("protected symbol");
3047 /* xgettext:c-format */
3048 (_("%B: relocation R_X86_64_GOTOFF64 against undefined %s"
3049 " `%s' can not be used when making a shared object"),
3050 input_bfd
, v
, h
->root
.root
.string
);
3051 bfd_set_error (bfd_error_bad_value
);
3054 else if (!bfd_link_executable (info
)
3055 && !SYMBOL_REFERENCES_LOCAL (info
, h
)
3056 && (h
->type
== STT_FUNC
3057 || h
->type
== STT_OBJECT
)
3058 && ELF_ST_VISIBILITY (h
->other
) == STV_PROTECTED
)
3061 /* xgettext:c-format */
3062 (_("%B: relocation R_X86_64_GOTOFF64 against protected %s"
3063 " `%s' can not be used when making a shared object"),
3065 h
->type
== STT_FUNC
? "function" : "data",
3066 h
->root
.root
.string
);
3067 bfd_set_error (bfd_error_bad_value
);
3072 /* Note that sgot is not involved in this
3073 calculation. We always want the start of .got.plt. If we
3074 defined _GLOBAL_OFFSET_TABLE_ in a different way, as is
3075 permitted by the ABI, we might have to change this
3077 relocation
-= htab
->elf
.sgotplt
->output_section
->vma
3078 + htab
->elf
.sgotplt
->output_offset
;
3081 case R_X86_64_GOTPC32
:
3082 case R_X86_64_GOTPC64
:
3083 /* Use global offset table as symbol value. */
3084 relocation
= htab
->elf
.sgotplt
->output_section
->vma
3085 + htab
->elf
.sgotplt
->output_offset
;
3086 unresolved_reloc
= FALSE
;
3089 case R_X86_64_PLTOFF64
:
3090 /* Relocation is PLT entry relative to GOT. For local
3091 symbols it's the symbol itself relative to GOT. */
3093 /* See PLT32 handling. */
3094 && (h
->plt
.offset
!= (bfd_vma
) -1
3095 || eh
->plt_got
.offset
!= (bfd_vma
) -1)
3096 && htab
->elf
.splt
!= NULL
)
3098 if (eh
->plt_got
.offset
!= (bfd_vma
) -1)
3100 /* Use the GOT PLT. */
3101 resolved_plt
= htab
->plt_got
;
3102 plt_offset
= eh
->plt_got
.offset
;
3104 else if (htab
->plt_second
!= NULL
)
3106 resolved_plt
= htab
->plt_second
;
3107 plt_offset
= eh
->plt_second
.offset
;
3111 resolved_plt
= htab
->elf
.splt
;
3112 plt_offset
= h
->plt
.offset
;
3115 relocation
= (resolved_plt
->output_section
->vma
3116 + resolved_plt
->output_offset
3118 unresolved_reloc
= FALSE
;
3121 relocation
-= htab
->elf
.sgotplt
->output_section
->vma
3122 + htab
->elf
.sgotplt
->output_offset
;
3125 case R_X86_64_PLT32
:
3126 case R_X86_64_PLT32_BND
:
3127 /* Relocation is to the entry for this symbol in the
3128 procedure linkage table. */
3130 /* Resolve a PLT32 reloc against a local symbol directly,
3131 without using the procedure linkage table. */
3135 if ((h
->plt
.offset
== (bfd_vma
) -1
3136 && eh
->plt_got
.offset
== (bfd_vma
) -1)
3137 || htab
->elf
.splt
== NULL
)
3139 /* We didn't make a PLT entry for this symbol. This
3140 happens when statically linking PIC code, or when
3141 using -Bsymbolic. */
3145 if (h
->plt
.offset
!= (bfd_vma
) -1)
3147 if (htab
->plt_second
!= NULL
)
3149 resolved_plt
= htab
->plt_second
;
3150 plt_offset
= eh
->plt_second
.offset
;
3154 resolved_plt
= htab
->elf
.splt
;
3155 plt_offset
= h
->plt
.offset
;
3160 /* Use the GOT PLT. */
3161 resolved_plt
= htab
->plt_got
;
3162 plt_offset
= eh
->plt_got
.offset
;
3165 relocation
= (resolved_plt
->output_section
->vma
3166 + resolved_plt
->output_offset
3168 unresolved_reloc
= FALSE
;
3171 case R_X86_64_SIZE32
:
3172 case R_X86_64_SIZE64
:
3173 /* Set to symbol size. */
3174 relocation
= st_size
;
3180 case R_X86_64_PC32_BND
:
3181 /* Don't complain about -fPIC if the symbol is undefined when
3182 building executable unless it is unresolved weak symbol or
3183 -z nocopyreloc is used. */
3184 if ((input_section
->flags
& SEC_ALLOC
) != 0
3185 && (input_section
->flags
& SEC_READONLY
) != 0
3187 && ((bfd_link_executable (info
)
3188 && ((h
->root
.type
== bfd_link_hash_undefweak
3189 && !resolved_to_zero
)
3190 || ((info
->nocopyreloc
3191 || (eh
->def_protected
3192 && elf_has_no_copy_on_protected (h
->root
.u
.def
.section
->owner
)))
3194 && !(h
->root
.u
.def
.section
->flags
& SEC_CODE
))))
3195 || bfd_link_dll (info
)))
3197 bfd_boolean fail
= FALSE
;
3199 = ((r_type
== R_X86_64_PC32
3200 || r_type
== R_X86_64_PC32_BND
)
3201 && is_32bit_relative_branch (contents
, rel
->r_offset
));
3203 if (SYMBOL_REFERENCES_LOCAL (info
, h
))
3205 /* Symbol is referenced locally. Make sure it is
3206 defined locally or for a branch. */
3207 fail
= (!(h
->def_regular
|| ELF_COMMON_DEF_P (h
))
3210 else if (!(bfd_link_pie (info
)
3211 && (h
->needs_copy
|| eh
->needs_copy
)))
3213 /* Symbol doesn't need copy reloc and isn't referenced
3214 locally. We only allow branch to symbol with
3215 non-default visibility. */
3217 || ELF_ST_VISIBILITY (h
->other
) == STV_DEFAULT
);
3221 return elf_x86_64_need_pic (info
, input_bfd
, input_section
,
3222 h
, NULL
, NULL
, howto
);
3231 /* FIXME: The ABI says the linker should make sure the value is
3232 the same when it's zeroextended to 64 bit. */
3235 if ((input_section
->flags
& SEC_ALLOC
) == 0)
3238 /* Don't copy a pc-relative relocation into the output file
3239 if the symbol needs copy reloc or the symbol is undefined
3240 when building executable. Copy dynamic function pointer
3241 relocations. Don't generate dynamic relocations against
3242 resolved undefined weak symbols in PIE. */
3243 if ((bfd_link_pic (info
)
3244 && !(bfd_link_pie (info
)
3248 || h
->root
.type
== bfd_link_hash_undefined
)
3249 && (IS_X86_64_PCREL_TYPE (r_type
)
3250 || r_type
== R_X86_64_SIZE32
3251 || r_type
== R_X86_64_SIZE64
))
3253 || ((ELF_ST_VISIBILITY (h
->other
) == STV_DEFAULT
3254 && !resolved_to_zero
)
3255 || h
->root
.type
!= bfd_link_hash_undefweak
))
3256 && ((! IS_X86_64_PCREL_TYPE (r_type
)
3257 && r_type
!= R_X86_64_SIZE32
3258 && r_type
!= R_X86_64_SIZE64
)
3259 || ! SYMBOL_CALLS_LOCAL (info
, h
)))
3260 || (ELIMINATE_COPY_RELOCS
3261 && !bfd_link_pic (info
)
3265 || eh
->func_pointer_refcount
> 0
3266 || (h
->root
.type
== bfd_link_hash_undefweak
3267 && !resolved_to_zero
))
3268 && ((h
->def_dynamic
&& !h
->def_regular
)
3269 /* Undefined weak symbol is bound locally when
3271 || h
->root
.type
== bfd_link_hash_undefined
)))
3273 Elf_Internal_Rela outrel
;
3274 bfd_boolean skip
, relocate
;
3277 /* When generating a shared object, these relocations
3278 are copied into the output file to be resolved at run
3284 _bfd_elf_section_offset (output_bfd
, info
, input_section
,
3286 if (outrel
.r_offset
== (bfd_vma
) -1)
3288 else if (outrel
.r_offset
== (bfd_vma
) -2)
3289 skip
= TRUE
, relocate
= TRUE
;
3291 outrel
.r_offset
+= (input_section
->output_section
->vma
3292 + input_section
->output_offset
);
3295 memset (&outrel
, 0, sizeof outrel
);
3297 /* h->dynindx may be -1 if this symbol was marked to
3301 && (IS_X86_64_PCREL_TYPE (r_type
)
3302 || !(bfd_link_executable (info
)
3303 || SYMBOLIC_BIND (info
, h
))
3304 || ! h
->def_regular
))
3306 outrel
.r_info
= htab
->r_info (h
->dynindx
, r_type
);
3307 outrel
.r_addend
= rel
->r_addend
;
3311 /* This symbol is local, or marked to become local.
3312 When relocation overflow check is disabled, we
3313 convert R_X86_64_32 to dynamic R_X86_64_RELATIVE. */
3314 if (r_type
== htab
->pointer_r_type
3315 || (r_type
== R_X86_64_32
3316 && info
->no_reloc_overflow_check
))
3319 outrel
.r_info
= htab
->r_info (0, R_X86_64_RELATIVE
);
3320 outrel
.r_addend
= relocation
+ rel
->r_addend
;
3322 else if (r_type
== R_X86_64_64
3323 && !ABI_64_P (output_bfd
))
3326 outrel
.r_info
= htab
->r_info (0,
3327 R_X86_64_RELATIVE64
);
3328 outrel
.r_addend
= relocation
+ rel
->r_addend
;
3329 /* Check addend overflow. */
3330 if ((outrel
.r_addend
& 0x80000000)
3331 != (rel
->r_addend
& 0x80000000))
3334 int addend
= rel
->r_addend
;
3335 if (h
&& h
->root
.root
.string
)
3336 name
= h
->root
.root
.string
;
3338 name
= bfd_elf_sym_name (input_bfd
, symtab_hdr
,
3341 /* xgettext:c-format */
3342 (_("%B: addend %s%#x in relocation %s against "
3343 "symbol `%s' at %#Lx in section `%A' is "
3345 input_bfd
, addend
< 0 ? "-" : "", addend
,
3346 howto
->name
, name
, rel
->r_offset
, input_section
);
3347 bfd_set_error (bfd_error_bad_value
);
3355 if (bfd_is_abs_section (sec
))
3357 else if (sec
== NULL
|| sec
->owner
== NULL
)
3359 bfd_set_error (bfd_error_bad_value
);
3366 /* We are turning this relocation into one
3367 against a section symbol. It would be
3368 proper to subtract the symbol's value,
3369 osec->vma, from the emitted reloc addend,
3370 but ld.so expects buggy relocs. */
3371 osec
= sec
->output_section
;
3372 sindx
= elf_section_data (osec
)->dynindx
;
3375 asection
*oi
= htab
->elf
.text_index_section
;
3376 sindx
= elf_section_data (oi
)->dynindx
;
3378 BFD_ASSERT (sindx
!= 0);
3381 outrel
.r_info
= htab
->r_info (sindx
, r_type
);
3382 outrel
.r_addend
= relocation
+ rel
->r_addend
;
3386 sreloc
= elf_section_data (input_section
)->sreloc
;
3388 if (sreloc
== NULL
|| sreloc
->contents
== NULL
)
3390 r
= bfd_reloc_notsupported
;
3391 goto check_relocation_error
;
3394 elf_append_rela (output_bfd
, sreloc
, &outrel
);
3396 /* If this reloc is against an external symbol, we do
3397 not want to fiddle with the addend. Otherwise, we
3398 need to include the symbol value so that it becomes
3399 an addend for the dynamic reloc. */
3406 case R_X86_64_TLSGD
:
3407 case R_X86_64_GOTPC32_TLSDESC
:
3408 case R_X86_64_TLSDESC_CALL
:
3409 case R_X86_64_GOTTPOFF
:
3410 tls_type
= GOT_UNKNOWN
;
3411 if (h
== NULL
&& local_got_offsets
)
3412 tls_type
= elf_x86_local_got_tls_type (input_bfd
) [r_symndx
];
3414 tls_type
= elf_x86_hash_entry (h
)->tls_type
;
3416 if (! elf_x86_64_tls_transition (info
, input_bfd
,
3417 input_section
, contents
,
3418 symtab_hdr
, sym_hashes
,
3419 &r_type
, tls_type
, rel
,
3420 relend
, h
, r_symndx
, TRUE
))
3423 if (r_type
== R_X86_64_TPOFF32
)
3425 bfd_vma roff
= rel
->r_offset
;
3427 BFD_ASSERT (! unresolved_reloc
);
3429 if (ELF32_R_TYPE (rel
->r_info
) == R_X86_64_TLSGD
)
3431 /* GD->LE transition. For 64bit, change
3432 .byte 0x66; leaq foo@tlsgd(%rip), %rdi
3433 .word 0x6666; rex64; call __tls_get_addr@PLT
3435 .byte 0x66; leaq foo@tlsgd(%rip), %rdi
3437 call *__tls_get_addr@GOTPCREL(%rip)
3438 which may be converted to
3439 addr32 call __tls_get_addr
3442 leaq foo@tpoff(%rax), %rax
3444 leaq foo@tlsgd(%rip), %rdi
3445 .word 0x6666; rex64; call __tls_get_addr@PLT
3447 leaq foo@tlsgd(%rip), %rdi
3449 call *__tls_get_addr@GOTPCREL(%rip)
3450 which may be converted to
3451 addr32 call __tls_get_addr
3454 leaq foo@tpoff(%rax), %rax
3455 For largepic, change:
3456 leaq foo@tlsgd(%rip), %rdi
3457 movabsq $__tls_get_addr@pltoff, %rax
3462 leaq foo@tpoff(%rax), %rax
3463 nopw 0x0(%rax,%rax,1) */
3465 if (ABI_64_P (output_bfd
))
3467 if (contents
[roff
+ 5] == 0xb8)
3469 memcpy (contents
+ roff
- 3,
3470 "\x64\x48\x8b\x04\x25\0\0\0\0\x48\x8d\x80"
3471 "\0\0\0\0\x66\x0f\x1f\x44\0", 22);
3475 memcpy (contents
+ roff
- 4,
3476 "\x64\x48\x8b\x04\x25\0\0\0\0\x48\x8d\x80\0\0\0",
3480 memcpy (contents
+ roff
- 3,
3481 "\x64\x8b\x04\x25\0\0\0\0\x48\x8d\x80\0\0\0",
3483 bfd_put_32 (output_bfd
,
3484 elf_x86_64_tpoff (info
, relocation
),
3485 contents
+ roff
+ 8 + largepic
);
3486 /* Skip R_X86_64_PC32, R_X86_64_PLT32,
3487 R_X86_64_GOTPCRELX and R_X86_64_PLTOFF64. */
3492 else if (ELF32_R_TYPE (rel
->r_info
) == R_X86_64_GOTPC32_TLSDESC
)
3494 /* GDesc -> LE transition.
3495 It's originally something like:
3496 leaq x@tlsdesc(%rip), %rax
3499 movl $x@tpoff, %rax. */
3501 unsigned int val
, type
;
3503 type
= bfd_get_8 (input_bfd
, contents
+ roff
- 3);
3504 val
= bfd_get_8 (input_bfd
, contents
+ roff
- 1);
3505 bfd_put_8 (output_bfd
, 0x48 | ((type
>> 2) & 1),
3506 contents
+ roff
- 3);
3507 bfd_put_8 (output_bfd
, 0xc7, contents
+ roff
- 2);
3508 bfd_put_8 (output_bfd
, 0xc0 | ((val
>> 3) & 7),
3509 contents
+ roff
- 1);
3510 bfd_put_32 (output_bfd
,
3511 elf_x86_64_tpoff (info
, relocation
),
3515 else if (ELF32_R_TYPE (rel
->r_info
) == R_X86_64_TLSDESC_CALL
)
3517 /* GDesc -> LE transition.
3522 bfd_put_8 (output_bfd
, 0x66, contents
+ roff
);
3523 bfd_put_8 (output_bfd
, 0x90, contents
+ roff
+ 1);
3526 else if (ELF32_R_TYPE (rel
->r_info
) == R_X86_64_GOTTPOFF
)
3528 /* IE->LE transition:
3529 For 64bit, originally it can be one of:
3530 movq foo@gottpoff(%rip), %reg
3531 addq foo@gottpoff(%rip), %reg
3534 leaq foo(%reg), %reg
3536 For 32bit, originally it can be one of:
3537 movq foo@gottpoff(%rip), %reg
3538 addl foo@gottpoff(%rip), %reg
3541 leal foo(%reg), %reg
3544 unsigned int val
, type
, reg
;
3547 val
= bfd_get_8 (input_bfd
, contents
+ roff
- 3);
3550 type
= bfd_get_8 (input_bfd
, contents
+ roff
- 2);
3551 reg
= bfd_get_8 (input_bfd
, contents
+ roff
- 1);
3557 bfd_put_8 (output_bfd
, 0x49,
3558 contents
+ roff
- 3);
3559 else if (!ABI_64_P (output_bfd
) && val
== 0x44)
3560 bfd_put_8 (output_bfd
, 0x41,
3561 contents
+ roff
- 3);
3562 bfd_put_8 (output_bfd
, 0xc7,
3563 contents
+ roff
- 2);
3564 bfd_put_8 (output_bfd
, 0xc0 | reg
,
3565 contents
+ roff
- 1);
3569 /* addq/addl -> addq/addl - addressing with %rsp/%r12
3572 bfd_put_8 (output_bfd
, 0x49,
3573 contents
+ roff
- 3);
3574 else if (!ABI_64_P (output_bfd
) && val
== 0x44)
3575 bfd_put_8 (output_bfd
, 0x41,
3576 contents
+ roff
- 3);
3577 bfd_put_8 (output_bfd
, 0x81,
3578 contents
+ roff
- 2);
3579 bfd_put_8 (output_bfd
, 0xc0 | reg
,
3580 contents
+ roff
- 1);
3584 /* addq/addl -> leaq/leal */
3586 bfd_put_8 (output_bfd
, 0x4d,
3587 contents
+ roff
- 3);
3588 else if (!ABI_64_P (output_bfd
) && val
== 0x44)
3589 bfd_put_8 (output_bfd
, 0x45,
3590 contents
+ roff
- 3);
3591 bfd_put_8 (output_bfd
, 0x8d,
3592 contents
+ roff
- 2);
3593 bfd_put_8 (output_bfd
, 0x80 | reg
| (reg
<< 3),
3594 contents
+ roff
- 1);
3596 bfd_put_32 (output_bfd
,
3597 elf_x86_64_tpoff (info
, relocation
),
3605 if (htab
->elf
.sgot
== NULL
)
3610 off
= h
->got
.offset
;
3611 offplt
= elf_x86_hash_entry (h
)->tlsdesc_got
;
3615 if (local_got_offsets
== NULL
)
3618 off
= local_got_offsets
[r_symndx
];
3619 offplt
= local_tlsdesc_gotents
[r_symndx
];
3626 Elf_Internal_Rela outrel
;
3630 if (htab
->elf
.srelgot
== NULL
)
3633 indx
= h
&& h
->dynindx
!= -1 ? h
->dynindx
: 0;
3635 if (GOT_TLS_GDESC_P (tls_type
))
3637 outrel
.r_info
= htab
->r_info (indx
, R_X86_64_TLSDESC
);
3638 BFD_ASSERT (htab
->sgotplt_jump_table_size
+ offplt
3639 + 2 * GOT_ENTRY_SIZE
<= htab
->elf
.sgotplt
->size
);
3640 outrel
.r_offset
= (htab
->elf
.sgotplt
->output_section
->vma
3641 + htab
->elf
.sgotplt
->output_offset
3643 + htab
->sgotplt_jump_table_size
);
3644 sreloc
= htab
->elf
.srelplt
;
3646 outrel
.r_addend
= relocation
- _bfd_x86_elf_dtpoff_base (info
);
3648 outrel
.r_addend
= 0;
3649 elf_append_rela (output_bfd
, sreloc
, &outrel
);
3652 sreloc
= htab
->elf
.srelgot
;
3654 outrel
.r_offset
= (htab
->elf
.sgot
->output_section
->vma
3655 + htab
->elf
.sgot
->output_offset
+ off
);
3657 if (GOT_TLS_GD_P (tls_type
))
3658 dr_type
= R_X86_64_DTPMOD64
;
3659 else if (GOT_TLS_GDESC_P (tls_type
))
3662 dr_type
= R_X86_64_TPOFF64
;
3664 bfd_put_64 (output_bfd
, 0, htab
->elf
.sgot
->contents
+ off
);
3665 outrel
.r_addend
= 0;
3666 if ((dr_type
== R_X86_64_TPOFF64
3667 || dr_type
== R_X86_64_TLSDESC
) && indx
== 0)
3668 outrel
.r_addend
= relocation
- _bfd_x86_elf_dtpoff_base (info
);
3669 outrel
.r_info
= htab
->r_info (indx
, dr_type
);
3671 elf_append_rela (output_bfd
, sreloc
, &outrel
);
3673 if (GOT_TLS_GD_P (tls_type
))
3677 BFD_ASSERT (! unresolved_reloc
);
3678 bfd_put_64 (output_bfd
,
3679 relocation
- _bfd_x86_elf_dtpoff_base (info
),
3680 htab
->elf
.sgot
->contents
+ off
+ GOT_ENTRY_SIZE
);
3684 bfd_put_64 (output_bfd
, 0,
3685 htab
->elf
.sgot
->contents
+ off
+ GOT_ENTRY_SIZE
);
3686 outrel
.r_info
= htab
->r_info (indx
,
3688 outrel
.r_offset
+= GOT_ENTRY_SIZE
;
3689 elf_append_rela (output_bfd
, sreloc
,
3698 local_got_offsets
[r_symndx
] |= 1;
3701 if (off
>= (bfd_vma
) -2
3702 && ! GOT_TLS_GDESC_P (tls_type
))
3704 if (r_type
== ELF32_R_TYPE (rel
->r_info
))
3706 if (r_type
== R_X86_64_GOTPC32_TLSDESC
3707 || r_type
== R_X86_64_TLSDESC_CALL
)
3708 relocation
= htab
->elf
.sgotplt
->output_section
->vma
3709 + htab
->elf
.sgotplt
->output_offset
3710 + offplt
+ htab
->sgotplt_jump_table_size
;
3712 relocation
= htab
->elf
.sgot
->output_section
->vma
3713 + htab
->elf
.sgot
->output_offset
+ off
;
3714 unresolved_reloc
= FALSE
;
3718 bfd_vma roff
= rel
->r_offset
;
3720 if (ELF32_R_TYPE (rel
->r_info
) == R_X86_64_TLSGD
)
3722 /* GD->IE transition. For 64bit, change
3723 .byte 0x66; leaq foo@tlsgd(%rip), %rdi
3724 .word 0x6666; rex64; call __tls_get_addr@PLT
3726 .byte 0x66; leaq foo@tlsgd(%rip), %rdi
3728 call *__tls_get_addr@GOTPCREL(%rip
3729 which may be converted to
3730 addr32 call __tls_get_addr
3733 addq foo@gottpoff(%rip), %rax
3735 leaq foo@tlsgd(%rip), %rdi
3736 .word 0x6666; rex64; call __tls_get_addr@PLT
3738 leaq foo@tlsgd(%rip), %rdi
3740 call *__tls_get_addr@GOTPCREL(%rip)
3741 which may be converted to
3742 addr32 call __tls_get_addr
3745 addq foo@gottpoff(%rip), %rax
3746 For largepic, change:
3747 leaq foo@tlsgd(%rip), %rdi
3748 movabsq $__tls_get_addr@pltoff, %rax
3753 addq foo@gottpoff(%rax), %rax
3754 nopw 0x0(%rax,%rax,1) */
3756 if (ABI_64_P (output_bfd
))
3758 if (contents
[roff
+ 5] == 0xb8)
3760 memcpy (contents
+ roff
- 3,
3761 "\x64\x48\x8b\x04\x25\0\0\0\0\x48\x03\x05"
3762 "\0\0\0\0\x66\x0f\x1f\x44\0", 22);
3766 memcpy (contents
+ roff
- 4,
3767 "\x64\x48\x8b\x04\x25\0\0\0\0\x48\x03\x05\0\0\0",
3771 memcpy (contents
+ roff
- 3,
3772 "\x64\x8b\x04\x25\0\0\0\0\x48\x03\x05\0\0\0",
3775 relocation
= (htab
->elf
.sgot
->output_section
->vma
3776 + htab
->elf
.sgot
->output_offset
+ off
3779 - input_section
->output_section
->vma
3780 - input_section
->output_offset
3782 bfd_put_32 (output_bfd
, relocation
,
3783 contents
+ roff
+ 8 + largepic
);
3784 /* Skip R_X86_64_PLT32/R_X86_64_PLTOFF64. */
3789 else if (ELF32_R_TYPE (rel
->r_info
) == R_X86_64_GOTPC32_TLSDESC
)
3791 /* GDesc -> IE transition.
3792 It's originally something like:
3793 leaq x@tlsdesc(%rip), %rax
3796 movq x@gottpoff(%rip), %rax # before xchg %ax,%ax. */
3798 /* Now modify the instruction as appropriate. To
3799 turn a leaq into a movq in the form we use it, it
3800 suffices to change the second byte from 0x8d to
3802 bfd_put_8 (output_bfd
, 0x8b, contents
+ roff
- 2);
3804 bfd_put_32 (output_bfd
,
3805 htab
->elf
.sgot
->output_section
->vma
3806 + htab
->elf
.sgot
->output_offset
+ off
3808 - input_section
->output_section
->vma
3809 - input_section
->output_offset
3814 else if (ELF32_R_TYPE (rel
->r_info
) == R_X86_64_TLSDESC_CALL
)
3816 /* GDesc -> IE transition.
3823 bfd_put_8 (output_bfd
, 0x66, contents
+ roff
);
3824 bfd_put_8 (output_bfd
, 0x90, contents
+ roff
+ 1);
3832 case R_X86_64_TLSLD
:
3833 if (! elf_x86_64_tls_transition (info
, input_bfd
,
3834 input_section
, contents
,
3835 symtab_hdr
, sym_hashes
,
3836 &r_type
, GOT_UNKNOWN
, rel
,
3837 relend
, h
, r_symndx
, TRUE
))
3840 if (r_type
!= R_X86_64_TLSLD
)
3842 /* LD->LE transition:
3843 leaq foo@tlsld(%rip), %rdi
3844 call __tls_get_addr@PLT
3845 For 64bit, we change it into:
3846 .word 0x6666; .byte 0x66; movq %fs:0, %rax
3847 For 32bit, we change it into:
3848 nopl 0x0(%rax); movl %fs:0, %eax
3850 leaq foo@tlsld(%rip), %rdi;
3851 call *__tls_get_addr@GOTPCREL(%rip)
3852 which may be converted to
3853 addr32 call __tls_get_addr
3854 For 64bit, we change it into:
3855 .word 0x6666; .word 0x6666; movq %fs:0, %rax
3856 For 32bit, we change it into:
3857 nopw 0x0(%rax); movl %fs:0, %eax
3858 For largepic, change:
3859 leaq foo@tlsgd(%rip), %rdi
3860 movabsq $__tls_get_addr@pltoff, %rax
3864 data16 data16 data16 nopw %cs:0x0(%rax,%rax,1)
3867 BFD_ASSERT (r_type
== R_X86_64_TPOFF32
);
3868 if (ABI_64_P (output_bfd
))
3870 if (contents
[rel
->r_offset
+ 5] == 0xb8)
3871 memcpy (contents
+ rel
->r_offset
- 3,
3872 "\x66\x66\x66\x66\x2e\x0f\x1f\x84\0\0\0\0\0"
3873 "\x64\x48\x8b\x04\x25\0\0\0", 22);
3874 else if (contents
[rel
->r_offset
+ 4] == 0xff
3875 || contents
[rel
->r_offset
+ 4] == 0x67)
3876 memcpy (contents
+ rel
->r_offset
- 3,
3877 "\x66\x66\x66\x66\x64\x48\x8b\x04\x25\0\0\0",
3880 memcpy (contents
+ rel
->r_offset
- 3,
3881 "\x66\x66\x66\x64\x48\x8b\x04\x25\0\0\0", 12);
3885 if (contents
[rel
->r_offset
+ 4] == 0xff)
3886 memcpy (contents
+ rel
->r_offset
- 3,
3887 "\x66\x0f\x1f\x40\x00\x64\x8b\x04\x25\0\0\0",
3890 memcpy (contents
+ rel
->r_offset
- 3,
3891 "\x0f\x1f\x40\x00\x64\x8b\x04\x25\0\0\0", 12);
3893 /* Skip R_X86_64_PC32, R_X86_64_PLT32, R_X86_64_GOTPCRELX
3894 and R_X86_64_PLTOFF64. */
3900 if (htab
->elf
.sgot
== NULL
)
3903 off
= htab
->tls_ld_or_ldm_got
.offset
;
3908 Elf_Internal_Rela outrel
;
3910 if (htab
->elf
.srelgot
== NULL
)
3913 outrel
.r_offset
= (htab
->elf
.sgot
->output_section
->vma
3914 + htab
->elf
.sgot
->output_offset
+ off
);
3916 bfd_put_64 (output_bfd
, 0,
3917 htab
->elf
.sgot
->contents
+ off
);
3918 bfd_put_64 (output_bfd
, 0,
3919 htab
->elf
.sgot
->contents
+ off
+ GOT_ENTRY_SIZE
);
3920 outrel
.r_info
= htab
->r_info (0, R_X86_64_DTPMOD64
);
3921 outrel
.r_addend
= 0;
3922 elf_append_rela (output_bfd
, htab
->elf
.srelgot
,
3924 htab
->tls_ld_or_ldm_got
.offset
|= 1;
3926 relocation
= htab
->elf
.sgot
->output_section
->vma
3927 + htab
->elf
.sgot
->output_offset
+ off
;
3928 unresolved_reloc
= FALSE
;
3931 case R_X86_64_DTPOFF32
:
3932 if (!bfd_link_executable (info
)
3933 || (input_section
->flags
& SEC_CODE
) == 0)
3934 relocation
-= _bfd_x86_elf_dtpoff_base (info
);
3936 relocation
= elf_x86_64_tpoff (info
, relocation
);
3939 case R_X86_64_TPOFF32
:
3940 case R_X86_64_TPOFF64
:
3941 BFD_ASSERT (bfd_link_executable (info
));
3942 relocation
= elf_x86_64_tpoff (info
, relocation
);
3945 case R_X86_64_DTPOFF64
:
3946 BFD_ASSERT ((input_section
->flags
& SEC_CODE
) == 0);
3947 relocation
-= _bfd_x86_elf_dtpoff_base (info
);
3954 /* Dynamic relocs are not propagated for SEC_DEBUGGING sections
3955 because such sections are not SEC_ALLOC and thus ld.so will
3956 not process them. */
3957 if (unresolved_reloc
3958 && !((input_section
->flags
& SEC_DEBUGGING
) != 0
3960 && _bfd_elf_section_offset (output_bfd
, info
, input_section
,
3961 rel
->r_offset
) != (bfd_vma
) -1)
3966 sec
= h
->root
.u
.def
.section
;
3967 if ((info
->nocopyreloc
3968 || (eh
->def_protected
3969 && elf_has_no_copy_on_protected (h
->root
.u
.def
.section
->owner
)))
3970 && !(h
->root
.u
.def
.section
->flags
& SEC_CODE
))
3971 return elf_x86_64_need_pic (info
, input_bfd
, input_section
,
3972 h
, NULL
, NULL
, howto
);
3977 /* xgettext:c-format */
3978 (_("%B(%A+%#Lx): unresolvable %s relocation against symbol `%s'"),
3983 h
->root
.root
.string
);
3989 r
= _bfd_final_link_relocate (howto
, input_bfd
, input_section
,
3990 contents
, rel
->r_offset
,
3991 relocation
, rel
->r_addend
);
3993 check_relocation_error
:
3994 if (r
!= bfd_reloc_ok
)
3999 name
= h
->root
.root
.string
;
4002 name
= bfd_elf_string_from_elf_section (input_bfd
,
4003 symtab_hdr
->sh_link
,
4008 name
= bfd_section_name (input_bfd
, sec
);
4011 if (r
== bfd_reloc_overflow
)
4013 if (eh
!= NULL
&& eh
->converted_reloc
)
4015 info
->callbacks
->einfo
4016 (_("%F%P: failed to convert GOTPCREL relocation; relink with --no-relax\n"));
4019 (*info
->callbacks
->reloc_overflow
)
4020 (info
, (h
? &h
->root
: NULL
), name
, howto
->name
,
4021 (bfd_vma
) 0, input_bfd
, input_section
, rel
->r_offset
);
4026 /* xgettext:c-format */
4027 (_("%B(%A+%#Lx): reloc against `%s': error %d"),
4028 input_bfd
, input_section
,
4029 rel
->r_offset
, name
, (int) r
);
4040 Elf_Internal_Shdr
*rel_hdr
;
4041 size_t deleted
= rel
- wrel
;
4043 rel_hdr
= _bfd_elf_single_rel_hdr (input_section
->output_section
);
4044 rel_hdr
->sh_size
-= rel_hdr
->sh_entsize
* deleted
;
4045 if (rel_hdr
->sh_size
== 0)
4047 /* It is too late to remove an empty reloc section. Leave
4049 ??? What is wrong with an empty section??? */
4050 rel_hdr
->sh_size
= rel_hdr
->sh_entsize
;
4053 rel_hdr
= _bfd_elf_single_rel_hdr (input_section
);
4054 rel_hdr
->sh_size
-= rel_hdr
->sh_entsize
* deleted
;
4055 input_section
->reloc_count
-= deleted
;
4061 /* Finish up dynamic symbol handling. We set the contents of various
4062 dynamic sections here. */
4065 elf_x86_64_finish_dynamic_symbol (bfd
*output_bfd
,
4066 struct bfd_link_info
*info
,
4067 struct elf_link_hash_entry
*h
,
4068 Elf_Internal_Sym
*sym
)
4070 struct elf_x86_link_hash_table
*htab
;
4071 bfd_boolean use_plt_second
;
4072 struct elf_x86_link_hash_entry
*eh
;
4073 bfd_boolean local_undefweak
;
4075 htab
= elf_x86_hash_table (info
, X86_64_ELF_DATA
);
4079 /* Use the second PLT section only if there is .plt section. */
4080 use_plt_second
= htab
->elf
.splt
!= NULL
&& htab
->plt_second
!= NULL
;
4082 eh
= (struct elf_x86_link_hash_entry
*) h
;
4083 if (eh
->no_finish_dynamic_symbol
)
4086 /* We keep PLT/GOT entries without dynamic PLT/GOT relocations for
4087 resolved undefined weak symbols in executable so that their
4088 references have value 0 at run-time. */
4089 local_undefweak
= UNDEFINED_WEAK_RESOLVED_TO_ZERO (info
,
4094 if (h
->plt
.offset
!= (bfd_vma
) -1)
4097 bfd_vma got_offset
, plt_offset
;
4098 Elf_Internal_Rela rela
;
4100 asection
*plt
, *gotplt
, *relplt
, *resolved_plt
;
4101 const struct elf_backend_data
*bed
;
4102 bfd_vma plt_got_pcrel_offset
;
4104 /* When building a static executable, use .iplt, .igot.plt and
4105 .rela.iplt sections for STT_GNU_IFUNC symbols. */
4106 if (htab
->elf
.splt
!= NULL
)
4108 plt
= htab
->elf
.splt
;
4109 gotplt
= htab
->elf
.sgotplt
;
4110 relplt
= htab
->elf
.srelplt
;
4114 plt
= htab
->elf
.iplt
;
4115 gotplt
= htab
->elf
.igotplt
;
4116 relplt
= htab
->elf
.irelplt
;
4119 /* This symbol has an entry in the procedure linkage table. Set
4121 if ((h
->dynindx
== -1
4123 && !((h
->forced_local
|| bfd_link_executable (info
))
4125 && h
->type
== STT_GNU_IFUNC
))
4131 /* Get the index in the procedure linkage table which
4132 corresponds to this symbol. This is the index of this symbol
4133 in all the symbols for which we are making plt entries. The
4134 first entry in the procedure linkage table is reserved.
4136 Get the offset into the .got table of the entry that
4137 corresponds to this function. Each .got entry is GOT_ENTRY_SIZE
4138 bytes. The first three are reserved for the dynamic linker.
4140 For static executables, we don't reserve anything. */
4142 if (plt
== htab
->elf
.splt
)
4144 got_offset
= (h
->plt
.offset
/ htab
->plt
.plt_entry_size
4145 - htab
->plt
.has_plt0
);
4146 got_offset
= (got_offset
+ 3) * GOT_ENTRY_SIZE
;
4150 got_offset
= h
->plt
.offset
/ htab
->plt
.plt_entry_size
;
4151 got_offset
= got_offset
* GOT_ENTRY_SIZE
;
4154 /* Fill in the entry in the procedure linkage table. */
4155 memcpy (plt
->contents
+ h
->plt
.offset
, htab
->plt
.plt_entry
,
4156 htab
->plt
.plt_entry_size
);
4159 memcpy (htab
->plt_second
->contents
+ eh
->plt_second
.offset
,
4160 htab
->non_lazy_plt
->plt_entry
,
4161 htab
->non_lazy_plt
->plt_entry_size
);
4163 resolved_plt
= htab
->plt_second
;
4164 plt_offset
= eh
->plt_second
.offset
;
4169 plt_offset
= h
->plt
.offset
;
4172 /* Insert the relocation positions of the plt section. */
4174 /* Put offset the PC-relative instruction referring to the GOT entry,
4175 subtracting the size of that instruction. */
4176 plt_got_pcrel_offset
= (gotplt
->output_section
->vma
4177 + gotplt
->output_offset
4179 - resolved_plt
->output_section
->vma
4180 - resolved_plt
->output_offset
4182 - htab
->plt
.plt_got_insn_size
);
4184 /* Check PC-relative offset overflow in PLT entry. */
4185 if ((plt_got_pcrel_offset
+ 0x80000000) > 0xffffffff)
4186 /* xgettext:c-format */
4187 info
->callbacks
->einfo (_("%F%B: PC-relative offset overflow in PLT entry for `%s'\n"),
4188 output_bfd
, h
->root
.root
.string
);
4190 bfd_put_32 (output_bfd
, plt_got_pcrel_offset
,
4191 (resolved_plt
->contents
+ plt_offset
4192 + htab
->plt
.plt_got_offset
));
4194 /* Fill in the entry in the global offset table, initially this
4195 points to the second part of the PLT entry. Leave the entry
4196 as zero for undefined weak symbol in PIE. No PLT relocation
4197 against undefined weak symbol in PIE. */
4198 if (!local_undefweak
)
4200 if (htab
->plt
.has_plt0
)
4201 bfd_put_64 (output_bfd
, (plt
->output_section
->vma
4202 + plt
->output_offset
4204 + htab
->lazy_plt
->plt_lazy_offset
),
4205 gotplt
->contents
+ got_offset
);
4207 /* Fill in the entry in the .rela.plt section. */
4208 rela
.r_offset
= (gotplt
->output_section
->vma
4209 + gotplt
->output_offset
4211 if (h
->dynindx
== -1
4212 || ((bfd_link_executable (info
)
4213 || ELF_ST_VISIBILITY (h
->other
) != STV_DEFAULT
)
4215 && h
->type
== STT_GNU_IFUNC
))
4217 info
->callbacks
->minfo (_("Local IFUNC function `%s' in %B\n"),
4218 h
->root
.root
.string
,
4219 h
->root
.u
.def
.section
->owner
);
4221 /* If an STT_GNU_IFUNC symbol is locally defined, generate
4222 R_X86_64_IRELATIVE instead of R_X86_64_JUMP_SLOT. */
4223 rela
.r_info
= htab
->r_info (0, R_X86_64_IRELATIVE
);
4224 rela
.r_addend
= (h
->root
.u
.def
.value
4225 + h
->root
.u
.def
.section
->output_section
->vma
4226 + h
->root
.u
.def
.section
->output_offset
);
4227 /* R_X86_64_IRELATIVE comes last. */
4228 plt_index
= htab
->next_irelative_index
--;
4232 rela
.r_info
= htab
->r_info (h
->dynindx
, R_X86_64_JUMP_SLOT
);
4234 plt_index
= htab
->next_jump_slot_index
++;
4237 /* Don't fill the second and third slots in PLT entry for
4238 static executables nor without PLT0. */
4239 if (plt
== htab
->elf
.splt
&& htab
->plt
.has_plt0
)
4242 = h
->plt
.offset
+ htab
->lazy_plt
->plt_plt_insn_end
;
4244 /* Put relocation index. */
4245 bfd_put_32 (output_bfd
, plt_index
,
4246 (plt
->contents
+ h
->plt
.offset
4247 + htab
->lazy_plt
->plt_reloc_offset
));
4249 /* Put offset for jmp .PLT0 and check for overflow. We don't
4250 check relocation index for overflow since branch displacement
4251 will overflow first. */
4252 if (plt0_offset
> 0x80000000)
4253 /* xgettext:c-format */
4254 info
->callbacks
->einfo (_("%F%B: branch displacement overflow in PLT entry for `%s'\n"),
4255 output_bfd
, h
->root
.root
.string
);
4256 bfd_put_32 (output_bfd
, - plt0_offset
,
4257 (plt
->contents
+ h
->plt
.offset
4258 + htab
->lazy_plt
->plt_plt_offset
));
4261 bed
= get_elf_backend_data (output_bfd
);
4262 loc
= relplt
->contents
+ plt_index
* bed
->s
->sizeof_rela
;
4263 bed
->s
->swap_reloca_out (output_bfd
, &rela
, loc
);
4266 else if (eh
->plt_got
.offset
!= (bfd_vma
) -1)
4268 bfd_vma got_offset
, plt_offset
;
4269 asection
*plt
, *got
;
4270 bfd_boolean got_after_plt
;
4271 int32_t got_pcrel_offset
;
4273 /* Set the entry in the GOT procedure linkage table. */
4274 plt
= htab
->plt_got
;
4275 got
= htab
->elf
.sgot
;
4276 got_offset
= h
->got
.offset
;
4278 if (got_offset
== (bfd_vma
) -1
4279 || (h
->type
== STT_GNU_IFUNC
&& h
->def_regular
)
4284 /* Use the non-lazy PLT entry template for the GOT PLT since they
4285 are the identical. */
4286 /* Fill in the entry in the GOT procedure linkage table. */
4287 plt_offset
= eh
->plt_got
.offset
;
4288 memcpy (plt
->contents
+ plt_offset
,
4289 htab
->non_lazy_plt
->plt_entry
,
4290 htab
->non_lazy_plt
->plt_entry_size
);
4292 /* Put offset the PC-relative instruction referring to the GOT
4293 entry, subtracting the size of that instruction. */
4294 got_pcrel_offset
= (got
->output_section
->vma
4295 + got
->output_offset
4297 - plt
->output_section
->vma
4298 - plt
->output_offset
4300 - htab
->non_lazy_plt
->plt_got_insn_size
);
4302 /* Check PC-relative offset overflow in GOT PLT entry. */
4303 got_after_plt
= got
->output_section
->vma
> plt
->output_section
->vma
;
4304 if ((got_after_plt
&& got_pcrel_offset
< 0)
4305 || (!got_after_plt
&& got_pcrel_offset
> 0))
4306 /* xgettext:c-format */
4307 info
->callbacks
->einfo (_("%F%B: PC-relative offset overflow in GOT PLT entry for `%s'\n"),
4308 output_bfd
, h
->root
.root
.string
);
4310 bfd_put_32 (output_bfd
, got_pcrel_offset
,
4311 (plt
->contents
+ plt_offset
4312 + htab
->non_lazy_plt
->plt_got_offset
));
4315 if (!local_undefweak
4317 && (h
->plt
.offset
!= (bfd_vma
) -1
4318 || eh
->plt_got
.offset
!= (bfd_vma
) -1))
4320 /* Mark the symbol as undefined, rather than as defined in
4321 the .plt section. Leave the value if there were any
4322 relocations where pointer equality matters (this is a clue
4323 for the dynamic linker, to make function pointer
4324 comparisons work between an application and shared
4325 library), otherwise set it to zero. If a function is only
4326 called from a binary, there is no need to slow down
4327 shared libraries because of that. */
4328 sym
->st_shndx
= SHN_UNDEF
;
4329 if (!h
->pointer_equality_needed
)
4333 /* Don't generate dynamic GOT relocation against undefined weak
4334 symbol in executable. */
4335 if (h
->got
.offset
!= (bfd_vma
) -1
4336 && ! GOT_TLS_GD_ANY_P (elf_x86_hash_entry (h
)->tls_type
)
4337 && elf_x86_hash_entry (h
)->tls_type
!= GOT_TLS_IE
4338 && !local_undefweak
)
4340 Elf_Internal_Rela rela
;
4341 asection
*relgot
= htab
->elf
.srelgot
;
4343 /* This symbol has an entry in the global offset table. Set it
4345 if (htab
->elf
.sgot
== NULL
|| htab
->elf
.srelgot
== NULL
)
4348 rela
.r_offset
= (htab
->elf
.sgot
->output_section
->vma
4349 + htab
->elf
.sgot
->output_offset
4350 + (h
->got
.offset
&~ (bfd_vma
) 1));
4352 /* If this is a static link, or it is a -Bsymbolic link and the
4353 symbol is defined locally or was forced to be local because
4354 of a version file, we just want to emit a RELATIVE reloc.
4355 The entry in the global offset table will already have been
4356 initialized in the relocate_section function. */
4358 && h
->type
== STT_GNU_IFUNC
)
4360 if (h
->plt
.offset
== (bfd_vma
) -1)
4362 /* STT_GNU_IFUNC is referenced without PLT. */
4363 if (htab
->elf
.splt
== NULL
)
4365 /* use .rel[a].iplt section to store .got relocations
4366 in static executable. */
4367 relgot
= htab
->elf
.irelplt
;
4369 if (SYMBOL_REFERENCES_LOCAL (info
, h
))
4371 info
->callbacks
->minfo (_("Local IFUNC function `%s' in %B\n"),
4373 h
->root
.root
.string
,
4374 h
->root
.u
.def
.section
->owner
);
4376 rela
.r_info
= htab
->r_info (0,
4377 R_X86_64_IRELATIVE
);
4378 rela
.r_addend
= (h
->root
.u
.def
.value
4379 + h
->root
.u
.def
.section
->output_section
->vma
4380 + h
->root
.u
.def
.section
->output_offset
);
4385 else if (bfd_link_pic (info
))
4387 /* Generate R_X86_64_GLOB_DAT. */
4395 if (!h
->pointer_equality_needed
)
4398 /* For non-shared object, we can't use .got.plt, which
4399 contains the real function addres if we need pointer
4400 equality. We load the GOT entry with the PLT entry. */
4401 if (htab
->plt_second
!= NULL
)
4403 plt
= htab
->plt_second
;
4404 plt_offset
= eh
->plt_second
.offset
;
4408 plt
= htab
->elf
.splt
? htab
->elf
.splt
: htab
->elf
.iplt
;
4409 plt_offset
= h
->plt
.offset
;
4411 bfd_put_64 (output_bfd
, (plt
->output_section
->vma
4412 + plt
->output_offset
4414 htab
->elf
.sgot
->contents
+ h
->got
.offset
);
4418 else if (bfd_link_pic (info
)
4419 && SYMBOL_REFERENCES_LOCAL (info
, h
))
4421 if (!(h
->def_regular
|| ELF_COMMON_DEF_P (h
)))
4423 BFD_ASSERT((h
->got
.offset
& 1) != 0);
4424 rela
.r_info
= htab
->r_info (0, R_X86_64_RELATIVE
);
4425 rela
.r_addend
= (h
->root
.u
.def
.value
4426 + h
->root
.u
.def
.section
->output_section
->vma
4427 + h
->root
.u
.def
.section
->output_offset
);
4431 BFD_ASSERT((h
->got
.offset
& 1) == 0);
4433 bfd_put_64 (output_bfd
, (bfd_vma
) 0,
4434 htab
->elf
.sgot
->contents
+ h
->got
.offset
);
4435 rela
.r_info
= htab
->r_info (h
->dynindx
, R_X86_64_GLOB_DAT
);
4439 elf_append_rela (output_bfd
, relgot
, &rela
);
4444 Elf_Internal_Rela rela
;
4447 /* This symbol needs a copy reloc. Set it up. */
4449 if (h
->dynindx
== -1
4450 || (h
->root
.type
!= bfd_link_hash_defined
4451 && h
->root
.type
!= bfd_link_hash_defweak
)
4452 || htab
->elf
.srelbss
== NULL
4453 || htab
->elf
.sreldynrelro
== NULL
)
4456 rela
.r_offset
= (h
->root
.u
.def
.value
4457 + h
->root
.u
.def
.section
->output_section
->vma
4458 + h
->root
.u
.def
.section
->output_offset
);
4459 rela
.r_info
= htab
->r_info (h
->dynindx
, R_X86_64_COPY
);
4461 if (h
->root
.u
.def
.section
== htab
->elf
.sdynrelro
)
4462 s
= htab
->elf
.sreldynrelro
;
4464 s
= htab
->elf
.srelbss
;
4465 elf_append_rela (output_bfd
, s
, &rela
);
4471 /* Finish up local dynamic symbol handling. We set the contents of
4472 various dynamic sections here. */
4475 elf_x86_64_finish_local_dynamic_symbol (void **slot
, void *inf
)
4477 struct elf_link_hash_entry
*h
4478 = (struct elf_link_hash_entry
*) *slot
;
4479 struct bfd_link_info
*info
4480 = (struct bfd_link_info
*) inf
;
4482 return elf_x86_64_finish_dynamic_symbol (info
->output_bfd
,
4486 /* Finish up undefined weak symbol handling in PIE. Fill its PLT entry
4487 here since undefined weak symbol may not be dynamic and may not be
4488 called for elf_x86_64_finish_dynamic_symbol. */
4491 elf_x86_64_pie_finish_undefweak_symbol (struct bfd_hash_entry
*bh
,
4494 struct elf_link_hash_entry
*h
= (struct elf_link_hash_entry
*) bh
;
4495 struct bfd_link_info
*info
= (struct bfd_link_info
*) inf
;
4497 if (h
->root
.type
!= bfd_link_hash_undefweak
4498 || h
->dynindx
!= -1)
4501 return elf_x86_64_finish_dynamic_symbol (info
->output_bfd
,
4505 /* Used to decide how to sort relocs in an optimal manner for the
4506 dynamic linker, before writing them out. */
4508 static enum elf_reloc_type_class
4509 elf_x86_64_reloc_type_class (const struct bfd_link_info
*info
,
4510 const asection
*rel_sec ATTRIBUTE_UNUSED
,
4511 const Elf_Internal_Rela
*rela
)
4513 bfd
*abfd
= info
->output_bfd
;
4514 const struct elf_backend_data
*bed
= get_elf_backend_data (abfd
);
4515 struct elf_x86_link_hash_table
*htab
4516 = elf_x86_hash_table (info
, X86_64_ELF_DATA
);
4518 if (htab
->elf
.dynsym
!= NULL
4519 && htab
->elf
.dynsym
->contents
!= NULL
)
4521 /* Check relocation against STT_GNU_IFUNC symbol if there are
4523 unsigned long r_symndx
= htab
->r_sym (rela
->r_info
);
4524 if (r_symndx
!= STN_UNDEF
)
4526 Elf_Internal_Sym sym
;
4527 if (!bed
->s
->swap_symbol_in (abfd
,
4528 (htab
->elf
.dynsym
->contents
4529 + r_symndx
* bed
->s
->sizeof_sym
),
4533 if (ELF_ST_TYPE (sym
.st_info
) == STT_GNU_IFUNC
)
4534 return reloc_class_ifunc
;
4538 switch ((int) ELF32_R_TYPE (rela
->r_info
))
4540 case R_X86_64_IRELATIVE
:
4541 return reloc_class_ifunc
;
4542 case R_X86_64_RELATIVE
:
4543 case R_X86_64_RELATIVE64
:
4544 return reloc_class_relative
;
4545 case R_X86_64_JUMP_SLOT
:
4546 return reloc_class_plt
;
4548 return reloc_class_copy
;
4550 return reloc_class_normal
;
4554 /* Finish up the dynamic sections. */
4557 elf_x86_64_finish_dynamic_sections (bfd
*output_bfd
,
4558 struct bfd_link_info
*info
)
4560 struct elf_x86_link_hash_table
*htab
;
4564 htab
= elf_x86_hash_table (info
, X86_64_ELF_DATA
);
4568 dynobj
= htab
->elf
.dynobj
;
4569 sdyn
= bfd_get_linker_section (dynobj
, ".dynamic");
4571 if (htab
->elf
.dynamic_sections_created
)
4573 bfd_byte
*dyncon
, *dynconend
;
4574 const struct elf_backend_data
*bed
;
4575 bfd_size_type sizeof_dyn
;
4577 if (sdyn
== NULL
|| htab
->elf
.sgot
== NULL
)
4580 bed
= get_elf_backend_data (dynobj
);
4581 sizeof_dyn
= bed
->s
->sizeof_dyn
;
4582 dyncon
= sdyn
->contents
;
4583 dynconend
= sdyn
->contents
+ sdyn
->size
;
4584 for (; dyncon
< dynconend
; dyncon
+= sizeof_dyn
)
4586 Elf_Internal_Dyn dyn
;
4589 (*bed
->s
->swap_dyn_in
) (dynobj
, dyncon
, &dyn
);
4597 s
= htab
->elf
.sgotplt
;
4598 dyn
.d_un
.d_ptr
= s
->output_section
->vma
+ s
->output_offset
;
4602 dyn
.d_un
.d_ptr
= htab
->elf
.srelplt
->output_section
->vma
;
4606 s
= htab
->elf
.srelplt
->output_section
;
4607 dyn
.d_un
.d_val
= s
->size
;
4610 case DT_TLSDESC_PLT
:
4612 dyn
.d_un
.d_ptr
= s
->output_section
->vma
+ s
->output_offset
4613 + htab
->tlsdesc_plt
;
4616 case DT_TLSDESC_GOT
:
4618 dyn
.d_un
.d_ptr
= s
->output_section
->vma
+ s
->output_offset
4619 + htab
->tlsdesc_got
;
4623 (*bed
->s
->swap_dyn_out
) (output_bfd
, &dyn
, dyncon
);
4626 if (htab
->elf
.splt
&& htab
->elf
.splt
->size
> 0)
4628 elf_section_data (htab
->elf
.splt
->output_section
)
4629 ->this_hdr
.sh_entsize
= htab
->plt
.plt_entry_size
;
4631 if (htab
->plt
.has_plt0
)
4633 /* Fill in the special first entry in the procedure linkage
4635 memcpy (htab
->elf
.splt
->contents
,
4636 htab
->lazy_plt
->plt0_entry
,
4637 htab
->lazy_plt
->plt0_entry_size
);
4638 /* Add offset for pushq GOT+8(%rip), since the instruction
4639 uses 6 bytes subtract this value. */
4640 bfd_put_32 (output_bfd
,
4641 (htab
->elf
.sgotplt
->output_section
->vma
4642 + htab
->elf
.sgotplt
->output_offset
4644 - htab
->elf
.splt
->output_section
->vma
4645 - htab
->elf
.splt
->output_offset
4647 (htab
->elf
.splt
->contents
4648 + htab
->lazy_plt
->plt0_got1_offset
));
4649 /* Add offset for the PC-relative instruction accessing
4650 GOT+16, subtracting the offset to the end of that
4652 bfd_put_32 (output_bfd
,
4653 (htab
->elf
.sgotplt
->output_section
->vma
4654 + htab
->elf
.sgotplt
->output_offset
4656 - htab
->elf
.splt
->output_section
->vma
4657 - htab
->elf
.splt
->output_offset
4658 - htab
->lazy_plt
->plt0_got2_insn_end
),
4659 (htab
->elf
.splt
->contents
4660 + htab
->lazy_plt
->plt0_got2_offset
));
4662 if (htab
->tlsdesc_plt
)
4664 bfd_put_64 (output_bfd
, (bfd_vma
) 0,
4665 htab
->elf
.sgot
->contents
+ htab
->tlsdesc_got
);
4667 memcpy (htab
->elf
.splt
->contents
+ htab
->tlsdesc_plt
,
4668 htab
->lazy_plt
->plt0_entry
,
4669 htab
->lazy_plt
->plt0_entry_size
);
4671 /* Add offset for pushq GOT+8(%rip), since the
4672 instruction uses 6 bytes subtract this value. */
4673 bfd_put_32 (output_bfd
,
4674 (htab
->elf
.sgotplt
->output_section
->vma
4675 + htab
->elf
.sgotplt
->output_offset
4677 - htab
->elf
.splt
->output_section
->vma
4678 - htab
->elf
.splt
->output_offset
4681 (htab
->elf
.splt
->contents
4683 + htab
->lazy_plt
->plt0_got1_offset
));
4684 /* Add offset for the PC-relative instruction accessing
4685 GOT+TDG, where TDG stands for htab->tlsdesc_got,
4686 subtracting the offset to the end of that
4688 bfd_put_32 (output_bfd
,
4689 (htab
->elf
.sgot
->output_section
->vma
4690 + htab
->elf
.sgot
->output_offset
4692 - htab
->elf
.splt
->output_section
->vma
4693 - htab
->elf
.splt
->output_offset
4695 - htab
->lazy_plt
->plt0_got2_insn_end
),
4696 (htab
->elf
.splt
->contents
4698 + htab
->lazy_plt
->plt0_got2_offset
));
4703 if (htab
->plt_got
!= NULL
&& htab
->plt_got
->size
> 0)
4704 elf_section_data (htab
->plt_got
->output_section
)
4705 ->this_hdr
.sh_entsize
= htab
->non_lazy_plt
->plt_entry_size
;
4707 if (htab
->plt_second
!= NULL
&& htab
->plt_second
->size
> 0)
4708 elf_section_data (htab
->plt_second
->output_section
)
4709 ->this_hdr
.sh_entsize
= htab
->non_lazy_plt
->plt_entry_size
;
4712 /* GOT is always created in setup_gnu_properties. But it may not be
4714 if (htab
->elf
.sgotplt
&& htab
->elf
.sgotplt
->size
> 0)
4716 if (bfd_is_abs_section (htab
->elf
.sgotplt
->output_section
))
4719 (_("discarded output section: `%A'"), htab
->elf
.sgotplt
);
4723 /* Set the first entry in the global offset table to the address of
4724 the dynamic section. */
4726 bfd_put_64 (output_bfd
, (bfd_vma
) 0, htab
->elf
.sgotplt
->contents
);
4728 bfd_put_64 (output_bfd
,
4729 sdyn
->output_section
->vma
+ sdyn
->output_offset
,
4730 htab
->elf
.sgotplt
->contents
);
4731 /* Write GOT[1] and GOT[2], needed for the dynamic linker. */
4732 bfd_put_64 (output_bfd
, (bfd_vma
) 0,
4733 htab
->elf
.sgotplt
->contents
+ GOT_ENTRY_SIZE
);
4734 bfd_put_64 (output_bfd
, (bfd_vma
) 0,
4735 htab
->elf
.sgotplt
->contents
+ GOT_ENTRY_SIZE
*2);
4737 elf_section_data (htab
->elf
.sgotplt
->output_section
)->this_hdr
.sh_entsize
4741 /* Adjust .eh_frame for .plt section. */
4742 if (htab
->plt_eh_frame
!= NULL
4743 && htab
->plt_eh_frame
->contents
!= NULL
)
4745 if (htab
->elf
.splt
!= NULL
4746 && htab
->elf
.splt
->size
!= 0
4747 && (htab
->elf
.splt
->flags
& SEC_EXCLUDE
) == 0
4748 && htab
->elf
.splt
->output_section
!= NULL
4749 && htab
->plt_eh_frame
->output_section
!= NULL
)
4751 bfd_vma plt_start
= htab
->elf
.splt
->output_section
->vma
;
4752 bfd_vma eh_frame_start
= htab
->plt_eh_frame
->output_section
->vma
4753 + htab
->plt_eh_frame
->output_offset
4754 + PLT_FDE_START_OFFSET
;
4755 bfd_put_signed_32 (dynobj
, plt_start
- eh_frame_start
,
4756 htab
->plt_eh_frame
->contents
4757 + PLT_FDE_START_OFFSET
);
4759 if (htab
->plt_eh_frame
->sec_info_type
== SEC_INFO_TYPE_EH_FRAME
)
4761 if (! _bfd_elf_write_section_eh_frame (output_bfd
, info
,
4763 htab
->plt_eh_frame
->contents
))
4768 /* Adjust .eh_frame for .plt.got section. */
4769 if (htab
->plt_got_eh_frame
!= NULL
4770 && htab
->plt_got_eh_frame
->contents
!= NULL
)
4772 if (htab
->plt_got
!= NULL
4773 && htab
->plt_got
->size
!= 0
4774 && (htab
->plt_got
->flags
& SEC_EXCLUDE
) == 0
4775 && htab
->plt_got
->output_section
!= NULL
4776 && htab
->plt_got_eh_frame
->output_section
!= NULL
)
4778 bfd_vma plt_start
= htab
->plt_got
->output_section
->vma
;
4779 bfd_vma eh_frame_start
= htab
->plt_got_eh_frame
->output_section
->vma
4780 + htab
->plt_got_eh_frame
->output_offset
4781 + PLT_FDE_START_OFFSET
;
4782 bfd_put_signed_32 (dynobj
, plt_start
- eh_frame_start
,
4783 htab
->plt_got_eh_frame
->contents
4784 + PLT_FDE_START_OFFSET
);
4786 if (htab
->plt_got_eh_frame
->sec_info_type
== SEC_INFO_TYPE_EH_FRAME
)
4788 if (! _bfd_elf_write_section_eh_frame (output_bfd
, info
,
4789 htab
->plt_got_eh_frame
,
4790 htab
->plt_got_eh_frame
->contents
))
4795 /* Adjust .eh_frame for the second PLT section. */
4796 if (htab
->plt_second_eh_frame
!= NULL
4797 && htab
->plt_second_eh_frame
->contents
!= NULL
)
4799 if (htab
->plt_second
!= NULL
4800 && htab
->plt_second
->size
!= 0
4801 && (htab
->plt_second
->flags
& SEC_EXCLUDE
) == 0
4802 && htab
->plt_second
->output_section
!= NULL
4803 && htab
->plt_second_eh_frame
->output_section
!= NULL
)
4805 bfd_vma plt_start
= htab
->plt_second
->output_section
->vma
;
4806 bfd_vma eh_frame_start
4807 = (htab
->plt_second_eh_frame
->output_section
->vma
4808 + htab
->plt_second_eh_frame
->output_offset
4809 + PLT_FDE_START_OFFSET
);
4810 bfd_put_signed_32 (dynobj
, plt_start
- eh_frame_start
,
4811 htab
->plt_second_eh_frame
->contents
4812 + PLT_FDE_START_OFFSET
);
4814 if (htab
->plt_second_eh_frame
->sec_info_type
4815 == SEC_INFO_TYPE_EH_FRAME
)
4817 if (! _bfd_elf_write_section_eh_frame (output_bfd
, info
,
4818 htab
->plt_second_eh_frame
,
4819 htab
->plt_second_eh_frame
->contents
))
4824 if (htab
->elf
.sgot
&& htab
->elf
.sgot
->size
> 0)
4825 elf_section_data (htab
->elf
.sgot
->output_section
)->this_hdr
.sh_entsize
4828 /* Fill PLT entries for undefined weak symbols in PIE. */
4829 if (bfd_link_pie (info
))
4830 bfd_hash_traverse (&info
->hash
->table
,
4831 elf_x86_64_pie_finish_undefweak_symbol
,
4837 /* Fill PLT/GOT entries and allocate dynamic relocations for local
4838 STT_GNU_IFUNC symbols, which aren't in the ELF linker hash table.
4839 It has to be done before elf_link_sort_relocs is called so that
4840 dynamic relocations are properly sorted. */
4843 elf_x86_64_output_arch_local_syms
4844 (bfd
*output_bfd ATTRIBUTE_UNUSED
,
4845 struct bfd_link_info
*info
,
4846 void *flaginfo ATTRIBUTE_UNUSED
,
4847 int (*func
) (void *, const char *,
4850 struct elf_link_hash_entry
*) ATTRIBUTE_UNUSED
)
4852 struct elf_x86_link_hash_table
*htab
4853 = elf_x86_hash_table (info
, X86_64_ELF_DATA
);
4857 /* Fill PLT and GOT entries for local STT_GNU_IFUNC symbols. */
4858 htab_traverse (htab
->loc_hash_table
,
4859 elf_x86_64_finish_local_dynamic_symbol
,
4865 /* Forward declaration. */
4866 static const struct elf_x86_lazy_plt_layout elf_x86_64_nacl_plt
;
4868 /* Similar to _bfd_elf_get_synthetic_symtab. Support PLTs with all
4869 dynamic relocations. */
4872 elf_x86_64_get_synthetic_symtab (bfd
*abfd
,
4873 long symcount ATTRIBUTE_UNUSED
,
4874 asymbol
**syms ATTRIBUTE_UNUSED
,
4881 bfd_byte
*plt_contents
;
4883 const struct elf_x86_lazy_plt_layout
*lazy_plt
;
4884 const struct elf_x86_non_lazy_plt_layout
*non_lazy_plt
;
4885 const struct elf_x86_lazy_plt_layout
*lazy_bnd_plt
;
4886 const struct elf_x86_non_lazy_plt_layout
*non_lazy_bnd_plt
;
4887 const struct elf_x86_lazy_plt_layout
*lazy_ibt_plt
;
4888 const struct elf_x86_non_lazy_plt_layout
*non_lazy_ibt_plt
;
4890 enum elf_x86_plt_type plt_type
;
4891 struct elf_x86_plt plts
[] =
4893 { ".plt", NULL
, NULL
, plt_unknown
, 0, 0, 0, 0 },
4894 { ".plt.got", NULL
, NULL
, plt_non_lazy
, 0, 0, 0, 0 },
4895 { ".plt.sec", NULL
, NULL
, plt_second
, 0, 0, 0, 0 },
4896 { ".plt.bnd", NULL
, NULL
, plt_second
, 0, 0, 0, 0 },
4897 { NULL
, NULL
, NULL
, plt_non_lazy
, 0, 0, 0, 0 }
4902 if ((abfd
->flags
& (DYNAMIC
| EXEC_P
)) == 0)
4905 if (dynsymcount
<= 0)
4908 relsize
= bfd_get_dynamic_reloc_upper_bound (abfd
);
4912 if (get_elf_x86_64_backend_data (abfd
)->os
== is_normal
)
4914 lazy_plt
= &elf_x86_64_lazy_plt
;
4915 non_lazy_plt
= &elf_x86_64_non_lazy_plt
;
4916 lazy_bnd_plt
= &elf_x86_64_lazy_bnd_plt
;
4917 non_lazy_bnd_plt
= &elf_x86_64_non_lazy_bnd_plt
;
4918 if (ABI_64_P (abfd
))
4920 lazy_ibt_plt
= &elf_x86_64_lazy_ibt_plt
;
4921 non_lazy_ibt_plt
= &elf_x86_64_non_lazy_ibt_plt
;
4925 lazy_ibt_plt
= &elf_x32_lazy_ibt_plt
;
4926 non_lazy_ibt_plt
= &elf_x32_non_lazy_ibt_plt
;
4931 lazy_plt
= &elf_x86_64_nacl_plt
;
4932 non_lazy_plt
= NULL
;
4933 lazy_bnd_plt
= NULL
;
4934 non_lazy_bnd_plt
= NULL
;
4935 lazy_ibt_plt
= NULL
;
4936 non_lazy_ibt_plt
= NULL
;
4940 for (j
= 0; plts
[j
].name
!= NULL
; j
++)
4942 plt
= bfd_get_section_by_name (abfd
, plts
[j
].name
);
4943 if (plt
== NULL
|| plt
->size
== 0)
4946 /* Get the PLT section contents. */
4947 plt_contents
= (bfd_byte
*) bfd_malloc (plt
->size
);
4948 if (plt_contents
== NULL
)
4950 if (!bfd_get_section_contents (abfd
, (asection
*) plt
,
4951 plt_contents
, 0, plt
->size
))
4953 free (plt_contents
);
4957 /* Check what kind of PLT it is. */
4958 plt_type
= plt_unknown
;
4959 if (plts
[j
].type
== plt_unknown
4960 && (plt
->size
>= (lazy_plt
->plt_entry_size
4961 + lazy_plt
->plt_entry_size
)))
4963 /* Match lazy PLT first. Need to check the first two
4965 if ((memcmp (plt_contents
, lazy_plt
->plt0_entry
,
4966 lazy_plt
->plt0_got1_offset
) == 0)
4967 && (memcmp (plt_contents
+ 6, lazy_plt
->plt0_entry
+ 6,
4969 plt_type
= plt_lazy
;
4970 else if (lazy_bnd_plt
!= NULL
4971 && (memcmp (plt_contents
, lazy_bnd_plt
->plt0_entry
,
4972 lazy_bnd_plt
->plt0_got1_offset
) == 0)
4973 && (memcmp (plt_contents
+ 6,
4974 lazy_bnd_plt
->plt0_entry
+ 6, 3) == 0))
4976 plt_type
= plt_lazy
| plt_second
;
4977 /* The fist entry in the lazy IBT PLT is the same as the
4979 if ((memcmp (plt_contents
+ lazy_ibt_plt
->plt_entry_size
,
4980 lazy_ibt_plt
->plt_entry
,
4981 lazy_ibt_plt
->plt_got_offset
) == 0))
4982 lazy_plt
= lazy_ibt_plt
;
4984 lazy_plt
= lazy_bnd_plt
;
4988 if (non_lazy_plt
!= NULL
4989 && (plt_type
== plt_unknown
|| plt_type
== plt_non_lazy
)
4990 && plt
->size
>= non_lazy_plt
->plt_entry_size
)
4992 /* Match non-lazy PLT. */
4993 if (memcmp (plt_contents
, non_lazy_plt
->plt_entry
,
4994 non_lazy_plt
->plt_got_offset
) == 0)
4995 plt_type
= plt_non_lazy
;
4998 if (plt_type
== plt_unknown
|| plt_type
== plt_second
)
5000 if (non_lazy_bnd_plt
!= NULL
5001 && plt
->size
>= non_lazy_bnd_plt
->plt_entry_size
5002 && (memcmp (plt_contents
, non_lazy_bnd_plt
->plt_entry
,
5003 non_lazy_bnd_plt
->plt_got_offset
) == 0))
5005 /* Match BND PLT. */
5006 plt_type
= plt_second
;
5007 non_lazy_plt
= non_lazy_bnd_plt
;
5009 else if (non_lazy_ibt_plt
!= NULL
5010 && plt
->size
>= non_lazy_ibt_plt
->plt_entry_size
5011 && (memcmp (plt_contents
,
5012 non_lazy_ibt_plt
->plt_entry
,
5013 non_lazy_ibt_plt
->plt_got_offset
) == 0))
5015 /* Match IBT PLT. */
5016 plt_type
= plt_second
;
5017 non_lazy_plt
= non_lazy_ibt_plt
;
5021 if (plt_type
== plt_unknown
)
5023 free (plt_contents
);
5028 plts
[j
].type
= plt_type
;
5030 if ((plt_type
& plt_lazy
))
5032 plts
[j
].plt_got_offset
= lazy_plt
->plt_got_offset
;
5033 plts
[j
].plt_got_insn_size
= lazy_plt
->plt_got_insn_size
;
5034 plts
[j
].plt_entry_size
= lazy_plt
->plt_entry_size
;
5035 /* Skip PLT0 in lazy PLT. */
5040 plts
[j
].plt_got_offset
= non_lazy_plt
->plt_got_offset
;
5041 plts
[j
].plt_got_insn_size
= non_lazy_plt
->plt_got_insn_size
;
5042 plts
[j
].plt_entry_size
= non_lazy_plt
->plt_entry_size
;
5046 /* Skip lazy PLT when the second PLT is used. */
5047 if (plt_type
== (plt_lazy
| plt_second
))
5051 n
= plt
->size
/ plts
[j
].plt_entry_size
;
5056 plts
[j
].contents
= plt_contents
;
5059 return _bfd_x86_elf_get_synthetic_symtab (abfd
, count
, relsize
,
5060 (bfd_vma
) 0, plts
, dynsyms
,
5064 /* Handle an x86-64 specific section when reading an object file. This
5065 is called when elfcode.h finds a section with an unknown type. */
5068 elf_x86_64_section_from_shdr (bfd
*abfd
, Elf_Internal_Shdr
*hdr
,
5069 const char *name
, int shindex
)
5071 if (hdr
->sh_type
!= SHT_X86_64_UNWIND
)
5074 if (! _bfd_elf_make_section_from_shdr (abfd
, hdr
, name
, shindex
))
5080 /* Hook called by the linker routine which adds symbols from an object
5081 file. We use it to put SHN_X86_64_LCOMMON items in .lbss, instead
5085 elf_x86_64_add_symbol_hook (bfd
*abfd
,
5086 struct bfd_link_info
*info ATTRIBUTE_UNUSED
,
5087 Elf_Internal_Sym
*sym
,
5088 const char **namep ATTRIBUTE_UNUSED
,
5089 flagword
*flagsp ATTRIBUTE_UNUSED
,
5095 switch (sym
->st_shndx
)
5097 case SHN_X86_64_LCOMMON
:
5098 lcomm
= bfd_get_section_by_name (abfd
, "LARGE_COMMON");
5101 lcomm
= bfd_make_section_with_flags (abfd
,
5105 | SEC_LINKER_CREATED
));
5108 elf_section_flags (lcomm
) |= SHF_X86_64_LARGE
;
5111 *valp
= sym
->st_size
;
5119 /* Given a BFD section, try to locate the corresponding ELF section
5123 elf_x86_64_elf_section_from_bfd_section (bfd
*abfd ATTRIBUTE_UNUSED
,
5124 asection
*sec
, int *index_return
)
5126 if (sec
== &_bfd_elf_large_com_section
)
5128 *index_return
= SHN_X86_64_LCOMMON
;
5134 /* Process a symbol. */
5137 elf_x86_64_symbol_processing (bfd
*abfd ATTRIBUTE_UNUSED
,
5140 elf_symbol_type
*elfsym
= (elf_symbol_type
*) asym
;
5142 switch (elfsym
->internal_elf_sym
.st_shndx
)
5144 case SHN_X86_64_LCOMMON
:
5145 asym
->section
= &_bfd_elf_large_com_section
;
5146 asym
->value
= elfsym
->internal_elf_sym
.st_size
;
5147 /* Common symbol doesn't set BSF_GLOBAL. */
5148 asym
->flags
&= ~BSF_GLOBAL
;
5154 elf_x86_64_common_definition (Elf_Internal_Sym
*sym
)
5156 return (sym
->st_shndx
== SHN_COMMON
5157 || sym
->st_shndx
== SHN_X86_64_LCOMMON
);
5161 elf_x86_64_common_section_index (asection
*sec
)
5163 if ((elf_section_flags (sec
) & SHF_X86_64_LARGE
) == 0)
5166 return SHN_X86_64_LCOMMON
;
5170 elf_x86_64_common_section (asection
*sec
)
5172 if ((elf_section_flags (sec
) & SHF_X86_64_LARGE
) == 0)
5173 return bfd_com_section_ptr
;
5175 return &_bfd_elf_large_com_section
;
5179 elf_x86_64_merge_symbol (struct elf_link_hash_entry
*h
,
5180 const Elf_Internal_Sym
*sym
,
5185 const asection
*oldsec
)
5187 /* A normal common symbol and a large common symbol result in a
5188 normal common symbol. We turn the large common symbol into a
5191 && h
->root
.type
== bfd_link_hash_common
5193 && bfd_is_com_section (*psec
)
5196 if (sym
->st_shndx
== SHN_COMMON
5197 && (elf_section_flags (oldsec
) & SHF_X86_64_LARGE
) != 0)
5199 h
->root
.u
.c
.p
->section
5200 = bfd_make_section_old_way (oldbfd
, "COMMON");
5201 h
->root
.u
.c
.p
->section
->flags
= SEC_ALLOC
;
5203 else if (sym
->st_shndx
== SHN_X86_64_LCOMMON
5204 && (elf_section_flags (oldsec
) & SHF_X86_64_LARGE
) == 0)
5205 *psec
= bfd_com_section_ptr
;
5212 elf_x86_64_additional_program_headers (bfd
*abfd
,
5213 struct bfd_link_info
*info ATTRIBUTE_UNUSED
)
5218 /* Check to see if we need a large readonly segment. */
5219 s
= bfd_get_section_by_name (abfd
, ".lrodata");
5220 if (s
&& (s
->flags
& SEC_LOAD
))
5223 /* Check to see if we need a large data segment. Since .lbss sections
5224 is placed right after the .bss section, there should be no need for
5225 a large data segment just because of .lbss. */
5226 s
= bfd_get_section_by_name (abfd
, ".ldata");
5227 if (s
&& (s
->flags
& SEC_LOAD
))
5233 /* Return TRUE iff relocations for INPUT are compatible with OUTPUT. */
5236 elf_x86_64_relocs_compatible (const bfd_target
*input
,
5237 const bfd_target
*output
)
5239 return ((xvec_get_elf_backend_data (input
)->s
->elfclass
5240 == xvec_get_elf_backend_data (output
)->s
->elfclass
)
5241 && _bfd_elf_relocs_compatible (input
, output
));
5244 /* Set up x86-64 GNU properties. Return the first relocatable ELF input
5245 with GNU properties if found. Otherwise, return NULL. */
5248 elf_x86_64_link_setup_gnu_properties (struct bfd_link_info
*info
)
5250 struct elf_x86_plt_layout_table plt_layout
;
5252 plt_layout
.is_vxworks
= FALSE
;
5253 if (get_elf_x86_64_backend_data (info
->output_bfd
)->os
== is_normal
)
5257 plt_layout
.lazy_plt
= &elf_x86_64_lazy_bnd_plt
;
5258 plt_layout
.non_lazy_plt
= &elf_x86_64_non_lazy_bnd_plt
;
5262 plt_layout
.lazy_plt
= &elf_x86_64_lazy_plt
;
5263 plt_layout
.non_lazy_plt
= &elf_x86_64_non_lazy_plt
;
5266 if (ABI_64_P (info
->output_bfd
))
5268 plt_layout
.lazy_ibt_plt
= &elf_x86_64_lazy_ibt_plt
;
5269 plt_layout
.non_lazy_ibt_plt
= &elf_x86_64_non_lazy_ibt_plt
;
5273 plt_layout
.lazy_ibt_plt
= &elf_x32_lazy_ibt_plt
;
5274 plt_layout
.non_lazy_ibt_plt
= &elf_x32_non_lazy_ibt_plt
;
5276 plt_layout
.normal_target
= TRUE
;
5280 plt_layout
.lazy_plt
= &elf_x86_64_nacl_plt
;
5281 plt_layout
.non_lazy_plt
= NULL
;
5282 plt_layout
.lazy_ibt_plt
= NULL
;
5283 plt_layout
.non_lazy_ibt_plt
= NULL
;
5284 plt_layout
.normal_target
= FALSE
;
5287 return _bfd_x86_elf_link_setup_gnu_properties (info
, &plt_layout
);
5290 static const struct bfd_elf_special_section
5291 elf_x86_64_special_sections
[]=
5293 { STRING_COMMA_LEN (".gnu.linkonce.lb"), -2, SHT_NOBITS
, SHF_ALLOC
+ SHF_WRITE
+ SHF_X86_64_LARGE
},
5294 { STRING_COMMA_LEN (".gnu.linkonce.lr"), -2, SHT_PROGBITS
, SHF_ALLOC
+ SHF_X86_64_LARGE
},
5295 { STRING_COMMA_LEN (".gnu.linkonce.lt"), -2, SHT_PROGBITS
, SHF_ALLOC
+ SHF_EXECINSTR
+ SHF_X86_64_LARGE
},
5296 { STRING_COMMA_LEN (".lbss"), -2, SHT_NOBITS
, SHF_ALLOC
+ SHF_WRITE
+ SHF_X86_64_LARGE
},
5297 { STRING_COMMA_LEN (".ldata"), -2, SHT_PROGBITS
, SHF_ALLOC
+ SHF_WRITE
+ SHF_X86_64_LARGE
},
5298 { STRING_COMMA_LEN (".lrodata"), -2, SHT_PROGBITS
, SHF_ALLOC
+ SHF_X86_64_LARGE
},
5299 { NULL
, 0, 0, 0, 0 }
5302 #define TARGET_LITTLE_SYM x86_64_elf64_vec
5303 #define TARGET_LITTLE_NAME "elf64-x86-64"
5304 #define ELF_ARCH bfd_arch_i386
5305 #define ELF_TARGET_ID X86_64_ELF_DATA
5306 #define ELF_MACHINE_CODE EM_X86_64
5307 #define ELF_MAXPAGESIZE 0x200000
5308 #define ELF_MINPAGESIZE 0x1000
5309 #define ELF_COMMONPAGESIZE 0x1000
5311 #define elf_backend_can_gc_sections 1
5312 #define elf_backend_can_refcount 1
5313 #define elf_backend_want_got_plt 1
5314 #define elf_backend_plt_readonly 1
5315 #define elf_backend_want_plt_sym 0
5316 #define elf_backend_got_header_size (GOT_ENTRY_SIZE*3)
5317 #define elf_backend_rela_normal 1
5318 #define elf_backend_plt_alignment 4
5319 #define elf_backend_extern_protected_data 1
5320 #define elf_backend_caches_rawsize 1
5321 #define elf_backend_dtrel_excludes_plt 1
5322 #define elf_backend_want_dynrelro 1
5324 #define elf_info_to_howto elf_x86_64_info_to_howto
5326 #define bfd_elf64_bfd_reloc_type_lookup elf_x86_64_reloc_type_lookup
5327 #define bfd_elf64_bfd_reloc_name_lookup \
5328 elf_x86_64_reloc_name_lookup
5330 #define elf_backend_relocs_compatible elf_x86_64_relocs_compatible
5331 #define elf_backend_check_relocs elf_x86_64_check_relocs
5332 #define elf_backend_create_dynamic_sections _bfd_elf_create_dynamic_sections
5333 #define elf_backend_finish_dynamic_sections elf_x86_64_finish_dynamic_sections
5334 #define elf_backend_finish_dynamic_symbol elf_x86_64_finish_dynamic_symbol
5335 #define elf_backend_output_arch_local_syms elf_x86_64_output_arch_local_syms
5336 #define elf_backend_grok_prstatus elf_x86_64_grok_prstatus
5337 #define elf_backend_grok_psinfo elf_x86_64_grok_psinfo
5339 #define elf_backend_write_core_note elf_x86_64_write_core_note
5341 #define elf_backend_reloc_type_class elf_x86_64_reloc_type_class
5342 #define elf_backend_relocate_section elf_x86_64_relocate_section
5343 #define elf_backend_init_index_section _bfd_elf_init_1_index_section
5344 #define elf_backend_object_p elf64_x86_64_elf_object_p
5345 #define bfd_elf64_get_synthetic_symtab elf_x86_64_get_synthetic_symtab
5347 #define elf_backend_section_from_shdr \
5348 elf_x86_64_section_from_shdr
5350 #define elf_backend_section_from_bfd_section \
5351 elf_x86_64_elf_section_from_bfd_section
5352 #define elf_backend_add_symbol_hook \
5353 elf_x86_64_add_symbol_hook
5354 #define elf_backend_symbol_processing \
5355 elf_x86_64_symbol_processing
5356 #define elf_backend_common_section_index \
5357 elf_x86_64_common_section_index
5358 #define elf_backend_common_section \
5359 elf_x86_64_common_section
5360 #define elf_backend_common_definition \
5361 elf_x86_64_common_definition
5362 #define elf_backend_merge_symbol \
5363 elf_x86_64_merge_symbol
5364 #define elf_backend_special_sections \
5365 elf_x86_64_special_sections
5366 #define elf_backend_additional_program_headers \
5367 elf_x86_64_additional_program_headers
5368 #define elf_backend_setup_gnu_properties \
5369 elf_x86_64_link_setup_gnu_properties
5371 #include "elf64-target.h"
5373 /* CloudABI support. */
5375 #undef TARGET_LITTLE_SYM
5376 #define TARGET_LITTLE_SYM x86_64_elf64_cloudabi_vec
5377 #undef TARGET_LITTLE_NAME
5378 #define TARGET_LITTLE_NAME "elf64-x86-64-cloudabi"
5381 #define ELF_OSABI ELFOSABI_CLOUDABI
5384 #define elf64_bed elf64_x86_64_cloudabi_bed
5386 #include "elf64-target.h"
5388 /* FreeBSD support. */
5390 #undef TARGET_LITTLE_SYM
5391 #define TARGET_LITTLE_SYM x86_64_elf64_fbsd_vec
5392 #undef TARGET_LITTLE_NAME
5393 #define TARGET_LITTLE_NAME "elf64-x86-64-freebsd"
5396 #define ELF_OSABI ELFOSABI_FREEBSD
5399 #define elf64_bed elf64_x86_64_fbsd_bed
5401 #include "elf64-target.h"
5403 /* Solaris 2 support. */
5405 #undef TARGET_LITTLE_SYM
5406 #define TARGET_LITTLE_SYM x86_64_elf64_sol2_vec
5407 #undef TARGET_LITTLE_NAME
5408 #define TARGET_LITTLE_NAME "elf64-x86-64-sol2"
5410 /* Restore default: we cannot use ELFOSABI_SOLARIS, otherwise ELFOSABI_NONE
5411 objects won't be recognized. */
5415 #define elf64_bed elf64_x86_64_sol2_bed
5417 /* The 64-bit static TLS arena size is rounded to the nearest 16-byte
5419 #undef elf_backend_static_tls_alignment
5420 #define elf_backend_static_tls_alignment 16
5422 /* The Solaris 2 ABI requires a plt symbol on all platforms.
5424 Cf. Linker and Libraries Guide, Ch. 2, Link-Editor, Generating the Output
5426 #undef elf_backend_want_plt_sym
5427 #define elf_backend_want_plt_sym 1
5429 #undef elf_backend_strtab_flags
5430 #define elf_backend_strtab_flags SHF_STRINGS
5433 elf64_x86_64_copy_solaris_special_section_fields (const bfd
*ibfd ATTRIBUTE_UNUSED
,
5434 bfd
*obfd ATTRIBUTE_UNUSED
,
5435 const Elf_Internal_Shdr
*isection ATTRIBUTE_UNUSED
,
5436 Elf_Internal_Shdr
*osection ATTRIBUTE_UNUSED
)
5438 /* PR 19938: FIXME: Need to add code for setting the sh_info
5439 and sh_link fields of Solaris specific section types. */
5443 #undef elf_backend_copy_special_section_fields
5444 #define elf_backend_copy_special_section_fields elf64_x86_64_copy_solaris_special_section_fields
5446 #include "elf64-target.h"
5448 /* Native Client support. */
5451 elf64_x86_64_nacl_elf_object_p (bfd
*abfd
)
5453 /* Set the right machine number for a NaCl x86-64 ELF64 file. */
5454 bfd_default_set_arch_mach (abfd
, bfd_arch_i386
, bfd_mach_x86_64_nacl
);
5458 #undef TARGET_LITTLE_SYM
5459 #define TARGET_LITTLE_SYM x86_64_elf64_nacl_vec
5460 #undef TARGET_LITTLE_NAME
5461 #define TARGET_LITTLE_NAME "elf64-x86-64-nacl"
5463 #define elf64_bed elf64_x86_64_nacl_bed
5465 #undef ELF_MAXPAGESIZE
5466 #undef ELF_MINPAGESIZE
5467 #undef ELF_COMMONPAGESIZE
5468 #define ELF_MAXPAGESIZE 0x10000
5469 #define ELF_MINPAGESIZE 0x10000
5470 #define ELF_COMMONPAGESIZE 0x10000
5472 /* Restore defaults. */
5474 #undef elf_backend_static_tls_alignment
5475 #undef elf_backend_want_plt_sym
5476 #define elf_backend_want_plt_sym 0
5477 #undef elf_backend_strtab_flags
5478 #undef elf_backend_copy_special_section_fields
5480 /* NaCl uses substantially different PLT entries for the same effects. */
5482 #undef elf_backend_plt_alignment
5483 #define elf_backend_plt_alignment 5
5484 #define NACL_PLT_ENTRY_SIZE 64
5485 #define NACLMASK 0xe0 /* 32-byte alignment mask. */
5487 static const bfd_byte elf_x86_64_nacl_plt0_entry
[NACL_PLT_ENTRY_SIZE
] =
5489 0xff, 0x35, 8, 0, 0, 0, /* pushq GOT+8(%rip) */
5490 0x4c, 0x8b, 0x1d, 16, 0, 0, 0, /* mov GOT+16(%rip), %r11 */
5491 0x41, 0x83, 0xe3, NACLMASK
, /* and $-32, %r11d */
5492 0x4d, 0x01, 0xfb, /* add %r15, %r11 */
5493 0x41, 0xff, 0xe3, /* jmpq *%r11 */
5495 /* 9-byte nop sequence to pad out to the next 32-byte boundary. */
5496 0x66, 0x0f, 0x1f, 0x84, 0, 0, 0, 0, 0, /* nopw 0x0(%rax,%rax,1) */
5498 /* 32 bytes of nop to pad out to the standard size. */
5499 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, /* excess data16 prefixes */
5500 0x2e, 0x0f, 0x1f, 0x84, 0, 0, 0, 0, 0, /* nopw %cs:0x0(%rax,%rax,1) */
5501 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, /* excess data16 prefixes */
5502 0x2e, 0x0f, 0x1f, 0x84, 0, 0, 0, 0, 0, /* nopw %cs:0x0(%rax,%rax,1) */
5503 0x66, /* excess data16 prefix */
5507 static const bfd_byte elf_x86_64_nacl_plt_entry
[NACL_PLT_ENTRY_SIZE
] =
5509 0x4c, 0x8b, 0x1d, 0, 0, 0, 0, /* mov name@GOTPCREL(%rip),%r11 */
5510 0x41, 0x83, 0xe3, NACLMASK
, /* and $-32, %r11d */
5511 0x4d, 0x01, 0xfb, /* add %r15, %r11 */
5512 0x41, 0xff, 0xe3, /* jmpq *%r11 */
5514 /* 15-byte nop sequence to pad out to the next 32-byte boundary. */
5515 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, /* excess data16 prefixes */
5516 0x2e, 0x0f, 0x1f, 0x84, 0, 0, 0, 0, 0, /* nopw %cs:0x0(%rax,%rax,1) */
5518 /* Lazy GOT entries point here (32-byte aligned). */
5519 0x68, /* pushq immediate */
5520 0, 0, 0, 0, /* replaced with index into relocation table. */
5521 0xe9, /* jmp relative */
5522 0, 0, 0, 0, /* replaced with offset to start of .plt0. */
5524 /* 22 bytes of nop to pad out to the standard size. */
5525 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, /* excess data16 prefixes */
5526 0x2e, 0x0f, 0x1f, 0x84, 0, 0, 0, 0, 0, /* nopw %cs:0x0(%rax,%rax,1) */
5527 0x0f, 0x1f, 0x80, 0, 0, 0, 0, /* nopl 0x0(%rax) */
5530 /* .eh_frame covering the .plt section. */
5532 static const bfd_byte elf_x86_64_nacl_eh_frame_plt
[] =
5534 #if (PLT_CIE_LENGTH != 20 \
5535 || PLT_FDE_LENGTH != 36 \
5536 || PLT_FDE_START_OFFSET != 4 + PLT_CIE_LENGTH + 8 \
5537 || PLT_FDE_LEN_OFFSET != 4 + PLT_CIE_LENGTH + 12)
5538 # error "Need elf_x86_64_backend_data parameters for eh_frame_plt offsets!"
5540 PLT_CIE_LENGTH
, 0, 0, 0, /* CIE length */
5541 0, 0, 0, 0, /* CIE ID */
5542 1, /* CIE version */
5543 'z', 'R', 0, /* Augmentation string */
5544 1, /* Code alignment factor */
5545 0x78, /* Data alignment factor */
5546 16, /* Return address column */
5547 1, /* Augmentation size */
5548 DW_EH_PE_pcrel
| DW_EH_PE_sdata4
, /* FDE encoding */
5549 DW_CFA_def_cfa
, 7, 8, /* DW_CFA_def_cfa: r7 (rsp) ofs 8 */
5550 DW_CFA_offset
+ 16, 1, /* DW_CFA_offset: r16 (rip) at cfa-8 */
5551 DW_CFA_nop
, DW_CFA_nop
,
5553 PLT_FDE_LENGTH
, 0, 0, 0, /* FDE length */
5554 PLT_CIE_LENGTH
+ 8, 0, 0, 0,/* CIE pointer */
5555 0, 0, 0, 0, /* R_X86_64_PC32 .plt goes here */
5556 0, 0, 0, 0, /* .plt size goes here */
5557 0, /* Augmentation size */
5558 DW_CFA_def_cfa_offset
, 16, /* DW_CFA_def_cfa_offset: 16 */
5559 DW_CFA_advance_loc
+ 6, /* DW_CFA_advance_loc: 6 to __PLT__+6 */
5560 DW_CFA_def_cfa_offset
, 24, /* DW_CFA_def_cfa_offset: 24 */
5561 DW_CFA_advance_loc
+ 58, /* DW_CFA_advance_loc: 58 to __PLT__+64 */
5562 DW_CFA_def_cfa_expression
, /* DW_CFA_def_cfa_expression */
5563 13, /* Block length */
5564 DW_OP_breg7
, 8, /* DW_OP_breg7 (rsp): 8 */
5565 DW_OP_breg16
, 0, /* DW_OP_breg16 (rip): 0 */
5566 DW_OP_const1u
, 63, DW_OP_and
, DW_OP_const1u
, 37, DW_OP_ge
,
5567 DW_OP_lit3
, DW_OP_shl
, DW_OP_plus
,
5568 DW_CFA_nop
, DW_CFA_nop
5571 static const struct elf_x86_lazy_plt_layout elf_x86_64_nacl_plt
=
5573 elf_x86_64_nacl_plt0_entry
, /* plt0_entry */
5574 NACL_PLT_ENTRY_SIZE
, /* plt0_entry_size */
5575 elf_x86_64_nacl_plt_entry
, /* plt_entry */
5576 NACL_PLT_ENTRY_SIZE
, /* plt_entry_size */
5577 2, /* plt0_got1_offset */
5578 9, /* plt0_got2_offset */
5579 13, /* plt0_got2_insn_end */
5580 3, /* plt_got_offset */
5581 33, /* plt_reloc_offset */
5582 38, /* plt_plt_offset */
5583 7, /* plt_got_insn_size */
5584 42, /* plt_plt_insn_end */
5585 32, /* plt_lazy_offset */
5586 elf_x86_64_nacl_plt0_entry
, /* pic_plt0_entry */
5587 elf_x86_64_nacl_plt_entry
, /* pic_plt_entry */
5588 elf_x86_64_nacl_eh_frame_plt
, /* eh_frame_plt */
5589 sizeof (elf_x86_64_nacl_eh_frame_plt
) /* eh_frame_plt_size */
5592 static const struct elf_x86_64_backend_data elf_x86_64_nacl_arch_bed
=
5597 #undef elf_backend_arch_data
5598 #define elf_backend_arch_data &elf_x86_64_nacl_arch_bed
5600 #undef elf_backend_object_p
5601 #define elf_backend_object_p elf64_x86_64_nacl_elf_object_p
5602 #undef elf_backend_modify_segment_map
5603 #define elf_backend_modify_segment_map nacl_modify_segment_map
5604 #undef elf_backend_modify_program_headers
5605 #define elf_backend_modify_program_headers nacl_modify_program_headers
5606 #undef elf_backend_final_write_processing
5607 #define elf_backend_final_write_processing nacl_final_write_processing
5609 #include "elf64-target.h"
5611 /* Native Client x32 support. */
5614 elf32_x86_64_nacl_elf_object_p (bfd
*abfd
)
5616 /* Set the right machine number for a NaCl x86-64 ELF32 file. */
5617 bfd_default_set_arch_mach (abfd
, bfd_arch_i386
, bfd_mach_x64_32_nacl
);
5621 #undef TARGET_LITTLE_SYM
5622 #define TARGET_LITTLE_SYM x86_64_elf32_nacl_vec
5623 #undef TARGET_LITTLE_NAME
5624 #define TARGET_LITTLE_NAME "elf32-x86-64-nacl"
5626 #define elf32_bed elf32_x86_64_nacl_bed
5628 #define bfd_elf32_bfd_reloc_type_lookup \
5629 elf_x86_64_reloc_type_lookup
5630 #define bfd_elf32_bfd_reloc_name_lookup \
5631 elf_x86_64_reloc_name_lookup
5632 #define bfd_elf32_get_synthetic_symtab \
5633 elf_x86_64_get_synthetic_symtab
5635 #undef elf_backend_object_p
5636 #define elf_backend_object_p \
5637 elf32_x86_64_nacl_elf_object_p
5639 #undef elf_backend_bfd_from_remote_memory
5640 #define elf_backend_bfd_from_remote_memory \
5641 _bfd_elf32_bfd_from_remote_memory
5643 #undef elf_backend_size_info
5644 #define elf_backend_size_info \
5645 _bfd_elf32_size_info
5647 #include "elf32-target.h"
5649 /* Restore defaults. */
5650 #undef elf_backend_object_p
5651 #define elf_backend_object_p elf64_x86_64_elf_object_p
5652 #undef elf_backend_bfd_from_remote_memory
5653 #undef elf_backend_size_info
5654 #undef elf_backend_modify_segment_map
5655 #undef elf_backend_modify_program_headers
5656 #undef elf_backend_final_write_processing
5658 /* Intel L1OM support. */
5661 elf64_l1om_elf_object_p (bfd
*abfd
)
5663 /* Set the right machine number for an L1OM elf64 file. */
5664 bfd_default_set_arch_mach (abfd
, bfd_arch_l1om
, bfd_mach_l1om
);
5668 #undef TARGET_LITTLE_SYM
5669 #define TARGET_LITTLE_SYM l1om_elf64_vec
5670 #undef TARGET_LITTLE_NAME
5671 #define TARGET_LITTLE_NAME "elf64-l1om"
5673 #define ELF_ARCH bfd_arch_l1om
5675 #undef ELF_MACHINE_CODE
5676 #define ELF_MACHINE_CODE EM_L1OM
5681 #define elf64_bed elf64_l1om_bed
5683 #undef elf_backend_object_p
5684 #define elf_backend_object_p elf64_l1om_elf_object_p
5686 /* Restore defaults. */
5687 #undef ELF_MAXPAGESIZE
5688 #undef ELF_MINPAGESIZE
5689 #undef ELF_COMMONPAGESIZE
5690 #define ELF_MAXPAGESIZE 0x200000
5691 #define ELF_MINPAGESIZE 0x1000
5692 #define ELF_COMMONPAGESIZE 0x1000
5693 #undef elf_backend_plt_alignment
5694 #define elf_backend_plt_alignment 4
5695 #undef elf_backend_arch_data
5696 #define elf_backend_arch_data &elf_x86_64_arch_bed
5698 #include "elf64-target.h"
5700 /* FreeBSD L1OM support. */
5702 #undef TARGET_LITTLE_SYM
5703 #define TARGET_LITTLE_SYM l1om_elf64_fbsd_vec
5704 #undef TARGET_LITTLE_NAME
5705 #define TARGET_LITTLE_NAME "elf64-l1om-freebsd"
5708 #define ELF_OSABI ELFOSABI_FREEBSD
5711 #define elf64_bed elf64_l1om_fbsd_bed
5713 #include "elf64-target.h"
5715 /* Intel K1OM support. */
5718 elf64_k1om_elf_object_p (bfd
*abfd
)
5720 /* Set the right machine number for an K1OM elf64 file. */
5721 bfd_default_set_arch_mach (abfd
, bfd_arch_k1om
, bfd_mach_k1om
);
5725 #undef TARGET_LITTLE_SYM
5726 #define TARGET_LITTLE_SYM k1om_elf64_vec
5727 #undef TARGET_LITTLE_NAME
5728 #define TARGET_LITTLE_NAME "elf64-k1om"
5730 #define ELF_ARCH bfd_arch_k1om
5732 #undef ELF_MACHINE_CODE
5733 #define ELF_MACHINE_CODE EM_K1OM
5738 #define elf64_bed elf64_k1om_bed
5740 #undef elf_backend_object_p
5741 #define elf_backend_object_p elf64_k1om_elf_object_p
5743 #undef elf_backend_static_tls_alignment
5745 #undef elf_backend_want_plt_sym
5746 #define elf_backend_want_plt_sym 0
5748 #include "elf64-target.h"
5750 /* FreeBSD K1OM support. */
5752 #undef TARGET_LITTLE_SYM
5753 #define TARGET_LITTLE_SYM k1om_elf64_fbsd_vec
5754 #undef TARGET_LITTLE_NAME
5755 #define TARGET_LITTLE_NAME "elf64-k1om-freebsd"
5758 #define ELF_OSABI ELFOSABI_FREEBSD
5761 #define elf64_bed elf64_k1om_fbsd_bed
5763 #include "elf64-target.h"
5765 /* 32bit x86-64 support. */
5767 #undef TARGET_LITTLE_SYM
5768 #define TARGET_LITTLE_SYM x86_64_elf32_vec
5769 #undef TARGET_LITTLE_NAME
5770 #define TARGET_LITTLE_NAME "elf32-x86-64"
5774 #define ELF_ARCH bfd_arch_i386
5776 #undef ELF_MACHINE_CODE
5777 #define ELF_MACHINE_CODE EM_X86_64
5781 #undef elf_backend_object_p
5782 #define elf_backend_object_p \
5783 elf32_x86_64_elf_object_p
5785 #undef elf_backend_bfd_from_remote_memory
5786 #define elf_backend_bfd_from_remote_memory \
5787 _bfd_elf32_bfd_from_remote_memory
5789 #undef elf_backend_size_info
5790 #define elf_backend_size_info \
5791 _bfd_elf32_size_info
5793 #include "elf32-target.h"