/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-2024 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 | 65.9k | (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 | | |
406 | | struct elf_x86_lazy_plt_layout |
407 | | { |
408 | | /* The first entry in a lazy procedure linkage table looks like this. */ |
409 | | const bfd_byte *plt0_entry; |
410 | | unsigned int plt0_entry_size; /* Size of PLT0 entry. */ |
411 | | |
412 | | /* Later entries in a lazy procedure linkage table look like this. */ |
413 | | const bfd_byte *plt_entry; |
414 | | unsigned int plt_entry_size; /* Size of each PLT entry. */ |
415 | | |
416 | | /* The TLSDESC entry in a lazy procedure linkage table looks like |
417 | | this. This is for x86-64 only. */ |
418 | | const bfd_byte *plt_tlsdesc_entry; |
419 | | unsigned int plt_tlsdesc_entry_size; /* Size of TLSDESC entry. */ |
420 | | |
421 | | /* Offsets into the TLSDESC entry that are to be replaced with |
422 | | GOT+8 and GOT+TDG. These are for x86-64 only. */ |
423 | | unsigned int plt_tlsdesc_got1_offset; |
424 | | unsigned int plt_tlsdesc_got2_offset; |
425 | | |
426 | | /* Offset of the end of the PC-relative instructions containing |
427 | | plt_tlsdesc_got1_offset and plt_tlsdesc_got2_offset. These |
428 | | are for x86-64 only. */ |
429 | | unsigned int plt_tlsdesc_got1_insn_end; |
430 | | unsigned int plt_tlsdesc_got2_insn_end; |
431 | | |
432 | | /* Offsets into plt0_entry that are to be replaced with GOT[1] and |
433 | | GOT[2]. */ |
434 | | unsigned int plt0_got1_offset; |
435 | | unsigned int plt0_got2_offset; |
436 | | |
437 | | /* Offset of the end of the PC-relative instruction containing |
438 | | plt0_got2_offset. This is for x86-64 only. */ |
439 | | unsigned int plt0_got2_insn_end; |
440 | | |
441 | | /* Offsets into plt_entry that are to be replaced with... */ |
442 | | unsigned int plt_got_offset; /* ... address of this symbol in .got. */ |
443 | | unsigned int plt_reloc_offset; /* ... offset into relocation table. */ |
444 | | unsigned int plt_plt_offset; /* ... offset to start of .plt. */ |
445 | | |
446 | | /* Length of the PC-relative instruction containing plt_got_offset. |
447 | | This is used for x86-64 only. */ |
448 | | unsigned int plt_got_insn_size; |
449 | | |
450 | | /* Offset of the end of the PC-relative jump to plt0_entry. This is |
451 | | used for x86-64 only. */ |
452 | | unsigned int plt_plt_insn_end; |
453 | | |
454 | | /* Offset into plt_entry where the initial value of the GOT entry |
455 | | points. */ |
456 | | unsigned int plt_lazy_offset; |
457 | | |
458 | | /* The first entry in a PIC lazy procedure linkage table looks like |
459 | | this. */ |
460 | | const bfd_byte *pic_plt0_entry; |
461 | | |
462 | | /* Subsequent entries in a PIC lazy procedure linkage table look |
463 | | like this. */ |
464 | | const bfd_byte *pic_plt_entry; |
465 | | |
466 | | /* .eh_frame covering the lazy .plt section. */ |
467 | | const bfd_byte *eh_frame_plt; |
468 | | unsigned int eh_frame_plt_size; |
469 | | }; |
470 | | |
471 | | struct elf_x86_non_lazy_plt_layout |
472 | | { |
473 | | /* Entries in a non-lazy procedure linkage table look like this. */ |
474 | | const bfd_byte *plt_entry; |
475 | | /* Entries in a PIC non-lazy procedure linkage table look like this. |
476 | | This is only used for i386 where absolute PLT and PIC PLT are |
477 | | different. */ |
478 | | const bfd_byte *pic_plt_entry; |
479 | | |
480 | | unsigned int plt_entry_size; /* Size of each PLT entry. */ |
481 | | |
482 | | /* Offsets into plt_entry that are to be replaced with... */ |
483 | | unsigned int plt_got_offset; /* ... address of this symbol in .got. */ |
484 | | |
485 | | /* Length of the PC-relative instruction containing plt_got_offset. |
486 | | This is used for x86-64 only. */ |
487 | | unsigned int plt_got_insn_size; |
488 | | |
489 | | /* .eh_frame covering the non-lazy .plt section. */ |
490 | | const bfd_byte *eh_frame_plt; |
491 | | unsigned int eh_frame_plt_size; |
492 | | }; |
493 | | |
494 | | struct elf_x86_plt_layout |
495 | | { |
496 | | /* The first entry in a lazy procedure linkage table looks like this. */ |
497 | | const bfd_byte *plt0_entry; |
498 | | /* Entries in a procedure linkage table look like this. */ |
499 | | const bfd_byte *plt_entry; |
500 | | unsigned int plt_entry_size; /* Size of each PLT entry. */ |
501 | | |
502 | | /* 1 has PLT0. */ |
503 | | unsigned int has_plt0; |
504 | | |
505 | | /* Offset of indirect branch in plt_entry. */ |
506 | | unsigned int plt_indirect_branch_offset; |
507 | | |
508 | | /* Offsets into plt_entry that are to be replaced with... */ |
509 | | unsigned int plt_got_offset; /* ... address of this symbol in .got. */ |
510 | | |
511 | | /* Length of the PC-relative instruction containing plt_got_offset. |
512 | | This is only used for x86-64. */ |
513 | | unsigned int plt_got_insn_size; |
514 | | |
515 | | /* Alignment of the .iplt section. */ |
516 | | unsigned int iplt_alignment; |
517 | | |
518 | | /* .eh_frame covering the .plt section. */ |
519 | | const bfd_byte *eh_frame_plt; |
520 | | unsigned int eh_frame_plt_size; |
521 | | }; |
522 | | |
523 | | /* Values in tls_type of x86 ELF linker hash entry. */ |
524 | 0 | #define GOT_UNKNOWN 0 |
525 | 0 | #define GOT_NORMAL 1 |
526 | 0 | #define GOT_TLS_GD 2 |
527 | 0 | #define GOT_TLS_IE 4 |
528 | 0 | #define GOT_TLS_IE_POS 5 |
529 | 0 | #define GOT_TLS_IE_NEG 6 |
530 | 0 | #define GOT_TLS_IE_BOTH 7 |
531 | 0 | #define GOT_TLS_GDESC 8 |
532 | 0 | #define GOT_ABS 9 |
533 | | #define GOT_TLS_GD_BOTH_P(type) \ |
534 | 0 | ((type) == (GOT_TLS_GD | GOT_TLS_GDESC)) |
535 | | #define GOT_TLS_GD_P(type) \ |
536 | 0 | ((type) == GOT_TLS_GD || GOT_TLS_GD_BOTH_P (type)) |
537 | | #define GOT_TLS_GDESC_P(type) \ |
538 | 0 | ((type) == GOT_TLS_GDESC || GOT_TLS_GD_BOTH_P (type)) |
539 | | #define GOT_TLS_GD_ANY_P(type) \ |
540 | 0 | (GOT_TLS_GD_P (type) || GOT_TLS_GDESC_P (type)) |
541 | | |
542 | | #define elf_x86_hash_entry(ent) \ |
543 | 0 | ((struct elf_x86_link_hash_entry *)(ent)) |
544 | | |
545 | | /* Information of an input relocation used to compute its contribution |
546 | | to the DT_RELR section size. */ |
547 | | |
548 | | struct elf_x86_relative_reloc_record |
549 | | { |
550 | | /* The original relocation info. */ |
551 | | Elf_Internal_Rela rel; |
552 | | /* The input or the GOT section where the relocation is applied. */ |
553 | | asection *sec; |
554 | | /* Local symbol info. NULL for global symbol. */ |
555 | | Elf_Internal_Sym *sym; |
556 | | union |
557 | | { |
558 | | /* Section where the local symbol is defined. */ |
559 | | asection *sym_sec; |
560 | | /* Global symbol hash. */ |
561 | | struct elf_link_hash_entry *h; |
562 | | } u; |
563 | | /* The offset into the output section where the relative relocation |
564 | | will be applied at run-time. */ |
565 | | bfd_vma offset; |
566 | | /* The run-time address. */ |
567 | | bfd_vma address; |
568 | | }; |
569 | | |
570 | | struct elf_x86_relative_reloc_data |
571 | | { |
572 | | bfd_size_type count; |
573 | | bfd_size_type size; |
574 | | struct elf_x86_relative_reloc_record *data; |
575 | | }; |
576 | | |
577 | | /* DT_RELR bitmap. */ |
578 | | struct elf_dt_relr_bitmap |
579 | | { |
580 | | bfd_size_type count; |
581 | | bfd_size_type size; |
582 | | union |
583 | | { |
584 | | /* 32-bit bitmap. */ |
585 | | uint32_t *elf32; |
586 | | /* 64-bit bitmap. */ |
587 | | uint64_t *elf64; |
588 | | } u; |
589 | | }; |
590 | | |
591 | | /* x86 ELF linker hash table. */ |
592 | | |
593 | | struct elf_x86_link_hash_table |
594 | | { |
595 | | struct elf_link_hash_table elf; |
596 | | |
597 | | /* Short-cuts to get to dynamic linker sections. */ |
598 | | asection *interp; |
599 | | asection *plt_eh_frame; |
600 | | asection *plt_second; |
601 | | asection *plt_second_eh_frame; |
602 | | asection *plt_got; |
603 | | asection *plt_got_eh_frame; |
604 | | |
605 | | sframe_encoder_ctx *plt_cfe_ctx; |
606 | | asection *plt_sframe; |
607 | | sframe_encoder_ctx *plt_second_cfe_ctx; |
608 | | asection *plt_second_sframe; |
609 | | |
610 | | /* Parameters describing PLT generation, lazy or non-lazy. */ |
611 | | struct elf_x86_plt_layout plt; |
612 | | |
613 | | /* Parameters describing lazy PLT generation. */ |
614 | | const struct elf_x86_lazy_plt_layout *lazy_plt; |
615 | | |
616 | | /* Parameters describing non-lazy PLT generation. */ |
617 | | const struct elf_x86_non_lazy_plt_layout *non_lazy_plt; |
618 | | |
619 | | /* The .sframe helper object for .plt section. |
620 | | This is used for x86-64 only. */ |
621 | | const struct elf_x86_sframe_plt *sframe_plt; |
622 | | |
623 | | union |
624 | | { |
625 | | bfd_signed_vma refcount; |
626 | | bfd_vma offset; |
627 | | } tls_ld_or_ldm_got; |
628 | | |
629 | | /* The amount of space used by the jump slots in the GOT. */ |
630 | | bfd_vma sgotplt_jump_table_size; |
631 | | |
632 | | /* _TLS_MODULE_BASE_ symbol. */ |
633 | | struct bfd_link_hash_entry *tls_module_base; |
634 | | |
635 | | /* Used by local STT_GNU_IFUNC symbols. */ |
636 | | htab_t loc_hash_table; |
637 | | void * loc_hash_memory; |
638 | | |
639 | | /* The index of the next R_X86_64_JUMP_SLOT entry in .rela.plt. */ |
640 | | bfd_vma next_jump_slot_index; |
641 | | /* The index of the next R_X86_64_IRELATIVE entry in .rela.plt. */ |
642 | | bfd_vma next_irelative_index; |
643 | | |
644 | | /* The (unloaded but important) .rel.plt.unloaded section on VxWorks. |
645 | | This is used for i386 only. */ |
646 | | asection *srelplt2; |
647 | | |
648 | | /* The index of the next unused R_386_TLS_DESC slot in .rel.plt. This |
649 | | is only used for i386. */ |
650 | | bfd_vma next_tls_desc_index; |
651 | | |
652 | | /* DT_RELR bitmap. */ |
653 | | struct elf_dt_relr_bitmap dt_relr_bitmap; |
654 | | |
655 | | /* Relative relocation data. */ |
656 | | struct elf_x86_relative_reloc_data relative_reloc; |
657 | | |
658 | | /* Unaligned relative relocation data. */ |
659 | | struct elf_x86_relative_reloc_data unaligned_relative_reloc; |
660 | | |
661 | | /* Number of relative reloc generation pass. */ |
662 | | unsigned int generate_relative_reloc_pass; |
663 | | |
664 | | /* Value used to fill the unused bytes of the first PLT entry. This |
665 | | is only used for i386. */ |
666 | | bfd_byte plt0_pad_byte; |
667 | | |
668 | | /* TRUE if GOT is referenced. */ |
669 | | unsigned int got_referenced : 1; |
670 | | |
671 | | /* TRUE if PLT is PC-relative. PLT in PDE and PC-relative PLT in PIE |
672 | | can be used as function address. |
673 | | |
674 | | NB: i386 has non-PIC PLT and PIC PLT. Only non-PIC PLT in PDE can |
675 | | be used as function address. PIC PLT in PIE can't be used as |
676 | | function address. */ |
677 | | unsigned int pcrel_plt : 1; |
678 | | |
679 | | bfd_vma (*r_info) (bfd_vma, bfd_vma); |
680 | | bfd_vma (*r_sym) (bfd_vma); |
681 | | bool (*is_reloc_section) (const char *); |
682 | | unsigned int sizeof_reloc; |
683 | | unsigned int got_entry_size; |
684 | | unsigned int pointer_r_type; |
685 | | unsigned int relative_r_type; |
686 | | int dynamic_interpreter_size; |
687 | | const char *dynamic_interpreter; |
688 | | const char *tls_get_addr; |
689 | | const char *relative_r_name; |
690 | | void (*elf_append_reloc) (bfd *, asection *, Elf_Internal_Rela *); |
691 | | void (*elf_write_addend) (bfd *, uint64_t, void *); |
692 | | void (*elf_write_addend_in_got) (bfd *, uint64_t, void *); |
693 | | |
694 | | /* Options passed from the linker. */ |
695 | | struct elf_linker_x86_params *params; |
696 | | }; |
697 | | |
698 | | struct elf_x86_init_table |
699 | | { |
700 | | /* The lazy PLT layout. */ |
701 | | const struct elf_x86_lazy_plt_layout *lazy_plt; |
702 | | |
703 | | /* The non-lazy PLT layout. */ |
704 | | const struct elf_x86_non_lazy_plt_layout *non_lazy_plt; |
705 | | |
706 | | /* The lazy PLT layout for IBT. */ |
707 | | const struct elf_x86_lazy_plt_layout *lazy_ibt_plt; |
708 | | |
709 | | /* The non-lazy PLT layout for IBT. */ |
710 | | const struct elf_x86_non_lazy_plt_layout *non_lazy_ibt_plt; |
711 | | |
712 | | /* The .sframe helper object for lazy .plt section. |
713 | | This is used for x86-64 only. */ |
714 | | const struct elf_x86_sframe_plt *sframe_lazy_plt; |
715 | | |
716 | | /* The .sframe helper object for non-lazy .plt section. |
717 | | This is used for x86-64 only. */ |
718 | | const struct elf_x86_sframe_plt *sframe_non_lazy_plt; |
719 | | |
720 | | /* The .sframe helper object for lazy IBT .plt section. |
721 | | This is used for x86-64 only. */ |
722 | | const struct elf_x86_sframe_plt *sframe_lazy_ibt_plt; |
723 | | |
724 | | /* The .sframe helper object for non-lazy IBT .plt section. |
725 | | This is used for x86-64 only. */ |
726 | | const struct elf_x86_sframe_plt *sframe_non_lazy_ibt_plt; |
727 | | |
728 | | bfd_byte plt0_pad_byte; |
729 | | |
730 | | bfd_vma (*r_info) (bfd_vma, bfd_vma); |
731 | | bfd_vma (*r_sym) (bfd_vma); |
732 | | }; |
733 | | |
734 | | struct elf_x86_obj_tdata |
735 | | { |
736 | | struct elf_obj_tdata root; |
737 | | |
738 | | /* tls_type for each local got entry. */ |
739 | | char *local_got_tls_type; |
740 | | |
741 | | /* GOTPLT entries for TLS descriptors. */ |
742 | | bfd_vma *local_tlsdesc_gotent; |
743 | | |
744 | | /* R_*_RELATIVE relocation in GOT for this local symbol has been |
745 | | processed. */ |
746 | | char *relative_reloc_done; |
747 | | }; |
748 | | |
749 | | enum elf_x86_plt_type |
750 | | { |
751 | | plt_non_lazy = 0, |
752 | | plt_lazy = 1 << 0, |
753 | | plt_pic = 1 << 1, |
754 | | plt_second = 1 << 2, |
755 | | plt_unknown = -1 |
756 | | }; |
757 | | |
758 | | struct elf_x86_plt |
759 | | { |
760 | | const char *name; |
761 | | asection *sec; |
762 | | bfd_byte *contents; |
763 | | enum elf_x86_plt_type type; |
764 | | unsigned int plt_got_offset; |
765 | | unsigned int plt_entry_size; |
766 | | unsigned int plt_got_insn_size; /* Only used for x86-64. */ |
767 | | long count; |
768 | | }; |
769 | | |
770 | | /* Set if a relocation is converted from a GOTPCREL relocation. */ |
771 | 0 | #define R_X86_64_converted_reloc_bit (1 << 7) |
772 | | |
773 | | #define elf_x86_tdata(abfd) \ |
774 | 0 | ((struct elf_x86_obj_tdata *) (abfd)->tdata.any) |
775 | | |
776 | | #define elf_x86_local_got_tls_type(abfd) \ |
777 | 0 | (elf_x86_tdata (abfd)->local_got_tls_type) |
778 | | |
779 | | #define elf_x86_local_tlsdesc_gotent(abfd) \ |
780 | 0 | (elf_x86_tdata (abfd)->local_tlsdesc_gotent) |
781 | | |
782 | | #define elf_x86_relative_reloc_done(abfd) \ |
783 | 0 | (elf_x86_tdata (abfd)->relative_reloc_done) |
784 | | |
785 | | #define elf_x86_compute_jump_table_size(htab) \ |
786 | 0 | ((htab)->elf.srelplt->reloc_count * (htab)->got_entry_size) |
787 | | |
788 | | #define is_x86_elf(bfd, htab) \ |
789 | 0 | (bfd_get_flavour (bfd) == bfd_target_elf_flavour \ |
790 | 0 | && elf_tdata (bfd) != NULL \ |
791 | 0 | && elf_object_id (bfd) == (htab)->elf.hash_table_id) |
792 | | |
793 | | /* Rename some of the generic section flags to better document how they |
794 | | are used here. */ |
795 | 0 | #define check_relocs_failed sec_flg0 |
796 | 0 | #define relative_reloc_packed sec_flg1 |
797 | | |
798 | | extern bool _bfd_x86_elf_mkobject |
799 | | (bfd *) ATTRIBUTE_HIDDEN; |
800 | | |
801 | | extern void _bfd_x86_elf_set_tls_module_base |
802 | | (struct bfd_link_info *) ATTRIBUTE_HIDDEN; |
803 | | |
804 | | extern bfd_vma _bfd_x86_elf_dtpoff_base |
805 | | (struct bfd_link_info *) ATTRIBUTE_HIDDEN; |
806 | | |
807 | | extern bool _bfd_x86_elf_readonly_dynrelocs |
808 | | (struct elf_link_hash_entry *, void *) ATTRIBUTE_HIDDEN; |
809 | | |
810 | | extern struct elf_link_hash_entry * _bfd_elf_x86_get_local_sym_hash |
811 | | (struct elf_x86_link_hash_table *, bfd *, const Elf_Internal_Rela *, |
812 | | bool) ATTRIBUTE_HIDDEN; |
813 | | |
814 | | extern hashval_t _bfd_x86_elf_local_htab_hash |
815 | | (const void *) ATTRIBUTE_HIDDEN; |
816 | | |
817 | | extern int _bfd_x86_elf_local_htab_eq |
818 | | (const void *, const void *) ATTRIBUTE_HIDDEN; |
819 | | |
820 | | extern struct bfd_hash_entry * _bfd_x86_elf_link_hash_newfunc |
821 | | (struct bfd_hash_entry *, struct bfd_hash_table *, const char *) |
822 | | ATTRIBUTE_HIDDEN; |
823 | | |
824 | | extern struct bfd_link_hash_table * _bfd_x86_elf_link_hash_table_create |
825 | | (bfd *) ATTRIBUTE_HIDDEN; |
826 | | |
827 | | extern int _bfd_x86_elf_compare_relocs |
828 | | (const void *, const void *) ATTRIBUTE_HIDDEN; |
829 | | |
830 | | extern bool _bfd_x86_elf_link_check_relocs |
831 | | (bfd *, struct bfd_link_info *) ATTRIBUTE_HIDDEN; |
832 | | |
833 | | extern bool _bfd_x86_elf_check_relocs |
834 | | (bfd *, struct bfd_link_info *, asection *, |
835 | | const Elf_Internal_Rela *) ATTRIBUTE_HIDDEN; |
836 | | |
837 | | extern bool _bfd_x86_elf_link_relax_section |
838 | | (bfd *, asection *, struct bfd_link_info *, bool *) ATTRIBUTE_HIDDEN; |
839 | | |
840 | | extern bool _bfd_elf_x86_size_relative_relocs |
841 | | (struct bfd_link_info *, bool *) ATTRIBUTE_HIDDEN; |
842 | | |
843 | | extern bool _bfd_elf_x86_finish_relative_relocs |
844 | | (struct bfd_link_info *) ATTRIBUTE_HIDDEN; |
845 | | |
846 | | extern void _bfd_elf32_write_addend |
847 | | (bfd *, uint64_t, void *) ATTRIBUTE_HIDDEN; |
848 | | extern void _bfd_elf64_write_addend |
849 | | (bfd *, uint64_t, void *) ATTRIBUTE_HIDDEN; |
850 | | |
851 | | extern bool _bfd_elf_x86_valid_reloc_p |
852 | | (asection *, struct bfd_link_info *, struct elf_x86_link_hash_table *, |
853 | | const Elf_Internal_Rela *, struct elf_link_hash_entry *, |
854 | | Elf_Internal_Sym *, Elf_Internal_Shdr *, bool *) ATTRIBUTE_HIDDEN; |
855 | | |
856 | | extern bool _bfd_x86_elf_late_size_sections |
857 | | (bfd *, struct bfd_link_info *) ATTRIBUTE_HIDDEN; |
858 | | |
859 | | extern struct elf_x86_link_hash_table *_bfd_x86_elf_finish_dynamic_sections |
860 | | (bfd *, struct bfd_link_info *) ATTRIBUTE_HIDDEN; |
861 | | |
862 | | extern bool _bfd_x86_elf_early_size_sections |
863 | | (bfd *, struct bfd_link_info *) ATTRIBUTE_HIDDEN; |
864 | | |
865 | | extern void _bfd_x86_elf_merge_symbol_attribute |
866 | | (struct elf_link_hash_entry *, unsigned int, bool, bool) |
867 | | ATTRIBUTE_HIDDEN; |
868 | | |
869 | | extern void _bfd_x86_elf_copy_indirect_symbol |
870 | | (struct bfd_link_info *, struct elf_link_hash_entry *, |
871 | | struct elf_link_hash_entry *) ATTRIBUTE_HIDDEN; |
872 | | |
873 | | extern bool _bfd_x86_elf_fixup_symbol |
874 | | (struct bfd_link_info *, struct elf_link_hash_entry *) ATTRIBUTE_HIDDEN; |
875 | | |
876 | | extern bool _bfd_x86_elf_hash_symbol |
877 | | (struct elf_link_hash_entry *) ATTRIBUTE_HIDDEN; |
878 | | |
879 | | extern bool _bfd_x86_elf_adjust_dynamic_symbol |
880 | | (struct bfd_link_info *, struct elf_link_hash_entry *) ATTRIBUTE_HIDDEN; |
881 | | |
882 | | extern void _bfd_x86_elf_hide_symbol |
883 | | (struct bfd_link_info *, struct elf_link_hash_entry *, |
884 | | bool) ATTRIBUTE_HIDDEN; |
885 | | |
886 | | extern bool _bfd_x86_elf_link_symbol_references_local |
887 | | (struct bfd_link_info *, struct elf_link_hash_entry *) ATTRIBUTE_HIDDEN; |
888 | | |
889 | | extern asection * _bfd_x86_elf_gc_mark_hook |
890 | | (asection *, struct bfd_link_info *, Elf_Internal_Rela *, |
891 | | struct elf_link_hash_entry *, Elf_Internal_Sym *) ATTRIBUTE_HIDDEN; |
892 | | |
893 | | extern long _bfd_x86_elf_get_synthetic_symtab |
894 | | (bfd *, long, long, bfd_vma, struct elf_x86_plt [], asymbol **, |
895 | | asymbol **) ATTRIBUTE_HIDDEN; |
896 | | |
897 | | extern enum elf_property_kind _bfd_x86_elf_parse_gnu_properties |
898 | | (bfd *, unsigned int, bfd_byte *, unsigned int) ATTRIBUTE_HIDDEN; |
899 | | |
900 | | extern bool _bfd_x86_elf_merge_gnu_properties |
901 | | (struct bfd_link_info *, bfd *, bfd *, elf_property *, elf_property *) |
902 | | ATTRIBUTE_HIDDEN; |
903 | | |
904 | | extern void _bfd_x86_elf_link_fixup_gnu_properties |
905 | | (struct bfd_link_info *, elf_property_list **) ATTRIBUTE_HIDDEN; |
906 | | |
907 | | extern bfd * _bfd_x86_elf_link_setup_gnu_properties |
908 | | (struct bfd_link_info *, struct elf_x86_init_table *) ATTRIBUTE_HIDDEN; |
909 | | |
910 | | extern void _bfd_x86_elf_link_fixup_ifunc_symbol |
911 | | (struct bfd_link_info *, struct elf_x86_link_hash_table *, |
912 | | struct elf_link_hash_entry *, Elf_Internal_Sym *sym) ATTRIBUTE_HIDDEN; |
913 | | |
914 | | extern void _bfd_x86_elf_link_report_relative_reloc |
915 | | (struct bfd_link_info *, asection *, struct elf_link_hash_entry *, |
916 | | Elf_Internal_Sym *, const char *, const void *) ATTRIBUTE_HIDDEN; |
917 | | |
918 | | #define bfd_elf64_mkobject \ |
919 | | _bfd_x86_elf_mkobject |
920 | | #define bfd_elf32_mkobject \ |
921 | | _bfd_x86_elf_mkobject |
922 | | #define bfd_elf64_bfd_link_hash_table_create \ |
923 | | _bfd_x86_elf_link_hash_table_create |
924 | | #define bfd_elf32_bfd_link_hash_table_create \ |
925 | | _bfd_x86_elf_link_hash_table_create |
926 | | #define bfd_elf64_bfd_link_check_relocs \ |
927 | | _bfd_x86_elf_link_check_relocs |
928 | | #define bfd_elf32_bfd_link_check_relocs \ |
929 | | _bfd_x86_elf_link_check_relocs |
930 | | #define bfd_elf32_bfd_relax_section \ |
931 | | _bfd_x86_elf_link_relax_section |
932 | | #define bfd_elf64_bfd_relax_section \ |
933 | | _bfd_x86_elf_link_relax_section |
934 | | |
935 | | #define elf_backend_check_relocs \ |
936 | | _bfd_x86_elf_check_relocs |
937 | | #define elf_backend_late_size_sections \ |
938 | | _bfd_x86_elf_late_size_sections |
939 | | #define elf_backend_merge_symbol_attribute \ |
940 | | _bfd_x86_elf_merge_symbol_attribute |
941 | | #define elf_backend_copy_indirect_symbol \ |
942 | | _bfd_x86_elf_copy_indirect_symbol |
943 | | #define elf_backend_fixup_symbol \ |
944 | | _bfd_x86_elf_fixup_symbol |
945 | | #define elf_backend_hash_symbol \ |
946 | | _bfd_x86_elf_hash_symbol |
947 | | #define elf_backend_adjust_dynamic_symbol \ |
948 | | _bfd_x86_elf_adjust_dynamic_symbol |
949 | | #define elf_backend_gc_mark_hook \ |
950 | | _bfd_x86_elf_gc_mark_hook |
951 | | #define elf_backend_omit_section_dynsym \ |
952 | | _bfd_elf_omit_section_dynsym_all |
953 | | #define elf_backend_parse_gnu_properties \ |
954 | | _bfd_x86_elf_parse_gnu_properties |
955 | | #define elf_backend_merge_gnu_properties \ |
956 | | _bfd_x86_elf_merge_gnu_properties |
957 | | #define elf_backend_fixup_gnu_properties \ |
958 | | _bfd_x86_elf_link_fixup_gnu_properties |
959 | | #define elf_backend_size_relative_relocs \ |
960 | | _bfd_elf_x86_size_relative_relocs |
961 | | #define elf_backend_finish_relative_relocs \ |
962 | | _bfd_elf_x86_finish_relative_relocs |
963 | | #define elf_backend_use_mmap true |
964 | | |
965 | | #define ELF_P_ALIGN ELF_MINPAGESIZE |
966 | | |
967 | | /* Allocate x86 GOT info for local symbols. */ |
968 | | |
969 | | static inline bool |
970 | | elf_x86_allocate_local_got_info (bfd *abfd, bfd_size_type count) |
971 | 0 | { |
972 | 0 | bfd_signed_vma *local_got_refcounts = elf_local_got_refcounts (abfd); |
973 | 0 | if (local_got_refcounts == NULL) |
974 | 0 | { |
975 | 0 | bfd_size_type size = count * (sizeof (bfd_signed_vma) |
976 | 0 | + sizeof (bfd_vma) |
977 | 0 | + 2 * sizeof(char)); |
978 | 0 | local_got_refcounts = (bfd_signed_vma *) bfd_zalloc (abfd, size); |
979 | 0 | if (local_got_refcounts == NULL) |
980 | 0 | return false; |
981 | 0 | elf_local_got_refcounts (abfd) = local_got_refcounts; |
982 | 0 | elf_x86_local_tlsdesc_gotent (abfd) = |
983 | 0 | (bfd_vma *) (local_got_refcounts + count); |
984 | 0 | elf_x86_local_got_tls_type (abfd) = |
985 | 0 | (char *) (local_got_refcounts + 2 * count); |
986 | 0 | elf_x86_relative_reloc_done (abfd) = |
987 | 0 | ((char *) (local_got_refcounts + 2 * count)) + count; |
988 | 0 | } |
989 | 0 | return true; |
990 | 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 |