/src/binutils-gdb/bfd/elfxx-x86.h
Line | Count | Source (jump to first uncovered line) |
1 | | /* x86 specific support for ELF |
2 | | Copyright (C) 2017-2025 Free Software Foundation, Inc. |
3 | | |
4 | | This file is part of BFD, the Binary File Descriptor library. |
5 | | |
6 | | This program is free software; you can redistribute it and/or modify |
7 | | it under the terms of the GNU General Public License as published by |
8 | | the Free Software Foundation; either version 3 of the License, or |
9 | | (at your option) any later version. |
10 | | |
11 | | This program is distributed in the hope that it will be useful, |
12 | | but WITHOUT ANY WARRANTY; without even the implied warranty of |
13 | | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
14 | | GNU General Public License for more details. |
15 | | |
16 | | You should have received a copy of the GNU General Public License |
17 | | along with this program; if not, write to the Free Software |
18 | | Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, |
19 | | MA 02110-1301, USA. */ |
20 | | |
21 | | /* Don't generate unused section symbols. */ |
22 | | #define TARGET_KEEP_UNUSED_SECTION_SYMBOLS false |
23 | | |
24 | | #include "sysdep.h" |
25 | | #include "bfd.h" |
26 | | #include "bfdlink.h" |
27 | | #include "libbfd.h" |
28 | | #include "elf-bfd.h" |
29 | | #include "hashtab.h" |
30 | | #include "elf-linker-x86.h" |
31 | | #include "elf/i386.h" |
32 | | #include "elf/x86-64.h" |
33 | | #include "sframe-api.h" |
34 | | |
35 | | #define X86_64_PCREL_TYPE_P(TYPE) \ |
36 | 0 | ((TYPE) == R_X86_64_PC8 \ |
37 | 0 | || (TYPE) == R_X86_64_PC16 \ |
38 | 0 | || (TYPE) == R_X86_64_PC32 \ |
39 | 0 | || (TYPE) == R_X86_64_PC64) |
40 | 0 | #define I386_PCREL_TYPE_P(TYPE) ((TYPE) == R_386_PC32) |
41 | | #define X86_PCREL_TYPE_P(IS_X86_64, TYPE) \ |
42 | 0 | ((IS_X86_64) ? X86_64_PCREL_TYPE_P (TYPE) : I386_PCREL_TYPE_P (TYPE)) |
43 | | |
44 | | #define X86_64_SIZE_TYPE_P(TYPE) \ |
45 | 0 | ((TYPE) == R_X86_64_SIZE32 || (TYPE) == R_X86_64_SIZE64) |
46 | 0 | #define I386_SIZE_TYPE_P(TYPE) ((TYPE) == R_386_SIZE32) |
47 | | #define X86_SIZE_TYPE_P(IS_X86_64, TYPE) \ |
48 | 0 | ((IS_X86_64) ? X86_64_SIZE_TYPE_P(TYPE) : I386_SIZE_TYPE_P (TYPE)) |
49 | | |
50 | | #define X86_64_GOT_TYPE_P(TYPE) \ |
51 | 0 | ((TYPE) == R_X86_64_GOTPCREL \ |
52 | 0 | || (TYPE) == R_X86_64_GOTPCRELX \ |
53 | 0 | || (TYPE) == R_X86_64_REX_GOTPCRELX \ |
54 | 0 | || (TYPE) == R_X86_64_GOT32 \ |
55 | 0 | || (TYPE) == R_X86_64_GOT64 \ |
56 | 0 | || (TYPE) == R_X86_64_GOTPCREL64 \ |
57 | 0 | || (TYPE) == R_X86_64_GOTPLT64) |
58 | | #define I386_GOT_TYPE_P(TYPE) \ |
59 | 0 | ((TYPE) == R_386_GOT32 || (TYPE) == R_386_GOT32X) |
60 | | #define X86_GOT_TYPE_P(IS_X86_64, TYPE) \ |
61 | 0 | ((IS_X86_64) ? X86_64_GOT_TYPE_P (TYPE) : I386_GOT_TYPE_P (TYPE)) |
62 | | |
63 | | #define X86_64_RELATIVE_RELOC_TYPE_P(TYPE) \ |
64 | 0 | (X86_64_PCREL_TYPE_P (TYPE) \ |
65 | 0 | || (TYPE) == R_X86_64_8 \ |
66 | 0 | || (TYPE) == R_X86_64_16 \ |
67 | 0 | || (TYPE) == R_X86_64_32 \ |
68 | 0 | || (TYPE) == R_X86_64_32S \ |
69 | 0 | || (TYPE) == R_X86_64_64) |
70 | | #define I386_RELATIVE_RELOC_TYPE_P(TYPE) \ |
71 | 0 | ((TYPE) == R_386_32 || (TYPE) == R_386_PC32) |
72 | | #define X86_RELATIVE_RELOC_TYPE_P(IS_X86_64, TYPE) \ |
73 | 0 | ((IS_X86_64) \ |
74 | 0 | ? X86_64_RELATIVE_RELOC_TYPE_P (TYPE) \ |
75 | 0 | : I386_RELATIVE_RELOC_TYPE_P(TYPE)) |
76 | | |
77 | | #define X86_64_NEED_DYNAMIC_RELOC_TYPE_P(TYPE) \ |
78 | 0 | (X86_64_SIZE_TYPE_P (TYPE) \ |
79 | 0 | || X86_64_RELATIVE_RELOC_TYPE_P (TYPE)) |
80 | | #define I386_NEED_DYNAMIC_RELOC_TYPE_P(TYPE) \ |
81 | 0 | (I386_SIZE_TYPE_P (TYPE) \ |
82 | 0 | || I386_RELATIVE_RELOC_TYPE_P (TYPE) \ |
83 | 0 | || (TYPE) == R_386_TLS_IE \ |
84 | 0 | || (TYPE) == R_386_TLS_LE \ |
85 | 0 | || (TYPE) == R_386_TLS_LE_32) |
86 | | #define X86_NEED_DYNAMIC_RELOC_TYPE_P(IS_X86_64, TYPE) \ |
87 | 0 | ((IS_X86_64) \ |
88 | 0 | ? X86_64_NEED_DYNAMIC_RELOC_TYPE_P (TYPE) \ |
89 | 0 | : I386_NEED_DYNAMIC_RELOC_TYPE_P (TYPE)) |
90 | | |
91 | | #define X86_LOCAL_GOT_RELATIVE_RELOC_P(IS_X86_64, INFO, SYM) \ |
92 | 0 | (bfd_link_pic (INFO) \ |
93 | 0 | && (!(IS_X86_64) || ((SYM) != NULL && (SYM)->st_shndx != SHN_ABS))) |
94 | | |
95 | 0 | #define PLT_CIE_LENGTH 20 |
96 | | #define PLT_FDE_LENGTH 36 |
97 | 0 | #define PLT_FDE_START_OFFSET 4 + PLT_CIE_LENGTH + 8 |
98 | | #define PLT_FDE_LEN_OFFSET 4 + PLT_CIE_LENGTH + 12 |
99 | | |
100 | | /* This must be the same as sframe_get_hdr_size (sfh). For x86-64, this value |
101 | | is the same as sizeof (sframe_header) because there is no SFrame auxilliary |
102 | | header. */ |
103 | 0 | #define PLT_SFRAME_FDE_START_OFFSET sizeof (sframe_header) |
104 | | |
105 | | #define ABI_64_P(abfd) \ |
106 | 93.5k | (get_elf_backend_data (abfd)->s->elfclass == ELFCLASS64) |
107 | | |
108 | | /* If ELIMINATE_COPY_RELOCS is non-zero, the linker will try to avoid |
109 | | copying dynamic variables from a shared lib into an app's dynbss |
110 | | section, and instead use a dynamic relocation to point into the |
111 | | shared lib. */ |
112 | 0 | #define ELIMINATE_COPY_RELOCS 1 |
113 | | |
114 | | #define elf_x86_hash_table(p, id) \ |
115 | 0 | (is_elf_hash_table ((p)->hash) \ |
116 | 0 | && elf_hash_table_id ((struct elf_link_hash_table *) ((p)->hash)) == (id) \ |
117 | 0 | ? ((struct elf_x86_link_hash_table *) ((p)->hash)) : NULL) |
118 | | |
119 | | /* Will references to this symbol always be local in this object? */ |
120 | | #define SYMBOL_REFERENCES_LOCAL_P(INFO, H) \ |
121 | 0 | _bfd_x86_elf_link_symbol_references_local ((INFO), (H)) |
122 | | |
123 | | /* TRUE if an undefined weak symbol should be resolved to 0. Local |
124 | | undefined weak symbol is always resolved to 0. Reference to an |
125 | | undefined weak symbol is resolved to 0 in executable if undefined |
126 | | weak symbol should be resolved to 0 (zero_undefweak > 0). */ |
127 | | #define UNDEFINED_WEAK_RESOLVED_TO_ZERO(INFO, EH) \ |
128 | 0 | ((EH)->elf.root.type == bfd_link_hash_undefweak \ |
129 | 0 | && (SYMBOL_REFERENCES_LOCAL_P ((INFO), &(EH)->elf) \ |
130 | 0 | || (bfd_link_executable (INFO) \ |
131 | 0 | && (EH)->zero_undefweak > 0))) |
132 | | |
133 | | /* Should copy relocation be generated for a symbol. Don't generate |
134 | | copy relocation against a protected symbol defined in a shared |
135 | | object. */ |
136 | | #define SYMBOL_NO_COPYRELOC(INFO, EH) \ |
137 | 0 | ((EH)->def_protected \ |
138 | 0 | && ((EH)->elf.root.type == bfd_link_hash_defined \ |
139 | 0 | || (EH)->elf.root.type == bfd_link_hash_defweak) \ |
140 | 0 | && ((EH)->elf.root.u.def.section->owner->flags & DYNAMIC) != 0 \ |
141 | 0 | && ((EH)->elf.root.u.def.section->flags & SEC_CODE) == 0) |
142 | | |
143 | | /* TRUE if dynamic relocation is needed. If we are creating a shared |
144 | | library, and this is a reloc against a global symbol, or a non PC |
145 | | relative reloc against a local symbol, then we need to copy the reloc |
146 | | into the shared library. However, if we are linking with -Bsymbolic, |
147 | | we do not need to copy a reloc against a global symbol which is |
148 | | defined in an object we are including in the link (i.e., DEF_REGULAR |
149 | | is set). |
150 | | |
151 | | If PCREL_PLT is true, don't generate dynamic relocation in PIE for |
152 | | PC-relative relocation against a dynamic function definition in data |
153 | | section when PLT address can be used. |
154 | | |
155 | | If on the other hand, we are creating an executable, we may need to |
156 | | keep relocations for symbols satisfied by a dynamic library if we |
157 | | manage to avoid copy relocs for the symbol. |
158 | | |
159 | | We also need to generate dynamic pointer relocation against |
160 | | STT_GNU_IFUNC symbol in the non-code section. */ |
161 | | #define NEED_DYNAMIC_RELOCATION_P(IS_X86_64, INFO, PCREL_PLT, H, SEC, \ |
162 | | R_TYPE, POINTER_TYPE) \ |
163 | 0 | ((bfd_link_pic (INFO) \ |
164 | 0 | && (! X86_PCREL_TYPE_P (IS_X86_64, R_TYPE) \ |
165 | 0 | || ((H) != NULL \ |
166 | 0 | && (! (bfd_link_pie (INFO) \ |
167 | 0 | || SYMBOLIC_BIND ((INFO), (H))) \ |
168 | 0 | || (H)->root.type == bfd_link_hash_defweak \ |
169 | 0 | || (!(bfd_link_pie (INFO) \ |
170 | 0 | && (PCREL_PLT) \ |
171 | 0 | && (H)->plt.refcount > 0 \ |
172 | 0 | && ((SEC)->flags & SEC_CODE) == 0 \ |
173 | 0 | && (H)->type == STT_FUNC \ |
174 | 0 | && (H)->def_dynamic) \ |
175 | 0 | && !(H)->def_regular))))) \ |
176 | 0 | || ((H) != NULL \ |
177 | 0 | && (H)->type == STT_GNU_IFUNC \ |
178 | 0 | && (R_TYPE) == POINTER_TYPE \ |
179 | 0 | && ((SEC)->flags & SEC_CODE) == 0) \ |
180 | 0 | || (ELIMINATE_COPY_RELOCS \ |
181 | 0 | && !bfd_link_pic (INFO) \ |
182 | 0 | && (H) != NULL \ |
183 | 0 | && ((H)->root.type == bfd_link_hash_defweak \ |
184 | 0 | || !(H)->def_regular))) |
185 | | |
186 | | /* TRUE if dynamic relocation should be generated. Don't copy a |
187 | | pc-relative relocation into the output file if the symbol needs |
188 | | copy reloc or the symbol is undefined when building executable. |
189 | | Copy dynamic function pointer relocations. Don't generate dynamic |
190 | | relocations against resolved undefined weak symbols in PIE, except |
191 | | when PC32_RELOC is TRUE. Undefined weak symbol is bound locally |
192 | | when PIC is false. Don't generate dynamic relocations against |
193 | | non-preemptible absolute symbol. NB: rel_from_abs is set on symbols |
194 | | defined by linker scripts from "dot" (also SEGMENT_START or ORIGIN) |
195 | | outside of an output section statement, which will be converted from |
196 | | absolute to section-relative in set_sym_sections called from |
197 | | ldexp_finalize_syms after ldemul_finish. */ |
198 | | #define GENERATE_DYNAMIC_RELOCATION_P(IS_X86_64, INFO, EH, R_TYPE, \ |
199 | | SEC, NEED_COPY_RELOC_IN_PIE, \ |
200 | | RESOLVED_TO_ZERO, PC32_RELOC) \ |
201 | 0 | ((bfd_link_pic (INFO) \ |
202 | 0 | && !(bfd_is_abs_section (SEC) \ |
203 | 0 | && ((EH) == NULL \ |
204 | 0 | || (EH)->elf.root.rel_from_abs == 0) \ |
205 | 0 | && ((EH) == NULL \ |
206 | 0 | || SYMBOL_REFERENCES_LOCAL (INFO, &(EH)->elf))) \ |
207 | 0 | && !(NEED_COPY_RELOC_IN_PIE) \ |
208 | 0 | && ((EH) == NULL \ |
209 | 0 | || ((ELF_ST_VISIBILITY ((EH)->elf.other) == STV_DEFAULT \ |
210 | 0 | && (!(RESOLVED_TO_ZERO) || PC32_RELOC)) \ |
211 | 0 | || (EH)->elf.root.type != bfd_link_hash_undefweak)) \ |
212 | 0 | && ((!X86_PCREL_TYPE_P (IS_X86_64, R_TYPE) \ |
213 | 0 | && !X86_SIZE_TYPE_P (IS_X86_64, R_TYPE)) \ |
214 | 0 | || ! SYMBOL_CALLS_LOCAL ((INFO), \ |
215 | 0 | (struct elf_link_hash_entry *) (EH)))) \ |
216 | 0 | || (ELIMINATE_COPY_RELOCS \ |
217 | 0 | && !bfd_link_pic (INFO) \ |
218 | 0 | && (EH) != NULL \ |
219 | 0 | && (EH)->elf.dynindx != -1 \ |
220 | 0 | && (!(EH)->elf.non_got_ref \ |
221 | 0 | || ((EH)->elf.root.type == bfd_link_hash_undefweak \ |
222 | 0 | && !(RESOLVED_TO_ZERO))) \ |
223 | 0 | && (((EH)->elf.def_dynamic && !(EH)->elf.def_regular) \ |
224 | 0 | || (EH)->elf.root.type == bfd_link_hash_undefined))) |
225 | | |
226 | | /* TRUE if this input relocation should be copied to output. H->dynindx |
227 | | may be -1 if this symbol was marked to become local. */ |
228 | | #define COPY_INPUT_RELOC_P(IS_X86_64, INFO, H, R_TYPE) \ |
229 | 0 | ((H) != NULL \ |
230 | 0 | && (H)->dynindx != -1 \ |
231 | 0 | && (X86_PCREL_TYPE_P (IS_X86_64, R_TYPE) \ |
232 | 0 | || !(bfd_link_executable (INFO) || SYMBOLIC_BIND ((INFO), (H))) \ |
233 | 0 | || !(H)->def_regular)) |
234 | | |
235 | | /* TRUE if this is actually a static link, or it is a -Bsymbolic link |
236 | | and the symbol is defined locally, or the symbol was forced to be |
237 | | local because of a version file. */ |
238 | | #define RESOLVED_LOCALLY_P(INFO, H, HTAB) \ |
239 | 0 | (!WILL_CALL_FINISH_DYNAMIC_SYMBOL ((HTAB)->elf.dynamic_sections_created, \ |
240 | 0 | bfd_link_pic (INFO), (H)) \ |
241 | 0 | || (bfd_link_pic (INFO) \ |
242 | 0 | && SYMBOL_REFERENCES_LOCAL_P ((INFO), (H))) \ |
243 | 0 | || (ELF_ST_VISIBILITY ((H)->other) \ |
244 | 0 | && (H)->root.type == bfd_link_hash_undefweak)) |
245 | | |
246 | | /* TRUE if this symbol isn't defined by a shared object. */ |
247 | | #define SYMBOL_DEFINED_NON_SHARED_P(H) \ |
248 | 0 | ((H)->def_regular \ |
249 | 0 | || (H)->root.linker_def \ |
250 | 0 | || (H)->root.ldscript_def \ |
251 | 0 | || ((struct elf_x86_link_hash_entry *) (H))->linker_def \ |
252 | 0 | || ELF_COMMON_DEF_P (H)) |
253 | | |
254 | | /* Return TRUE if the symbol described by a linker hash entry H is |
255 | | going to be absolute. Similar to bfd_is_abs_symbol, but excluding |
256 | | all linker-script defined symbols. */ |
257 | | #define ABS_SYMBOL_P(H) \ |
258 | 0 | (bfd_is_abs_symbol (&(H)->root) && !(H)->root.ldscript_def) |
259 | | |
260 | | /* TRUE if relative relocation should be generated. GOT reference to |
261 | | global symbol in PIC will lead to dynamic symbol. It becomes a |
262 | | problem when "time" or "times" is defined as a variable in an |
263 | | executable, clashing with functions of the same name in libc. If a |
264 | | symbol isn't undefined weak symbol, don't make it dynamic in PIC and |
265 | | generate relative relocation. Don't generate relative relocation |
266 | | against non-preemptible absolute symbol. */ |
267 | | #define GENERATE_RELATIVE_RELOC_P(INFO, H) \ |
268 | 0 | ((H)->dynindx == -1 \ |
269 | 0 | && !(H)->forced_local \ |
270 | 0 | && (H)->root.type != bfd_link_hash_undefweak \ |
271 | 0 | && bfd_link_pic (INFO) \ |
272 | 0 | && !ABS_SYMBOL_P (H)) |
273 | | |
274 | | /* TRUE if this is a pointer reference to a local IFUNC. */ |
275 | | #define POINTER_LOCAL_IFUNC_P(INFO, H) \ |
276 | 0 | ((H)->dynindx == -1 \ |
277 | 0 | || (H)->forced_local \ |
278 | 0 | || bfd_link_executable (INFO)) |
279 | | |
280 | | /* TRUE if this is a PLT reference to a local IFUNC. */ |
281 | | #define PLT_LOCAL_IFUNC_P(INFO, H) \ |
282 | 0 | ((H)->dynindx == -1 \ |
283 | 0 | || ((bfd_link_executable (INFO) \ |
284 | 0 | || ELF_ST_VISIBILITY ((H)->other) != STV_DEFAULT) \ |
285 | 0 | && (H)->def_regular \ |
286 | 0 | && (H)->type == STT_GNU_IFUNC)) |
287 | | |
288 | | /* TRUE if TLS IE->LE transition is OK. */ |
289 | | #define TLS_TRANSITION_IE_TO_LE_P(INFO, H, TLS_TYPE) \ |
290 | 0 | (bfd_link_executable (INFO) \ |
291 | 0 | && (H) != NULL \ |
292 | 0 | && (H)->dynindx == -1 \ |
293 | 0 | && (TLS_TYPE & GOT_TLS_IE)) |
294 | | |
295 | | /* Verify that the symbol has an entry in the procedure linkage table. */ |
296 | | #define VERIFY_PLT_ENTRY(INFO, H, PLT, GOTPLT, RELPLT, LOCAL_UNDEFWEAK) \ |
297 | 0 | do \ |
298 | 0 | { \ |
299 | 0 | if (((H)->dynindx == -1 \ |
300 | 0 | && !LOCAL_UNDEFWEAK \ |
301 | 0 | && !(((H)->forced_local || bfd_link_executable (INFO)) \ |
302 | 0 | && (H)->def_regular \ |
303 | 0 | && (H)->type == STT_GNU_IFUNC)) \ |
304 | 0 | || (PLT) == NULL \ |
305 | 0 | || (GOTPLT) == NULL \ |
306 | 0 | || (RELPLT) == NULL) \ |
307 | 0 | abort (); \ |
308 | 0 | } \ |
309 | 0 | while (0); |
310 | | |
311 | | /* Verify that the symbol supports copy relocation. */ |
312 | | #define VERIFY_COPY_RELOC(H, HTAB) \ |
313 | 0 | do \ |
314 | 0 | { \ |
315 | 0 | if ((H)->dynindx == -1 \ |
316 | 0 | || ((H)->root.type != bfd_link_hash_defined \ |
317 | 0 | && (H)->root.type != bfd_link_hash_defweak) \ |
318 | 0 | || (HTAB)->elf.srelbss == NULL \ |
319 | 0 | || (HTAB)->elf.sreldynrelro == NULL) \ |
320 | 0 | abort (); \ |
321 | 0 | } \ |
322 | 0 | while (0); |
323 | | |
324 | | /* x86 ELF linker hash entry. */ |
325 | | |
326 | | struct elf_x86_link_hash_entry |
327 | | { |
328 | | struct elf_link_hash_entry elf; |
329 | | |
330 | | unsigned char tls_type; |
331 | | |
332 | | /* Bit 0: Symbol has no GOT nor PLT relocations. |
333 | | Bit 1: Symbol has non-GOT/non-PLT relocations in text sections. |
334 | | zero_undefweak is initialized to 1 and undefined weak symbol |
335 | | should be resolved to 0 if zero_undefweak > 0. */ |
336 | | unsigned int zero_undefweak : 2; |
337 | | |
338 | | /* Don't call finish_dynamic_symbol on this symbol. */ |
339 | | unsigned int no_finish_dynamic_symbol : 1; |
340 | | |
341 | | /* R_*_RELATIVE relocation in GOT for this symbol has been |
342 | | processed. */ |
343 | | unsigned int got_relative_reloc_done : 1; |
344 | | |
345 | | /* TRUE if symbol is __tls_get_addr. */ |
346 | | unsigned int tls_get_addr : 1; |
347 | | |
348 | | /* TRUE if symbol is defined as a protected symbol. */ |
349 | | unsigned int def_protected : 1; |
350 | | |
351 | | /* 0: Symbol references are unknown. |
352 | | 1: Symbol references aren't local. |
353 | | 2: Symbol references are local. |
354 | | */ |
355 | | unsigned int local_ref : 2; |
356 | | |
357 | | /* TRUE if symbol is defined by linker. */ |
358 | | unsigned int linker_def : 1; |
359 | | |
360 | | /* TRUE if symbol is referenced by a non-GOT/non-PLT relocation in a |
361 | | relocatable object file without indirect external access marker. */ |
362 | | unsigned int non_got_ref_without_indirect_extern_access : 1; |
363 | | |
364 | | /* TRUE if symbol is referenced by R_386_GOTOFF relocation. This is |
365 | | only used by i386. */ |
366 | | unsigned int gotoff_ref : 1; |
367 | | |
368 | | /* TRUE if a weak symbol with a real definition needs a copy reloc. |
369 | | When there is a weak symbol with a real definition, the processor |
370 | | independent code will have arranged for us to see the real |
371 | | definition first. We need to copy the needs_copy bit from the |
372 | | real definition and check it when allowing copy reloc in PIE. This |
373 | | is only used by x86-64. */ |
374 | | unsigned int needs_copy : 1; |
375 | | |
376 | | /* Information about the GOT PLT entry. Filled when there are both |
377 | | GOT and PLT relocations against the same function. */ |
378 | | union gotplt_union plt_got; |
379 | | |
380 | | /* Information about the second PLT entry. */ |
381 | | union gotplt_union plt_second; |
382 | | |
383 | | /* Offset of the GOTPLT entry reserved for the TLS descriptor, |
384 | | starting at the end of the jump table. */ |
385 | | bfd_vma tlsdesc_got; |
386 | | }; |
387 | | |
388 | | #define SFRAME_PLT0_MAX_NUM_FRES 2 |
389 | | #define SFRAME_PLTN_MAX_NUM_FRES 2 |
390 | | |
391 | | struct elf_x86_sframe_plt |
392 | | { |
393 | | unsigned int plt0_entry_size; |
394 | | unsigned int plt0_num_fres; |
395 | | const sframe_frame_row_entry *plt0_fres[SFRAME_PLT0_MAX_NUM_FRES]; |
396 | | |
397 | | unsigned int pltn_entry_size; |
398 | | unsigned int pltn_num_fres; |
399 | | const sframe_frame_row_entry *pltn_fres[SFRAME_PLTN_MAX_NUM_FRES]; |
400 | | |
401 | | unsigned int sec_pltn_entry_size; |
402 | | unsigned int sec_pltn_num_fres; |
403 | | const sframe_frame_row_entry *sec_pltn_fres[SFRAME_PLTN_MAX_NUM_FRES]; |
404 | | |
405 | | unsigned int plt_got_entry_size; |
406 | | unsigned int plt_got_num_fres; |
407 | | const sframe_frame_row_entry *plt_got_fres[SFRAME_PLTN_MAX_NUM_FRES]; |
408 | | }; |
409 | | |
410 | | struct elf_x86_lazy_plt_layout |
411 | | { |
412 | | /* The first entry in a lazy procedure linkage table looks like this. */ |
413 | | const bfd_byte *plt0_entry; |
414 | | unsigned int plt0_entry_size; /* Size of PLT0 entry. */ |
415 | | |
416 | | /* Later entries in a lazy procedure linkage table look like this. */ |
417 | | const bfd_byte *plt_entry; |
418 | | unsigned int plt_entry_size; /* Size of each PLT entry. */ |
419 | | |
420 | | /* The TLSDESC entry in a lazy procedure linkage table looks like |
421 | | this. This is for x86-64 only. */ |
422 | | const bfd_byte *plt_tlsdesc_entry; |
423 | | unsigned int plt_tlsdesc_entry_size; /* Size of TLSDESC entry. */ |
424 | | |
425 | | /* Offsets into the TLSDESC entry that are to be replaced with |
426 | | GOT+8 and GOT+TDG. These are for x86-64 only. */ |
427 | | unsigned int plt_tlsdesc_got1_offset; |
428 | | unsigned int plt_tlsdesc_got2_offset; |
429 | | |
430 | | /* Offset of the end of the PC-relative instructions containing |
431 | | plt_tlsdesc_got1_offset and plt_tlsdesc_got2_offset. These |
432 | | are for x86-64 only. */ |
433 | | unsigned int plt_tlsdesc_got1_insn_end; |
434 | | unsigned int plt_tlsdesc_got2_insn_end; |
435 | | |
436 | | /* Offsets into plt0_entry that are to be replaced with GOT[1] and |
437 | | GOT[2]. */ |
438 | | unsigned int plt0_got1_offset; |
439 | | unsigned int plt0_got2_offset; |
440 | | |
441 | | /* Offset of the end of the PC-relative instruction containing |
442 | | plt0_got2_offset. This is for x86-64 only. */ |
443 | | unsigned int plt0_got2_insn_end; |
444 | | |
445 | | /* Offsets into plt_entry that are to be replaced with... */ |
446 | | unsigned int plt_got_offset; /* ... address of this symbol in .got. */ |
447 | | unsigned int plt_reloc_offset; /* ... offset into relocation table. */ |
448 | | unsigned int plt_plt_offset; /* ... offset to start of .plt. */ |
449 | | |
450 | | /* Length of the PC-relative instruction containing plt_got_offset. |
451 | | This is used for x86-64 only. */ |
452 | | unsigned int plt_got_insn_size; |
453 | | |
454 | | /* Offset of the end of the PC-relative jump to plt0_entry. This is |
455 | | used for x86-64 only. */ |
456 | | unsigned int plt_plt_insn_end; |
457 | | |
458 | | /* Offset into plt_entry where the initial value of the GOT entry |
459 | | points. */ |
460 | | unsigned int plt_lazy_offset; |
461 | | |
462 | | /* The first entry in a PIC lazy procedure linkage table looks like |
463 | | this. */ |
464 | | const bfd_byte *pic_plt0_entry; |
465 | | |
466 | | /* Subsequent entries in a PIC lazy procedure linkage table look |
467 | | like this. */ |
468 | | const bfd_byte *pic_plt_entry; |
469 | | |
470 | | /* .eh_frame covering the lazy .plt section. */ |
471 | | const bfd_byte *eh_frame_plt; |
472 | | unsigned int eh_frame_plt_size; |
473 | | }; |
474 | | |
475 | | struct elf_x86_non_lazy_plt_layout |
476 | | { |
477 | | /* Entries in a non-lazy procedure linkage table look like this. */ |
478 | | const bfd_byte *plt_entry; |
479 | | /* Entries in a PIC non-lazy procedure linkage table look like this. |
480 | | This is only used for i386 where absolute PLT and PIC PLT are |
481 | | different. */ |
482 | | const bfd_byte *pic_plt_entry; |
483 | | |
484 | | unsigned int plt_entry_size; /* Size of each PLT entry. */ |
485 | | |
486 | | /* Offsets into plt_entry that are to be replaced with... */ |
487 | | unsigned int plt_got_offset; /* ... address of this symbol in .got. */ |
488 | | |
489 | | /* Length of the PC-relative instruction containing plt_got_offset. |
490 | | This is used for x86-64 only. */ |
491 | | unsigned int plt_got_insn_size; |
492 | | |
493 | | /* .eh_frame covering the non-lazy .plt section. */ |
494 | | const bfd_byte *eh_frame_plt; |
495 | | unsigned int eh_frame_plt_size; |
496 | | }; |
497 | | |
498 | | struct elf_x86_plt_layout |
499 | | { |
500 | | /* The first entry in a lazy procedure linkage table looks like this. */ |
501 | | const bfd_byte *plt0_entry; |
502 | | /* Entries in a procedure linkage table look like this. */ |
503 | | const bfd_byte *plt_entry; |
504 | | unsigned int plt_entry_size; /* Size of each PLT entry. */ |
505 | | |
506 | | /* 1 has PLT0. */ |
507 | | unsigned int has_plt0; |
508 | | |
509 | | /* Offset of indirect branch in plt_entry. */ |
510 | | unsigned int plt_indirect_branch_offset; |
511 | | |
512 | | /* Offsets into plt_entry that are to be replaced with... */ |
513 | | unsigned int plt_got_offset; /* ... address of this symbol in .got. */ |
514 | | |
515 | | /* Length of the PC-relative instruction containing plt_got_offset. |
516 | | This is only used for x86-64. */ |
517 | | unsigned int plt_got_insn_size; |
518 | | |
519 | | /* Alignment of the .iplt section. */ |
520 | | unsigned int iplt_alignment; |
521 | | |
522 | | /* .eh_frame covering the .plt section. */ |
523 | | const bfd_byte *eh_frame_plt; |
524 | | unsigned int eh_frame_plt_size; |
525 | | }; |
526 | | |
527 | | /* Values in tls_type of x86 ELF linker hash entry. */ |
528 | 0 | #define GOT_UNKNOWN 0 |
529 | 0 | #define GOT_NORMAL 1 |
530 | 0 | #define GOT_TLS_GD 2 |
531 | 0 | #define GOT_TLS_IE 4 |
532 | 0 | #define GOT_TLS_IE_POS 5 |
533 | 0 | #define GOT_TLS_IE_NEG 6 |
534 | 0 | #define GOT_TLS_IE_BOTH 7 |
535 | 0 | #define GOT_TLS_GDESC 8 |
536 | 0 | #define GOT_ABS 9 |
537 | | #define GOT_TLS_GD_BOTH_P(type) \ |
538 | 0 | ((type) == (GOT_TLS_GD | GOT_TLS_GDESC)) |
539 | | #define GOT_TLS_GD_P(type) \ |
540 | 0 | ((type) == GOT_TLS_GD || GOT_TLS_GD_BOTH_P (type)) |
541 | | #define GOT_TLS_GDESC_P(type) \ |
542 | 0 | ((type) == GOT_TLS_GDESC || GOT_TLS_GD_BOTH_P (type)) |
543 | | #define GOT_TLS_GD_ANY_P(type) \ |
544 | 0 | (GOT_TLS_GD_P (type) || GOT_TLS_GDESC_P (type)) |
545 | | |
546 | | #define elf_x86_hash_entry(ent) \ |
547 | 0 | ((struct elf_x86_link_hash_entry *)(ent)) |
548 | | |
549 | | /* Information of an input relocation used to compute its contribution |
550 | | to the DT_RELR section size. */ |
551 | | |
552 | | struct elf_x86_relative_reloc_record |
553 | | { |
554 | | /* The original relocation info. */ |
555 | | Elf_Internal_Rela rel; |
556 | | /* The input or the GOT section where the relocation is applied. */ |
557 | | asection *sec; |
558 | | /* Local symbol info. NULL for global symbol. */ |
559 | | Elf_Internal_Sym *sym; |
560 | | union |
561 | | { |
562 | | /* Section where the local symbol is defined. */ |
563 | | asection *sym_sec; |
564 | | /* Global symbol hash. */ |
565 | | struct elf_link_hash_entry *h; |
566 | | } u; |
567 | | /* The offset into the output section where the relative relocation |
568 | | will be applied at run-time. */ |
569 | | bfd_vma offset; |
570 | | /* The run-time address. */ |
571 | | bfd_vma address; |
572 | | }; |
573 | | |
574 | | struct elf_x86_relative_reloc_data |
575 | | { |
576 | | bfd_size_type count; |
577 | | bfd_size_type size; |
578 | | struct elf_x86_relative_reloc_record *data; |
579 | | }; |
580 | | |
581 | | /* DT_RELR bitmap. */ |
582 | | struct elf_dt_relr_bitmap |
583 | | { |
584 | | bfd_size_type count; |
585 | | bfd_size_type size; |
586 | | union |
587 | | { |
588 | | /* 32-bit bitmap. */ |
589 | | uint32_t *elf32; |
590 | | /* 64-bit bitmap. */ |
591 | | uint64_t *elf64; |
592 | | } u; |
593 | | }; |
594 | | |
595 | | /* x86 ELF linker hash table. */ |
596 | | |
597 | | struct elf_x86_link_hash_table |
598 | | { |
599 | | struct elf_link_hash_table elf; |
600 | | |
601 | | /* Short-cuts to get to dynamic linker sections. */ |
602 | | asection *interp; |
603 | | asection *plt_eh_frame; |
604 | | asection *plt_second; |
605 | | asection *plt_second_eh_frame; |
606 | | asection *plt_got; |
607 | | asection *plt_got_eh_frame; |
608 | | |
609 | | sframe_encoder_ctx *plt_cfe_ctx; |
610 | | asection *plt_sframe; |
611 | | sframe_encoder_ctx *plt_second_cfe_ctx; |
612 | | asection *plt_second_sframe; |
613 | | sframe_encoder_ctx *plt_got_cfe_ctx; |
614 | | asection *plt_got_sframe; |
615 | | |
616 | | /* Parameters describing PLT generation, lazy or non-lazy. */ |
617 | | struct elf_x86_plt_layout plt; |
618 | | |
619 | | /* Parameters describing lazy PLT generation. */ |
620 | | const struct elf_x86_lazy_plt_layout *lazy_plt; |
621 | | |
622 | | /* Parameters describing non-lazy PLT generation. */ |
623 | | const struct elf_x86_non_lazy_plt_layout *non_lazy_plt; |
624 | | |
625 | | /* The .sframe helper object for .plt section. |
626 | | This is used for x86-64 only. */ |
627 | | const struct elf_x86_sframe_plt *sframe_plt; |
628 | | |
629 | | union |
630 | | { |
631 | | bfd_signed_vma refcount; |
632 | | bfd_vma offset; |
633 | | } tls_ld_or_ldm_got; |
634 | | |
635 | | /* The amount of space used by the jump slots in the GOT. */ |
636 | | bfd_vma sgotplt_jump_table_size; |
637 | | |
638 | | /* _TLS_MODULE_BASE_ symbol. */ |
639 | | struct bfd_link_hash_entry *tls_module_base; |
640 | | |
641 | | /* Used by local STT_GNU_IFUNC symbols. */ |
642 | | htab_t loc_hash_table; |
643 | | void * loc_hash_memory; |
644 | | |
645 | | /* The index of the next R_X86_64_JUMP_SLOT entry in .rela.plt. */ |
646 | | bfd_vma next_jump_slot_index; |
647 | | /* The index of the next R_X86_64_IRELATIVE entry in .rela.plt. */ |
648 | | bfd_vma next_irelative_index; |
649 | | |
650 | | /* The (unloaded but important) .rel.plt.unloaded section on VxWorks. |
651 | | This is used for i386 only. */ |
652 | | asection *srelplt2; |
653 | | |
654 | | /* The index of the next unused R_386_TLS_DESC slot in .rel.plt. This |
655 | | is only used for i386. */ |
656 | | bfd_vma next_tls_desc_index; |
657 | | |
658 | | /* DT_RELR bitmap. */ |
659 | | struct elf_dt_relr_bitmap dt_relr_bitmap; |
660 | | |
661 | | /* Relative relocation data. */ |
662 | | struct elf_x86_relative_reloc_data relative_reloc; |
663 | | |
664 | | /* Unaligned relative relocation data. */ |
665 | | struct elf_x86_relative_reloc_data unaligned_relative_reloc; |
666 | | |
667 | | /* Number of relative reloc generation pass. */ |
668 | | unsigned int generate_relative_reloc_pass; |
669 | | |
670 | | /* Value used to fill the unused bytes of the first PLT entry. This |
671 | | is only used for i386. */ |
672 | | bfd_byte plt0_pad_byte; |
673 | | |
674 | | /* TRUE if GOT is referenced. */ |
675 | | unsigned int got_referenced : 1; |
676 | | |
677 | | /* TRUE if PLT is PC-relative. PLT in PDE and PC-relative PLT in PIE |
678 | | can be used as function address. |
679 | | |
680 | | NB: i386 has non-PIC PLT and PIC PLT. Only non-PIC PLT in PDE can |
681 | | be used as function address. PIC PLT in PIE can't be used as |
682 | | function address. */ |
683 | | unsigned int pcrel_plt : 1; |
684 | | |
685 | | bfd_vma (*r_info) (bfd_vma, bfd_vma); |
686 | | bfd_vma (*r_sym) (bfd_vma); |
687 | | bool (*is_reloc_section) (const char *); |
688 | | unsigned int sizeof_reloc; |
689 | | unsigned int got_entry_size; |
690 | | unsigned int pointer_r_type; |
691 | | unsigned int relative_r_type; |
692 | | int dynamic_interpreter_size; |
693 | | const char *dynamic_interpreter; |
694 | | const char *tls_get_addr; |
695 | | const char *relative_r_name; |
696 | | const char *ax_register; |
697 | | void (*elf_append_reloc) (bfd *, asection *, Elf_Internal_Rela *); |
698 | | void (*elf_write_addend) (bfd *, uint64_t, void *); |
699 | | void (*elf_write_addend_in_got) (bfd *, uint64_t, void *); |
700 | | |
701 | | /* Options passed from the linker. */ |
702 | | struct elf_linker_x86_params *params; |
703 | | }; |
704 | | |
705 | | struct elf_x86_init_table |
706 | | { |
707 | | /* The lazy PLT layout. */ |
708 | | const struct elf_x86_lazy_plt_layout *lazy_plt; |
709 | | |
710 | | /* The non-lazy PLT layout. */ |
711 | | const struct elf_x86_non_lazy_plt_layout *non_lazy_plt; |
712 | | |
713 | | /* The lazy PLT layout for IBT. */ |
714 | | const struct elf_x86_lazy_plt_layout *lazy_ibt_plt; |
715 | | |
716 | | /* The non-lazy PLT layout for IBT. */ |
717 | | const struct elf_x86_non_lazy_plt_layout *non_lazy_ibt_plt; |
718 | | |
719 | | /* The .sframe helper object for lazy .plt section. |
720 | | This is used for x86-64 only. */ |
721 | | const struct elf_x86_sframe_plt *sframe_lazy_plt; |
722 | | |
723 | | /* The .sframe helper object for non-lazy .plt section. |
724 | | This is used for x86-64 only. */ |
725 | | const struct elf_x86_sframe_plt *sframe_non_lazy_plt; |
726 | | |
727 | | /* The .sframe helper object for lazy IBT .plt section. |
728 | | This is used for x86-64 only. */ |
729 | | const struct elf_x86_sframe_plt *sframe_lazy_ibt_plt; |
730 | | |
731 | | /* The .sframe helper object for non-lazy IBT .plt section. |
732 | | This is used for x86-64 only. */ |
733 | | const struct elf_x86_sframe_plt *sframe_non_lazy_ibt_plt; |
734 | | |
735 | | bfd_byte plt0_pad_byte; |
736 | | |
737 | | bfd_vma (*r_info) (bfd_vma, bfd_vma); |
738 | | bfd_vma (*r_sym) (bfd_vma); |
739 | | }; |
740 | | |
741 | | struct elf_x86_obj_tdata |
742 | | { |
743 | | struct elf_obj_tdata root; |
744 | | |
745 | | /* tls_type for each local got entry. */ |
746 | | char *local_got_tls_type; |
747 | | |
748 | | /* GOTPLT entries for TLS descriptors. */ |
749 | | bfd_vma *local_tlsdesc_gotent; |
750 | | |
751 | | /* R_*_RELATIVE relocation in GOT for this local symbol has been |
752 | | processed. */ |
753 | | char *relative_reloc_done; |
754 | | }; |
755 | | |
756 | | enum elf_x86_plt_type |
757 | | { |
758 | | plt_non_lazy = 0, |
759 | | plt_lazy = 1 << 0, |
760 | | plt_pic = 1 << 1, |
761 | | plt_second = 1 << 2, |
762 | | plt_unknown = -1 |
763 | | }; |
764 | | |
765 | | struct elf_x86_plt |
766 | | { |
767 | | const char *name; |
768 | | asection *sec; |
769 | | bfd_byte *contents; |
770 | | enum elf_x86_plt_type type; |
771 | | unsigned int plt_got_offset; |
772 | | unsigned int plt_entry_size; |
773 | | unsigned int plt_got_insn_size; /* Only used for x86-64. */ |
774 | | long count; |
775 | | }; |
776 | | |
777 | | enum elf_x86_tls_error_type |
778 | | { |
779 | | elf_x86_tls_error_none, |
780 | | elf_x86_tls_error_add_mov, |
781 | | elf_x86_tls_error_add_movrs, |
782 | | elf_x86_tls_error_add_sub_mov, |
783 | | elf_x86_tls_error_indirect_call, |
784 | | elf_x86_tls_error_lea, |
785 | | elf_x86_tls_error_yes |
786 | | }; |
787 | | |
788 | | /* Set if a relocation is converted from a GOTPCREL relocation. */ |
789 | 0 | #define R_X86_64_converted_reloc_bit (1 << 7) |
790 | | |
791 | | #define elf_x86_tdata(abfd) \ |
792 | 0 | ((struct elf_x86_obj_tdata *) (abfd)->tdata.any) |
793 | | |
794 | | #define elf_x86_local_got_tls_type(abfd) \ |
795 | 0 | (elf_x86_tdata (abfd)->local_got_tls_type) |
796 | | |
797 | | #define elf_x86_local_tlsdesc_gotent(abfd) \ |
798 | 0 | (elf_x86_tdata (abfd)->local_tlsdesc_gotent) |
799 | | |
800 | | #define elf_x86_relative_reloc_done(abfd) \ |
801 | 0 | (elf_x86_tdata (abfd)->relative_reloc_done) |
802 | | |
803 | | #define elf_x86_compute_jump_table_size(htab) \ |
804 | 0 | ((htab)->elf.srelplt->reloc_count * (htab)->got_entry_size) |
805 | | |
806 | | #define is_x86_elf(bfd, htab) \ |
807 | 0 | (bfd_get_flavour (bfd) == bfd_target_elf_flavour \ |
808 | 0 | && elf_tdata (bfd) != NULL \ |
809 | 0 | && elf_object_id (bfd) == (htab)->elf.hash_table_id) |
810 | | |
811 | | /* Rename some of the generic section flags to better document how they |
812 | | are used here. */ |
813 | 0 | #define check_relocs_failed sec_flg0 |
814 | 0 | #define relative_reloc_packed sec_flg1 |
815 | | |
816 | | extern bool _bfd_x86_elf_mkobject |
817 | | (bfd *) ATTRIBUTE_HIDDEN; |
818 | | |
819 | | extern void _bfd_x86_elf_set_tls_module_base |
820 | | (struct bfd_link_info *) ATTRIBUTE_HIDDEN; |
821 | | |
822 | | extern bfd_vma _bfd_x86_elf_dtpoff_base |
823 | | (struct bfd_link_info *) ATTRIBUTE_HIDDEN; |
824 | | |
825 | | extern bool _bfd_x86_elf_readonly_dynrelocs |
826 | | (struct elf_link_hash_entry *, void *) ATTRIBUTE_HIDDEN; |
827 | | |
828 | | extern struct elf_link_hash_entry * _bfd_elf_x86_get_local_sym_hash |
829 | | (struct elf_x86_link_hash_table *, bfd *, const Elf_Internal_Rela *, |
830 | | bool) ATTRIBUTE_HIDDEN; |
831 | | |
832 | | extern hashval_t _bfd_x86_elf_local_htab_hash |
833 | | (const void *) ATTRIBUTE_HIDDEN; |
834 | | |
835 | | extern int _bfd_x86_elf_local_htab_eq |
836 | | (const void *, const void *) ATTRIBUTE_HIDDEN; |
837 | | |
838 | | extern struct bfd_hash_entry * _bfd_x86_elf_link_hash_newfunc |
839 | | (struct bfd_hash_entry *, struct bfd_hash_table *, const char *) |
840 | | ATTRIBUTE_HIDDEN; |
841 | | |
842 | | extern struct bfd_link_hash_table * _bfd_x86_elf_link_hash_table_create |
843 | | (bfd *) ATTRIBUTE_HIDDEN; |
844 | | |
845 | | extern int _bfd_x86_elf_compare_relocs |
846 | | (const void *, const void *) ATTRIBUTE_HIDDEN; |
847 | | |
848 | | extern bool _bfd_x86_elf_link_check_relocs |
849 | | (bfd *, struct bfd_link_info *) ATTRIBUTE_HIDDEN; |
850 | | |
851 | | extern bool _bfd_x86_elf_check_relocs |
852 | | (bfd *, struct bfd_link_info *, asection *, |
853 | | const Elf_Internal_Rela *) ATTRIBUTE_HIDDEN; |
854 | | |
855 | | extern bool _bfd_x86_elf_link_relax_section |
856 | | (bfd *, asection *, struct bfd_link_info *, bool *) ATTRIBUTE_HIDDEN; |
857 | | |
858 | | extern bool _bfd_elf_x86_size_relative_relocs |
859 | | (struct bfd_link_info *, bool *) ATTRIBUTE_HIDDEN; |
860 | | |
861 | | extern bool _bfd_elf_x86_finish_relative_relocs |
862 | | (struct bfd_link_info *) ATTRIBUTE_HIDDEN; |
863 | | |
864 | | extern void _bfd_elf32_write_addend |
865 | | (bfd *, uint64_t, void *) ATTRIBUTE_HIDDEN; |
866 | | extern void _bfd_elf64_write_addend |
867 | | (bfd *, uint64_t, void *) ATTRIBUTE_HIDDEN; |
868 | | |
869 | | extern bool _bfd_elf_x86_valid_reloc_p |
870 | | (asection *, struct bfd_link_info *, struct elf_x86_link_hash_table *, |
871 | | const Elf_Internal_Rela *, struct elf_link_hash_entry *, |
872 | | Elf_Internal_Sym *, Elf_Internal_Shdr *, bool *) ATTRIBUTE_HIDDEN; |
873 | | |
874 | | extern bool _bfd_x86_elf_late_size_sections |
875 | | (bfd *, struct bfd_link_info *) ATTRIBUTE_HIDDEN; |
876 | | |
877 | | extern struct elf_x86_link_hash_table *_bfd_x86_elf_finish_dynamic_sections |
878 | | (bfd *, struct bfd_link_info *) ATTRIBUTE_HIDDEN; |
879 | | |
880 | | extern bool _bfd_x86_elf_early_size_sections |
881 | | (bfd *, struct bfd_link_info *) ATTRIBUTE_HIDDEN; |
882 | | |
883 | | extern void _bfd_x86_elf_merge_symbol_attribute |
884 | | (struct elf_link_hash_entry *, unsigned int, bool, bool) |
885 | | ATTRIBUTE_HIDDEN; |
886 | | |
887 | | extern void _bfd_x86_elf_copy_indirect_symbol |
888 | | (struct bfd_link_info *, struct elf_link_hash_entry *, |
889 | | struct elf_link_hash_entry *) ATTRIBUTE_HIDDEN; |
890 | | |
891 | | extern bool _bfd_x86_elf_fixup_symbol |
892 | | (struct bfd_link_info *, struct elf_link_hash_entry *) ATTRIBUTE_HIDDEN; |
893 | | |
894 | | extern bool _bfd_x86_elf_hash_symbol |
895 | | (struct elf_link_hash_entry *) ATTRIBUTE_HIDDEN; |
896 | | |
897 | | extern bool _bfd_x86_elf_adjust_dynamic_symbol |
898 | | (struct bfd_link_info *, struct elf_link_hash_entry *) ATTRIBUTE_HIDDEN; |
899 | | |
900 | | extern void _bfd_x86_elf_hide_symbol |
901 | | (struct bfd_link_info *, struct elf_link_hash_entry *, |
902 | | bool) ATTRIBUTE_HIDDEN; |
903 | | |
904 | | extern bool _bfd_x86_elf_link_symbol_references_local |
905 | | (struct bfd_link_info *, struct elf_link_hash_entry *) ATTRIBUTE_HIDDEN; |
906 | | |
907 | | extern asection * _bfd_x86_elf_gc_mark_hook |
908 | | (asection *, struct bfd_link_info *, Elf_Internal_Rela *, |
909 | | struct elf_link_hash_entry *, Elf_Internal_Sym *) ATTRIBUTE_HIDDEN; |
910 | | |
911 | | extern long _bfd_x86_elf_get_synthetic_symtab |
912 | | (bfd *, long, long, bfd_vma, struct elf_x86_plt [], asymbol **, |
913 | | asymbol **) ATTRIBUTE_HIDDEN; |
914 | | |
915 | | extern enum elf_property_kind _bfd_x86_elf_parse_gnu_properties |
916 | | (bfd *, unsigned int, bfd_byte *, unsigned int) ATTRIBUTE_HIDDEN; |
917 | | |
918 | | extern bool _bfd_x86_elf_merge_gnu_properties |
919 | | (struct bfd_link_info *, bfd *, bfd *, elf_property *, elf_property *) |
920 | | ATTRIBUTE_HIDDEN; |
921 | | |
922 | | extern void _bfd_x86_elf_link_fixup_gnu_properties |
923 | | (struct bfd_link_info *, elf_property_list **) ATTRIBUTE_HIDDEN; |
924 | | |
925 | | extern bfd * _bfd_x86_elf_link_setup_gnu_properties |
926 | | (struct bfd_link_info *, struct elf_x86_init_table *) ATTRIBUTE_HIDDEN; |
927 | | |
928 | | extern void _bfd_x86_elf_link_fixup_ifunc_symbol |
929 | | (struct bfd_link_info *, struct elf_x86_link_hash_table *, |
930 | | struct elf_link_hash_entry *, Elf_Internal_Sym *sym) ATTRIBUTE_HIDDEN; |
931 | | |
932 | | extern void _bfd_x86_elf_link_report_relative_reloc |
933 | | (struct bfd_link_info *, asection *, struct elf_link_hash_entry *, |
934 | | Elf_Internal_Sym *, const char *, const void *) ATTRIBUTE_HIDDEN; |
935 | | |
936 | | extern void _bfd_x86_elf_link_report_tls_transition_error |
937 | | (struct bfd_link_info *, bfd *, asection *, Elf_Internal_Shdr *, |
938 | | struct elf_link_hash_entry *, Elf_Internal_Sym *, |
939 | | const Elf_Internal_Rela *, const char *, const char *, |
940 | | enum elf_x86_tls_error_type); |
941 | | |
942 | | #define bfd_elf64_mkobject \ |
943 | | _bfd_x86_elf_mkobject |
944 | | #define bfd_elf32_mkobject \ |
945 | | _bfd_x86_elf_mkobject |
946 | | #define bfd_elf64_bfd_link_hash_table_create \ |
947 | | _bfd_x86_elf_link_hash_table_create |
948 | | #define bfd_elf32_bfd_link_hash_table_create \ |
949 | | _bfd_x86_elf_link_hash_table_create |
950 | | #define bfd_elf64_bfd_link_check_relocs \ |
951 | | _bfd_x86_elf_link_check_relocs |
952 | | #define bfd_elf32_bfd_link_check_relocs \ |
953 | | _bfd_x86_elf_link_check_relocs |
954 | | #define bfd_elf32_bfd_relax_section \ |
955 | | _bfd_x86_elf_link_relax_section |
956 | | #define bfd_elf64_bfd_relax_section \ |
957 | | _bfd_x86_elf_link_relax_section |
958 | | |
959 | | #define elf_backend_check_relocs \ |
960 | | _bfd_x86_elf_check_relocs |
961 | | #define elf_backend_late_size_sections \ |
962 | | _bfd_x86_elf_late_size_sections |
963 | | #define elf_backend_merge_symbol_attribute \ |
964 | | _bfd_x86_elf_merge_symbol_attribute |
965 | | #define elf_backend_copy_indirect_symbol \ |
966 | | _bfd_x86_elf_copy_indirect_symbol |
967 | | #define elf_backend_fixup_symbol \ |
968 | | _bfd_x86_elf_fixup_symbol |
969 | | #define elf_backend_hash_symbol \ |
970 | | _bfd_x86_elf_hash_symbol |
971 | | #define elf_backend_adjust_dynamic_symbol \ |
972 | | _bfd_x86_elf_adjust_dynamic_symbol |
973 | | #define elf_backend_gc_mark_hook \ |
974 | | _bfd_x86_elf_gc_mark_hook |
975 | | #define elf_backend_omit_section_dynsym \ |
976 | | _bfd_elf_omit_section_dynsym_all |
977 | | #define elf_backend_parse_gnu_properties \ |
978 | | _bfd_x86_elf_parse_gnu_properties |
979 | | #define elf_backend_merge_gnu_properties \ |
980 | | _bfd_x86_elf_merge_gnu_properties |
981 | | #define elf_backend_fixup_gnu_properties \ |
982 | | _bfd_x86_elf_link_fixup_gnu_properties |
983 | | #define elf_backend_size_relative_relocs \ |
984 | | _bfd_elf_x86_size_relative_relocs |
985 | | #define elf_backend_finish_relative_relocs \ |
986 | | _bfd_elf_x86_finish_relative_relocs |
987 | | #define elf_backend_use_mmap true |
988 | | |
989 | | #define ELF_P_ALIGN ELF_MINPAGESIZE |
990 | | |
991 | | /* Allocate x86 GOT info for local symbols. */ |
992 | | |
993 | | static inline bool |
994 | | elf_x86_allocate_local_got_info (bfd *abfd, bfd_size_type count) |
995 | 0 | { |
996 | 0 | bfd_signed_vma *local_got_refcounts = elf_local_got_refcounts (abfd); |
997 | 0 | if (local_got_refcounts == NULL) |
998 | 0 | { |
999 | 0 | bfd_size_type size = count * (sizeof (bfd_signed_vma) |
1000 | 0 | + sizeof (bfd_vma) |
1001 | 0 | + 2 * sizeof(char)); |
1002 | 0 | local_got_refcounts = (bfd_signed_vma *) bfd_zalloc (abfd, size); |
1003 | 0 | if (local_got_refcounts == NULL) |
1004 | 0 | return false; |
1005 | 0 | elf_local_got_refcounts (abfd) = local_got_refcounts; |
1006 | 0 | elf_x86_local_tlsdesc_gotent (abfd) = |
1007 | 0 | (bfd_vma *) (local_got_refcounts + count); |
1008 | 0 | elf_x86_local_got_tls_type (abfd) = |
1009 | 0 | (char *) (local_got_refcounts + 2 * count); |
1010 | 0 | elf_x86_relative_reloc_done (abfd) = |
1011 | 0 | ((char *) (local_got_refcounts + 2 * count)) + count; |
1012 | 0 | } |
1013 | 0 | return true; |
1014 | 0 | } Unexecuted instantiation: elf64-x86-64.c:elf_x86_allocate_local_got_info Unexecuted instantiation: elfxx-x86.c:elf_x86_allocate_local_got_info Unexecuted instantiation: elf32-i386.c:elf_x86_allocate_local_got_info |