elf32-i386.c revision 1.10 1 1.1 skrll /* Intel 80386/80486-specific support for 32-bit ELF
2 1.10 christos Copyright (C) 1993-2018 Free Software Foundation, Inc.
3 1.1 skrll
4 1.1 skrll This file is part of BFD, the Binary File Descriptor library.
5 1.1 skrll
6 1.1 skrll This program is free software; you can redistribute it and/or modify
7 1.1 skrll it under the terms of the GNU General Public License as published by
8 1.1 skrll the Free Software Foundation; either version 3 of the License, or
9 1.1 skrll (at your option) any later version.
10 1.1 skrll
11 1.1 skrll This program is distributed in the hope that it will be useful,
12 1.1 skrll but WITHOUT ANY WARRANTY; without even the implied warranty of
13 1.1 skrll MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 1.1 skrll GNU General Public License for more details.
15 1.1 skrll
16 1.1 skrll You should have received a copy of the GNU General Public License
17 1.1 skrll along with this program; if not, write to the Free Software
18 1.1 skrll Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
19 1.1 skrll MA 02110-1301, USA. */
20 1.1 skrll
21 1.10 christos #include "elfxx-x86.h"
22 1.5 christos #include "elf-nacl.h"
23 1.1 skrll #include "elf-vxworks.h"
24 1.5 christos #include "dwarf2.h"
25 1.6 christos #include "opcode/i386.h"
26 1.1 skrll
27 1.1 skrll /* 386 uses REL relocations instead of RELA. */
28 1.1 skrll #define USE_REL 1
29 1.1 skrll
30 1.1 skrll #include "elf/i386.h"
31 1.1 skrll
32 1.1 skrll static reloc_howto_type elf_howto_table[]=
33 1.1 skrll {
34 1.6 christos HOWTO(R_386_NONE, 0, 3, 0, FALSE, 0, complain_overflow_dont,
35 1.1 skrll bfd_elf_generic_reloc, "R_386_NONE",
36 1.1 skrll TRUE, 0x00000000, 0x00000000, FALSE),
37 1.1 skrll HOWTO(R_386_32, 0, 2, 32, FALSE, 0, complain_overflow_bitfield,
38 1.1 skrll bfd_elf_generic_reloc, "R_386_32",
39 1.1 skrll TRUE, 0xffffffff, 0xffffffff, FALSE),
40 1.1 skrll HOWTO(R_386_PC32, 0, 2, 32, TRUE, 0, complain_overflow_bitfield,
41 1.1 skrll bfd_elf_generic_reloc, "R_386_PC32",
42 1.1 skrll TRUE, 0xffffffff, 0xffffffff, TRUE),
43 1.1 skrll HOWTO(R_386_GOT32, 0, 2, 32, FALSE, 0, complain_overflow_bitfield,
44 1.1 skrll bfd_elf_generic_reloc, "R_386_GOT32",
45 1.1 skrll TRUE, 0xffffffff, 0xffffffff, FALSE),
46 1.1 skrll HOWTO(R_386_PLT32, 0, 2, 32, TRUE, 0, complain_overflow_bitfield,
47 1.1 skrll bfd_elf_generic_reloc, "R_386_PLT32",
48 1.1 skrll TRUE, 0xffffffff, 0xffffffff, TRUE),
49 1.1 skrll HOWTO(R_386_COPY, 0, 2, 32, FALSE, 0, complain_overflow_bitfield,
50 1.1 skrll bfd_elf_generic_reloc, "R_386_COPY",
51 1.1 skrll TRUE, 0xffffffff, 0xffffffff, FALSE),
52 1.1 skrll HOWTO(R_386_GLOB_DAT, 0, 2, 32, FALSE, 0, complain_overflow_bitfield,
53 1.1 skrll bfd_elf_generic_reloc, "R_386_GLOB_DAT",
54 1.1 skrll TRUE, 0xffffffff, 0xffffffff, FALSE),
55 1.1 skrll HOWTO(R_386_JUMP_SLOT, 0, 2, 32, FALSE, 0, complain_overflow_bitfield,
56 1.1 skrll bfd_elf_generic_reloc, "R_386_JUMP_SLOT",
57 1.1 skrll TRUE, 0xffffffff, 0xffffffff, FALSE),
58 1.1 skrll HOWTO(R_386_RELATIVE, 0, 2, 32, FALSE, 0, complain_overflow_bitfield,
59 1.1 skrll bfd_elf_generic_reloc, "R_386_RELATIVE",
60 1.1 skrll TRUE, 0xffffffff, 0xffffffff, FALSE),
61 1.1 skrll HOWTO(R_386_GOTOFF, 0, 2, 32, FALSE, 0, complain_overflow_bitfield,
62 1.1 skrll bfd_elf_generic_reloc, "R_386_GOTOFF",
63 1.1 skrll TRUE, 0xffffffff, 0xffffffff, FALSE),
64 1.1 skrll HOWTO(R_386_GOTPC, 0, 2, 32, TRUE, 0, complain_overflow_bitfield,
65 1.1 skrll bfd_elf_generic_reloc, "R_386_GOTPC",
66 1.1 skrll TRUE, 0xffffffff, 0xffffffff, TRUE),
67 1.1 skrll
68 1.1 skrll /* We have a gap in the reloc numbers here.
69 1.1 skrll R_386_standard counts the number up to this point, and
70 1.1 skrll R_386_ext_offset is the value to subtract from a reloc type of
71 1.1 skrll R_386_16 thru R_386_PC8 to form an index into this table. */
72 1.1 skrll #define R_386_standard (R_386_GOTPC + 1)
73 1.1 skrll #define R_386_ext_offset (R_386_TLS_TPOFF - R_386_standard)
74 1.1 skrll
75 1.1 skrll /* These relocs are a GNU extension. */
76 1.1 skrll HOWTO(R_386_TLS_TPOFF, 0, 2, 32, FALSE, 0, complain_overflow_bitfield,
77 1.1 skrll bfd_elf_generic_reloc, "R_386_TLS_TPOFF",
78 1.1 skrll TRUE, 0xffffffff, 0xffffffff, FALSE),
79 1.1 skrll HOWTO(R_386_TLS_IE, 0, 2, 32, FALSE, 0, complain_overflow_bitfield,
80 1.1 skrll bfd_elf_generic_reloc, "R_386_TLS_IE",
81 1.1 skrll TRUE, 0xffffffff, 0xffffffff, FALSE),
82 1.1 skrll HOWTO(R_386_TLS_GOTIE, 0, 2, 32, FALSE, 0, complain_overflow_bitfield,
83 1.1 skrll bfd_elf_generic_reloc, "R_386_TLS_GOTIE",
84 1.1 skrll TRUE, 0xffffffff, 0xffffffff, FALSE),
85 1.1 skrll HOWTO(R_386_TLS_LE, 0, 2, 32, FALSE, 0, complain_overflow_bitfield,
86 1.1 skrll bfd_elf_generic_reloc, "R_386_TLS_LE",
87 1.1 skrll TRUE, 0xffffffff, 0xffffffff, FALSE),
88 1.1 skrll HOWTO(R_386_TLS_GD, 0, 2, 32, FALSE, 0, complain_overflow_bitfield,
89 1.1 skrll bfd_elf_generic_reloc, "R_386_TLS_GD",
90 1.1 skrll TRUE, 0xffffffff, 0xffffffff, FALSE),
91 1.1 skrll HOWTO(R_386_TLS_LDM, 0, 2, 32, FALSE, 0, complain_overflow_bitfield,
92 1.1 skrll bfd_elf_generic_reloc, "R_386_TLS_LDM",
93 1.1 skrll TRUE, 0xffffffff, 0xffffffff, FALSE),
94 1.1 skrll HOWTO(R_386_16, 0, 1, 16, FALSE, 0, complain_overflow_bitfield,
95 1.1 skrll bfd_elf_generic_reloc, "R_386_16",
96 1.1 skrll TRUE, 0xffff, 0xffff, FALSE),
97 1.1 skrll HOWTO(R_386_PC16, 0, 1, 16, TRUE, 0, complain_overflow_bitfield,
98 1.1 skrll bfd_elf_generic_reloc, "R_386_PC16",
99 1.1 skrll TRUE, 0xffff, 0xffff, TRUE),
100 1.1 skrll HOWTO(R_386_8, 0, 0, 8, FALSE, 0, complain_overflow_bitfield,
101 1.1 skrll bfd_elf_generic_reloc, "R_386_8",
102 1.1 skrll TRUE, 0xff, 0xff, FALSE),
103 1.1 skrll HOWTO(R_386_PC8, 0, 0, 8, TRUE, 0, complain_overflow_signed,
104 1.1 skrll bfd_elf_generic_reloc, "R_386_PC8",
105 1.1 skrll TRUE, 0xff, 0xff, TRUE),
106 1.1 skrll
107 1.1 skrll #define R_386_ext (R_386_PC8 + 1 - R_386_ext_offset)
108 1.1 skrll #define R_386_tls_offset (R_386_TLS_LDO_32 - R_386_ext)
109 1.1 skrll /* These are common with Solaris TLS implementation. */
110 1.1 skrll HOWTO(R_386_TLS_LDO_32, 0, 2, 32, FALSE, 0, complain_overflow_bitfield,
111 1.1 skrll bfd_elf_generic_reloc, "R_386_TLS_LDO_32",
112 1.1 skrll TRUE, 0xffffffff, 0xffffffff, FALSE),
113 1.1 skrll HOWTO(R_386_TLS_IE_32, 0, 2, 32, FALSE, 0, complain_overflow_bitfield,
114 1.1 skrll bfd_elf_generic_reloc, "R_386_TLS_IE_32",
115 1.1 skrll TRUE, 0xffffffff, 0xffffffff, FALSE),
116 1.1 skrll HOWTO(R_386_TLS_LE_32, 0, 2, 32, FALSE, 0, complain_overflow_bitfield,
117 1.1 skrll bfd_elf_generic_reloc, "R_386_TLS_LE_32",
118 1.1 skrll TRUE, 0xffffffff, 0xffffffff, FALSE),
119 1.1 skrll HOWTO(R_386_TLS_DTPMOD32, 0, 2, 32, FALSE, 0, complain_overflow_bitfield,
120 1.1 skrll bfd_elf_generic_reloc, "R_386_TLS_DTPMOD32",
121 1.1 skrll TRUE, 0xffffffff, 0xffffffff, FALSE),
122 1.1 skrll HOWTO(R_386_TLS_DTPOFF32, 0, 2, 32, FALSE, 0, complain_overflow_bitfield,
123 1.1 skrll bfd_elf_generic_reloc, "R_386_TLS_DTPOFF32",
124 1.1 skrll TRUE, 0xffffffff, 0xffffffff, FALSE),
125 1.1 skrll HOWTO(R_386_TLS_TPOFF32, 0, 2, 32, FALSE, 0, complain_overflow_bitfield,
126 1.1 skrll bfd_elf_generic_reloc, "R_386_TLS_TPOFF32",
127 1.1 skrll TRUE, 0xffffffff, 0xffffffff, FALSE),
128 1.6 christos HOWTO(R_386_SIZE32, 0, 2, 32, FALSE, 0, complain_overflow_unsigned,
129 1.6 christos bfd_elf_generic_reloc, "R_386_SIZE32",
130 1.6 christos TRUE, 0xffffffff, 0xffffffff, FALSE),
131 1.1 skrll HOWTO(R_386_TLS_GOTDESC, 0, 2, 32, FALSE, 0, complain_overflow_bitfield,
132 1.1 skrll bfd_elf_generic_reloc, "R_386_TLS_GOTDESC",
133 1.1 skrll TRUE, 0xffffffff, 0xffffffff, FALSE),
134 1.1 skrll HOWTO(R_386_TLS_DESC_CALL, 0, 0, 0, FALSE, 0, complain_overflow_dont,
135 1.1 skrll bfd_elf_generic_reloc, "R_386_TLS_DESC_CALL",
136 1.1 skrll FALSE, 0, 0, FALSE),
137 1.1 skrll HOWTO(R_386_TLS_DESC, 0, 2, 32, FALSE, 0, complain_overflow_bitfield,
138 1.1 skrll bfd_elf_generic_reloc, "R_386_TLS_DESC",
139 1.1 skrll TRUE, 0xffffffff, 0xffffffff, FALSE),
140 1.4 christos HOWTO(R_386_IRELATIVE, 0, 2, 32, FALSE, 0, complain_overflow_bitfield,
141 1.4 christos bfd_elf_generic_reloc, "R_386_IRELATIVE",
142 1.4 christos TRUE, 0xffffffff, 0xffffffff, FALSE),
143 1.6 christos HOWTO(R_386_GOT32X, 0, 2, 32, FALSE, 0, complain_overflow_bitfield,
144 1.6 christos bfd_elf_generic_reloc, "R_386_GOT32X",
145 1.6 christos TRUE, 0xffffffff, 0xffffffff, FALSE),
146 1.1 skrll
147 1.1 skrll /* Another gap. */
148 1.6 christos #define R_386_ext2 (R_386_GOT32X + 1 - R_386_tls_offset)
149 1.6 christos #define R_386_vt_offset (R_386_GNU_VTINHERIT - R_386_ext2)
150 1.1 skrll
151 1.1 skrll /* GNU extension to record C++ vtable hierarchy. */
152 1.1 skrll HOWTO (R_386_GNU_VTINHERIT, /* type */
153 1.1 skrll 0, /* rightshift */
154 1.1 skrll 2, /* size (0 = byte, 1 = short, 2 = long) */
155 1.1 skrll 0, /* bitsize */
156 1.1 skrll FALSE, /* pc_relative */
157 1.1 skrll 0, /* bitpos */
158 1.1 skrll complain_overflow_dont, /* complain_on_overflow */
159 1.1 skrll NULL, /* special_function */
160 1.1 skrll "R_386_GNU_VTINHERIT", /* name */
161 1.1 skrll FALSE, /* partial_inplace */
162 1.1 skrll 0, /* src_mask */
163 1.1 skrll 0, /* dst_mask */
164 1.1 skrll FALSE), /* pcrel_offset */
165 1.1 skrll
166 1.1 skrll /* GNU extension to record C++ vtable member usage. */
167 1.1 skrll HOWTO (R_386_GNU_VTENTRY, /* type */
168 1.1 skrll 0, /* rightshift */
169 1.1 skrll 2, /* size (0 = byte, 1 = short, 2 = long) */
170 1.1 skrll 0, /* bitsize */
171 1.1 skrll FALSE, /* pc_relative */
172 1.1 skrll 0, /* bitpos */
173 1.1 skrll complain_overflow_dont, /* complain_on_overflow */
174 1.1 skrll _bfd_elf_rel_vtable_reloc_fn, /* special_function */
175 1.1 skrll "R_386_GNU_VTENTRY", /* name */
176 1.1 skrll FALSE, /* partial_inplace */
177 1.1 skrll 0, /* src_mask */
178 1.1 skrll 0, /* dst_mask */
179 1.1 skrll FALSE) /* pcrel_offset */
180 1.1 skrll
181 1.1 skrll #define R_386_vt (R_386_GNU_VTENTRY + 1 - R_386_vt_offset)
182 1.1 skrll
183 1.1 skrll };
184 1.1 skrll
185 1.10 christos #define X86_PCREL_TYPE_P(TYPE) ((TYPE) == R_386_PC32)
186 1.10 christos
187 1.10 christos #define X86_SIZE_TYPE_P(TYPE) ((TYPE) == R_386_SIZE32)
188 1.10 christos
189 1.1 skrll #ifdef DEBUG_GEN_RELOC
190 1.1 skrll #define TRACE(str) \
191 1.1 skrll fprintf (stderr, "i386 bfd reloc lookup %d (%s)\n", code, str)
192 1.1 skrll #else
193 1.1 skrll #define TRACE(str)
194 1.1 skrll #endif
195 1.1 skrll
196 1.1 skrll static reloc_howto_type *
197 1.1 skrll elf_i386_reloc_type_lookup (bfd *abfd ATTRIBUTE_UNUSED,
198 1.1 skrll bfd_reloc_code_real_type code)
199 1.1 skrll {
200 1.1 skrll switch (code)
201 1.1 skrll {
202 1.1 skrll case BFD_RELOC_NONE:
203 1.1 skrll TRACE ("BFD_RELOC_NONE");
204 1.1 skrll return &elf_howto_table[R_386_NONE];
205 1.1 skrll
206 1.1 skrll case BFD_RELOC_32:
207 1.1 skrll TRACE ("BFD_RELOC_32");
208 1.1 skrll return &elf_howto_table[R_386_32];
209 1.1 skrll
210 1.1 skrll case BFD_RELOC_CTOR:
211 1.1 skrll TRACE ("BFD_RELOC_CTOR");
212 1.1 skrll return &elf_howto_table[R_386_32];
213 1.1 skrll
214 1.1 skrll case BFD_RELOC_32_PCREL:
215 1.1 skrll TRACE ("BFD_RELOC_PC32");
216 1.1 skrll return &elf_howto_table[R_386_PC32];
217 1.1 skrll
218 1.1 skrll case BFD_RELOC_386_GOT32:
219 1.1 skrll TRACE ("BFD_RELOC_386_GOT32");
220 1.1 skrll return &elf_howto_table[R_386_GOT32];
221 1.1 skrll
222 1.1 skrll case BFD_RELOC_386_PLT32:
223 1.1 skrll TRACE ("BFD_RELOC_386_PLT32");
224 1.1 skrll return &elf_howto_table[R_386_PLT32];
225 1.1 skrll
226 1.1 skrll case BFD_RELOC_386_COPY:
227 1.1 skrll TRACE ("BFD_RELOC_386_COPY");
228 1.1 skrll return &elf_howto_table[R_386_COPY];
229 1.1 skrll
230 1.1 skrll case BFD_RELOC_386_GLOB_DAT:
231 1.1 skrll TRACE ("BFD_RELOC_386_GLOB_DAT");
232 1.1 skrll return &elf_howto_table[R_386_GLOB_DAT];
233 1.1 skrll
234 1.1 skrll case BFD_RELOC_386_JUMP_SLOT:
235 1.1 skrll TRACE ("BFD_RELOC_386_JUMP_SLOT");
236 1.1 skrll return &elf_howto_table[R_386_JUMP_SLOT];
237 1.1 skrll
238 1.1 skrll case BFD_RELOC_386_RELATIVE:
239 1.1 skrll TRACE ("BFD_RELOC_386_RELATIVE");
240 1.1 skrll return &elf_howto_table[R_386_RELATIVE];
241 1.1 skrll
242 1.1 skrll case BFD_RELOC_386_GOTOFF:
243 1.1 skrll TRACE ("BFD_RELOC_386_GOTOFF");
244 1.1 skrll return &elf_howto_table[R_386_GOTOFF];
245 1.1 skrll
246 1.1 skrll case BFD_RELOC_386_GOTPC:
247 1.1 skrll TRACE ("BFD_RELOC_386_GOTPC");
248 1.1 skrll return &elf_howto_table[R_386_GOTPC];
249 1.1 skrll
250 1.1 skrll /* These relocs are a GNU extension. */
251 1.1 skrll case BFD_RELOC_386_TLS_TPOFF:
252 1.1 skrll TRACE ("BFD_RELOC_386_TLS_TPOFF");
253 1.1 skrll return &elf_howto_table[R_386_TLS_TPOFF - R_386_ext_offset];
254 1.1 skrll
255 1.1 skrll case BFD_RELOC_386_TLS_IE:
256 1.1 skrll TRACE ("BFD_RELOC_386_TLS_IE");
257 1.1 skrll return &elf_howto_table[R_386_TLS_IE - R_386_ext_offset];
258 1.1 skrll
259 1.1 skrll case BFD_RELOC_386_TLS_GOTIE:
260 1.1 skrll TRACE ("BFD_RELOC_386_TLS_GOTIE");
261 1.1 skrll return &elf_howto_table[R_386_TLS_GOTIE - R_386_ext_offset];
262 1.1 skrll
263 1.1 skrll case BFD_RELOC_386_TLS_LE:
264 1.1 skrll TRACE ("BFD_RELOC_386_TLS_LE");
265 1.1 skrll return &elf_howto_table[R_386_TLS_LE - R_386_ext_offset];
266 1.1 skrll
267 1.1 skrll case BFD_RELOC_386_TLS_GD:
268 1.1 skrll TRACE ("BFD_RELOC_386_TLS_GD");
269 1.1 skrll return &elf_howto_table[R_386_TLS_GD - R_386_ext_offset];
270 1.1 skrll
271 1.1 skrll case BFD_RELOC_386_TLS_LDM:
272 1.1 skrll TRACE ("BFD_RELOC_386_TLS_LDM");
273 1.1 skrll return &elf_howto_table[R_386_TLS_LDM - R_386_ext_offset];
274 1.1 skrll
275 1.1 skrll case BFD_RELOC_16:
276 1.1 skrll TRACE ("BFD_RELOC_16");
277 1.1 skrll return &elf_howto_table[R_386_16 - R_386_ext_offset];
278 1.1 skrll
279 1.1 skrll case BFD_RELOC_16_PCREL:
280 1.1 skrll TRACE ("BFD_RELOC_16_PCREL");
281 1.1 skrll return &elf_howto_table[R_386_PC16 - R_386_ext_offset];
282 1.1 skrll
283 1.1 skrll case BFD_RELOC_8:
284 1.1 skrll TRACE ("BFD_RELOC_8");
285 1.1 skrll return &elf_howto_table[R_386_8 - R_386_ext_offset];
286 1.1 skrll
287 1.1 skrll case BFD_RELOC_8_PCREL:
288 1.1 skrll TRACE ("BFD_RELOC_8_PCREL");
289 1.1 skrll return &elf_howto_table[R_386_PC8 - R_386_ext_offset];
290 1.1 skrll
291 1.1 skrll /* Common with Sun TLS implementation. */
292 1.1 skrll case BFD_RELOC_386_TLS_LDO_32:
293 1.1 skrll TRACE ("BFD_RELOC_386_TLS_LDO_32");
294 1.1 skrll return &elf_howto_table[R_386_TLS_LDO_32 - R_386_tls_offset];
295 1.1 skrll
296 1.1 skrll case BFD_RELOC_386_TLS_IE_32:
297 1.1 skrll TRACE ("BFD_RELOC_386_TLS_IE_32");
298 1.1 skrll return &elf_howto_table[R_386_TLS_IE_32 - R_386_tls_offset];
299 1.1 skrll
300 1.1 skrll case BFD_RELOC_386_TLS_LE_32:
301 1.1 skrll TRACE ("BFD_RELOC_386_TLS_LE_32");
302 1.1 skrll return &elf_howto_table[R_386_TLS_LE_32 - R_386_tls_offset];
303 1.1 skrll
304 1.1 skrll case BFD_RELOC_386_TLS_DTPMOD32:
305 1.1 skrll TRACE ("BFD_RELOC_386_TLS_DTPMOD32");
306 1.1 skrll return &elf_howto_table[R_386_TLS_DTPMOD32 - R_386_tls_offset];
307 1.1 skrll
308 1.1 skrll case BFD_RELOC_386_TLS_DTPOFF32:
309 1.1 skrll TRACE ("BFD_RELOC_386_TLS_DTPOFF32");
310 1.1 skrll return &elf_howto_table[R_386_TLS_DTPOFF32 - R_386_tls_offset];
311 1.1 skrll
312 1.1 skrll case BFD_RELOC_386_TLS_TPOFF32:
313 1.1 skrll TRACE ("BFD_RELOC_386_TLS_TPOFF32");
314 1.1 skrll return &elf_howto_table[R_386_TLS_TPOFF32 - R_386_tls_offset];
315 1.1 skrll
316 1.6 christos case BFD_RELOC_SIZE32:
317 1.6 christos TRACE ("BFD_RELOC_SIZE32");
318 1.6 christos return &elf_howto_table[R_386_SIZE32 - R_386_tls_offset];
319 1.6 christos
320 1.1 skrll case BFD_RELOC_386_TLS_GOTDESC:
321 1.1 skrll TRACE ("BFD_RELOC_386_TLS_GOTDESC");
322 1.1 skrll return &elf_howto_table[R_386_TLS_GOTDESC - R_386_tls_offset];
323 1.1 skrll
324 1.1 skrll case BFD_RELOC_386_TLS_DESC_CALL:
325 1.1 skrll TRACE ("BFD_RELOC_386_TLS_DESC_CALL");
326 1.1 skrll return &elf_howto_table[R_386_TLS_DESC_CALL - R_386_tls_offset];
327 1.1 skrll
328 1.1 skrll case BFD_RELOC_386_TLS_DESC:
329 1.1 skrll TRACE ("BFD_RELOC_386_TLS_DESC");
330 1.1 skrll return &elf_howto_table[R_386_TLS_DESC - R_386_tls_offset];
331 1.1 skrll
332 1.4 christos case BFD_RELOC_386_IRELATIVE:
333 1.4 christos TRACE ("BFD_RELOC_386_IRELATIVE");
334 1.5 christos return &elf_howto_table[R_386_IRELATIVE - R_386_tls_offset];
335 1.4 christos
336 1.6 christos case BFD_RELOC_386_GOT32X:
337 1.6 christos TRACE ("BFD_RELOC_386_GOT32X");
338 1.6 christos return &elf_howto_table[R_386_GOT32X - R_386_tls_offset];
339 1.6 christos
340 1.1 skrll case BFD_RELOC_VTABLE_INHERIT:
341 1.1 skrll TRACE ("BFD_RELOC_VTABLE_INHERIT");
342 1.1 skrll return &elf_howto_table[R_386_GNU_VTINHERIT - R_386_vt_offset];
343 1.1 skrll
344 1.1 skrll case BFD_RELOC_VTABLE_ENTRY:
345 1.1 skrll TRACE ("BFD_RELOC_VTABLE_ENTRY");
346 1.1 skrll return &elf_howto_table[R_386_GNU_VTENTRY - R_386_vt_offset];
347 1.1 skrll
348 1.1 skrll default:
349 1.1 skrll break;
350 1.1 skrll }
351 1.1 skrll
352 1.1 skrll TRACE ("Unknown");
353 1.1 skrll return 0;
354 1.1 skrll }
355 1.1 skrll
356 1.1 skrll static reloc_howto_type *
357 1.1 skrll elf_i386_reloc_name_lookup (bfd *abfd ATTRIBUTE_UNUSED,
358 1.1 skrll const char *r_name)
359 1.1 skrll {
360 1.1 skrll unsigned int i;
361 1.1 skrll
362 1.1 skrll for (i = 0; i < sizeof (elf_howto_table) / sizeof (elf_howto_table[0]); i++)
363 1.1 skrll if (elf_howto_table[i].name != NULL
364 1.1 skrll && strcasecmp (elf_howto_table[i].name, r_name) == 0)
365 1.1 skrll return &elf_howto_table[i];
366 1.1 skrll
367 1.1 skrll return NULL;
368 1.1 skrll }
369 1.1 skrll
370 1.1 skrll static reloc_howto_type *
371 1.1 skrll elf_i386_rtype_to_howto (bfd *abfd, unsigned r_type)
372 1.1 skrll {
373 1.1 skrll unsigned int indx;
374 1.1 skrll
375 1.1 skrll if ((indx = r_type) >= R_386_standard
376 1.1 skrll && ((indx = r_type - R_386_ext_offset) - R_386_standard
377 1.1 skrll >= R_386_ext - R_386_standard)
378 1.1 skrll && ((indx = r_type - R_386_tls_offset) - R_386_ext
379 1.6 christos >= R_386_ext2 - R_386_ext)
380 1.6 christos && ((indx = r_type - R_386_vt_offset) - R_386_ext2
381 1.6 christos >= R_386_vt - R_386_ext2))
382 1.1 skrll {
383 1.10 christos /* xgettext:c-format */
384 1.10 christos _bfd_error_handler (_("%B: invalid relocation type %d"),
385 1.10 christos abfd, (int) r_type);
386 1.1 skrll indx = R_386_NONE;
387 1.1 skrll }
388 1.6 christos /* PR 17512: file: 0f67f69d. */
389 1.6 christos if (elf_howto_table [indx].type != r_type)
390 1.6 christos return NULL;
391 1.1 skrll return &elf_howto_table[indx];
392 1.1 skrll }
393 1.1 skrll
394 1.1 skrll static void
395 1.1 skrll elf_i386_info_to_howto_rel (bfd *abfd ATTRIBUTE_UNUSED,
396 1.1 skrll arelent *cache_ptr,
397 1.1 skrll Elf_Internal_Rela *dst)
398 1.1 skrll {
399 1.1 skrll unsigned int r_type = ELF32_R_TYPE (dst->r_info);
400 1.1 skrll cache_ptr->howto = elf_i386_rtype_to_howto (abfd, r_type);
401 1.1 skrll }
402 1.1 skrll
403 1.1 skrll /* Return whether a symbol name implies a local label. The UnixWare
404 1.1 skrll 2.1 cc generates temporary symbols that start with .X, so we
405 1.1 skrll recognize them here. FIXME: do other SVR4 compilers also use .X?.
406 1.1 skrll If so, we should move the .X recognition into
407 1.1 skrll _bfd_elf_is_local_label_name. */
408 1.1 skrll
409 1.1 skrll static bfd_boolean
410 1.1 skrll elf_i386_is_local_label_name (bfd *abfd, const char *name)
411 1.1 skrll {
412 1.1 skrll if (name[0] == '.' && name[1] == 'X')
413 1.1 skrll return TRUE;
414 1.1 skrll
415 1.1 skrll return _bfd_elf_is_local_label_name (abfd, name);
416 1.1 skrll }
417 1.1 skrll
418 1.1 skrll /* Support for core dump NOTE sections. */
420 1.1 skrll
421 1.1 skrll static bfd_boolean
422 1.1 skrll elf_i386_grok_prstatus (bfd *abfd, Elf_Internal_Note *note)
423 1.1 skrll {
424 1.1 skrll int offset;
425 1.1 skrll size_t size;
426 1.1 skrll
427 1.1 skrll if (note->namesz == 8 && strcmp (note->namedata, "FreeBSD") == 0)
428 1.1 skrll {
429 1.1 skrll int pr_version = bfd_get_32 (abfd, note->descdata);
430 1.1 skrll
431 1.10 christos if (pr_version != 1)
432 1.1 skrll return FALSE;
433 1.1 skrll
434 1.6 christos /* pr_cursig */
435 1.1 skrll elf_tdata (abfd)->core->signal = bfd_get_32 (abfd, note->descdata + 20);
436 1.1 skrll
437 1.6 christos /* pr_pid */
438 1.1 skrll elf_tdata (abfd)->core->lwpid = bfd_get_32 (abfd, note->descdata + 24);
439 1.1 skrll
440 1.1 skrll /* pr_reg */
441 1.1 skrll offset = 28;
442 1.1 skrll size = bfd_get_32 (abfd, note->descdata + 8);
443 1.1 skrll }
444 1.1 skrll else
445 1.1 skrll {
446 1.1 skrll switch (note->descsz)
447 1.1 skrll {
448 1.1 skrll default:
449 1.1 skrll return FALSE;
450 1.1 skrll
451 1.1 skrll case 144: /* Linux/i386 */
452 1.6 christos /* pr_cursig */
453 1.1 skrll elf_tdata (abfd)->core->signal = bfd_get_16 (abfd, note->descdata + 12);
454 1.1 skrll
455 1.6 christos /* pr_pid */
456 1.1 skrll elf_tdata (abfd)->core->lwpid = bfd_get_32 (abfd, note->descdata + 24);
457 1.1 skrll
458 1.1 skrll /* pr_reg */
459 1.1 skrll offset = 72;
460 1.1 skrll size = 68;
461 1.1 skrll
462 1.1 skrll break;
463 1.1 skrll }
464 1.1 skrll }
465 1.1 skrll
466 1.1 skrll /* Make a ".reg/999" section. */
467 1.1 skrll return _bfd_elfcore_make_pseudosection (abfd, ".reg",
468 1.1 skrll size, note->descpos + offset);
469 1.1 skrll }
470 1.1 skrll
471 1.1 skrll static bfd_boolean
472 1.1 skrll elf_i386_grok_psinfo (bfd *abfd, Elf_Internal_Note *note)
473 1.1 skrll {
474 1.1 skrll if (note->namesz == 8 && strcmp (note->namedata, "FreeBSD") == 0)
475 1.1 skrll {
476 1.1 skrll int pr_version = bfd_get_32 (abfd, note->descdata);
477 1.1 skrll
478 1.1 skrll if (pr_version != 1)
479 1.1 skrll return FALSE;
480 1.6 christos
481 1.1 skrll elf_tdata (abfd)->core->program
482 1.6 christos = _bfd_elfcore_strndup (abfd, note->descdata + 8, 17);
483 1.1 skrll elf_tdata (abfd)->core->command
484 1.1 skrll = _bfd_elfcore_strndup (abfd, note->descdata + 25, 81);
485 1.1 skrll }
486 1.1 skrll else
487 1.1 skrll {
488 1.1 skrll switch (note->descsz)
489 1.1 skrll {
490 1.1 skrll default:
491 1.1 skrll return FALSE;
492 1.1 skrll
493 1.6 christos case 124: /* Linux/i386 elf_prpsinfo. */
494 1.4 christos elf_tdata (abfd)->core->pid
495 1.6 christos = bfd_get_32 (abfd, note->descdata + 12);
496 1.1 skrll elf_tdata (abfd)->core->program
497 1.6 christos = _bfd_elfcore_strndup (abfd, note->descdata + 28, 16);
498 1.1 skrll elf_tdata (abfd)->core->command
499 1.1 skrll = _bfd_elfcore_strndup (abfd, note->descdata + 44, 80);
500 1.1 skrll }
501 1.1 skrll }
502 1.1 skrll
503 1.1 skrll /* Note that for some reason, a spurious space is tacked
504 1.1 skrll onto the end of the args in some (at least one anyway)
505 1.1 skrll implementations, so strip it off if it exists. */
506 1.6 christos {
507 1.1 skrll char *command = elf_tdata (abfd)->core->command;
508 1.1 skrll int n = strlen (command);
509 1.1 skrll
510 1.1 skrll if (0 < n && command[n - 1] == ' ')
511 1.1 skrll command[n - 1] = '\0';
512 1.1 skrll }
513 1.1 skrll
514 1.1 skrll return TRUE;
515 1.1 skrll }
516 1.1 skrll
517 1.1 skrll /* Functions for the i386 ELF linker.
519 1.1 skrll
520 1.1 skrll In order to gain some understanding of code in this file without
521 1.1 skrll knowing all the intricate details of the linker, note the
522 1.1 skrll following:
523 1.1 skrll
524 1.1 skrll Functions named elf_i386_* are called by external routines, other
525 1.1 skrll functions are only called locally. elf_i386_* functions appear
526 1.1 skrll in this file more or less in the order in which they are called
527 1.1 skrll from external routines. eg. elf_i386_check_relocs is called
528 1.1 skrll early in the link process, elf_i386_finish_dynamic_sections is
529 1.10 christos one of the last functions. */
530 1.10 christos
531 1.1 skrll /* The size in bytes of an entry in the lazy procedure linkage table. */
532 1.1 skrll #define LAZY_PLT_ENTRY_SIZE 16
533 1.1 skrll
534 1.1 skrll /* The name of the dynamic interpreter. This is put in the .interp
535 1.3 drochner section. */
536 1.1 skrll
537 1.1 skrll #define ELF_DYNAMIC_INTERPRETER "/libexec/ld.elf_so"
538 1.10 christos
539 1.10 christos
540 1.1 skrll /* The size in bytes of an entry in the non-lazy procedure linkage
541 1.10 christos table. */
542 1.1 skrll
543 1.10 christos #define NON_LAZY_PLT_ENTRY_SIZE 8
544 1.10 christos
545 1.10 christos /* The first entry in an absolute lazy procedure linkage table looks
546 1.1 skrll like this. See the SVR4 ABI i386 supplement to see how this works.
547 1.10 christos Will be padded to LAZY_PLT_ENTRY_SIZE with lazy_plt->plt0_pad_byte. */
548 1.1 skrll
549 1.1 skrll static const bfd_byte elf_i386_lazy_plt0_entry[12] =
550 1.1 skrll {
551 1.1 skrll 0xff, 0x35, /* pushl contents of address */
552 1.1 skrll 0, 0, 0, 0, /* replaced with address of .got + 4. */
553 1.1 skrll 0xff, 0x25, /* jmp indirect */
554 1.1 skrll 0, 0, 0, 0 /* replaced with address of .got + 8. */
555 1.10 christos };
556 1.10 christos
557 1.1 skrll /* Subsequent entries in an absolute lazy procedure linkage table look
558 1.10 christos like this. */
559 1.1 skrll
560 1.1 skrll static const bfd_byte elf_i386_lazy_plt_entry[LAZY_PLT_ENTRY_SIZE] =
561 1.1 skrll {
562 1.1 skrll 0xff, 0x25, /* jmp indirect */
563 1.1 skrll 0, 0, 0, 0, /* replaced with address of this symbol in .got. */
564 1.1 skrll 0x68, /* pushl immediate */
565 1.1 skrll 0, 0, 0, 0, /* replaced with offset into relocation table. */
566 1.1 skrll 0xe9, /* jmp relative */
567 1.1 skrll 0, 0, 0, 0 /* replaced with offset to start of .plt. */
568 1.10 christos };
569 1.10 christos
570 1.10 christos /* The first entry in a PIC lazy procedure linkage table look like
571 1.1 skrll this. Will be padded to LAZY_PLT_ENTRY_SIZE with
572 1.10 christos lazy_plt->plt0_pad_byte. */
573 1.1 skrll
574 1.1 skrll static const bfd_byte elf_i386_pic_lazy_plt0_entry[12] =
575 1.1 skrll {
576 1.1 skrll 0xff, 0xb3, 4, 0, 0, 0, /* pushl 4(%ebx) */
577 1.1 skrll 0xff, 0xa3, 8, 0, 0, 0 /* jmp *8(%ebx) */
578 1.10 christos };
579 1.10 christos
580 1.1 skrll /* Subsequent entries in a PIC lazy procedure linkage table look like
581 1.10 christos this. */
582 1.1 skrll
583 1.1 skrll static const bfd_byte elf_i386_pic_lazy_plt_entry[LAZY_PLT_ENTRY_SIZE] =
584 1.1 skrll {
585 1.1 skrll 0xff, 0xa3, /* jmp *offset(%ebx) */
586 1.1 skrll 0, 0, 0, 0, /* replaced with offset of this symbol in .got. */
587 1.1 skrll 0x68, /* pushl immediate */
588 1.1 skrll 0, 0, 0, 0, /* replaced with offset into relocation table. */
589 1.1 skrll 0xe9, /* jmp relative */
590 1.1 skrll 0, 0, 0, 0 /* replaced with offset to start of .plt. */
591 1.10 christos };
592 1.6 christos
593 1.10 christos /* Entries in the non-lazy procedure linkage table look like this. */
594 1.6 christos
595 1.6 christos static const bfd_byte elf_i386_non_lazy_plt_entry[NON_LAZY_PLT_ENTRY_SIZE] =
596 1.6 christos {
597 1.6 christos 0xff, 0x25, /* jmp indirect */
598 1.6 christos 0, 0, 0, 0, /* replaced with offset of this symbol in .got. */
599 1.6 christos 0x66, 0x90 /* xchg %ax,%ax */
600 1.10 christos };
601 1.10 christos
602 1.6 christos /* Entries in the PIC non-lazy procedure linkage table look like
603 1.10 christos this. */
604 1.6 christos
605 1.6 christos static const bfd_byte elf_i386_pic_non_lazy_plt_entry[NON_LAZY_PLT_ENTRY_SIZE] =
606 1.6 christos {
607 1.6 christos 0xff, 0xa3, /* jmp *offset(%ebx) */
608 1.6 christos 0, 0, 0, 0, /* replaced with offset of this symbol in .got. */
609 1.6 christos 0x66, 0x90 /* xchg %ax,%ax */
610 1.10 christos };
611 1.10 christos
612 1.10 christos /* The first entry in an absolute IBT-enabled lazy procedure linkage
613 1.10 christos table looks like this. */
614 1.10 christos
615 1.10 christos static const bfd_byte elf_i386_lazy_ibt_plt0_entry[LAZY_PLT_ENTRY_SIZE] =
616 1.10 christos {
617 1.10 christos 0xff, 0x35, 0, 0, 0, 0, /* pushl GOT[1] */
618 1.10 christos 0xff, 0x25, 0, 0, 0, 0, /* jmp *GOT[2] */
619 1.10 christos 0x0f, 0x1f, 0x40, 0x00 /* nopl 0(%rax) */
620 1.10 christos };
621 1.10 christos
622 1.10 christos /* Subsequent entries for an absolute IBT-enabled lazy procedure linkage
623 1.10 christos table look like this. Subsequent entries for a PIC IBT-enabled lazy
624 1.10 christos procedure linkage table are the same. */
625 1.10 christos
626 1.10 christos static const bfd_byte elf_i386_lazy_ibt_plt_entry[LAZY_PLT_ENTRY_SIZE] =
627 1.10 christos {
628 1.10 christos 0xf3, 0x0f, 0x1e, 0xfb, /* endbr32 */
629 1.10 christos 0x68, 0, 0, 0, 0, /* pushl immediate */
630 1.10 christos 0xe9, 0, 0, 0, 0, /* jmp relative */
631 1.10 christos 0x66, 0x90 /* xchg %ax,%ax */
632 1.10 christos };
633 1.10 christos
634 1.10 christos /* The first entry in a PIC IBT-enabled lazy procedure linkage table
635 1.10 christos look like. */
636 1.10 christos
637 1.10 christos static const bfd_byte elf_i386_pic_lazy_ibt_plt0_entry[LAZY_PLT_ENTRY_SIZE] =
638 1.10 christos {
639 1.10 christos 0xff, 0xb3, 4, 0, 0, 0, /* pushl 4(%ebx) */
640 1.10 christos 0xff, 0xa3, 8, 0, 0, 0, /* jmp *8(%ebx) */
641 1.10 christos 0x0f, 0x1f, 0x40, 0x00 /* nopl 0(%rax) */
642 1.10 christos };
643 1.10 christos
644 1.10 christos /* Entries for branches with IBT-enabled in the absolute non-lazey
645 1.10 christos procedure linkage table look like this. They have the same size
646 1.10 christos as the lazy PLT entry. */
647 1.10 christos
648 1.10 christos static const bfd_byte elf_i386_non_lazy_ibt_plt_entry[LAZY_PLT_ENTRY_SIZE] =
649 1.10 christos {
650 1.10 christos 0xf3, 0x0f, 0x1e, 0xfb, /* endbr32 */
651 1.10 christos 0xff, 0x25, 0, 0, 0, 0, /* jmp *name@GOT */
652 1.10 christos 0x66, 0x0f, 0x1f, 0x44, 0x00, 0x00 /* nopw 0x0(%rax,%rax,1) */
653 1.10 christos };
654 1.10 christos
655 1.10 christos /* Entries for branches with IBT-enabled in the PIC non-lazey procedure
656 1.10 christos linkage table look like this. They have the same size as the lazy
657 1.10 christos PLT entry. */
658 1.10 christos
659 1.10 christos static const bfd_byte elf_i386_pic_non_lazy_ibt_plt_entry[LAZY_PLT_ENTRY_SIZE] =
660 1.10 christos {
661 1.10 christos 0xf3, 0x0f, 0x1e, 0xfb, /* endbr32 */
662 1.10 christos 0xff, 0xa3, 0, 0, 0, 0, /* jmp *name@GOT(%ebx) */
663 1.10 christos 0x66, 0x0f, 0x1f, 0x44, 0x00, 0x00 /* nopw 0x0(%rax,%rax,1) */
664 1.10 christos };
665 1.5 christos
666 1.10 christos /* .eh_frame covering the lazy .plt section. */
667 1.5 christos
668 1.5 christos static const bfd_byte elf_i386_eh_frame_lazy_plt[] =
669 1.5 christos {
670 1.5 christos PLT_CIE_LENGTH, 0, 0, 0, /* CIE length */
671 1.5 christos 0, 0, 0, 0, /* CIE ID */
672 1.5 christos 1, /* CIE version */
673 1.5 christos 'z', 'R', 0, /* Augmentation string */
674 1.5 christos 1, /* Code alignment factor */
675 1.5 christos 0x7c, /* Data alignment factor */
676 1.5 christos 8, /* Return address column */
677 1.5 christos 1, /* Augmentation size */
678 1.5 christos DW_EH_PE_pcrel | DW_EH_PE_sdata4, /* FDE encoding */
679 1.5 christos DW_CFA_def_cfa, 4, 4, /* DW_CFA_def_cfa: r4 (esp) ofs 4 */
680 1.5 christos DW_CFA_offset + 8, 1, /* DW_CFA_offset: r8 (eip) at cfa-4 */
681 1.5 christos DW_CFA_nop, DW_CFA_nop,
682 1.5 christos
683 1.5 christos PLT_FDE_LENGTH, 0, 0, 0, /* FDE length */
684 1.5 christos PLT_CIE_LENGTH + 8, 0, 0, 0, /* CIE pointer */
685 1.5 christos 0, 0, 0, 0, /* R_386_PC32 .plt goes here */
686 1.5 christos 0, 0, 0, 0, /* .plt size goes here */
687 1.5 christos 0, /* Augmentation size */
688 1.5 christos DW_CFA_def_cfa_offset, 8, /* DW_CFA_def_cfa_offset: 8 */
689 1.5 christos DW_CFA_advance_loc + 6, /* DW_CFA_advance_loc: 6 to __PLT__+6 */
690 1.5 christos DW_CFA_def_cfa_offset, 12, /* DW_CFA_def_cfa_offset: 12 */
691 1.5 christos DW_CFA_advance_loc + 10, /* DW_CFA_advance_loc: 10 to __PLT__+16 */
692 1.5 christos DW_CFA_def_cfa_expression, /* DW_CFA_def_cfa_expression */
693 1.5 christos 11, /* Block length */
694 1.5 christos DW_OP_breg4, 4, /* DW_OP_breg4 (esp): 4 */
695 1.5 christos DW_OP_breg8, 0, /* DW_OP_breg8 (eip): 0 */
696 1.5 christos DW_OP_lit15, DW_OP_and, DW_OP_lit11, DW_OP_ge,
697 1.5 christos DW_OP_lit2, DW_OP_shl, DW_OP_plus,
698 1.5 christos DW_CFA_nop, DW_CFA_nop, DW_CFA_nop, DW_CFA_nop
699 1.10 christos };
700 1.10 christos
701 1.10 christos /* .eh_frame covering the lazy .plt section with IBT-enabled. */
702 1.5 christos
703 1.10 christos static const bfd_byte elf_i386_eh_frame_lazy_ibt_plt[] =
704 1.10 christos {
705 1.10 christos PLT_CIE_LENGTH, 0, 0, 0, /* CIE length */
706 1.10 christos 0, 0, 0, 0, /* CIE ID */
707 1.10 christos 1, /* CIE version */
708 1.10 christos 'z', 'R', 0, /* Augmentation string */
709 1.10 christos 1, /* Code alignment factor */
710 1.10 christos 0x7c, /* Data alignment factor */
711 1.10 christos 8, /* Return address column */
712 1.10 christos 1, /* Augmentation size */
713 1.10 christos DW_EH_PE_pcrel | DW_EH_PE_sdata4, /* FDE encoding */
714 1.10 christos DW_CFA_def_cfa, 4, 4, /* DW_CFA_def_cfa: r4 (esp) ofs 4 */
715 1.5 christos DW_CFA_offset + 8, 1, /* DW_CFA_offset: r8 (eip) at cfa-4 */
716 1.10 christos DW_CFA_nop, DW_CFA_nop,
717 1.10 christos
718 1.10 christos PLT_FDE_LENGTH, 0, 0, 0, /* FDE length */
719 1.10 christos PLT_CIE_LENGTH + 8, 0, 0, 0, /* CIE pointer */
720 1.10 christos 0, 0, 0, 0, /* R_386_PC32 .plt goes here */
721 1.10 christos 0, 0, 0, 0, /* .plt size goes here */
722 1.10 christos 0, /* Augmentation size */
723 1.10 christos DW_CFA_def_cfa_offset, 8, /* DW_CFA_def_cfa_offset: 8 */
724 1.10 christos DW_CFA_advance_loc + 6, /* DW_CFA_advance_loc: 6 to __PLT__+6 */
725 1.10 christos DW_CFA_def_cfa_offset, 12, /* DW_CFA_def_cfa_offset: 12 */
726 1.10 christos DW_CFA_advance_loc + 10, /* DW_CFA_advance_loc: 10 to __PLT__+16 */
727 1.10 christos DW_CFA_def_cfa_expression, /* DW_CFA_def_cfa_expression */
728 1.10 christos 11, /* Block length */
729 1.10 christos DW_OP_breg4, 4, /* DW_OP_breg4 (esp): 4 */
730 1.10 christos DW_OP_breg8, 0, /* DW_OP_breg8 (eip): 0 */
731 1.10 christos DW_OP_lit15, DW_OP_and, DW_OP_lit9, DW_OP_ge,
732 1.10 christos DW_OP_lit2, DW_OP_shl, DW_OP_plus,
733 1.5 christos DW_CFA_nop, DW_CFA_nop, DW_CFA_nop, DW_CFA_nop
734 1.10 christos };
735 1.5 christos
736 1.10 christos /* .eh_frame covering the non-lazy .plt section. */
737 1.10 christos
738 1.10 christos static const bfd_byte elf_i386_eh_frame_non_lazy_plt[] =
739 1.10 christos {
740 1.10 christos #define PLT_GOT_FDE_LENGTH 16
741 1.10 christos PLT_CIE_LENGTH, 0, 0, 0, /* CIE length */
742 1.10 christos 0, 0, 0, 0, /* CIE ID */
743 1.10 christos 1, /* CIE version */
744 1.10 christos 'z', 'R', 0, /* Augmentation string */
745 1.10 christos 1, /* Code alignment factor */
746 1.10 christos 0x7c, /* Data alignment factor */
747 1.10 christos 8, /* Return address column */
748 1.10 christos 1, /* Augmentation size */
749 1.10 christos DW_EH_PE_pcrel | DW_EH_PE_sdata4, /* FDE encoding */
750 1.10 christos DW_CFA_def_cfa, 4, 4, /* DW_CFA_def_cfa: r4 (esp) ofs 4 */
751 1.5 christos DW_CFA_offset + 8, 1, /* DW_CFA_offset: r8 (eip) at cfa-4 */
752 1.10 christos DW_CFA_nop, DW_CFA_nop,
753 1.10 christos
754 1.10 christos PLT_GOT_FDE_LENGTH, 0, 0, 0, /* FDE length */
755 1.10 christos PLT_CIE_LENGTH + 8, 0, 0, 0, /* CIE pointer */
756 1.10 christos 0, 0, 0, 0, /* the start of non-lazy .plt goes here */
757 1.10 christos 0, 0, 0, 0, /* non-lazy .plt size goes here */
758 1.10 christos 0, /* Augmentation size */
759 1.5 christos DW_CFA_nop, DW_CFA_nop, DW_CFA_nop
760 1.10 christos };
761 1.10 christos
762 1.10 christos /* These are the standard parameters. */
763 1.10 christos static const struct elf_x86_lazy_plt_layout elf_i386_lazy_plt =
764 1.10 christos {
765 1.10 christos elf_i386_lazy_plt0_entry, /* plt0_entry */
766 1.10 christos sizeof (elf_i386_lazy_plt0_entry), /* plt0_entry_size */
767 1.10 christos elf_i386_lazy_plt_entry, /* plt_entry */
768 1.10 christos LAZY_PLT_ENTRY_SIZE, /* plt_entry_size */
769 1.10 christos 2, /* plt0_got1_offset */
770 1.10 christos 8, /* plt0_got2_offset */
771 1.10 christos 0, /* plt0_got2_insn_end */
772 1.10 christos 2, /* plt_got_offset */
773 1.10 christos 7, /* plt_reloc_offset */
774 1.10 christos 12, /* plt_plt_offset */
775 1.10 christos 0, /* plt_got_insn_size */
776 1.10 christos 0, /* plt_plt_insn_end */
777 1.10 christos 6, /* plt_lazy_offset */
778 1.10 christos elf_i386_pic_lazy_plt0_entry, /* pic_plt0_entry */
779 1.10 christos elf_i386_pic_lazy_plt_entry, /* pic_plt_entry */
780 1.10 christos elf_i386_eh_frame_lazy_plt, /* eh_frame_plt */
781 1.5 christos sizeof (elf_i386_eh_frame_lazy_plt) /* eh_frame_plt_size */
782 1.10 christos };
783 1.10 christos
784 1.10 christos static const struct elf_x86_non_lazy_plt_layout elf_i386_non_lazy_plt =
785 1.10 christos {
786 1.10 christos elf_i386_non_lazy_plt_entry, /* plt_entry */
787 1.10 christos elf_i386_pic_non_lazy_plt_entry, /* pic_plt_entry */
788 1.10 christos NON_LAZY_PLT_ENTRY_SIZE, /* plt_entry_size */
789 1.10 christos 2, /* plt_got_offset */
790 1.10 christos 0, /* plt_got_insn_size */
791 1.10 christos elf_i386_eh_frame_non_lazy_plt, /* eh_frame_plt */
792 1.5 christos sizeof (elf_i386_eh_frame_non_lazy_plt) /* eh_frame_plt_size */
793 1.10 christos };
794 1.10 christos
795 1.10 christos static const struct elf_x86_lazy_plt_layout elf_i386_lazy_ibt_plt =
796 1.10 christos {
797 1.10 christos elf_i386_lazy_ibt_plt0_entry, /* plt0_entry */
798 1.10 christos sizeof (elf_i386_lazy_ibt_plt0_entry), /* plt0_entry_size */
799 1.10 christos elf_i386_lazy_ibt_plt_entry, /* plt_entry */
800 1.10 christos LAZY_PLT_ENTRY_SIZE, /* plt_entry_size */
801 1.10 christos 2, /* plt0_got1_offset */
802 1.10 christos 8, /* plt0_got2_offset */
803 1.10 christos 0, /* plt0_got2_insn_end */
804 1.10 christos 4+2, /* plt_got_offset */
805 1.10 christos 4+1, /* plt_reloc_offset */
806 1.10 christos 4+6, /* plt_plt_offset */
807 1.10 christos 0, /* plt_got_insn_size */
808 1.10 christos 0, /* plt_plt_insn_end */
809 1.10 christos 0, /* plt_lazy_offset */
810 1.10 christos elf_i386_pic_lazy_ibt_plt0_entry, /* pic_plt0_entry */
811 1.10 christos elf_i386_lazy_ibt_plt_entry, /* pic_plt_entry */
812 1.10 christos elf_i386_eh_frame_lazy_ibt_plt, /* eh_frame_plt */
813 1.5 christos sizeof (elf_i386_eh_frame_lazy_ibt_plt) /* eh_frame_plt_size */
814 1.10 christos };
815 1.5 christos
816 1.10 christos static const struct elf_x86_non_lazy_plt_layout elf_i386_non_lazy_ibt_plt =
817 1.10 christos {
818 1.10 christos elf_i386_non_lazy_ibt_plt_entry, /* plt_entry */
819 1.10 christos elf_i386_pic_non_lazy_ibt_plt_entry,/* pic_plt_entry */
820 1.10 christos LAZY_PLT_ENTRY_SIZE, /* plt_entry_size */
821 1.10 christos 4+2, /* plt_got_offset */
822 1.10 christos 0, /* plt_got_insn_size */
823 1.5 christos elf_i386_eh_frame_non_lazy_plt, /* eh_frame_plt */
824 1.5 christos sizeof (elf_i386_eh_frame_non_lazy_plt) /* eh_frame_plt_size */
825 1.5 christos };
826 1.1 skrll
827 1.1 skrll
829 1.1 skrll /* On VxWorks, the .rel.plt.unloaded section has absolute relocations
830 1.1 skrll for the PLTResolve stub and then for each PLT entry. */
831 1.1 skrll #define PLTRESOLVE_RELOCS_SHLIB 0
832 1.5 christos #define PLTRESOLVE_RELOCS 2
833 1.10 christos #define PLT_NON_JUMP_SLOT_RELOCS 2
834 1.5 christos
835 1.10 christos /* These are the standard parameters. */
836 1.5 christos static const struct elf_x86_backend_data elf_i386_arch_bed =
837 1.5 christos {
838 1.5 christos is_normal /* os */
839 1.5 christos };
840 1.1 skrll
841 1.1 skrll #define elf_backend_arch_data &elf_i386_arch_bed
842 1.1 skrll
843 1.1 skrll /* Return TRUE if the TLS access code sequence support transition
844 1.9 christos from R_TYPE. */
845 1.1 skrll
846 1.1 skrll static bfd_boolean
847 1.1 skrll elf_i386_check_tls_transition (asection *sec,
848 1.1 skrll bfd_byte *contents,
849 1.1 skrll Elf_Internal_Shdr *symtab_hdr,
850 1.1 skrll struct elf_link_hash_entry **sym_hashes,
851 1.1 skrll unsigned int r_type,
852 1.9 christos const Elf_Internal_Rela *rel,
853 1.1 skrll const Elf_Internal_Rela *relend)
854 1.1 skrll {
855 1.1 skrll unsigned int val, type, reg;
856 1.9 christos unsigned long r_symndx;
857 1.10 christos struct elf_link_hash_entry *h;
858 1.1 skrll bfd_vma offset;
859 1.1 skrll bfd_byte *call;
860 1.1 skrll bfd_boolean indirect_call;
861 1.1 skrll
862 1.1 skrll offset = rel->r_offset;
863 1.1 skrll switch (r_type)
864 1.1 skrll {
865 1.1 skrll case R_386_TLS_GD:
866 1.1 skrll case R_386_TLS_LDM:
867 1.9 christos if (offset < 2 || (rel + 1) >= relend)
868 1.9 christos return FALSE;
869 1.9 christos
870 1.9 christos indirect_call = FALSE;
871 1.1 skrll call = contents + offset + 4;
872 1.1 skrll val = *(call - 5);
873 1.4 christos type = *(call - 6);
874 1.9 christos if (r_type == R_386_TLS_GD)
875 1.9 christos {
876 1.9 christos /* Check transition from GD access model. Only
877 1.9 christos leal foo@tlsgd(,%ebx,1), %eax
878 1.9 christos call ___tls_get_addr@PLT
879 1.9 christos or
880 1.9 christos leal foo@tlsgd(%ebx) %eax
881 1.9 christos call ___tls_get_addr@PLT
882 1.9 christos nop
883 1.9 christos or
884 1.9 christos leal foo@tlsgd(%reg), %eax
885 1.1 skrll call *___tls_get_addr@GOT(%reg)
886 1.9 christos which may be converted to
887 1.9 christos addr32 call ___tls_get_addr
888 1.1 skrll can transit to different access model. */
889 1.1 skrll if ((offset + 10) > sec->size
890 1.1 skrll || (type != 0x8d && type != 0x04))
891 1.1 skrll return FALSE;
892 1.9 christos
893 1.9 christos if (type == 0x04)
894 1.1 skrll {
895 1.1 skrll /* leal foo@tlsgd(,%ebx,1), %eax
896 1.1 skrll call ___tls_get_addr@PLT */
897 1.9 christos if (offset < 3)
898 1.9 christos return FALSE;
899 1.9 christos
900 1.1 skrll if (*(call - 7) != 0x8d
901 1.1 skrll || val != 0x1d
902 1.1 skrll || call[0] != 0xe8)
903 1.1 skrll return FALSE;
904 1.9 christos }
905 1.9 christos else
906 1.9 christos {
907 1.9 christos /* This must be
908 1.9 christos leal foo@tlsgd(%ebx), %eax
909 1.9 christos call ___tls_get_addr@PLT
910 1.9 christos nop
911 1.9 christos or
912 1.9 christos leal foo@tlsgd(%reg), %eax
913 1.9 christos call *___tls_get_addr@GOT(%reg)
914 1.9 christos which may be converted to
915 1.9 christos addr32 call ___tls_get_addr
916 1.9 christos
917 1.9 christos %eax can't be used as the GOT base register since it
918 1.1 skrll is used to pass parameter to ___tls_get_addr. */
919 1.1 skrll reg = val & 7;
920 1.9 christos if ((val & 0xf8) != 0x80 || reg == 4 || reg == 0)
921 1.9 christos return FALSE;
922 1.9 christos
923 1.9 christos indirect_call = call[0] == 0xff;
924 1.9 christos if (!(reg == 3 && call[0] == 0xe8 && call[5] == 0x90)
925 1.9 christos && !(call[0] == 0x67 && call[1] == 0xe8)
926 1.1 skrll && !(indirect_call
927 1.1 skrll && (call[1] & 0xf8) == 0x90
928 1.1 skrll && (call[1] & 0x7) == reg))
929 1.1 skrll return FALSE;
930 1.1 skrll }
931 1.1 skrll }
932 1.9 christos else
933 1.9 christos {
934 1.9 christos /* Check transition from LD access model. Only
935 1.9 christos leal foo@tlsldm(%ebx), %eax
936 1.9 christos call ___tls_get_addr@PLT
937 1.9 christos or
938 1.9 christos leal foo@tlsldm(%reg), %eax
939 1.1 skrll call *___tls_get_addr@GOT(%reg)
940 1.1 skrll which may be converted to
941 1.1 skrll addr32 call ___tls_get_addr
942 1.1 skrll can transit to different access model. */
943 1.9 christos if (type != 0x8d || (offset + 9) > sec->size)
944 1.9 christos return FALSE;
945 1.9 christos
946 1.9 christos /* %eax can't be used as the GOT base register since it is
947 1.9 christos used to pass parameter to ___tls_get_addr. */
948 1.9 christos reg = val & 7;
949 1.9 christos if ((val & 0xf8) != 0x80 || reg == 4 || reg == 0)
950 1.9 christos return FALSE;
951 1.9 christos
952 1.9 christos indirect_call = call[0] == 0xff;
953 1.9 christos if (!(reg == 3 && call[0] == 0xe8)
954 1.9 christos && !(call[0] == 0x67 && call[1] == 0xe8)
955 1.1 skrll && !(indirect_call
956 1.1 skrll && (call[1] & 0xf8) == 0x90
957 1.1 skrll && (call[1] & 0x7) == reg))
958 1.1 skrll return FALSE;
959 1.1 skrll }
960 1.1 skrll
961 1.1 skrll r_symndx = ELF32_R_SYM (rel[1].r_info);
962 1.1 skrll if (r_symndx < symtab_hdr->sh_info)
963 1.10 christos return FALSE;
964 1.10 christos
965 1.9 christos h = sym_hashes[r_symndx - symtab_hdr->sh_info];
966 1.9 christos if (h == NULL
967 1.9 christos || !((struct elf_x86_link_hash_entry *) h)->tls_get_addr)
968 1.9 christos return FALSE;
969 1.9 christos else if (indirect_call)
970 1.9 christos return (ELF32_R_TYPE (rel[1].r_info) == R_386_GOT32X);
971 1.1 skrll else
972 1.1 skrll return (ELF32_R_TYPE (rel[1].r_info) == R_386_PC32
973 1.1 skrll || ELF32_R_TYPE (rel[1].r_info) == R_386_PLT32);
974 1.1 skrll
975 1.1 skrll case R_386_TLS_IE:
976 1.1 skrll /* Check transition from IE access model:
977 1.1 skrll movl foo@indntpoff(%rip), %eax
978 1.1 skrll movl foo@indntpoff(%rip), %reg
979 1.1 skrll addl foo@indntpoff(%rip), %reg
980 1.1 skrll */
981 1.1 skrll
982 1.1 skrll if (offset < 1 || (offset + 4) > sec->size)
983 1.1 skrll return FALSE;
984 1.1 skrll
985 1.1 skrll /* Check "movl foo@tpoff(%rip), %eax" first. */
986 1.1 skrll val = bfd_get_8 (abfd, contents + offset - 1);
987 1.1 skrll if (val == 0xa1)
988 1.1 skrll return TRUE;
989 1.1 skrll
990 1.1 skrll if (offset < 2)
991 1.1 skrll return FALSE;
992 1.1 skrll
993 1.1 skrll /* Check movl|addl foo@tpoff(%rip), %reg. */
994 1.1 skrll type = bfd_get_8 (abfd, contents + offset - 2);
995 1.1 skrll return ((type == 0x8b || type == 0x03)
996 1.1 skrll && (val & 0xc7) == 0x05);
997 1.1 skrll
998 1.1 skrll case R_386_TLS_GOTIE:
999 1.1 skrll case R_386_TLS_IE_32:
1000 1.1 skrll /* Check transition from {IE_32,GOTIE} access model:
1001 1.1 skrll subl foo@{tpoff,gontoff}(%reg1), %reg2
1002 1.1 skrll movl foo@{tpoff,gontoff}(%reg1), %reg2
1003 1.1 skrll addl foo@{tpoff,gontoff}(%reg1), %reg2
1004 1.1 skrll */
1005 1.1 skrll
1006 1.1 skrll if (offset < 2 || (offset + 4) > sec->size)
1007 1.1 skrll return FALSE;
1008 1.1 skrll
1009 1.1 skrll val = bfd_get_8 (abfd, contents + offset - 1);
1010 1.1 skrll if ((val & 0xc0) != 0x80 || (val & 7) == 4)
1011 1.1 skrll return FALSE;
1012 1.1 skrll
1013 1.1 skrll type = bfd_get_8 (abfd, contents + offset - 2);
1014 1.1 skrll return type == 0x8b || type == 0x2b || type == 0x03;
1015 1.1 skrll
1016 1.1 skrll case R_386_TLS_GOTDESC:
1017 1.1 skrll /* Check transition from GDesc access model:
1018 1.1 skrll leal x@tlsdesc(%ebx), %eax
1019 1.1 skrll
1020 1.1 skrll Make sure it's a leal adding ebx to a 32-bit offset
1021 1.1 skrll into any register, although it's probably almost always
1022 1.1 skrll going to be eax. */
1023 1.1 skrll
1024 1.1 skrll if (offset < 2 || (offset + 4) > sec->size)
1025 1.1 skrll return FALSE;
1026 1.1 skrll
1027 1.1 skrll if (bfd_get_8 (abfd, contents + offset - 2) != 0x8d)
1028 1.1 skrll return FALSE;
1029 1.1 skrll
1030 1.1 skrll val = bfd_get_8 (abfd, contents + offset - 1);
1031 1.1 skrll return (val & 0xc7) == 0x83;
1032 1.9 christos
1033 1.1 skrll case R_386_TLS_DESC_CALL:
1034 1.1 skrll /* Check transition from GDesc access model:
1035 1.1 skrll call *x@tlsdesc(%eax)
1036 1.9 christos */
1037 1.9 christos if (offset + 2 <= sec->size)
1038 1.9 christos {
1039 1.1 skrll /* Make sure that it's a call *x@tlsdesc(%eax). */
1040 1.1 skrll call = contents + offset;
1041 1.1 skrll return call[0] == 0xff && call[1] == 0x10;
1042 1.1 skrll }
1043 1.1 skrll
1044 1.1 skrll return FALSE;
1045 1.1 skrll
1046 1.1 skrll default:
1047 1.1 skrll abort ();
1048 1.1 skrll }
1049 1.1 skrll }
1050 1.1 skrll
1051 1.1 skrll /* Return TRUE if the TLS access transition is OK or no transition
1052 1.1 skrll will be performed. Update R_TYPE if there is a transition. */
1053 1.1 skrll
1054 1.1 skrll static bfd_boolean
1055 1.1 skrll elf_i386_tls_transition (struct bfd_link_info *info, bfd *abfd,
1056 1.1 skrll asection *sec, bfd_byte *contents,
1057 1.1 skrll Elf_Internal_Shdr *symtab_hdr,
1058 1.1 skrll struct elf_link_hash_entry **sym_hashes,
1059 1.4 christos unsigned int *r_type, int tls_type,
1060 1.9 christos const Elf_Internal_Rela *rel,
1061 1.9 christos const Elf_Internal_Rela *relend,
1062 1.1 skrll struct elf_link_hash_entry *h,
1063 1.1 skrll unsigned long r_symndx,
1064 1.1 skrll bfd_boolean from_relocate_section)
1065 1.1 skrll {
1066 1.1 skrll unsigned int from_type = *r_type;
1067 1.4 christos unsigned int to_type = from_type;
1068 1.4 christos bfd_boolean check = TRUE;
1069 1.4 christos
1070 1.4 christos /* Skip TLS transition for functions. */
1071 1.4 christos if (h != NULL
1072 1.4 christos && (h->type == STT_FUNC
1073 1.1 skrll || h->type == STT_GNU_IFUNC))
1074 1.1 skrll return TRUE;
1075 1.1 skrll
1076 1.1 skrll switch (from_type)
1077 1.1 skrll {
1078 1.1 skrll case R_386_TLS_GD:
1079 1.1 skrll case R_386_TLS_GOTDESC:
1080 1.1 skrll case R_386_TLS_DESC_CALL:
1081 1.6 christos case R_386_TLS_IE_32:
1082 1.1 skrll case R_386_TLS_IE:
1083 1.1 skrll case R_386_TLS_GOTIE:
1084 1.1 skrll if (bfd_link_executable (info))
1085 1.1 skrll {
1086 1.1 skrll if (h == NULL)
1087 1.1 skrll to_type = R_386_TLS_LE_32;
1088 1.1 skrll else if (from_type != R_386_TLS_IE
1089 1.1 skrll && from_type != R_386_TLS_GOTIE)
1090 1.9 christos to_type = R_386_TLS_IE_32;
1091 1.9 christos }
1092 1.9 christos
1093 1.1 skrll /* When we are called from elf_i386_relocate_section, there may
1094 1.1 skrll be additional transitions based on TLS_TYPE. */
1095 1.1 skrll if (from_relocate_section)
1096 1.10 christos {
1097 1.1 skrll unsigned int new_to_type = to_type;
1098 1.1 skrll
1099 1.1 skrll if (TLS_TRANSITION_IE_TO_LE_P (info, h, tls_type))
1100 1.1 skrll new_to_type = R_386_TLS_LE_32;
1101 1.1 skrll
1102 1.1 skrll if (to_type == R_386_TLS_GD
1103 1.1 skrll || to_type == R_386_TLS_GOTDESC
1104 1.1 skrll || to_type == R_386_TLS_DESC_CALL)
1105 1.1 skrll {
1106 1.1 skrll if (tls_type == GOT_TLS_IE_POS)
1107 1.1 skrll new_to_type = R_386_TLS_GOTIE;
1108 1.1 skrll else if (tls_type & GOT_TLS_IE)
1109 1.1 skrll new_to_type = R_386_TLS_IE_32;
1110 1.1 skrll }
1111 1.1 skrll
1112 1.1 skrll /* We checked the transition before when we were called from
1113 1.1 skrll elf_i386_check_relocs. We only want to check the new
1114 1.1 skrll transition which hasn't been checked before. */
1115 1.1 skrll check = new_to_type != to_type && from_type == to_type;
1116 1.1 skrll to_type = new_to_type;
1117 1.1 skrll }
1118 1.1 skrll
1119 1.6 christos break;
1120 1.1 skrll
1121 1.1 skrll case R_386_TLS_LDM:
1122 1.1 skrll if (bfd_link_executable (info))
1123 1.1 skrll to_type = R_386_TLS_LE_32;
1124 1.1 skrll break;
1125 1.1 skrll
1126 1.1 skrll default:
1127 1.1 skrll return TRUE;
1128 1.1 skrll }
1129 1.1 skrll
1130 1.1 skrll /* Return TRUE if there is no transition. */
1131 1.1 skrll if (from_type == to_type)
1132 1.1 skrll return TRUE;
1133 1.9 christos
1134 1.1 skrll /* Check if the transition can be performed. */
1135 1.1 skrll if (check
1136 1.1 skrll && ! elf_i386_check_tls_transition (sec, contents,
1137 1.1 skrll symtab_hdr, sym_hashes,
1138 1.4 christos from_type, rel, relend))
1139 1.1 skrll {
1140 1.1 skrll reloc_howto_type *from, *to;
1141 1.1 skrll const char *name;
1142 1.1 skrll
1143 1.4 christos from = elf_i386_rtype_to_howto (abfd, from_type);
1144 1.4 christos to = elf_i386_rtype_to_howto (abfd, to_type);
1145 1.4 christos
1146 1.4 christos if (h)
1147 1.10 christos name = h->root.root.string;
1148 1.4 christos else
1149 1.10 christos {
1150 1.4 christos struct elf_x86_link_hash_table *htab;
1151 1.4 christos
1152 1.4 christos htab = elf_x86_hash_table (info, I386_ELF_DATA);
1153 1.4 christos if (htab == NULL)
1154 1.4 christos name = "*unknown*";
1155 1.4 christos else
1156 1.4 christos {
1157 1.4 christos Elf_Internal_Sym *isym;
1158 1.4 christos
1159 1.4 christos isym = bfd_sym_from_r_symndx (&htab->sym_cache,
1160 1.4 christos abfd, r_symndx);
1161 1.4 christos name = bfd_elf_sym_name (abfd, symtab_hdr, isym, NULL);
1162 1.10 christos }
1163 1.10 christos }
1164 1.10 christos
1165 1.1 skrll _bfd_error_handler
1166 1.10 christos /* xgettext:c-format */
1167 1.10 christos (_("%B: TLS transition from %s to %s against `%s' at %#Lx "
1168 1.1 skrll "in section `%A' failed"),
1169 1.1 skrll abfd, from->name, to->name, name,
1170 1.1 skrll rel->r_offset, sec);
1171 1.1 skrll bfd_set_error (bfd_error_bad_value);
1172 1.1 skrll return FALSE;
1173 1.1 skrll }
1174 1.1 skrll
1175 1.1 skrll *r_type = to_type;
1176 1.9 christos return TRUE;
1177 1.9 christos }
1178 1.9 christos
1179 1.9 christos /* With the local symbol, foo, we convert
1180 1.9 christos mov foo@GOT[(%reg1)], %reg2
1181 1.9 christos to
1182 1.9 christos lea foo[@GOTOFF(%reg1)], %reg2
1183 1.9 christos and convert
1184 1.9 christos call/jmp *foo@GOT[(%reg)]
1185 1.9 christos to
1186 1.9 christos nop call foo/jmp foo nop
1187 1.9 christos When PIC is false, convert
1188 1.9 christos test %reg1, foo@GOT[(%reg2)]
1189 1.9 christos to
1190 1.9 christos test $foo, %reg1
1191 1.9 christos and convert
1192 1.9 christos binop foo@GOT[(%reg1)], %reg2
1193 1.9 christos to
1194 1.9 christos binop $foo, %reg2
1195 1.9 christos where binop is one of adc, add, and, cmp, or, sbb, sub, xor
1196 1.9 christos instructions. */
1197 1.9 christos
1198 1.9 christos static
1199 1.10 christos bfd_boolean
1200 1.9 christos elf_i386_convert_load_reloc (bfd *abfd, Elf_Internal_Shdr *symtab_hdr,
1201 1.9 christos bfd_byte *contents,
1202 1.9 christos unsigned int *r_type_p,
1203 1.9 christos Elf_Internal_Rela *irel,
1204 1.9 christos struct elf_link_hash_entry *h,
1205 1.10 christos bfd_boolean *converted,
1206 1.9 christos struct bfd_link_info *link_info)
1207 1.9 christos {
1208 1.9 christos struct elf_x86_link_hash_table *htab;
1209 1.9 christos unsigned int opcode;
1210 1.9 christos unsigned int modrm;
1211 1.9 christos bfd_boolean baseless;
1212 1.9 christos Elf_Internal_Sym *isym;
1213 1.9 christos unsigned int addend;
1214 1.9 christos unsigned int nop;
1215 1.9 christos bfd_vma nop_offset;
1216 1.9 christos bfd_boolean is_pic;
1217 1.9 christos bfd_boolean to_reloc_32;
1218 1.10 christos unsigned int r_type;
1219 1.10 christos unsigned int r_symndx;
1220 1.9 christos bfd_vma roff = irel->r_offset;
1221 1.9 christos bfd_boolean local_ref;
1222 1.9 christos struct elf_x86_link_hash_entry *eh;
1223 1.9 christos
1224 1.9 christos if (roff < 2)
1225 1.9 christos return TRUE;
1226 1.9 christos
1227 1.9 christos /* Addend for R_386_GOT32X relocations must be 0. */
1228 1.9 christos addend = bfd_get_32 (abfd, contents + roff);
1229 1.10 christos if (addend != 0)
1230 1.9 christos return TRUE;
1231 1.9 christos
1232 1.10 christos htab = elf_x86_hash_table (link_info, I386_ELF_DATA);
1233 1.9 christos is_pic = bfd_link_pic (link_info);
1234 1.9 christos
1235 1.9 christos r_type = *r_type_p;
1236 1.9 christos r_symndx = ELF32_R_SYM (irel->r_info);
1237 1.9 christos
1238 1.9 christos modrm = bfd_get_8 (abfd, contents + roff - 1);
1239 1.9 christos baseless = (modrm & 0xc7) == 0x5;
1240 1.9 christos
1241 1.9 christos if (baseless && is_pic)
1242 1.9 christos {
1243 1.9 christos /* For PIC, disallow R_386_GOT32X without a base register
1244 1.9 christos since we don't know what the GOT base is. */
1245 1.9 christos const char *name;
1246 1.9 christos
1247 1.9 christos if (h == NULL)
1248 1.9 christos {
1249 1.9 christos isym = bfd_sym_from_r_symndx (&htab->sym_cache, abfd,
1250 1.9 christos r_symndx);
1251 1.9 christos name = bfd_elf_sym_name (abfd, symtab_hdr, isym, NULL);
1252 1.9 christos }
1253 1.10 christos else
1254 1.10 christos name = h->root.root.string;
1255 1.10 christos
1256 1.10 christos _bfd_error_handler
1257 1.9 christos /* xgettext:c-format */
1258 1.9 christos (_("%B: direct GOT relocation R_386_GOT32X against `%s' without base"
1259 1.9 christos " register can not be used when making a shared object"),
1260 1.9 christos abfd, name);
1261 1.9 christos return FALSE;
1262 1.9 christos }
1263 1.9 christos
1264 1.9 christos opcode = bfd_get_8 (abfd, contents + roff - 2);
1265 1.9 christos
1266 1.9 christos /* Convert to R_386_32 if PIC is false or there is no base
1267 1.10 christos register. */
1268 1.10 christos to_reloc_32 = !is_pic || baseless;
1269 1.9 christos
1270 1.9 christos eh = elf_x86_hash_entry (h);
1271 1.9 christos
1272 1.9 christos /* Try to convert R_386_GOT32X. Get the symbol referred to by the
1273 1.9 christos reloc. */
1274 1.9 christos if (h == NULL)
1275 1.9 christos {
1276 1.9 christos if (opcode == 0x0ff)
1277 1.9 christos /* Convert "call/jmp *foo@GOT[(%reg)]". */
1278 1.9 christos goto convert_branch;
1279 1.9 christos else
1280 1.9 christos /* Convert "mov foo@GOT[(%reg1)], %reg2",
1281 1.9 christos "test %reg1, foo@GOT(%reg2)" and
1282 1.9 christos "binop foo@GOT[(%reg1)], %reg2". */
1283 1.10 christos goto convert_load;
1284 1.10 christos }
1285 1.10 christos
1286 1.9 christos /* NB: Also set linker_def via SYMBOL_REFERENCES_LOCAL_P. */
1287 1.9 christos local_ref = SYMBOL_REFERENCES_LOCAL_P (link_info, h);
1288 1.10 christos
1289 1.10 christos /* Undefined weak symbol is only bound locally in executable
1290 1.10 christos and its reference is resolved as 0. */
1291 1.9 christos if (h->root.type == bfd_link_hash_undefweak
1292 1.9 christos && !eh->linker_def
1293 1.9 christos && local_ref)
1294 1.9 christos {
1295 1.9 christos if (opcode == 0xff)
1296 1.9 christos {
1297 1.9 christos /* No direct branch to 0 for PIC. */
1298 1.9 christos if (is_pic)
1299 1.9 christos return TRUE;
1300 1.9 christos else
1301 1.9 christos goto convert_branch;
1302 1.9 christos }
1303 1.9 christos else
1304 1.9 christos {
1305 1.9 christos /* We can convert load of address 0 to R_386_32. */
1306 1.9 christos to_reloc_32 = TRUE;
1307 1.9 christos goto convert_load;
1308 1.9 christos }
1309 1.9 christos }
1310 1.9 christos
1311 1.9 christos if (opcode == 0xff)
1312 1.9 christos {
1313 1.10 christos /* We have "call/jmp *foo@GOT[(%reg)]". */
1314 1.9 christos if ((h->root.type == bfd_link_hash_defined
1315 1.9 christos || h->root.type == bfd_link_hash_defweak)
1316 1.9 christos && local_ref)
1317 1.9 christos {
1318 1.9 christos /* The function is locally defined. */
1319 1.9 christos convert_branch:
1320 1.9 christos /* Convert R_386_GOT32X to R_386_PC32. */
1321 1.9 christos if (modrm == 0x15 || (modrm & 0xf8) == 0x90)
1322 1.9 christos {
1323 1.9 christos /* Convert to "nop call foo". ADDR_PREFIX_OPCODE
1324 1.9 christos is a nop prefix. */
1325 1.10 christos modrm = 0xe8;
1326 1.9 christos /* To support TLS optimization, always use addr32 prefix
1327 1.9 christos for "call *___tls_get_addr@GOT(%reg)". */
1328 1.9 christos if (eh && eh->tls_get_addr)
1329 1.9 christos {
1330 1.9 christos nop = 0x67;
1331 1.9 christos nop_offset = irel->r_offset - 2;
1332 1.9 christos }
1333 1.9 christos else
1334 1.9 christos {
1335 1.9 christos nop = link_info->call_nop_byte;
1336 1.9 christos if (link_info->call_nop_as_suffix)
1337 1.9 christos {
1338 1.9 christos nop_offset = roff + 3;
1339 1.9 christos irel->r_offset -= 1;
1340 1.9 christos }
1341 1.9 christos else
1342 1.9 christos nop_offset = roff - 2;
1343 1.9 christos }
1344 1.9 christos }
1345 1.9 christos else
1346 1.9 christos {
1347 1.9 christos /* Convert to "jmp foo nop". */
1348 1.9 christos modrm = 0xe9;
1349 1.9 christos nop = NOP_OPCODE;
1350 1.9 christos nop_offset = roff + 3;
1351 1.9 christos irel->r_offset -= 1;
1352 1.9 christos }
1353 1.9 christos
1354 1.9 christos bfd_put_8 (abfd, nop, contents + nop_offset);
1355 1.9 christos bfd_put_8 (abfd, modrm, contents + irel->r_offset - 1);
1356 1.9 christos /* When converting to PC-relative relocation, we
1357 1.10 christos need to adjust addend by -4. */
1358 1.9 christos bfd_put_32 (abfd, -4, contents + irel->r_offset);
1359 1.9 christos irel->r_info = ELF32_R_INFO (r_symndx, R_386_PC32);
1360 1.9 christos *r_type_p = R_386_PC32;
1361 1.9 christos *converted = TRUE;
1362 1.9 christos }
1363 1.9 christos }
1364 1.9 christos else
1365 1.9 christos {
1366 1.9 christos /* We have "mov foo@GOT[(%re1g)], %reg2",
1367 1.9 christos "test %reg1, foo@GOT(%reg2)" and
1368 1.9 christos "binop foo@GOT[(%reg1)], %reg2".
1369 1.9 christos
1370 1.9 christos Avoid optimizing _DYNAMIC since ld.so may use its
1371 1.9 christos link-time address. */
1372 1.9 christos if (h == htab->elf.hdynamic)
1373 1.10 christos return TRUE;
1374 1.10 christos
1375 1.10 christos /* def_regular is set by an assignment in a linker script in
1376 1.10 christos bfd_elf_record_link_assignment. start_stop is set on
1377 1.10 christos __start_SECNAME/__stop_SECNAME which mark section SECNAME. */
1378 1.10 christos if (h->start_stop
1379 1.10 christos || eh->linker_def
1380 1.10 christos || ((h->def_regular
1381 1.9 christos || h->root.type == bfd_link_hash_defined
1382 1.9 christos || h->root.type == bfd_link_hash_defweak)
1383 1.9 christos && local_ref))
1384 1.9 christos {
1385 1.9 christos convert_load:
1386 1.9 christos if (opcode == 0x8b)
1387 1.9 christos {
1388 1.9 christos if (to_reloc_32)
1389 1.9 christos {
1390 1.9 christos /* Convert "mov foo@GOT[(%reg1)], %reg2" to
1391 1.9 christos "mov $foo, %reg2" with R_386_32. */
1392 1.9 christos r_type = R_386_32;
1393 1.9 christos modrm = 0xc0 | (modrm & 0x38) >> 3;
1394 1.9 christos bfd_put_8 (abfd, modrm, contents + roff - 1);
1395 1.9 christos opcode = 0xc7;
1396 1.9 christos }
1397 1.9 christos else
1398 1.9 christos {
1399 1.9 christos /* Convert "mov foo@GOT(%reg1), %reg2" to
1400 1.9 christos "lea foo@GOTOFF(%reg1), %reg2". */
1401 1.9 christos r_type = R_386_GOTOFF;
1402 1.9 christos opcode = 0x8d;
1403 1.9 christos }
1404 1.9 christos }
1405 1.9 christos else
1406 1.9 christos {
1407 1.9 christos /* Only R_386_32 is supported. */
1408 1.9 christos if (!to_reloc_32)
1409 1.9 christos return TRUE;
1410 1.9 christos
1411 1.9 christos if (opcode == 0x85)
1412 1.9 christos {
1413 1.9 christos /* Convert "test %reg1, foo@GOT(%reg2)" to
1414 1.9 christos "test $foo, %reg1". */
1415 1.9 christos modrm = 0xc0 | (modrm & 0x38) >> 3;
1416 1.9 christos opcode = 0xf7;
1417 1.9 christos }
1418 1.9 christos else
1419 1.9 christos {
1420 1.9 christos /* Convert "binop foo@GOT(%reg1), %reg2" to
1421 1.9 christos "binop $foo, %reg2". */
1422 1.9 christos modrm = (0xc0
1423 1.9 christos | (modrm & 0x38) >> 3
1424 1.9 christos | (opcode & 0x3c));
1425 1.9 christos opcode = 0x81;
1426 1.9 christos }
1427 1.9 christos bfd_put_8 (abfd, modrm, contents + roff - 1);
1428 1.9 christos r_type = R_386_32;
1429 1.9 christos }
1430 1.10 christos
1431 1.9 christos bfd_put_8 (abfd, opcode, contents + roff - 2);
1432 1.9 christos irel->r_info = ELF32_R_INFO (r_symndx, r_type);
1433 1.9 christos *r_type_p = r_type;
1434 1.9 christos *converted = TRUE;
1435 1.9 christos }
1436 1.9 christos }
1437 1.9 christos
1438 1.6 christos return TRUE;
1439 1.6 christos }
1440 1.10 christos
1441 1.6 christos /* Rename some of the generic section flags to better document how they
1442 1.1 skrll are used here. */
1443 1.1 skrll #define check_relocs_failed sec_flg0
1444 1.1 skrll
1445 1.1 skrll /* Look through the relocs for a section during the first phase, and
1446 1.1 skrll calculate needed space in the global offset table, procedure linkage
1447 1.1 skrll table, and dynamic reloc sections. */
1448 1.1 skrll
1449 1.1 skrll static bfd_boolean
1450 1.1 skrll elf_i386_check_relocs (bfd *abfd,
1451 1.1 skrll struct bfd_link_info *info,
1452 1.10 christos asection *sec,
1453 1.1 skrll const Elf_Internal_Rela *relocs)
1454 1.1 skrll {
1455 1.1 skrll struct elf_x86_link_hash_table *htab;
1456 1.1 skrll Elf_Internal_Shdr *symtab_hdr;
1457 1.1 skrll struct elf_link_hash_entry **sym_hashes;
1458 1.9 christos const Elf_Internal_Rela *rel;
1459 1.10 christos const Elf_Internal_Rela *rel_end;
1460 1.1 skrll asection *sreloc;
1461 1.6 christos bfd_byte *contents;
1462 1.1 skrll bfd_boolean converted;
1463 1.1 skrll
1464 1.9 christos if (bfd_link_relocatable (info))
1465 1.9 christos return TRUE;
1466 1.9 christos
1467 1.9 christos /* Don't do anything special with non-loaded, non-alloced sections.
1468 1.9 christos In particular, any relocs in such sections should not affect GOT
1469 1.9 christos and PLT reference counting (ie. we don't allow them to create GOT
1470 1.9 christos or PLT entries), there's no possibility or desire to optimize TLS
1471 1.9 christos relocs, and there's not much point in propagating relocs to shared
1472 1.9 christos libs that the dynamic linker won't relocate. */
1473 1.10 christos if ((sec->flags & SEC_ALLOC) == 0)
1474 1.4 christos return TRUE;
1475 1.9 christos
1476 1.9 christos htab = elf_x86_hash_table (info, I386_ELF_DATA);
1477 1.9 christos if (htab == NULL)
1478 1.9 christos {
1479 1.9 christos sec->check_relocs_failed = 1;
1480 1.10 christos return FALSE;
1481 1.10 christos }
1482 1.9 christos
1483 1.9 christos BFD_ASSERT (is_x86_elf (abfd, htab));
1484 1.9 christos
1485 1.9 christos /* Get the section contents. */
1486 1.9 christos if (elf_section_data (sec)->this_hdr.contents != NULL)
1487 1.9 christos contents = elf_section_data (sec)->this_hdr.contents;
1488 1.9 christos else if (!bfd_malloc_and_get_section (abfd, sec, &contents))
1489 1.9 christos {
1490 1.4 christos sec->check_relocs_failed = 1;
1491 1.1 skrll return FALSE;
1492 1.1 skrll }
1493 1.1 skrll
1494 1.10 christos symtab_hdr = &elf_symtab_hdr (abfd);
1495 1.10 christos sym_hashes = elf_sym_hashes (abfd);
1496 1.1 skrll
1497 1.1 skrll converted = FALSE;
1498 1.1 skrll
1499 1.1 skrll sreloc = NULL;
1500 1.1 skrll
1501 1.1 skrll rel_end = relocs + sec->reloc_count;
1502 1.10 christos for (rel = relocs; rel < rel_end; rel++)
1503 1.1 skrll {
1504 1.10 christos unsigned int r_type;
1505 1.4 christos unsigned int r_symndx;
1506 1.4 christos struct elf_link_hash_entry *h;
1507 1.6 christos struct elf_x86_link_hash_entry *eh;
1508 1.1 skrll Elf_Internal_Sym *isym;
1509 1.1 skrll const char *name;
1510 1.1 skrll bfd_boolean size_reloc;
1511 1.1 skrll
1512 1.1 skrll r_symndx = ELF32_R_SYM (rel->r_info);
1513 1.1 skrll r_type = ELF32_R_TYPE (rel->r_info);
1514 1.10 christos
1515 1.10 christos if (r_symndx >= NUM_SHDR_ENTRIES (symtab_hdr))
1516 1.10 christos {
1517 1.9 christos /* xgettext:c-format */
1518 1.1 skrll _bfd_error_handler (_("%B: bad symbol index: %d"),
1519 1.1 skrll abfd, r_symndx);
1520 1.1 skrll goto error_return;
1521 1.4 christos }
1522 1.4 christos
1523 1.4 christos if (r_symndx < symtab_hdr->sh_info)
1524 1.4 christos {
1525 1.4 christos /* A local symbol. */
1526 1.9 christos isym = bfd_sym_from_r_symndx (&htab->sym_cache,
1527 1.4 christos abfd, r_symndx);
1528 1.4 christos if (isym == NULL)
1529 1.4 christos goto error_return;
1530 1.4 christos
1531 1.10 christos /* Check relocation against local STT_GNU_IFUNC symbol. */
1532 1.4 christos if (ELF32_ST_TYPE (isym->st_info) == STT_GNU_IFUNC)
1533 1.9 christos {
1534 1.4 christos h = _bfd_elf_x86_get_local_sym_hash (htab, abfd, rel, TRUE);
1535 1.4 christos if (h == NULL)
1536 1.10 christos goto error_return;
1537 1.10 christos
1538 1.4 christos /* Fake a STT_GNU_IFUNC symbol. */
1539 1.4 christos h->root.root.string = bfd_elf_sym_name (abfd, symtab_hdr,
1540 1.4 christos isym, NULL);
1541 1.4 christos h->type = STT_GNU_IFUNC;
1542 1.4 christos h->def_regular = 1;
1543 1.4 christos h->ref_regular = 1;
1544 1.4 christos h->forced_local = 1;
1545 1.4 christos h->root.type = bfd_link_hash_defined;
1546 1.4 christos }
1547 1.1 skrll else
1548 1.1 skrll h = NULL;
1549 1.4 christos }
1550 1.1 skrll else
1551 1.1 skrll {
1552 1.1 skrll isym = NULL;
1553 1.1 skrll h = sym_hashes[r_symndx - symtab_hdr->sh_info];
1554 1.1 skrll while (h->root.type == bfd_link_hash_indirect
1555 1.1 skrll || h->root.type == bfd_link_hash_warning)
1556 1.10 christos h = (struct elf_link_hash_entry *) h->root.u.i.link;
1557 1.4 christos }
1558 1.4 christos
1559 1.10 christos eh = (struct elf_x86_link_hash_entry *) h;
1560 1.10 christos if (h != NULL)
1561 1.10 christos {
1562 1.10 christos if (r_type == R_386_GOTOFF)
1563 1.10 christos eh->gotoff_ref = 1;
1564 1.6 christos
1565 1.6 christos /* It is referenced by a non-shared object. */
1566 1.6 christos h->ref_regular = 1;
1567 1.6 christos
1568 1.4 christos if (h->type == STT_GNU_IFUNC)
1569 1.4 christos elf_tdata (info->output_bfd)->has_gnu_symbols
1570 1.10 christos |= elf_gnu_symbol_ifunc;
1571 1.10 christos }
1572 1.10 christos
1573 1.10 christos if (r_type == R_386_GOT32X
1574 1.10 christos && (h == NULL || h->type != STT_GNU_IFUNC))
1575 1.10 christos {
1576 1.10 christos Elf_Internal_Rela *irel = (Elf_Internal_Rela *) rel;
1577 1.10 christos if (!elf_i386_convert_load_reloc (abfd, symtab_hdr, contents,
1578 1.10 christos &r_type, irel, h,
1579 1.10 christos &converted, info))
1580 1.9 christos goto error_return;
1581 1.1 skrll }
1582 1.1 skrll
1583 1.9 christos if (! elf_i386_tls_transition (info, abfd, sec, contents,
1584 1.9 christos symtab_hdr, sym_hashes,
1585 1.1 skrll &r_type, GOT_UNKNOWN,
1586 1.1 skrll rel, rel_end, h, r_symndx, FALSE))
1587 1.1 skrll goto error_return;
1588 1.1 skrll
1589 1.10 christos switch (r_type)
1590 1.1 skrll {
1591 1.1 skrll case R_386_TLS_LDM:
1592 1.1 skrll htab->tls_ld_or_ldm_got.refcount = 1;
1593 1.1 skrll goto create_got;
1594 1.1 skrll
1595 1.1 skrll case R_386_PLT32:
1596 1.1 skrll /* This symbol requires a procedure linkage table entry. We
1597 1.1 skrll actually build the entry in adjust_dynamic_symbol,
1598 1.1 skrll because this might be a case of linking PIC code which is
1599 1.1 skrll never referenced by a dynamic object, in which case we
1600 1.1 skrll don't need to generate a procedure linkage table entry
1601 1.1 skrll after all. */
1602 1.1 skrll
1603 1.1 skrll /* If this is a local symbol, we resolve it directly without
1604 1.1 skrll creating a procedure linkage table entry. */
1605 1.10 christos if (h == NULL)
1606 1.1 skrll continue;
1607 1.10 christos
1608 1.1 skrll eh->zero_undefweak &= 0x2;
1609 1.1 skrll h->needs_plt = 1;
1610 1.6 christos h->plt.refcount = 1;
1611 1.6 christos break;
1612 1.6 christos
1613 1.6 christos case R_386_SIZE32:
1614 1.1 skrll size_reloc = TRUE;
1615 1.1 skrll goto do_size;
1616 1.1 skrll
1617 1.6 christos case R_386_TLS_IE_32:
1618 1.1 skrll case R_386_TLS_IE:
1619 1.1 skrll case R_386_TLS_GOTIE:
1620 1.1 skrll if (!bfd_link_executable (info))
1621 1.1 skrll info->flags |= DF_STATIC_TLS;
1622 1.6 christos /* Fall through */
1623 1.1 skrll
1624 1.1 skrll case R_386_GOT32:
1625 1.1 skrll case R_386_GOT32X:
1626 1.1 skrll case R_386_TLS_GD:
1627 1.1 skrll case R_386_TLS_GOTDESC:
1628 1.1 skrll case R_386_TLS_DESC_CALL:
1629 1.1 skrll /* This symbol requires a global offset table entry. */
1630 1.1 skrll {
1631 1.1 skrll int tls_type, old_tls_type;
1632 1.1 skrll
1633 1.6 christos switch (r_type)
1634 1.6 christos {
1635 1.6 christos default:
1636 1.6 christos case R_386_GOT32:
1637 1.1 skrll case R_386_GOT32X:
1638 1.1 skrll tls_type = GOT_NORMAL;
1639 1.1 skrll break;
1640 1.1 skrll case R_386_TLS_GD: tls_type = GOT_TLS_GD; break;
1641 1.1 skrll case R_386_TLS_GOTDESC:
1642 1.1 skrll case R_386_TLS_DESC_CALL:
1643 1.1 skrll tls_type = GOT_TLS_GDESC; break;
1644 1.1 skrll case R_386_TLS_IE_32:
1645 1.1 skrll if (ELF32_R_TYPE (rel->r_info) == r_type)
1646 1.1 skrll tls_type = GOT_TLS_IE_NEG;
1647 1.1 skrll else
1648 1.1 skrll /* If this is a GD->IE transition, we may use either of
1649 1.1 skrll R_386_TLS_TPOFF and R_386_TLS_TPOFF32. */
1650 1.1 skrll tls_type = GOT_TLS_IE;
1651 1.1 skrll break;
1652 1.1 skrll case R_386_TLS_IE:
1653 1.1 skrll case R_386_TLS_GOTIE:
1654 1.1 skrll tls_type = GOT_TLS_IE_POS; break;
1655 1.1 skrll }
1656 1.10 christos
1657 1.10 christos if (h != NULL)
1658 1.1 skrll {
1659 1.1 skrll h->got.refcount = 1;
1660 1.1 skrll old_tls_type = elf_x86_hash_entry (h)->tls_type;
1661 1.1 skrll }
1662 1.1 skrll else
1663 1.1 skrll {
1664 1.1 skrll bfd_signed_vma *local_got_refcounts;
1665 1.1 skrll
1666 1.1 skrll /* This is a global offset table entry for a local symbol. */
1667 1.1 skrll local_got_refcounts = elf_local_got_refcounts (abfd);
1668 1.1 skrll if (local_got_refcounts == NULL)
1669 1.1 skrll {
1670 1.1 skrll bfd_size_type size;
1671 1.1 skrll
1672 1.4 christos size = symtab_hdr->sh_info;
1673 1.10 christos size *= (sizeof (bfd_signed_vma)
1674 1.1 skrll + sizeof (bfd_vma) + sizeof(char));
1675 1.9 christos local_got_refcounts = (bfd_signed_vma *)
1676 1.1 skrll bfd_zalloc (abfd, size);
1677 1.10 christos if (local_got_refcounts == NULL)
1678 1.1 skrll goto error_return;
1679 1.10 christos elf_local_got_refcounts (abfd) = local_got_refcounts;
1680 1.1 skrll elf_x86_local_tlsdesc_gotent (abfd)
1681 1.1 skrll = (bfd_vma *) (local_got_refcounts + symtab_hdr->sh_info);
1682 1.10 christos elf_x86_local_got_tls_type (abfd)
1683 1.10 christos = (char *) (local_got_refcounts + 2 * symtab_hdr->sh_info);
1684 1.1 skrll }
1685 1.1 skrll local_got_refcounts[r_symndx] = 1;
1686 1.1 skrll old_tls_type = elf_x86_local_got_tls_type (abfd) [r_symndx];
1687 1.1 skrll }
1688 1.1 skrll
1689 1.1 skrll if ((old_tls_type & GOT_TLS_IE) && (tls_type & GOT_TLS_IE))
1690 1.1 skrll tls_type |= old_tls_type;
1691 1.1 skrll /* If a TLS symbol is accessed using IE at least once,
1692 1.1 skrll there is no point to use dynamic model for it. */
1693 1.1 skrll else if (old_tls_type != tls_type && old_tls_type != GOT_UNKNOWN
1694 1.1 skrll && (! GOT_TLS_GD_ANY_P (old_tls_type)
1695 1.1 skrll || (tls_type & GOT_TLS_IE) == 0))
1696 1.1 skrll {
1697 1.1 skrll if ((old_tls_type & GOT_TLS_IE) && GOT_TLS_GD_ANY_P (tls_type))
1698 1.1 skrll tls_type = old_tls_type;
1699 1.1 skrll else if (GOT_TLS_GD_ANY_P (old_tls_type)
1700 1.1 skrll && GOT_TLS_GD_ANY_P (tls_type))
1701 1.4 christos tls_type |= old_tls_type;
1702 1.4 christos else
1703 1.4 christos {
1704 1.4 christos if (h)
1705 1.4 christos name = h->root.root.string;
1706 1.10 christos else
1707 1.10 christos name = bfd_elf_sym_name (abfd, symtab_hdr, isym,
1708 1.1 skrll NULL);
1709 1.1 skrll _bfd_error_handler
1710 1.4 christos /* xgettext:c-format */
1711 1.6 christos (_("%B: `%s' accessed both as normal and "
1712 1.9 christos "thread local symbol"),
1713 1.1 skrll abfd, name);
1714 1.1 skrll bfd_set_error (bfd_error_bad_value);
1715 1.1 skrll goto error_return;
1716 1.1 skrll }
1717 1.1 skrll }
1718 1.1 skrll
1719 1.10 christos if (old_tls_type != tls_type)
1720 1.1 skrll {
1721 1.10 christos if (h != NULL)
1722 1.1 skrll elf_x86_hash_entry (h)->tls_type = tls_type;
1723 1.1 skrll else
1724 1.1 skrll elf_x86_local_got_tls_type (abfd) [r_symndx] = tls_type;
1725 1.1 skrll }
1726 1.1 skrll }
1727 1.1 skrll /* Fall through */
1728 1.1 skrll
1729 1.1 skrll case R_386_GOTOFF:
1730 1.9 christos case R_386_GOTPC:
1731 1.9 christos create_got:
1732 1.10 christos if (r_type != R_386_TLS_IE)
1733 1.9 christos {
1734 1.9 christos if (eh != NULL)
1735 1.1 skrll eh->zero_undefweak &= 0x2;
1736 1.1 skrll break;
1737 1.1 skrll }
1738 1.1 skrll /* Fall through */
1739 1.9 christos
1740 1.10 christos case R_386_TLS_LE_32:
1741 1.6 christos case R_386_TLS_LE:
1742 1.1 skrll if (eh != NULL)
1743 1.1 skrll eh->zero_undefweak &= 0x2;
1744 1.9 christos if (bfd_link_executable (info))
1745 1.1 skrll break;
1746 1.1 skrll info->flags |= DF_STATIC_TLS;
1747 1.1 skrll goto do_relocation;
1748 1.9 christos
1749 1.10 christos case R_386_32:
1750 1.9 christos case R_386_PC32:
1751 1.9 christos if (eh != NULL && (sec->flags & SEC_CODE) != 0)
1752 1.9 christos eh->zero_undefweak |= 0x2;
1753 1.9 christos do_relocation:
1754 1.9 christos /* We are called after all symbols have been resolved. Only
1755 1.9 christos relocation against STT_GNU_IFUNC symbol must go through
1756 1.9 christos PLT. */
1757 1.1 skrll if (h != NULL
1758 1.10 christos && (bfd_link_executable (info)
1759 1.9 christos || h->type == STT_GNU_IFUNC))
1760 1.6 christos {
1761 1.6 christos bfd_boolean func_pointer_ref = FALSE;
1762 1.6 christos
1763 1.6 christos if (r_type == R_386_PC32)
1764 1.6 christos {
1765 1.6 christos /* Since something like ".long foo - ." may be used
1766 1.6 christos as pointer, make sure that PLT is used if foo is
1767 1.10 christos a function defined in a shared library. */
1768 1.10 christos if ((sec->flags & SEC_CODE) == 0)
1769 1.10 christos h->pointer_equality_needed = 1;
1770 1.10 christos else if (h->type == STT_GNU_IFUNC
1771 1.10 christos && bfd_link_pic (info))
1772 1.10 christos {
1773 1.10 christos _bfd_error_handler
1774 1.10 christos /* xgettext:c-format */
1775 1.10 christos (_("%B: unsupported non-PIC call to IFUNC `%s'"),
1776 1.10 christos abfd, h->root.root.string);
1777 1.6 christos bfd_set_error (bfd_error_bad_value);
1778 1.6 christos goto error_return;
1779 1.6 christos }
1780 1.6 christos }
1781 1.6 christos else
1782 1.6 christos {
1783 1.6 christos h->pointer_equality_needed = 1;
1784 1.10 christos /* R_386_32 can be resolved at run-time. */
1785 1.10 christos if (r_type == R_386_32
1786 1.10 christos && (sec->flags & SEC_READONLY) == 0)
1787 1.10 christos func_pointer_ref = TRUE;
1788 1.10 christos }
1789 1.10 christos
1790 1.10 christos if (!func_pointer_ref)
1791 1.10 christos {
1792 1.10 christos /* If this reloc is in a read-only section, we might
1793 1.10 christos need a copy reloc. We can't check reliably at this
1794 1.10 christos stage whether the section is read-only, as input
1795 1.10 christos sections have not yet been mapped to output sections.
1796 1.10 christos Tentatively set the flag for now, and correct in
1797 1.10 christos adjust_dynamic_symbol. */
1798 1.10 christos h->non_got_ref = 1;
1799 1.10 christos
1800 1.10 christos /* We may need a .plt entry if the symbol is a function
1801 1.10 christos defined in a shared lib or is a function referenced
1802 1.10 christos from the code or read-only section. */
1803 1.6 christos if (!h->def_regular
1804 1.1 skrll || (sec->flags & (SEC_CODE | SEC_READONLY)) != 0)
1805 1.1 skrll h->plt.refcount = 1;
1806 1.6 christos }
1807 1.6 christos }
1808 1.10 christos
1809 1.10 christos size_reloc = FALSE;
1810 1.1 skrll do_size:
1811 1.4 christos if (NEED_DYNAMIC_RELOCATION_P (info, h, sec, r_type,
1812 1.4 christos R_386_32))
1813 1.1 skrll {
1814 1.1 skrll struct elf_dyn_relocs *p;
1815 1.1 skrll struct elf_dyn_relocs **head;
1816 1.1 skrll
1817 1.1 skrll /* We must copy these reloc types into the output file.
1818 1.1 skrll Create a reloc section in dynobj and make room for
1819 1.4 christos this reloc. */
1820 1.4 christos if (sreloc == NULL)
1821 1.4 christos {
1822 1.1 skrll sreloc = _bfd_elf_make_dynamic_reloc_section
1823 1.9 christos (sec, htab->elf.dynobj, 2, abfd, /*rela?*/ FALSE);
1824 1.1 skrll
1825 1.1 skrll if (sreloc == NULL)
1826 1.1 skrll goto error_return;
1827 1.1 skrll }
1828 1.1 skrll
1829 1.1 skrll /* If this is a global symbol, we count the number of
1830 1.6 christos relocations we need for this symbol. */
1831 1.1 skrll if (h != NULL)
1832 1.1 skrll {
1833 1.1 skrll head = &eh->dyn_relocs;
1834 1.1 skrll }
1835 1.1 skrll else
1836 1.1 skrll {
1837 1.4 christos /* Track dynamic relocs needed for local syms too.
1838 1.4 christos We really need local syms available to do this
1839 1.4 christos easily. Oh well. */
1840 1.4 christos void **vpp;
1841 1.4 christos asection *s;
1842 1.4 christos
1843 1.9 christos isym = bfd_sym_from_r_symndx (&htab->sym_cache,
1844 1.1 skrll abfd, r_symndx);
1845 1.4 christos if (isym == NULL)
1846 1.1 skrll goto error_return;
1847 1.4 christos
1848 1.1 skrll s = bfd_section_from_elf_index (abfd, isym->st_shndx);
1849 1.1 skrll if (s == NULL)
1850 1.4 christos s = sec;
1851 1.1 skrll
1852 1.1 skrll vpp = &elf_section_data (s)->local_dynrel;
1853 1.1 skrll head = (struct elf_dyn_relocs **)vpp;
1854 1.1 skrll }
1855 1.1 skrll
1856 1.1 skrll p = *head;
1857 1.4 christos if (p == NULL || p->sec != sec)
1858 1.10 christos {
1859 1.1 skrll bfd_size_type amt = sizeof *p;
1860 1.9 christos p = (struct elf_dyn_relocs *) bfd_alloc (htab->elf.dynobj,
1861 1.1 skrll amt);
1862 1.1 skrll if (p == NULL)
1863 1.1 skrll goto error_return;
1864 1.1 skrll p->next = *head;
1865 1.1 skrll *head = p;
1866 1.1 skrll p->sec = sec;
1867 1.1 skrll p->count = 0;
1868 1.1 skrll p->pc_count = 0;
1869 1.6 christos }
1870 1.6 christos
1871 1.1 skrll p->count += 1;
1872 1.1 skrll /* Count size relocation as PC-relative relocation. */
1873 1.1 skrll if (r_type == R_386_PC32 || size_reloc)
1874 1.1 skrll p->pc_count += 1;
1875 1.1 skrll }
1876 1.1 skrll break;
1877 1.1 skrll
1878 1.1 skrll /* This relocation describes the C++ object vtable hierarchy.
1879 1.9 christos Reconstruct it for later use during GC. */
1880 1.1 skrll case R_386_GNU_VTINHERIT:
1881 1.1 skrll if (!bfd_elf_gc_record_vtinherit (abfd, sec, h, rel->r_offset))
1882 1.1 skrll goto error_return;
1883 1.1 skrll break;
1884 1.1 skrll
1885 1.1 skrll /* This relocation describes which C++ vtable entries are actually
1886 1.1 skrll used. Record for later use during GC. */
1887 1.1 skrll case R_386_GNU_VTENTRY:
1888 1.9 christos BFD_ASSERT (h != NULL);
1889 1.1 skrll if (h != NULL
1890 1.1 skrll && !bfd_elf_gc_record_vtentry (abfd, sec, h, rel->r_offset))
1891 1.1 skrll goto error_return;
1892 1.1 skrll break;
1893 1.1 skrll
1894 1.9 christos default:
1895 1.9 christos break;
1896 1.9 christos }
1897 1.1 skrll }
1898 1.10 christos
1899 1.6 christos if (elf_section_data (sec)->this_hdr.contents != contents)
1900 1.6 christos {
1901 1.6 christos if (!converted && !info->keep_memory)
1902 1.10 christos free (contents);
1903 1.10 christos else
1904 1.6 christos {
1905 1.6 christos /* Cache the section contents for elf_link_input_bfd if any
1906 1.6 christos load is converted or --no-keep-memory isn't used. */
1907 1.6 christos elf_section_data (sec)->this_hdr.contents = contents;
1908 1.10 christos }
1909 1.10 christos }
1910 1.10 christos
1911 1.10 christos /* Cache relocations if any load is converted. */
1912 1.1 skrll if (elf_section_data (sec)->relocs != relocs && converted)
1913 1.10 christos elf_section_data (sec)->relocs = (Elf_Internal_Rela *) relocs;
1914 1.10 christos
1915 1.10 christos return TRUE;
1916 1.10 christos
1917 1.10 christos error_return:
1918 1.10 christos if (elf_section_data (sec)->this_hdr.contents != contents)
1919 1.1 skrll free (contents);
1920 1.1 skrll sec->check_relocs_failed = 1;
1921 1.1 skrll return FALSE;
1922 1.1 skrll }
1923 1.1 skrll
1924 1.1 skrll /* Set the correct type for an x86 ELF section. We do this by the
1925 1.1 skrll section name, which is a hack, but ought to work. */
1926 1.1 skrll
1927 1.1 skrll static bfd_boolean
1928 1.1 skrll elf_i386_fake_sections (bfd *abfd ATTRIBUTE_UNUSED,
1929 1.4 christos Elf_Internal_Shdr *hdr,
1930 1.1 skrll asection *sec)
1931 1.1 skrll {
1932 1.1 skrll const char *name;
1933 1.1 skrll
1934 1.1 skrll name = bfd_get_section_name (abfd, sec);
1935 1.1 skrll
1936 1.1 skrll /* This is an ugly, but unfortunately necessary hack that is
1937 1.1 skrll needed when producing EFI binaries on x86. It tells
1938 1.1 skrll elf.c:elf_fake_sections() not to consider ".reloc" as a section
1939 1.1 skrll containing ELF relocation info. We need this hack in order to
1940 1.1 skrll be able to generate ELF binaries that can be translated into
1941 1.1 skrll EFI applications (which are essentially COFF objects). Those
1942 1.1 skrll files contain a COFF ".reloc" section inside an ELFNN object,
1943 1.1 skrll which would normally cause BFD to segfault because it would
1944 1.1 skrll attempt to interpret this section as containing relocation
1945 1.1 skrll entries for section "oc". With this hack enabled, ".reloc"
1946 1.1 skrll will be treated as a normal data section, which will avoid the
1947 1.1 skrll segfault. However, you won't be able to create an ELFNN binary
1948 1.1 skrll with a section named "oc" that needs relocations, but that's
1949 1.1 skrll the kind of ugly side-effects you get when detecting section
1950 1.1 skrll types based on their names... In practice, this limitation is
1951 1.1 skrll unlikely to bite. */
1952 1.1 skrll if (strcmp (name, ".reloc") == 0)
1953 1.1 skrll hdr->sh_type = SHT_PROGBITS;
1954 1.1 skrll
1955 1.1 skrll return TRUE;
1956 1.1 skrll }
1957 1.1 skrll
1958 1.1 skrll /* Return the relocation value for @tpoff relocation
1959 1.4 christos if STT_TLS virtual address is ADDRESS. */
1960 1.1 skrll
1961 1.1 skrll static bfd_vma
1962 1.4 christos elf_i386_tpoff (struct bfd_link_info *info, bfd_vma address)
1963 1.4 christos {
1964 1.1 skrll struct elf_link_hash_table *htab = elf_hash_table (info);
1965 1.1 skrll const struct elf_backend_data *bed = get_elf_backend_data (info->output_bfd);
1966 1.1 skrll bfd_vma static_tls_size;
1967 1.1 skrll
1968 1.4 christos /* If tls_sec is NULL, we should have signalled an error already. */
1969 1.4 christos if (htab->tls_sec == NULL)
1970 1.4 christos return 0;
1971 1.4 christos
1972 1.1 skrll /* Consider special static TLS alignment requirements. */
1973 1.1 skrll static_tls_size = BFD_ALIGN (htab->tls_size, bed->static_tls_alignment);
1974 1.1 skrll return static_tls_size + htab->tls_sec->vma - address;
1975 1.1 skrll }
1976 1.1 skrll
1977 1.1 skrll /* Relocate an i386 ELF section. */
1978 1.1 skrll
1979 1.1 skrll static bfd_boolean
1980 1.1 skrll elf_i386_relocate_section (bfd *output_bfd,
1981 1.1 skrll struct bfd_link_info *info,
1982 1.1 skrll bfd *input_bfd,
1983 1.1 skrll asection *input_section,
1984 1.1 skrll bfd_byte *contents,
1985 1.1 skrll Elf_Internal_Rela *relocs,
1986 1.10 christos Elf_Internal_Sym *local_syms,
1987 1.1 skrll asection **local_sections)
1988 1.1 skrll {
1989 1.1 skrll struct elf_x86_link_hash_table *htab;
1990 1.1 skrll Elf_Internal_Shdr *symtab_hdr;
1991 1.1 skrll struct elf_link_hash_entry **sym_hashes;
1992 1.6 christos bfd_vma *local_got_offsets;
1993 1.1 skrll bfd_vma *local_tlsdesc_gotents;
1994 1.1 skrll Elf_Internal_Rela *rel;
1995 1.5 christos Elf_Internal_Rela *wrel;
1996 1.1 skrll Elf_Internal_Rela *relend;
1997 1.9 christos bfd_boolean is_vxworks_tls;
1998 1.9 christos unsigned plt_entry_size;
1999 1.9 christos
2000 1.9 christos /* Skip if check_relocs failed. */
2001 1.10 christos if (input_section->check_relocs_failed)
2002 1.4 christos return FALSE;
2003 1.4 christos
2004 1.10 christos htab = elf_x86_hash_table (info, I386_ELF_DATA);
2005 1.10 christos if (htab == NULL)
2006 1.10 christos return FALSE;
2007 1.1 skrll
2008 1.1 skrll BFD_ASSERT (is_x86_elf (input_bfd, htab));
2009 1.1 skrll
2010 1.10 christos symtab_hdr = &elf_symtab_hdr (input_bfd);
2011 1.1 skrll sym_hashes = elf_sym_hashes (input_bfd);
2012 1.1 skrll local_got_offsets = elf_local_got_offsets (input_bfd);
2013 1.10 christos local_tlsdesc_gotents = elf_x86_local_tlsdesc_gotent (input_bfd);
2014 1.10 christos /* We have to handle relocations in vxworks .tls_vars sections
2015 1.1 skrll specially, because the dynamic loader is 'weird'. */
2016 1.1 skrll is_vxworks_tls = (htab->target_os == is_vxworks
2017 1.1 skrll && bfd_link_pic (info)
2018 1.10 christos && !strcmp (input_section->output_section->name,
2019 1.1 skrll ".tls_vars"));
2020 1.10 christos
2021 1.5 christos _bfd_x86_elf_set_tls_module_base (info);
2022 1.6 christos
2023 1.1 skrll plt_entry_size = htab->plt.plt_entry_size;
2024 1.6 christos
2025 1.1 skrll rel = wrel = relocs;
2026 1.10 christos relend = relocs + input_section->reloc_count;
2027 1.1 skrll for (; rel < relend; wrel++, rel++)
2028 1.1 skrll {
2029 1.1 skrll unsigned int r_type, r_type_tls;
2030 1.10 christos reloc_howto_type *howto;
2031 1.1 skrll unsigned long r_symndx;
2032 1.1 skrll struct elf_link_hash_entry *h;
2033 1.6 christos struct elf_x86_link_hash_entry *eh;
2034 1.1 skrll Elf_Internal_Sym *sym;
2035 1.1 skrll asection *sec;
2036 1.1 skrll bfd_vma off, offplt, plt_offset;
2037 1.1 skrll bfd_vma relocation;
2038 1.1 skrll bfd_boolean unresolved_reloc;
2039 1.6 christos bfd_reloc_status_type r;
2040 1.6 christos unsigned int indx;
2041 1.9 christos int tls_type;
2042 1.10 christos bfd_vma st_size;
2043 1.1 skrll asection *resolved_plt;
2044 1.1 skrll bfd_boolean resolved_to_zero;
2045 1.1 skrll bfd_boolean relative_reloc;
2046 1.1 skrll
2047 1.6 christos r_type = ELF32_R_TYPE (rel->r_info);
2048 1.6 christos if (r_type == R_386_GNU_VTINHERIT
2049 1.6 christos || r_type == R_386_GNU_VTENTRY)
2050 1.6 christos {
2051 1.6 christos if (wrel != rel)
2052 1.1 skrll *wrel = *rel;
2053 1.1 skrll continue;
2054 1.1 skrll }
2055 1.1 skrll
2056 1.1 skrll if ((indx = r_type) >= R_386_standard
2057 1.6 christos && ((indx = r_type - R_386_ext_offset) - R_386_standard
2058 1.10 christos >= R_386_ext - R_386_standard)
2059 1.10 christos && ((indx = r_type - R_386_tls_offset) - R_386_ext
2060 1.1 skrll >= R_386_ext2 - R_386_ext))
2061 1.1 skrll return _bfd_unrecognized_reloc (input_bfd, input_section, r_type);
2062 1.1 skrll
2063 1.1 skrll howto = elf_howto_table + indx;
2064 1.1 skrll
2065 1.1 skrll r_symndx = ELF32_R_SYM (rel->r_info);
2066 1.1 skrll h = NULL;
2067 1.1 skrll sym = NULL;
2068 1.1 skrll sec = NULL;
2069 1.1 skrll unresolved_reloc = FALSE;
2070 1.1 skrll if (r_symndx < symtab_hdr->sh_info)
2071 1.1 skrll {
2072 1.1 skrll sym = local_syms + r_symndx;
2073 1.1 skrll sec = local_sections[r_symndx];
2074 1.6 christos relocation = (sec->output_section->vma
2075 1.1 skrll + sec->output_offset
2076 1.1 skrll + sym->st_value);
2077 1.1 skrll st_size = sym->st_size;
2078 1.6 christos
2079 1.1 skrll if (ELF_ST_TYPE (sym->st_info) == STT_SECTION
2080 1.1 skrll && ((sec->flags & SEC_MERGE) != 0
2081 1.1 skrll || (bfd_link_relocatable (info)
2082 1.1 skrll && sec->output_offset != 0)))
2083 1.1 skrll {
2084 1.1 skrll bfd_vma addend;
2085 1.1 skrll bfd_byte *where = contents + rel->r_offset;
2086 1.1 skrll
2087 1.1 skrll switch (howto->size)
2088 1.1 skrll {
2089 1.1 skrll case 0:
2090 1.1 skrll addend = bfd_get_8 (input_bfd, where);
2091 1.1 skrll if (howto->pc_relative)
2092 1.1 skrll {
2093 1.1 skrll addend = (addend ^ 0x80) - 0x80;
2094 1.1 skrll addend += 1;
2095 1.1 skrll }
2096 1.1 skrll break;
2097 1.1 skrll case 1:
2098 1.1 skrll addend = bfd_get_16 (input_bfd, where);
2099 1.1 skrll if (howto->pc_relative)
2100 1.1 skrll {
2101 1.1 skrll addend = (addend ^ 0x8000) - 0x8000;
2102 1.1 skrll addend += 2;
2103 1.1 skrll }
2104 1.1 skrll break;
2105 1.1 skrll case 2:
2106 1.1 skrll addend = bfd_get_32 (input_bfd, where);
2107 1.1 skrll if (howto->pc_relative)
2108 1.1 skrll {
2109 1.1 skrll addend = (addend ^ 0x80000000) - 0x80000000;
2110 1.1 skrll addend += 4;
2111 1.1 skrll }
2112 1.1 skrll break;
2113 1.1 skrll default:
2114 1.6 christos abort ();
2115 1.1 skrll }
2116 1.1 skrll
2117 1.1 skrll if (bfd_link_relocatable (info))
2118 1.1 skrll addend += sec->output_offset;
2119 1.1 skrll else
2120 1.1 skrll {
2121 1.1 skrll asection *msec = sec;
2122 1.1 skrll addend = _bfd_elf_rel_local_sym (output_bfd, sym, &msec,
2123 1.1 skrll addend);
2124 1.1 skrll addend -= relocation;
2125 1.1 skrll addend += msec->output_section->vma + msec->output_offset;
2126 1.1 skrll }
2127 1.1 skrll
2128 1.1 skrll switch (howto->size)
2129 1.1 skrll {
2130 1.1 skrll case 0:
2131 1.1 skrll /* FIXME: overflow checks. */
2132 1.1 skrll if (howto->pc_relative)
2133 1.1 skrll addend -= 1;
2134 1.1 skrll bfd_put_8 (input_bfd, addend, where);
2135 1.1 skrll break;
2136 1.1 skrll case 1:
2137 1.1 skrll if (howto->pc_relative)
2138 1.1 skrll addend -= 2;
2139 1.1 skrll bfd_put_16 (input_bfd, addend, where);
2140 1.1 skrll break;
2141 1.1 skrll case 2:
2142 1.1 skrll if (howto->pc_relative)
2143 1.1 skrll addend -= 4;
2144 1.1 skrll bfd_put_32 (input_bfd, addend, where);
2145 1.6 christos break;
2146 1.4 christos }
2147 1.4 christos }
2148 1.4 christos else if (!bfd_link_relocatable (info)
2149 1.10 christos && ELF32_ST_TYPE (sym->st_info) == STT_GNU_IFUNC)
2150 1.10 christos {
2151 1.4 christos /* Relocate against local STT_GNU_IFUNC symbol. */
2152 1.4 christos h = _bfd_elf_x86_get_local_sym_hash (htab, input_bfd, rel,
2153 1.4 christos FALSE);
2154 1.5 christos if (h == NULL)
2155 1.4 christos abort ();
2156 1.4 christos
2157 1.4 christos /* Set STT_GNU_IFUNC symbol value. */
2158 1.1 skrll h->root.u.def.value = sym->st_value;
2159 1.1 skrll h->root.u.def.section = sec;
2160 1.1 skrll }
2161 1.4 christos }
2162 1.6 christos else
2163 1.1 skrll {
2164 1.1 skrll bfd_boolean warned ATTRIBUTE_UNUSED;
2165 1.1 skrll bfd_boolean ignored ATTRIBUTE_UNUSED;
2166 1.1 skrll
2167 1.6 christos RELOC_FOR_GLOBAL_SYMBOL (info, input_bfd, input_section, rel,
2168 1.6 christos r_symndx, symtab_hdr, sym_hashes,
2169 1.1 skrll h, sec, relocation,
2170 1.1 skrll unresolved_reloc, warned, ignored);
2171 1.5 christos st_size = h->size;
2172 1.6 christos }
2173 1.6 christos
2174 1.6 christos if (sec != NULL && discarded_section (sec))
2175 1.6 christos {
2176 1.6 christos _bfd_clear_contents (howto, input_bfd, input_section,
2177 1.6 christos contents + rel->r_offset);
2178 1.6 christos wrel->r_offset = rel->r_offset;
2179 1.6 christos wrel->r_info = 0;
2180 1.6 christos wrel->r_addend = 0;
2181 1.6 christos
2182 1.6 christos /* For ld -r, remove relocations in debug sections against
2183 1.6 christos sections defined in discarded sections. Not done for
2184 1.6 christos eh_frame editing code expects to be present. */
2185 1.6 christos if (bfd_link_relocatable (info)
2186 1.6 christos && (input_section->flags & SEC_DEBUGGING))
2187 1.6 christos wrel--;
2188 1.1 skrll
2189 1.6 christos continue;
2190 1.6 christos }
2191 1.6 christos
2192 1.6 christos if (bfd_link_relocatable (info))
2193 1.6 christos {
2194 1.6 christos if (wrel != rel)
2195 1.1 skrll *wrel = *rel;
2196 1.10 christos continue;
2197 1.10 christos }
2198 1.4 christos
2199 1.4 christos eh = (struct elf_x86_link_hash_entry *) h;
2200 1.4 christos
2201 1.4 christos /* Since STT_GNU_IFUNC symbol must go through PLT, we handle
2202 1.4 christos it here if it is defined in a non-shared object. */
2203 1.4 christos if (h != NULL
2204 1.10 christos && h->type == STT_GNU_IFUNC
2205 1.4 christos && h->def_regular)
2206 1.4 christos {
2207 1.4 christos asection *gotplt, *base_got;
2208 1.6 christos bfd_vma plt_index;
2209 1.6 christos const char *name;
2210 1.6 christos
2211 1.6 christos if ((input_section->flags & SEC_ALLOC) == 0)
2212 1.6 christos {
2213 1.6 christos /* Dynamic relocs are not propagated for SEC_DEBUGGING
2214 1.6 christos sections because such sections are not SEC_ALLOC and
2215 1.6 christos thus ld.so will not process them. */
2216 1.6 christos if ((input_section->flags & SEC_DEBUGGING) != 0)
2217 1.4 christos continue;
2218 1.4 christos abort ();
2219 1.4 christos }
2220 1.4 christos
2221 1.10 christos /* STT_GNU_IFUNC symbol must go through PLT. */
2222 1.10 christos if (htab->elf.splt != NULL)
2223 1.10 christos {
2224 1.10 christos if (htab->plt_second != NULL)
2225 1.10 christos {
2226 1.10 christos resolved_plt = htab->plt_second;
2227 1.10 christos plt_offset = eh->plt_second.offset;
2228 1.10 christos }
2229 1.10 christos else
2230 1.10 christos {
2231 1.4 christos resolved_plt = htab->elf.splt;
2232 1.4 christos plt_offset = h->plt.offset;
2233 1.4 christos }
2234 1.4 christos gotplt = htab->elf.sgotplt;
2235 1.10 christos }
2236 1.10 christos else
2237 1.4 christos {
2238 1.4 christos resolved_plt = htab->elf.iplt;
2239 1.4 christos plt_offset = h->plt.offset;
2240 1.4 christos gotplt = htab->elf.igotplt;
2241 1.4 christos }
2242 1.4 christos
2243 1.9 christos switch (r_type)
2244 1.4 christos {
2245 1.4 christos default:
2246 1.6 christos break;
2247 1.4 christos
2248 1.4 christos case R_386_GOT32:
2249 1.4 christos case R_386_GOT32X:
2250 1.4 christos base_got = htab->elf.sgot;
2251 1.4 christos off = h->got.offset;
2252 1.4 christos
2253 1.4 christos if (base_got == NULL)
2254 1.4 christos abort ();
2255 1.4 christos
2256 1.4 christos if (off == (bfd_vma) -1)
2257 1.4 christos {
2258 1.4 christos /* We can't use h->got.offset here to save state, or
2259 1.9 christos even just remember the offset, as finish_dynamic_symbol
2260 1.9 christos would use that as offset into .got. */
2261 1.9 christos
2262 1.4 christos if (h->plt.offset == (bfd_vma) -1)
2263 1.4 christos abort ();
2264 1.10 christos
2265 1.10 christos if (htab->elf.splt != NULL)
2266 1.4 christos {
2267 1.4 christos plt_index = (h->plt.offset / plt_entry_size
2268 1.4 christos - htab->plt.has_plt0);
2269 1.4 christos off = (plt_index + 3) * 4;
2270 1.4 christos base_got = htab->elf.sgotplt;
2271 1.5 christos }
2272 1.4 christos else
2273 1.4 christos {
2274 1.4 christos plt_index = h->plt.offset / plt_entry_size;
2275 1.4 christos off = plt_index * 4;
2276 1.4 christos base_got = htab->elf.igotplt;
2277 1.4 christos }
2278 1.4 christos
2279 1.4 christos if (h->dynindx == -1
2280 1.4 christos || h->forced_local
2281 1.4 christos || info->symbolic)
2282 1.4 christos {
2283 1.4 christos /* This references the local defitionion. We must
2284 1.4 christos initialize this entry in the global offset table.
2285 1.4 christos Since the offset must always be a multiple of 8,
2286 1.4 christos we use the least significant bit to record
2287 1.4 christos whether we have initialized it already.
2288 1.4 christos
2289 1.4 christos When doing a dynamic link, we create a .rela.got
2290 1.4 christos relocation entry to initialize the value. This
2291 1.4 christos is done in the finish_dynamic_symbol routine. */
2292 1.4 christos if ((off & 1) != 0)
2293 1.4 christos off &= ~1;
2294 1.4 christos else
2295 1.4 christos {
2296 1.4 christos bfd_put_32 (output_bfd, relocation,
2297 1.4 christos base_got->contents + off);
2298 1.4 christos h->got.offset |= 1;
2299 1.4 christos }
2300 1.8 christos }
2301 1.8 christos
2302 1.8 christos relocation = off;
2303 1.8 christos }
2304 1.8 christos else
2305 1.8 christos relocation = (base_got->output_section->vma
2306 1.8 christos + base_got->output_offset + off
2307 1.10 christos - gotplt->output_section->vma
2308 1.10 christos - gotplt->output_offset);
2309 1.10 christos
2310 1.8 christos if (rel->r_offset > 1
2311 1.8 christos && (*(contents + rel->r_offset - 1) & 0xc7) == 0x5
2312 1.8 christos && *(contents + rel->r_offset - 2) != 0x8d)
2313 1.4 christos {
2314 1.8 christos if (bfd_link_pic (info))
2315 1.8 christos goto disallow_got32;
2316 1.8 christos
2317 1.4 christos /* Add the GOT base if there is no base register. */
2318 1.8 christos relocation += (gotplt->output_section->vma
2319 1.4 christos + gotplt->output_offset);
2320 1.4 christos }
2321 1.8 christos else if (htab->elf.splt == NULL)
2322 1.4 christos {
2323 1.4 christos /* Adjust for static executables. */
2324 1.4 christos relocation += gotplt->output_offset;
2325 1.9 christos }
2326 1.9 christos
2327 1.9 christos goto do_relocation;
2328 1.9 christos }
2329 1.9 christos
2330 1.9 christos if (h->plt.offset == (bfd_vma) -1)
2331 1.9 christos {
2332 1.9 christos /* Handle static pointers of STT_GNU_IFUNC symbols. */
2333 1.9 christos if (r_type == R_386_32
2334 1.9 christos && (input_section->flags & SEC_CODE) == 0)
2335 1.9 christos goto do_ifunc_pointer;
2336 1.10 christos goto bad_ifunc_reloc;
2337 1.10 christos }
2338 1.9 christos
2339 1.9 christos relocation = (resolved_plt->output_section->vma
2340 1.9 christos + resolved_plt->output_offset + plt_offset);
2341 1.9 christos
2342 1.9 christos switch (r_type)
2343 1.9 christos {
2344 1.9 christos default:
2345 1.9 christos bad_ifunc_reloc:
2346 1.9 christos if (h->root.root.string)
2347 1.9 christos name = h->root.root.string;
2348 1.10 christos else
2349 1.10 christos name = bfd_elf_sym_name (input_bfd, symtab_hdr, sym,
2350 1.9 christos NULL);
2351 1.9 christos _bfd_error_handler
2352 1.9 christos /* xgettext:c-format */
2353 1.9 christos (_("%B: relocation %s against STT_GNU_IFUNC "
2354 1.9 christos "symbol `%s' isn't supported"), input_bfd,
2355 1.9 christos howto->name, name);
2356 1.9 christos bfd_set_error (bfd_error_bad_value);
2357 1.9 christos return FALSE;
2358 1.9 christos
2359 1.9 christos case R_386_32:
2360 1.9 christos /* Generate dynamic relcoation only when there is a
2361 1.9 christos non-GOT reference in a shared object. */
2362 1.9 christos if ((bfd_link_pic (info) && h->non_got_ref)
2363 1.9 christos || h->plt.offset == (bfd_vma) -1)
2364 1.9 christos {
2365 1.9 christos Elf_Internal_Rela outrel;
2366 1.9 christos asection *sreloc;
2367 1.9 christos bfd_vma offset;
2368 1.9 christos
2369 1.9 christos do_ifunc_pointer:
2370 1.9 christos /* Need a dynamic relocation to get the real function
2371 1.9 christos adddress. */
2372 1.9 christos offset = _bfd_elf_section_offset (output_bfd,
2373 1.9 christos info,
2374 1.9 christos input_section,
2375 1.9 christos rel->r_offset);
2376 1.9 christos if (offset == (bfd_vma) -1
2377 1.9 christos || offset == (bfd_vma) -2)
2378 1.9 christos abort ();
2379 1.9 christos
2380 1.9 christos outrel.r_offset = (input_section->output_section->vma
2381 1.10 christos + input_section->output_offset
2382 1.9 christos + offset);
2383 1.10 christos
2384 1.10 christos if (POINTER_LOCAL_IFUNC_P (info, h))
2385 1.10 christos {
2386 1.10 christos info->callbacks->minfo (_("Local IFUNC function `%s' in %B\n"),
2387 1.9 christos h->root.root.string,
2388 1.9 christos h->root.u.def.section->owner);
2389 1.9 christos
2390 1.9 christos /* This symbol is resolved locally. */
2391 1.9 christos outrel.r_info = ELF32_R_INFO (0, R_386_IRELATIVE);
2392 1.9 christos bfd_put_32 (output_bfd,
2393 1.9 christos (h->root.u.def.value
2394 1.9 christos + h->root.u.def.section->output_section->vma
2395 1.9 christos + h->root.u.def.section->output_offset),
2396 1.9 christos contents + offset);
2397 1.9 christos }
2398 1.9 christos else
2399 1.9 christos outrel.r_info = ELF32_R_INFO (h->dynindx, r_type);
2400 1.9 christos
2401 1.9 christos /* Dynamic relocations are stored in
2402 1.9 christos 1. .rel.ifunc section in PIC object.
2403 1.9 christos 2. .rel.got section in dynamic executable.
2404 1.9 christos 3. .rel.iplt section in static executable. */
2405 1.9 christos if (bfd_link_pic (info))
2406 1.9 christos sreloc = htab->elf.irelifunc;
2407 1.9 christos else if (htab->elf.splt != NULL)
2408 1.9 christos sreloc = htab->elf.srelgot;
2409 1.9 christos else
2410 1.9 christos sreloc = htab->elf.irelplt;
2411 1.9 christos elf_append_rel (output_bfd, sreloc, &outrel);
2412 1.9 christos
2413 1.9 christos /* If this reloc is against an external symbol, we
2414 1.9 christos do not want to fiddle with the addend. Otherwise,
2415 1.9 christos we need to include the symbol value so that it
2416 1.9 christos becomes an addend for the dynamic reloc. For an
2417 1.9 christos internal symbol, we have updated addend. */
2418 1.9 christos continue;
2419 1.9 christos }
2420 1.9 christos /* FALLTHROUGH */
2421 1.4 christos case R_386_PC32:
2422 1.4 christos case R_386_PLT32:
2423 1.4 christos goto do_relocation;
2424 1.4 christos
2425 1.4 christos case R_386_GOTOFF:
2426 1.4 christos relocation -= (gotplt->output_section->vma
2427 1.4 christos + gotplt->output_offset);
2428 1.4 christos goto do_relocation;
2429 1.9 christos }
2430 1.10 christos }
2431 1.9 christos
2432 1.1 skrll resolved_to_zero = (eh != NULL
2433 1.1 skrll && UNDEFINED_WEAK_RESOLVED_TO_ZERO (info, eh));
2434 1.6 christos
2435 1.6 christos switch (r_type)
2436 1.6 christos {
2437 1.6 christos case R_386_GOT32X:
2438 1.6 christos /* Avoid optimizing _DYNAMIC since ld.so may use its
2439 1.6 christos link-time address. */
2440 1.6 christos if (h == htab->elf.hdynamic)
2441 1.6 christos goto r_386_got32;
2442 1.6 christos
2443 1.6 christos if (bfd_link_pic (info))
2444 1.6 christos {
2445 1.6 christos /* It is OK to convert mov to lea and convert indirect
2446 1.6 christos branch to direct branch. It is OK to convert adc,
2447 1.6 christos add, and, cmp, or, sbb, sub, test, xor only when PIC
2448 1.6 christos is false. */
2449 1.6 christos unsigned int opcode, addend;
2450 1.6 christos addend = bfd_get_32 (input_bfd, contents + rel->r_offset);
2451 1.6 christos if (addend != 0)
2452 1.6 christos goto r_386_got32;
2453 1.6 christos opcode = bfd_get_8 (input_bfd, contents + rel->r_offset - 2);
2454 1.6 christos if (opcode != 0x8b && opcode != 0xff)
2455 1.6 christos goto r_386_got32;
2456 1.6 christos }
2457 1.6 christos
2458 1.6 christos /* Resolve "mov GOT[(%reg)], %reg",
2459 1.6 christos "call/jmp *GOT[(%reg)]", "test %reg, foo@GOT[(%reg)]"
2460 1.6 christos and "binop foo@GOT[(%reg)], %reg". */
2461 1.6 christos if (h == NULL
2462 1.6 christos || (h->plt.offset == (bfd_vma) -1
2463 1.6 christos && h->got.offset == (bfd_vma) -1)
2464 1.6 christos || htab->elf.sgotplt == NULL)
2465 1.6 christos abort ();
2466 1.6 christos
2467 1.6 christos offplt = (htab->elf.sgotplt->output_section->vma
2468 1.6 christos + htab->elf.sgotplt->output_offset);
2469 1.8 christos
2470 1.8 christos /* It is relative to .got.plt section. */
2471 1.8 christos if (h->got.offset != (bfd_vma) -1)
2472 1.6 christos /* Use GOT entry. Mask off the least significant bit in
2473 1.6 christos GOT offset which may be set by R_386_GOT32 processing
2474 1.8 christos below. */
2475 1.6 christos relocation = (htab->elf.sgot->output_section->vma
2476 1.6 christos + htab->elf.sgot->output_offset
2477 1.10 christos + (h->got.offset & ~1) - offplt);
2478 1.10 christos else
2479 1.6 christos /* Use GOTPLT entry. */
2480 1.6 christos relocation = (h->plt.offset / plt_entry_size
2481 1.6 christos - htab->plt.has_plt0 + 3) * 4;
2482 1.6 christos
2483 1.6 christos if (!bfd_link_pic (info))
2484 1.6 christos {
2485 1.6 christos /* If not PIC, add the .got.plt section address for
2486 1.6 christos baseless addressing. */
2487 1.6 christos unsigned int modrm;
2488 1.6 christos modrm = bfd_get_8 (input_bfd, contents + rel->r_offset - 1);
2489 1.6 christos if ((modrm & 0xc7) == 0x5)
2490 1.6 christos relocation += offplt;
2491 1.6 christos }
2492 1.6 christos
2493 1.1 skrll unresolved_reloc = FALSE;
2494 1.6 christos break;
2495 1.1 skrll
2496 1.1 skrll case R_386_GOT32:
2497 1.4 christos r_386_got32:
2498 1.1 skrll /* Relocation is to the entry for this symbol in the global
2499 1.1 skrll offset table. */
2500 1.10 christos if (htab->elf.sgot == NULL)
2501 1.1 skrll abort ();
2502 1.1 skrll
2503 1.1 skrll relative_reloc = FALSE;
2504 1.10 christos if (h != NULL)
2505 1.10 christos {
2506 1.10 christos off = h->got.offset;
2507 1.10 christos if (RESOLVED_LOCALLY_P (info, h, htab))
2508 1.10 christos {
2509 1.10 christos /* We must initialize this entry in the global offset
2510 1.1 skrll table. Since the offset must always be a multiple
2511 1.1 skrll of 4, we use the least significant bit to record
2512 1.1 skrll whether we have initialized it already.
2513 1.1 skrll
2514 1.1 skrll When doing a dynamic link, we create a .rel.got
2515 1.1 skrll relocation entry to initialize the value. This
2516 1.1 skrll is done in the finish_dynamic_symbol routine. */
2517 1.1 skrll if ((off & 1) != 0)
2518 1.1 skrll off &= ~1;
2519 1.4 christos else
2520 1.1 skrll {
2521 1.10 christos bfd_put_32 (output_bfd, relocation,
2522 1.10 christos htab->elf.sgot->contents + off);
2523 1.10 christos h->got.offset |= 1;
2524 1.10 christos
2525 1.10 christos if (GENERATE_RELATIVE_RELOC_P (info, h))
2526 1.10 christos {
2527 1.10 christos /* PR ld/21402: If this symbol isn't dynamic
2528 1.10 christos in PIC, generate R_386_RELATIVE here. */
2529 1.1 skrll eh->no_finish_dynamic_symbol = 1;
2530 1.1 skrll relative_reloc = TRUE;
2531 1.1 skrll }
2532 1.1 skrll }
2533 1.1 skrll }
2534 1.1 skrll else
2535 1.1 skrll unresolved_reloc = FALSE;
2536 1.1 skrll }
2537 1.1 skrll else
2538 1.1 skrll {
2539 1.1 skrll if (local_got_offsets == NULL)
2540 1.1 skrll abort ();
2541 1.1 skrll
2542 1.1 skrll off = local_got_offsets[r_symndx];
2543 1.1 skrll
2544 1.1 skrll /* The offset must always be a multiple of 4. We use
2545 1.1 skrll the least significant bit to record whether we have
2546 1.1 skrll already generated the necessary reloc. */
2547 1.1 skrll if ((off & 1) != 0)
2548 1.1 skrll off &= ~1;
2549 1.4 christos else
2550 1.10 christos {
2551 1.1 skrll bfd_put_32 (output_bfd, relocation,
2552 1.6 christos htab->elf.sgot->contents + off);
2553 1.10 christos local_got_offsets[r_symndx] |= 1;
2554 1.10 christos
2555 1.10 christos if (bfd_link_pic (info))
2556 1.10 christos relative_reloc = TRUE;
2557 1.10 christos }
2558 1.10 christos }
2559 1.10 christos
2560 1.10 christos if (relative_reloc)
2561 1.1 skrll {
2562 1.10 christos asection *s;
2563 1.10 christos Elf_Internal_Rela outrel;
2564 1.10 christos
2565 1.1 skrll s = htab->elf.srelgot;
2566 1.10 christos if (s == NULL)
2567 1.10 christos abort ();
2568 1.10 christos
2569 1.10 christos outrel.r_offset = (htab->elf.sgot->output_section->vma
2570 1.10 christos + htab->elf.sgot->output_offset
2571 1.1 skrll + off);
2572 1.1 skrll outrel.r_info = ELF32_R_INFO (0, R_386_RELATIVE);
2573 1.1 skrll elf_append_rel (output_bfd, s, &outrel);
2574 1.1 skrll }
2575 1.1 skrll
2576 1.8 christos if (off >= (bfd_vma) -2)
2577 1.8 christos abort ();
2578 1.10 christos
2579 1.10 christos relocation = (htab->elf.sgot->output_section->vma
2580 1.10 christos + htab->elf.sgot->output_offset + off);
2581 1.8 christos if (rel->r_offset > 1
2582 1.8 christos && (*(contents + rel->r_offset - 1) & 0xc7) == 0x5
2583 1.8 christos && *(contents + rel->r_offset - 2) != 0x8d)
2584 1.8 christos {
2585 1.10 christos if (bfd_link_pic (info))
2586 1.10 christos {
2587 1.8 christos /* For PIC, disallow R_386_GOT32 without a base
2588 1.8 christos register, except for "lea foo@GOT, %reg", since
2589 1.8 christos we don't know what the GOT base is. */
2590 1.10 christos const char *name;
2591 1.8 christos
2592 1.8 christos disallow_got32:
2593 1.8 christos if (h == NULL || h->root.root.string == NULL)
2594 1.8 christos name = bfd_elf_sym_name (input_bfd, symtab_hdr, sym,
2595 1.8 christos NULL);
2596 1.10 christos else
2597 1.10 christos name = h->root.root.string;
2598 1.10 christos
2599 1.10 christos _bfd_error_handler
2600 1.10 christos /* xgettext:c-format */
2601 1.8 christos (_("%B: direct GOT relocation %s against `%s'"
2602 1.8 christos " without base register can not be used"
2603 1.8 christos " when making a shared object"),
2604 1.8 christos input_bfd, howto->name, name);
2605 1.8 christos bfd_set_error (bfd_error_bad_value);
2606 1.8 christos return FALSE;
2607 1.8 christos }
2608 1.8 christos }
2609 1.8 christos else
2610 1.8 christos {
2611 1.8 christos /* Subtract the .got.plt section address only with a base
2612 1.8 christos register. */
2613 1.8 christos relocation -= (htab->elf.sgotplt->output_section->vma
2614 1.1 skrll + htab->elf.sgotplt->output_offset);
2615 1.1 skrll }
2616 1.1 skrll
2617 1.1 skrll break;
2618 1.1 skrll
2619 1.1 skrll case R_386_GOTOFF:
2620 1.6 christos /* Relocation is relative to the start of the global offset
2621 1.6 christos table. */
2622 1.6 christos
2623 1.6 christos /* Check to make sure it isn't a protected function or data
2624 1.6 christos symbol for shared library since it may not be local when
2625 1.1 skrll used as function address or with copy relocation. We also
2626 1.1 skrll need to make sure that a symbol is referenced locally. */
2627 1.1 skrll if (!bfd_link_executable (info) && h)
2628 1.1 skrll {
2629 1.1 skrll if (!h->def_regular)
2630 1.1 skrll {
2631 1.1 skrll const char *v;
2632 1.1 skrll
2633 1.1 skrll switch (ELF_ST_VISIBILITY (h->other))
2634 1.1 skrll {
2635 1.1 skrll case STV_HIDDEN:
2636 1.1 skrll v = _("hidden symbol");
2637 1.1 skrll break;
2638 1.1 skrll case STV_INTERNAL:
2639 1.1 skrll v = _("internal symbol");
2640 1.1 skrll break;
2641 1.1 skrll case STV_PROTECTED:
2642 1.1 skrll v = _("protected symbol");
2643 1.1 skrll break;
2644 1.1 skrll default:
2645 1.1 skrll v = _("symbol");
2646 1.10 christos break;
2647 1.10 christos }
2648 1.10 christos
2649 1.10 christos _bfd_error_handler
2650 1.1 skrll /* xgettext:c-format */
2651 1.1 skrll (_("%B: relocation R_386_GOTOFF against undefined %s"
2652 1.1 skrll " `%s' can not be used when making a shared object"),
2653 1.1 skrll input_bfd, v, h->root.root.string);
2654 1.10 christos bfd_set_error (bfd_error_bad_value);
2655 1.6 christos return FALSE;
2656 1.6 christos }
2657 1.1 skrll else if (!SYMBOL_REFERENCES_LOCAL_P (info, h)
2658 1.1 skrll && (h->type == STT_FUNC
2659 1.10 christos || h->type == STT_OBJECT)
2660 1.10 christos && ELF_ST_VISIBILITY (h->other) == STV_PROTECTED)
2661 1.10 christos {
2662 1.10 christos _bfd_error_handler
2663 1.6 christos /* xgettext:c-format */
2664 1.6 christos (_("%B: relocation R_386_GOTOFF against protected %s"
2665 1.6 christos " `%s' can not be used when making a shared object"),
2666 1.1 skrll input_bfd,
2667 1.1 skrll h->type == STT_FUNC ? "function" : "data",
2668 1.1 skrll h->root.root.string);
2669 1.1 skrll bfd_set_error (bfd_error_bad_value);
2670 1.1 skrll return FALSE;
2671 1.1 skrll }
2672 1.1 skrll }
2673 1.1 skrll
2674 1.1 skrll /* Note that sgot is not involved in this
2675 1.1 skrll calculation. We always want the start of .got.plt. If we
2676 1.4 christos defined _GLOBAL_OFFSET_TABLE_ in a different way, as is
2677 1.4 christos permitted by the ABI, we might have to change this
2678 1.1 skrll calculation. */
2679 1.1 skrll relocation -= htab->elf.sgotplt->output_section->vma
2680 1.1 skrll + htab->elf.sgotplt->output_offset;
2681 1.1 skrll break;
2682 1.4 christos
2683 1.4 christos case R_386_GOTPC:
2684 1.1 skrll /* Use global offset table as symbol value. */
2685 1.1 skrll relocation = htab->elf.sgotplt->output_section->vma
2686 1.1 skrll + htab->elf.sgotplt->output_offset;
2687 1.1 skrll unresolved_reloc = FALSE;
2688 1.1 skrll break;
2689 1.1 skrll
2690 1.1 skrll case R_386_PLT32:
2691 1.1 skrll /* Relocation is to the entry for this symbol in the
2692 1.1 skrll procedure linkage table. */
2693 1.1 skrll
2694 1.1 skrll /* Resolve a PLT32 reloc against a local symbol directly,
2695 1.1 skrll without using the procedure linkage table. */
2696 1.6 christos if (h == NULL)
2697 1.6 christos break;
2698 1.4 christos
2699 1.1 skrll if ((h->plt.offset == (bfd_vma) -1
2700 1.1 skrll && eh->plt_got.offset == (bfd_vma) -1)
2701 1.1 skrll || htab->elf.splt == NULL)
2702 1.1 skrll {
2703 1.1 skrll /* We didn't make a PLT entry for this symbol. This
2704 1.1 skrll happens when statically linking PIC code, or when
2705 1.1 skrll using -Bsymbolic. */
2706 1.6 christos break;
2707 1.6 christos }
2708 1.10 christos
2709 1.10 christos if (h->plt.offset != (bfd_vma) -1)
2710 1.10 christos {
2711 1.10 christos if (htab->plt_second != NULL)
2712 1.10 christos {
2713 1.10 christos resolved_plt = htab->plt_second;
2714 1.10 christos plt_offset = eh->plt_second.offset;
2715 1.10 christos }
2716 1.10 christos else
2717 1.10 christos {
2718 1.6 christos resolved_plt = htab->elf.splt;
2719 1.6 christos plt_offset = h->plt.offset;
2720 1.6 christos }
2721 1.6 christos }
2722 1.6 christos else
2723 1.6 christos {
2724 1.6 christos resolved_plt = htab->plt_got;
2725 1.6 christos plt_offset = eh->plt_got.offset;
2726 1.6 christos }
2727 1.6 christos
2728 1.1 skrll relocation = (resolved_plt->output_section->vma
2729 1.1 skrll + resolved_plt->output_offset
2730 1.1 skrll + plt_offset);
2731 1.6 christos unresolved_reloc = FALSE;
2732 1.6 christos break;
2733 1.6 christos
2734 1.6 christos case R_386_SIZE32:
2735 1.6 christos /* Set to symbol size. */
2736 1.1 skrll relocation = st_size;
2737 1.1 skrll /* Fall through. */
2738 1.1 skrll
2739 1.1 skrll case R_386_32:
2740 1.1 skrll case R_386_PC32:
2741 1.1 skrll if ((input_section->flags & SEC_ALLOC) == 0
2742 1.10 christos || is_vxworks_tls)
2743 1.10 christos break;
2744 1.10 christos
2745 1.1 skrll if (GENERATE_DYNAMIC_RELOCATION_P (info, eh, r_type,
2746 1.1 skrll FALSE, resolved_to_zero,
2747 1.1 skrll (r_type == R_386_PC32)))
2748 1.1 skrll {
2749 1.1 skrll Elf_Internal_Rela outrel;
2750 1.1 skrll bfd_boolean skip, relocate;
2751 1.1 skrll asection *sreloc;
2752 1.1 skrll
2753 1.1 skrll /* When generating a shared object, these relocations
2754 1.1 skrll are copied into the output file to be resolved at run
2755 1.1 skrll time. */
2756 1.1 skrll
2757 1.1 skrll skip = FALSE;
2758 1.1 skrll relocate = FALSE;
2759 1.1 skrll
2760 1.1 skrll outrel.r_offset =
2761 1.1 skrll _bfd_elf_section_offset (output_bfd, info, input_section,
2762 1.1 skrll rel->r_offset);
2763 1.1 skrll if (outrel.r_offset == (bfd_vma) -1)
2764 1.1 skrll skip = TRUE;
2765 1.1 skrll else if (outrel.r_offset == (bfd_vma) -2)
2766 1.1 skrll skip = TRUE, relocate = TRUE;
2767 1.1 skrll outrel.r_offset += (input_section->output_section->vma
2768 1.1 skrll + input_section->output_offset);
2769 1.10 christos
2770 1.1 skrll if (skip)
2771 1.1 skrll memset (&outrel, 0, sizeof outrel);
2772 1.1 skrll else if (COPY_INPUT_RELOC_P (info, h, r_type))
2773 1.1 skrll outrel.r_info = ELF32_R_INFO (h->dynindx, r_type);
2774 1.1 skrll else
2775 1.1 skrll {
2776 1.1 skrll /* This symbol is local, or marked to become local. */
2777 1.1 skrll relocate = TRUE;
2778 1.1 skrll outrel.r_info = ELF32_R_INFO (0, R_386_RELATIVE);
2779 1.4 christos }
2780 1.5 christos
2781 1.5 christos sreloc = elf_section_data (input_section)->sreloc;
2782 1.5 christos
2783 1.5 christos if (sreloc == NULL || sreloc->contents == NULL)
2784 1.5 christos {
2785 1.4 christos r = bfd_reloc_notsupported;
2786 1.5 christos goto check_relocation_error;
2787 1.1 skrll }
2788 1.1 skrll
2789 1.1 skrll elf_append_rel (output_bfd, sreloc, &outrel);
2790 1.1 skrll
2791 1.1 skrll /* If this reloc is against an external symbol, we do
2792 1.1 skrll not want to fiddle with the addend. Otherwise, we
2793 1.1 skrll need to include the symbol value so that it becomes
2794 1.1 skrll an addend for the dynamic reloc. */
2795 1.1 skrll if (! relocate)
2796 1.1 skrll continue;
2797 1.1 skrll }
2798 1.6 christos break;
2799 1.1 skrll
2800 1.1 skrll case R_386_TLS_IE:
2801 1.1 skrll if (!bfd_link_executable (info))
2802 1.1 skrll {
2803 1.1 skrll Elf_Internal_Rela outrel;
2804 1.1 skrll asection *sreloc;
2805 1.1 skrll
2806 1.1 skrll outrel.r_offset = rel->r_offset
2807 1.1 skrll + input_section->output_section->vma
2808 1.1 skrll + input_section->output_offset;
2809 1.1 skrll outrel.r_info = ELF32_R_INFO (0, R_386_RELATIVE);
2810 1.5 christos sreloc = elf_section_data (input_section)->sreloc;
2811 1.1 skrll if (sreloc == NULL)
2812 1.1 skrll abort ();
2813 1.1 skrll elf_append_rel (output_bfd, sreloc, &outrel);
2814 1.1 skrll }
2815 1.1 skrll /* Fall through */
2816 1.1 skrll
2817 1.1 skrll case R_386_TLS_GD:
2818 1.1 skrll case R_386_TLS_GOTDESC:
2819 1.1 skrll case R_386_TLS_DESC_CALL:
2820 1.1 skrll case R_386_TLS_IE_32:
2821 1.10 christos case R_386_TLS_GOTIE:
2822 1.1 skrll tls_type = GOT_UNKNOWN;
2823 1.10 christos if (h == NULL && local_got_offsets)
2824 1.1 skrll tls_type = elf_x86_local_got_tls_type (input_bfd) [r_symndx];
2825 1.1 skrll else if (h != NULL)
2826 1.1 skrll tls_type = elf_x86_hash_entry(h)->tls_type;
2827 1.10 christos if (tls_type == GOT_TLS_IE)
2828 1.1 skrll tls_type = GOT_TLS_IE_NEG;
2829 1.1 skrll
2830 1.1 skrll r_type_tls = r_type;
2831 1.10 christos if (! elf_i386_tls_transition (info, input_bfd,
2832 1.9 christos input_section, contents,
2833 1.1 skrll symtab_hdr, sym_hashes,
2834 1.1 skrll &r_type_tls, tls_type, rel,
2835 1.10 christos relend, h, r_symndx, TRUE))
2836 1.1 skrll return FALSE;
2837 1.1 skrll
2838 1.10 christos if (r_type_tls == R_386_TLS_LE_32)
2839 1.1 skrll {
2840 1.1 skrll BFD_ASSERT (! unresolved_reloc);
2841 1.1 skrll if (r_type == R_386_TLS_GD)
2842 1.1 skrll {
2843 1.1 skrll unsigned int type;
2844 1.9 christos bfd_vma roff;
2845 1.1 skrll
2846 1.1 skrll /* GD->LE transition. */
2847 1.9 christos type = *(contents + rel->r_offset - 2);
2848 1.9 christos if (type == 0x04)
2849 1.9 christos {
2850 1.9 christos /* Change
2851 1.9 christos leal foo@tlsgd(,%ebx,1), %eax
2852 1.9 christos call ___tls_get_addr@PLT
2853 1.1 skrll into:
2854 1.1 skrll movl %gs:0, %eax
2855 1.1 skrll subl $foo@tpoff, %eax
2856 1.1 skrll (6 byte form of subl). */
2857 1.1 skrll roff = rel->r_offset + 5;
2858 1.9 christos }
2859 1.9 christos else
2860 1.9 christos {
2861 1.9 christos /* Change
2862 1.9 christos leal foo@tlsgd(%ebx), %eax
2863 1.9 christos call ___tls_get_addr@PLT
2864 1.9 christos nop
2865 1.9 christos or
2866 1.9 christos leal foo@tlsgd(%reg), %eax
2867 1.9 christos call *___tls_get_addr@GOT(%reg)
2868 1.9 christos which may be converted to
2869 1.1 skrll addr32 call ___tls_get_addr
2870 1.1 skrll into:
2871 1.1 skrll movl %gs:0, %eax; subl $foo@tpoff, %eax
2872 1.9 christos (6 byte form of subl). */
2873 1.9 christos roff = rel->r_offset + 6;
2874 1.4 christos }
2875 1.1 skrll memcpy (contents + roff - 8,
2876 1.9 christos "\x65\xa1\0\0\0\0\x81\xe8\0\0\0", 12);
2877 1.1 skrll bfd_put_32 (output_bfd, elf_i386_tpoff (info, relocation),
2878 1.6 christos contents + roff);
2879 1.1 skrll /* Skip R_386_PC32, R_386_PLT32 and R_386_GOT32X. */
2880 1.1 skrll rel++;
2881 1.10 christos wrel++;
2882 1.1 skrll continue;
2883 1.1 skrll }
2884 1.1 skrll else if (r_type == R_386_TLS_GOTDESC)
2885 1.1 skrll {
2886 1.1 skrll /* GDesc -> LE transition.
2887 1.1 skrll It's originally something like:
2888 1.1 skrll leal x@tlsdesc(%ebx), %eax
2889 1.1 skrll
2890 1.1 skrll leal x@ntpoff, %eax
2891 1.1 skrll
2892 1.1 skrll Registers other than %eax may be set up here. */
2893 1.1 skrll
2894 1.1 skrll unsigned int val;
2895 1.1 skrll bfd_vma roff;
2896 1.1 skrll
2897 1.1 skrll roff = rel->r_offset;
2898 1.1 skrll val = bfd_get_8 (input_bfd, contents + roff - 1);
2899 1.1 skrll
2900 1.1 skrll /* Now modify the instruction as appropriate. */
2901 1.1 skrll /* aoliva FIXME: remove the above and xor the byte
2902 1.4 christos below with 0x86. */
2903 1.1 skrll bfd_put_8 (output_bfd, val ^ 0x86,
2904 1.1 skrll contents + roff - 1);
2905 1.1 skrll bfd_put_32 (output_bfd, -elf_i386_tpoff (info, relocation),
2906 1.10 christos contents + roff);
2907 1.1 skrll continue;
2908 1.1 skrll }
2909 1.1 skrll else if (r_type == R_386_TLS_DESC_CALL)
2910 1.1 skrll {
2911 1.1 skrll /* GDesc -> LE transition.
2912 1.1 skrll It's originally:
2913 1.1 skrll call *(%eax)
2914 1.1 skrll Turn it into:
2915 1.4 christos xchg %ax,%ax */
2916 1.1 skrll
2917 1.1 skrll bfd_vma roff;
2918 1.1 skrll
2919 1.1 skrll roff = rel->r_offset;
2920 1.1 skrll bfd_put_8 (output_bfd, 0x66, contents + roff);
2921 1.10 christos bfd_put_8 (output_bfd, 0x90, contents + roff + 1);
2922 1.1 skrll continue;
2923 1.1 skrll }
2924 1.1 skrll else if (r_type == R_386_TLS_IE)
2925 1.1 skrll {
2926 1.1 skrll unsigned int val;
2927 1.1 skrll
2928 1.1 skrll /* IE->LE transition:
2929 1.1 skrll Originally it can be one of:
2930 1.1 skrll movl foo, %eax
2931 1.1 skrll movl foo, %reg
2932 1.1 skrll addl foo, %reg
2933 1.1 skrll We change it into:
2934 1.1 skrll movl $foo, %eax
2935 1.1 skrll movl $foo, %reg
2936 1.1 skrll addl $foo, %reg. */
2937 1.1 skrll val = bfd_get_8 (input_bfd, contents + rel->r_offset - 1);
2938 1.1 skrll if (val == 0xa1)
2939 1.1 skrll {
2940 1.1 skrll /* movl foo, %eax. */
2941 1.1 skrll bfd_put_8 (output_bfd, 0xb8,
2942 1.1 skrll contents + rel->r_offset - 1);
2943 1.1 skrll }
2944 1.1 skrll else
2945 1.1 skrll {
2946 1.1 skrll unsigned int type;
2947 1.1 skrll
2948 1.1 skrll type = bfd_get_8 (input_bfd,
2949 1.1 skrll contents + rel->r_offset - 2);
2950 1.1 skrll switch (type)
2951 1.1 skrll {
2952 1.1 skrll case 0x8b:
2953 1.1 skrll /* movl */
2954 1.1 skrll bfd_put_8 (output_bfd, 0xc7,
2955 1.1 skrll contents + rel->r_offset - 2);
2956 1.1 skrll bfd_put_8 (output_bfd,
2957 1.1 skrll 0xc0 | ((val >> 3) & 7),
2958 1.1 skrll contents + rel->r_offset - 1);
2959 1.1 skrll break;
2960 1.1 skrll case 0x03:
2961 1.1 skrll /* addl */
2962 1.1 skrll bfd_put_8 (output_bfd, 0x81,
2963 1.1 skrll contents + rel->r_offset - 2);
2964 1.1 skrll bfd_put_8 (output_bfd,
2965 1.1 skrll 0xc0 | ((val >> 3) & 7),
2966 1.1 skrll contents + rel->r_offset - 1);
2967 1.1 skrll break;
2968 1.1 skrll default:
2969 1.1 skrll BFD_FAIL ();
2970 1.4 christos break;
2971 1.1 skrll }
2972 1.1 skrll }
2973 1.1 skrll bfd_put_32 (output_bfd, -elf_i386_tpoff (info, relocation),
2974 1.1 skrll contents + rel->r_offset);
2975 1.1 skrll continue;
2976 1.1 skrll }
2977 1.1 skrll else
2978 1.1 skrll {
2979 1.1 skrll unsigned int val, type;
2980 1.1 skrll
2981 1.1 skrll /* {IE_32,GOTIE}->LE transition:
2982 1.1 skrll Originally it can be one of:
2983 1.1 skrll subl foo(%reg1), %reg2
2984 1.1 skrll movl foo(%reg1), %reg2
2985 1.1 skrll addl foo(%reg1), %reg2
2986 1.1 skrll We change it into:
2987 1.1 skrll subl $foo, %reg2
2988 1.1 skrll movl $foo, %reg2 (6 byte form)
2989 1.1 skrll addl $foo, %reg2. */
2990 1.1 skrll type = bfd_get_8 (input_bfd, contents + rel->r_offset - 2);
2991 1.1 skrll val = bfd_get_8 (input_bfd, contents + rel->r_offset - 1);
2992 1.1 skrll if (type == 0x8b)
2993 1.1 skrll {
2994 1.1 skrll /* movl */
2995 1.1 skrll bfd_put_8 (output_bfd, 0xc7,
2996 1.1 skrll contents + rel->r_offset - 2);
2997 1.1 skrll bfd_put_8 (output_bfd, 0xc0 | ((val >> 3) & 7),
2998 1.1 skrll contents + rel->r_offset - 1);
2999 1.1 skrll }
3000 1.1 skrll else if (type == 0x2b)
3001 1.1 skrll {
3002 1.1 skrll /* subl */
3003 1.1 skrll bfd_put_8 (output_bfd, 0x81,
3004 1.1 skrll contents + rel->r_offset - 2);
3005 1.1 skrll bfd_put_8 (output_bfd, 0xe8 | ((val >> 3) & 7),
3006 1.1 skrll contents + rel->r_offset - 1);
3007 1.1 skrll }
3008 1.1 skrll else if (type == 0x03)
3009 1.1 skrll {
3010 1.1 skrll /* addl */
3011 1.1 skrll bfd_put_8 (output_bfd, 0x81,
3012 1.1 skrll contents + rel->r_offset - 2);
3013 1.1 skrll bfd_put_8 (output_bfd, 0xc0 | ((val >> 3) & 7),
3014 1.1 skrll contents + rel->r_offset - 1);
3015 1.10 christos }
3016 1.4 christos else
3017 1.1 skrll BFD_FAIL ();
3018 1.1 skrll if (r_type == R_386_TLS_GOTIE)
3019 1.4 christos bfd_put_32 (output_bfd, -elf_i386_tpoff (info, relocation),
3020 1.1 skrll contents + rel->r_offset);
3021 1.1 skrll else
3022 1.1 skrll bfd_put_32 (output_bfd, elf_i386_tpoff (info, relocation),
3023 1.1 skrll contents + rel->r_offset);
3024 1.1 skrll continue;
3025 1.4 christos }
3026 1.1 skrll }
3027 1.1 skrll
3028 1.1 skrll if (htab->elf.sgot == NULL)
3029 1.1 skrll abort ();
3030 1.1 skrll
3031 1.10 christos if (h != NULL)
3032 1.1 skrll {
3033 1.1 skrll off = h->got.offset;
3034 1.1 skrll offplt = elf_x86_hash_entry (h)->tlsdesc_got;
3035 1.1 skrll }
3036 1.1 skrll else
3037 1.1 skrll {
3038 1.1 skrll if (local_got_offsets == NULL)
3039 1.1 skrll abort ();
3040 1.1 skrll
3041 1.1 skrll off = local_got_offsets[r_symndx];
3042 1.1 skrll offplt = local_tlsdesc_gotents[r_symndx];
3043 1.1 skrll }
3044 1.1 skrll
3045 1.1 skrll if ((off & 1) != 0)
3046 1.1 skrll off &= ~1;
3047 1.4 christos else
3048 1.1 skrll {
3049 1.1 skrll Elf_Internal_Rela outrel;
3050 1.4 christos int dr_type;
3051 1.1 skrll asection *sreloc;
3052 1.1 skrll
3053 1.1 skrll if (htab->elf.srelgot == NULL)
3054 1.1 skrll abort ();
3055 1.1 skrll
3056 1.1 skrll indx = h && h->dynindx != -1 ? h->dynindx : 0;
3057 1.5 christos
3058 1.1 skrll if (GOT_TLS_GDESC_P (tls_type))
3059 1.1 skrll {
3060 1.4 christos bfd_byte *loc;
3061 1.4 christos outrel.r_info = ELF32_R_INFO (indx, R_386_TLS_DESC);
3062 1.4 christos BFD_ASSERT (htab->sgotplt_jump_table_size + offplt + 8
3063 1.1 skrll <= htab->elf.sgotplt->size);
3064 1.1 skrll outrel.r_offset = (htab->elf.sgotplt->output_section->vma
3065 1.4 christos + htab->elf.sgotplt->output_offset
3066 1.1 skrll + offplt
3067 1.1 skrll + htab->sgotplt_jump_table_size);
3068 1.1 skrll sreloc = htab->elf.srelplt;
3069 1.1 skrll loc = sreloc->contents;
3070 1.6 christos loc += (htab->next_tls_desc_index++
3071 1.1 skrll * sizeof (Elf32_External_Rel));
3072 1.1 skrll BFD_ASSERT (loc + sizeof (Elf32_External_Rel)
3073 1.1 skrll <= sreloc->contents + sreloc->size);
3074 1.1 skrll bfd_elf32_swap_reloc_out (output_bfd, &outrel, loc);
3075 1.1 skrll if (indx == 0)
3076 1.10 christos {
3077 1.4 christos BFD_ASSERT (! unresolved_reloc);
3078 1.1 skrll bfd_put_32 (output_bfd,
3079 1.1 skrll relocation - _bfd_x86_elf_dtpoff_base (info),
3080 1.1 skrll htab->elf.sgotplt->contents + offplt
3081 1.1 skrll + htab->sgotplt_jump_table_size + 4);
3082 1.1 skrll }
3083 1.4 christos else
3084 1.1 skrll {
3085 1.1 skrll bfd_put_32 (output_bfd, 0,
3086 1.1 skrll htab->elf.sgotplt->contents + offplt
3087 1.1 skrll + htab->sgotplt_jump_table_size + 4);
3088 1.4 christos }
3089 1.1 skrll }
3090 1.4 christos
3091 1.4 christos sreloc = htab->elf.srelgot;
3092 1.1 skrll
3093 1.1 skrll outrel.r_offset = (htab->elf.sgot->output_section->vma
3094 1.1 skrll + htab->elf.sgot->output_offset + off);
3095 1.1 skrll
3096 1.1 skrll if (GOT_TLS_GD_P (tls_type))
3097 1.1 skrll dr_type = R_386_TLS_DTPMOD32;
3098 1.1 skrll else if (GOT_TLS_GDESC_P (tls_type))
3099 1.1 skrll goto dr_done;
3100 1.1 skrll else if (tls_type == GOT_TLS_IE_POS)
3101 1.1 skrll dr_type = R_386_TLS_TPOFF;
3102 1.1 skrll else
3103 1.4 christos dr_type = R_386_TLS_TPOFF32;
3104 1.10 christos
3105 1.4 christos if (dr_type == R_386_TLS_TPOFF && indx == 0)
3106 1.1 skrll bfd_put_32 (output_bfd,
3107 1.5 christos relocation - _bfd_x86_elf_dtpoff_base (info),
3108 1.10 christos htab->elf.sgot->contents + off);
3109 1.4 christos else if (dr_type == R_386_TLS_TPOFF32 && indx == 0)
3110 1.1 skrll bfd_put_32 (output_bfd,
3111 1.1 skrll _bfd_x86_elf_dtpoff_base (info) - relocation,
3112 1.4 christos htab->elf.sgot->contents + off);
3113 1.1 skrll else if (dr_type != R_386_TLS_DESC)
3114 1.1 skrll bfd_put_32 (output_bfd, 0,
3115 1.5 christos htab->elf.sgot->contents + off);
3116 1.1 skrll outrel.r_info = ELF32_R_INFO (indx, dr_type);
3117 1.1 skrll
3118 1.1 skrll elf_append_rel (output_bfd, sreloc, &outrel);
3119 1.1 skrll
3120 1.1 skrll if (GOT_TLS_GD_P (tls_type))
3121 1.10 christos {
3122 1.1 skrll if (indx == 0)
3123 1.10 christos {
3124 1.4 christos BFD_ASSERT (! unresolved_reloc);
3125 1.1 skrll bfd_put_32 (output_bfd,
3126 1.1 skrll relocation - _bfd_x86_elf_dtpoff_base (info),
3127 1.1 skrll htab->elf.sgot->contents + off + 4);
3128 1.1 skrll }
3129 1.4 christos else
3130 1.1 skrll {
3131 1.1 skrll bfd_put_32 (output_bfd, 0,
3132 1.1 skrll htab->elf.sgot->contents + off + 4);
3133 1.5 christos outrel.r_info = ELF32_R_INFO (indx,
3134 1.1 skrll R_386_TLS_DTPOFF32);
3135 1.1 skrll outrel.r_offset += 4;
3136 1.1 skrll elf_append_rel (output_bfd, sreloc, &outrel);
3137 1.1 skrll }
3138 1.1 skrll }
3139 1.4 christos else if (tls_type == GOT_TLS_IE_BOTH)
3140 1.10 christos {
3141 1.4 christos bfd_put_32 (output_bfd,
3142 1.4 christos (indx == 0
3143 1.1 skrll ? relocation - _bfd_x86_elf_dtpoff_base (info)
3144 1.1 skrll : 0),
3145 1.5 christos htab->elf.sgot->contents + off + 4);
3146 1.1 skrll outrel.r_info = ELF32_R_INFO (indx, R_386_TLS_TPOFF);
3147 1.1 skrll outrel.r_offset += 4;
3148 1.1 skrll elf_append_rel (output_bfd, sreloc, &outrel);
3149 1.1 skrll }
3150 1.1 skrll
3151 1.1 skrll dr_done:
3152 1.1 skrll if (h != NULL)
3153 1.1 skrll h->got.offset |= 1;
3154 1.1 skrll else
3155 1.1 skrll local_got_offsets[r_symndx] |= 1;
3156 1.1 skrll }
3157 1.1 skrll
3158 1.10 christos if (off >= (bfd_vma) -2
3159 1.10 christos && ! GOT_TLS_GDESC_P (tls_type))
3160 1.1 skrll abort ();
3161 1.1 skrll if (r_type_tls == R_386_TLS_GOTDESC
3162 1.1 skrll || r_type_tls == R_386_TLS_DESC_CALL)
3163 1.1 skrll {
3164 1.10 christos relocation = htab->sgotplt_jump_table_size + offplt;
3165 1.1 skrll unresolved_reloc = FALSE;
3166 1.4 christos }
3167 1.4 christos else if (r_type_tls == r_type)
3168 1.4 christos {
3169 1.4 christos bfd_vma g_o_t = htab->elf.sgotplt->output_section->vma
3170 1.1 skrll + htab->elf.sgotplt->output_offset;
3171 1.1 skrll relocation = htab->elf.sgot->output_section->vma
3172 1.1 skrll + htab->elf.sgot->output_offset + off - g_o_t;
3173 1.1 skrll if ((r_type == R_386_TLS_IE || r_type == R_386_TLS_GOTIE)
3174 1.1 skrll && tls_type == GOT_TLS_IE_BOTH)
3175 1.1 skrll relocation += 4;
3176 1.1 skrll if (r_type == R_386_TLS_IE)
3177 1.10 christos relocation += g_o_t;
3178 1.1 skrll unresolved_reloc = FALSE;
3179 1.1 skrll }
3180 1.1 skrll else if (r_type == R_386_TLS_GD)
3181 1.1 skrll {
3182 1.1 skrll unsigned int val, type;
3183 1.9 christos bfd_vma roff;
3184 1.9 christos
3185 1.1 skrll /* GD->IE transition. */
3186 1.1 skrll type = *(contents + rel->r_offset - 2);
3187 1.9 christos val = *(contents + rel->r_offset - 1);
3188 1.9 christos if (type == 0x04)
3189 1.9 christos {
3190 1.9 christos /* Change
3191 1.9 christos leal foo@tlsgd(,%ebx,1), %eax
3192 1.9 christos call ___tls_get_addr@PLT
3193 1.1 skrll into:
3194 1.1 skrll movl %gs:0, %eax
3195 1.1 skrll subl $foo@gottpoff(%ebx), %eax. */
3196 1.1 skrll val >>= 3;
3197 1.1 skrll roff = rel->r_offset - 3;
3198 1.9 christos }
3199 1.9 christos else
3200 1.9 christos {
3201 1.9 christos /* Change
3202 1.9 christos leal foo@tlsgd(%ebx), %eax
3203 1.9 christos call ___tls_get_addr@PLT
3204 1.9 christos nop
3205 1.9 christos or
3206 1.9 christos leal foo@tlsgd(%reg), %eax
3207 1.9 christos call *___tls_get_addr@GOT(%reg)
3208 1.9 christos which may be converted to
3209 1.9 christos addr32 call ___tls_get_addr
3210 1.1 skrll into:
3211 1.1 skrll movl %gs:0, %eax;
3212 1.1 skrll subl $foo@gottpoff(%reg), %eax. */
3213 1.1 skrll roff = rel->r_offset - 2;
3214 1.1 skrll }
3215 1.1 skrll memcpy (contents + roff,
3216 1.1 skrll "\x65\xa1\0\0\0\0\x2b\x80\0\0\0", 12);
3217 1.1 skrll contents[roff + 7] = 0x80 | (val & 7);
3218 1.1 skrll /* If foo is used only with foo@gotntpoff(%reg) and
3219 1.1 skrll foo@indntpoff, but not with foo@gottpoff(%reg), change
3220 1.1 skrll subl $foo@gottpoff(%reg), %eax
3221 1.1 skrll into:
3222 1.1 skrll addl $foo@gotntpoff(%reg), %eax. */
3223 1.4 christos if (tls_type == GOT_TLS_IE_POS)
3224 1.4 christos contents[roff + 6] = 0x03;
3225 1.4 christos bfd_put_32 (output_bfd,
3226 1.4 christos htab->elf.sgot->output_section->vma
3227 1.1 skrll + htab->elf.sgot->output_offset + off
3228 1.9 christos - htab->elf.sgotplt->output_section->vma
3229 1.1 skrll - htab->elf.sgotplt->output_offset,
3230 1.6 christos contents + roff + 8);
3231 1.1 skrll /* Skip R_386_PLT32 and R_386_GOT32X. */
3232 1.1 skrll rel++;
3233 1.10 christos wrel++;
3234 1.1 skrll continue;
3235 1.1 skrll }
3236 1.1 skrll else if (r_type == R_386_TLS_GOTDESC)
3237 1.1 skrll {
3238 1.1 skrll /* GDesc -> IE transition.
3239 1.1 skrll It's originally something like:
3240 1.1 skrll leal x@tlsdesc(%ebx), %eax
3241 1.1 skrll
3242 1.1 skrll Change it to:
3243 1.1 skrll movl x@gotntpoff(%ebx), %eax # before xchg %ax,%ax
3244 1.1 skrll or:
3245 1.1 skrll movl x@gottpoff(%ebx), %eax # before negl %eax
3246 1.1 skrll
3247 1.1 skrll Registers other than %eax may be set up here. */
3248 1.1 skrll
3249 1.1 skrll bfd_vma roff;
3250 1.1 skrll
3251 1.1 skrll /* First, make sure it's a leal adding ebx to a 32-bit
3252 1.1 skrll offset into any register, although it's probably
3253 1.1 skrll almost always going to be eax. */
3254 1.1 skrll roff = rel->r_offset;
3255 1.1 skrll
3256 1.1 skrll /* Now modify the instruction as appropriate. */
3257 1.1 skrll /* To turn a leal into a movl in the form we use it, it
3258 1.1 skrll suffices to change the first byte from 0x8d to 0x8b.
3259 1.1 skrll aoliva FIXME: should we decide to keep the leal, all
3260 1.1 skrll we have to do is remove the statement below, and
3261 1.1 skrll adjust the relaxation of R_386_TLS_DESC_CALL. */
3262 1.1 skrll bfd_put_8 (output_bfd, 0x8b, contents + roff - 2);
3263 1.1 skrll
3264 1.1 skrll if (tls_type == GOT_TLS_IE_BOTH)
3265 1.4 christos off += 4;
3266 1.4 christos
3267 1.4 christos bfd_put_32 (output_bfd,
3268 1.4 christos htab->elf.sgot->output_section->vma
3269 1.1 skrll + htab->elf.sgot->output_offset + off
3270 1.1 skrll - htab->elf.sgotplt->output_section->vma
3271 1.1 skrll - htab->elf.sgotplt->output_offset,
3272 1.10 christos contents + roff);
3273 1.1 skrll continue;
3274 1.1 skrll }
3275 1.1 skrll else if (r_type == R_386_TLS_DESC_CALL)
3276 1.1 skrll {
3277 1.1 skrll /* GDesc -> IE transition.
3278 1.1 skrll It's originally:
3279 1.1 skrll call *(%eax)
3280 1.1 skrll
3281 1.1 skrll Change it to:
3282 1.1 skrll xchg %ax,%ax
3283 1.1 skrll or
3284 1.1 skrll negl %eax
3285 1.1 skrll depending on how we transformed the TLS_GOTDESC above.
3286 1.1 skrll */
3287 1.1 skrll
3288 1.1 skrll bfd_vma roff;
3289 1.1 skrll
3290 1.1 skrll roff = rel->r_offset;
3291 1.1 skrll
3292 1.1 skrll /* Now modify the instruction as appropriate. */
3293 1.1 skrll if (tls_type != GOT_TLS_IE_NEG)
3294 1.1 skrll {
3295 1.1 skrll /* xchg %ax,%ax */
3296 1.1 skrll bfd_put_8 (output_bfd, 0x66, contents + roff);
3297 1.1 skrll bfd_put_8 (output_bfd, 0x90, contents + roff + 1);
3298 1.1 skrll }
3299 1.1 skrll else
3300 1.1 skrll {
3301 1.1 skrll /* negl %eax */
3302 1.1 skrll bfd_put_8 (output_bfd, 0xf7, contents + roff);
3303 1.1 skrll bfd_put_8 (output_bfd, 0xd8, contents + roff + 1);
3304 1.1 skrll }
3305 1.1 skrll
3306 1.1 skrll continue;
3307 1.1 skrll }
3308 1.1 skrll else
3309 1.1 skrll BFD_ASSERT (FALSE);
3310 1.1 skrll break;
3311 1.1 skrll
3312 1.1 skrll case R_386_TLS_LDM:
3313 1.1 skrll if (! elf_i386_tls_transition (info, input_bfd,
3314 1.9 christos input_section, contents,
3315 1.1 skrll symtab_hdr, sym_hashes,
3316 1.1 skrll &r_type, GOT_UNKNOWN, rel,
3317 1.1 skrll relend, h, r_symndx, TRUE))
3318 1.1 skrll return FALSE;
3319 1.9 christos
3320 1.9 christos if (r_type != R_386_TLS_LDM)
3321 1.9 christos {
3322 1.9 christos /* LD->LE transition. Change
3323 1.9 christos leal foo@tlsldm(%ebx) %eax
3324 1.9 christos call ___tls_get_addr@PLT
3325 1.9 christos into:
3326 1.9 christos movl %gs:0, %eax
3327 1.9 christos nop
3328 1.9 christos leal 0(%esi,1), %esi
3329 1.9 christos or change
3330 1.9 christos leal foo@tlsldm(%reg) %eax
3331 1.9 christos call *___tls_get_addr@GOT(%reg)
3332 1.9 christos which may be converted to
3333 1.9 christos addr32 call ___tls_get_addr
3334 1.1 skrll into:
3335 1.9 christos movl %gs:0, %eax
3336 1.9 christos leal 0(%esi), %esi */
3337 1.9 christos BFD_ASSERT (r_type == R_386_TLS_LE_32);
3338 1.9 christos if (*(contents + rel->r_offset + 4) == 0xff
3339 1.9 christos || *(contents + rel->r_offset + 4) == 0x67)
3340 1.9 christos memcpy (contents + rel->r_offset - 2,
3341 1.9 christos "\x65\xa1\0\0\0\0\x8d\xb6\0\0\0", 12);
3342 1.1 skrll else
3343 1.1 skrll memcpy (contents + rel->r_offset - 2,
3344 1.6 christos "\x65\xa1\0\0\0\0\x90\x8d\x74\x26", 11);
3345 1.1 skrll /* Skip R_386_PC32/R_386_PLT32. */
3346 1.1 skrll rel++;
3347 1.1 skrll wrel++;
3348 1.4 christos continue;
3349 1.1 skrll }
3350 1.1 skrll
3351 1.10 christos if (htab->elf.sgot == NULL)
3352 1.1 skrll abort ();
3353 1.1 skrll
3354 1.1 skrll off = htab->tls_ld_or_ldm_got.offset;
3355 1.1 skrll if (off & 1)
3356 1.1 skrll off &= ~1;
3357 1.1 skrll else
3358 1.4 christos {
3359 1.1 skrll Elf_Internal_Rela outrel;
3360 1.1 skrll
3361 1.4 christos if (htab->elf.srelgot == NULL)
3362 1.4 christos abort ();
3363 1.1 skrll
3364 1.1 skrll outrel.r_offset = (htab->elf.sgot->output_section->vma
3365 1.4 christos + htab->elf.sgot->output_offset + off);
3366 1.1 skrll
3367 1.4 christos bfd_put_32 (output_bfd, 0,
3368 1.1 skrll htab->elf.sgot->contents + off);
3369 1.5 christos bfd_put_32 (output_bfd, 0,
3370 1.10 christos htab->elf.sgot->contents + off + 4);
3371 1.1 skrll outrel.r_info = ELF32_R_INFO (0, R_386_TLS_DTPMOD32);
3372 1.4 christos elf_append_rel (output_bfd, htab->elf.srelgot, &outrel);
3373 1.4 christos htab->tls_ld_or_ldm_got.offset |= 1;
3374 1.4 christos }
3375 1.4 christos relocation = htab->elf.sgot->output_section->vma
3376 1.1 skrll + htab->elf.sgot->output_offset + off
3377 1.1 skrll - htab->elf.sgotplt->output_section->vma
3378 1.1 skrll - htab->elf.sgotplt->output_offset;
3379 1.1 skrll unresolved_reloc = FALSE;
3380 1.6 christos break;
3381 1.6 christos
3382 1.10 christos case R_386_TLS_LDO_32:
3383 1.1 skrll if (!bfd_link_executable (info)
3384 1.1 skrll || (input_section->flags & SEC_CODE) == 0)
3385 1.4 christos relocation -= _bfd_x86_elf_dtpoff_base (info);
3386 1.1 skrll else
3387 1.1 skrll /* When converting LDO to LE, we must negate. */
3388 1.1 skrll relocation = -elf_i386_tpoff (info, relocation);
3389 1.1 skrll break;
3390 1.6 christos
3391 1.1 skrll case R_386_TLS_LE_32:
3392 1.1 skrll case R_386_TLS_LE:
3393 1.1 skrll if (!bfd_link_executable (info))
3394 1.1 skrll {
3395 1.1 skrll Elf_Internal_Rela outrel;
3396 1.1 skrll asection *sreloc;
3397 1.1 skrll
3398 1.1 skrll outrel.r_offset = rel->r_offset
3399 1.1 skrll + input_section->output_section->vma
3400 1.1 skrll + input_section->output_offset;
3401 1.1 skrll if (h != NULL && h->dynindx != -1)
3402 1.1 skrll indx = h->dynindx;
3403 1.1 skrll else
3404 1.1 skrll indx = 0;
3405 1.1 skrll if (r_type == R_386_TLS_LE_32)
3406 1.1 skrll outrel.r_info = ELF32_R_INFO (indx, R_386_TLS_TPOFF32);
3407 1.1 skrll else
3408 1.1 skrll outrel.r_info = ELF32_R_INFO (indx, R_386_TLS_TPOFF);
3409 1.5 christos sreloc = elf_section_data (input_section)->sreloc;
3410 1.1 skrll if (sreloc == NULL)
3411 1.1 skrll abort ();
3412 1.1 skrll elf_append_rel (output_bfd, sreloc, &outrel);
3413 1.10 christos if (indx)
3414 1.1 skrll continue;
3415 1.10 christos else if (r_type == R_386_TLS_LE_32)
3416 1.1 skrll relocation = _bfd_x86_elf_dtpoff_base (info) - relocation;
3417 1.1 skrll else
3418 1.4 christos relocation -= _bfd_x86_elf_dtpoff_base (info);
3419 1.1 skrll }
3420 1.4 christos else if (r_type == R_386_TLS_LE_32)
3421 1.1 skrll relocation = elf_i386_tpoff (info, relocation);
3422 1.1 skrll else
3423 1.1 skrll relocation = -elf_i386_tpoff (info, relocation);
3424 1.1 skrll break;
3425 1.1 skrll
3426 1.1 skrll default:
3427 1.1 skrll break;
3428 1.1 skrll }
3429 1.1 skrll
3430 1.1 skrll /* Dynamic relocs are not propagated for SEC_DEBUGGING sections
3431 1.1 skrll because such sections are not SEC_ALLOC and thus ld.so will
3432 1.5 christos not process them. */
3433 1.5 christos if (unresolved_reloc
3434 1.5 christos && !((input_section->flags & SEC_DEBUGGING) != 0
3435 1.1 skrll && h->def_dynamic)
3436 1.10 christos && _bfd_elf_section_offset (output_bfd, info, input_section,
3437 1.10 christos rel->r_offset) != (bfd_vma) -1)
3438 1.10 christos {
3439 1.1 skrll _bfd_error_handler
3440 1.1 skrll /* xgettext:c-format */
3441 1.10 christos (_("%B(%A+%#Lx): unresolvable %s relocation against symbol `%s'"),
3442 1.1 skrll input_bfd,
3443 1.1 skrll input_section,
3444 1.1 skrll rel->r_offset,
3445 1.1 skrll howto->name,
3446 1.1 skrll h->root.root.string);
3447 1.4 christos return FALSE;
3448 1.1 skrll }
3449 1.1 skrll
3450 1.1 skrll do_relocation:
3451 1.1 skrll r = _bfd_final_link_relocate (howto, input_bfd, input_section,
3452 1.5 christos contents, rel->r_offset,
3453 1.1 skrll relocation, 0);
3454 1.1 skrll
3455 1.1 skrll check_relocation_error:
3456 1.1 skrll if (r != bfd_reloc_ok)
3457 1.1 skrll {
3458 1.1 skrll const char *name;
3459 1.1 skrll
3460 1.1 skrll if (h != NULL)
3461 1.1 skrll name = h->root.root.string;
3462 1.1 skrll else
3463 1.1 skrll {
3464 1.1 skrll name = bfd_elf_string_from_elf_section (input_bfd,
3465 1.1 skrll symtab_hdr->sh_link,
3466 1.1 skrll sym->st_name);
3467 1.1 skrll if (name == NULL)
3468 1.1 skrll return FALSE;
3469 1.1 skrll if (*name == '\0')
3470 1.1 skrll name = bfd_section_name (input_bfd, sec);
3471 1.9 christos }
3472 1.9 christos
3473 1.9 christos if (r == bfd_reloc_overflow)
3474 1.1 skrll (*info->callbacks->reloc_overflow)
3475 1.1 skrll (info, (h ? &h->root : NULL), name, howto->name,
3476 1.10 christos (bfd_vma) 0, input_bfd, input_section, rel->r_offset);
3477 1.10 christos else
3478 1.10 christos {
3479 1.1 skrll _bfd_error_handler
3480 1.10 christos /* xgettext:c-format */
3481 1.1 skrll (_("%B(%A+%#Lx): reloc against `%s': error %d"),
3482 1.1 skrll input_bfd, input_section,
3483 1.1 skrll rel->r_offset, name, (int) r);
3484 1.6 christos return FALSE;
3485 1.6 christos }
3486 1.6 christos }
3487 1.6 christos
3488 1.6 christos if (wrel != rel)
3489 1.6 christos *wrel = *rel;
3490 1.6 christos }
3491 1.6 christos
3492 1.6 christos if (wrel != rel)
3493 1.6 christos {
3494 1.6 christos Elf_Internal_Shdr *rel_hdr;
3495 1.6 christos size_t deleted = rel - wrel;
3496 1.6 christos
3497 1.6 christos rel_hdr = _bfd_elf_single_rel_hdr (input_section->output_section);
3498 1.6 christos rel_hdr->sh_size -= rel_hdr->sh_entsize * deleted;
3499 1.6 christos if (rel_hdr->sh_size == 0)
3500 1.6 christos {
3501 1.6 christos /* It is too late to remove an empty reloc section. Leave
3502 1.6 christos one NONE reloc.
3503 1.6 christos ??? What is wrong with an empty section??? */
3504 1.6 christos rel_hdr->sh_size = rel_hdr->sh_entsize;
3505 1.6 christos deleted -= 1;
3506 1.6 christos }
3507 1.1 skrll rel_hdr = _bfd_elf_single_rel_hdr (input_section);
3508 1.1 skrll rel_hdr->sh_size -= rel_hdr->sh_entsize * deleted;
3509 1.1 skrll input_section->reloc_count -= deleted;
3510 1.1 skrll }
3511 1.1 skrll
3512 1.1 skrll return TRUE;
3513 1.1 skrll }
3514 1.1 skrll
3515 1.1 skrll /* Finish up dynamic symbol handling. We set the contents of various
3516 1.1 skrll dynamic sections here. */
3517 1.1 skrll
3518 1.1 skrll static bfd_boolean
3519 1.1 skrll elf_i386_finish_dynamic_symbol (bfd *output_bfd,
3520 1.1 skrll struct bfd_link_info *info,
3521 1.10 christos struct elf_link_hash_entry *h,
3522 1.5 christos Elf_Internal_Sym *sym)
3523 1.10 christos {
3524 1.9 christos struct elf_x86_link_hash_table *htab;
3525 1.10 christos unsigned plt_entry_size;
3526 1.1 skrll struct elf_x86_link_hash_entry *eh;
3527 1.10 christos bfd_boolean local_undefweak;
3528 1.4 christos bfd_boolean use_plt_second;
3529 1.4 christos
3530 1.1 skrll htab = elf_x86_hash_table (info, I386_ELF_DATA);
3531 1.10 christos if (htab == NULL)
3532 1.10 christos return FALSE;
3533 1.10 christos
3534 1.10 christos plt_entry_size = htab->plt.plt_entry_size;
3535 1.5 christos
3536 1.10 christos /* Use the second PLT section only if there is .plt section. */
3537 1.10 christos use_plt_second = htab->elf.splt != NULL && htab->plt_second != NULL;
3538 1.10 christos
3539 1.6 christos eh = (struct elf_x86_link_hash_entry *) h;
3540 1.9 christos if (eh->no_finish_dynamic_symbol)
3541 1.9 christos abort ();
3542 1.9 christos
3543 1.10 christos /* We keep PLT/GOT entries without dynamic PLT/GOT relocations for
3544 1.9 christos resolved undefined weak symbols in executable so that their
3545 1.1 skrll references have value 0 at run-time. */
3546 1.1 skrll local_undefweak = UNDEFINED_WEAK_RESOLVED_TO_ZERO (info, eh);
3547 1.10 christos
3548 1.1 skrll if (h->plt.offset != (bfd_vma) -1)
3549 1.1 skrll {
3550 1.1 skrll bfd_vma plt_index, plt_offset;
3551 1.10 christos bfd_vma got_offset;
3552 1.4 christos Elf_Internal_Rela rel;
3553 1.4 christos bfd_byte *loc;
3554 1.4 christos asection *plt, *resolved_plt, *gotplt, *relplt;
3555 1.4 christos
3556 1.4 christos /* When building a static executable, use .iplt, .igot.plt and
3557 1.4 christos .rel.iplt sections for STT_GNU_IFUNC symbols. */
3558 1.4 christos if (htab->elf.splt != NULL)
3559 1.4 christos {
3560 1.4 christos plt = htab->elf.splt;
3561 1.4 christos gotplt = htab->elf.sgotplt;
3562 1.4 christos relplt = htab->elf.srelplt;
3563 1.4 christos }
3564 1.4 christos else
3565 1.4 christos {
3566 1.4 christos plt = htab->elf.iplt;
3567 1.1 skrll gotplt = htab->elf.igotplt;
3568 1.10 christos relplt = htab->elf.irelplt;
3569 1.1 skrll }
3570 1.1 skrll
3571 1.1 skrll VERIFY_PLT_ENTRY (info, h, plt, gotplt, relplt, local_undefweak)
3572 1.1 skrll
3573 1.4 christos /* Get the index in the procedure linkage table which
3574 1.1 skrll corresponds to this symbol. This is the index of this symbol
3575 1.4 christos in all the symbols for which we are making plt entries. The
3576 1.1 skrll first entry in the procedure linkage table is reserved.
3577 1.4 christos
3578 1.4 christos Get the offset into the .got table of the entry that
3579 1.4 christos corresponds to this function. Each .got entry is 4 bytes.
3580 1.4 christos The first three are reserved.
3581 1.4 christos
3582 1.4 christos For static executables, we don't reserve anything. */
3583 1.10 christos
3584 1.10 christos if (plt == htab->elf.splt)
3585 1.5 christos {
3586 1.4 christos got_offset = (h->plt.offset / plt_entry_size
3587 1.4 christos - htab->plt.has_plt0);
3588 1.4 christos got_offset = (got_offset + 3) * 4;
3589 1.5 christos }
3590 1.5 christos else
3591 1.4 christos {
3592 1.1 skrll got_offset = h->plt.offset / plt_entry_size;
3593 1.10 christos got_offset = got_offset * 4;
3594 1.10 christos }
3595 1.10 christos
3596 1.10 christos /* Fill in the entry in the procedure linkage table and update
3597 1.10 christos the first slot. */
3598 1.10 christos memcpy (plt->contents + h->plt.offset, htab->plt.plt_entry,
3599 1.10 christos plt_entry_size);
3600 1.10 christos
3601 1.10 christos if (use_plt_second)
3602 1.10 christos {
3603 1.10 christos const bfd_byte *plt_entry;
3604 1.10 christos if (bfd_link_pic (info))
3605 1.10 christos plt_entry = htab->non_lazy_plt->pic_plt_entry;
3606 1.10 christos else
3607 1.10 christos plt_entry = htab->non_lazy_plt->plt_entry;
3608 1.10 christos memcpy (htab->plt_second->contents + eh->plt_second.offset,
3609 1.10 christos plt_entry, htab->non_lazy_plt->plt_entry_size);
3610 1.10 christos
3611 1.10 christos resolved_plt = htab->plt_second;
3612 1.10 christos plt_offset = eh->plt_second.offset;
3613 1.10 christos }
3614 1.10 christos else
3615 1.10 christos {
3616 1.10 christos resolved_plt = plt;
3617 1.6 christos plt_offset = h->plt.offset;
3618 1.1 skrll }
3619 1.1 skrll
3620 1.4 christos if (! bfd_link_pic (info))
3621 1.4 christos {
3622 1.1 skrll bfd_put_32 (output_bfd,
3623 1.10 christos (gotplt->output_section->vma
3624 1.10 christos + gotplt->output_offset
3625 1.1 skrll + got_offset),
3626 1.10 christos resolved_plt->contents + plt_offset
3627 1.1 skrll + htab->plt.plt_got_offset);
3628 1.1 skrll
3629 1.1 skrll if (htab->target_os == is_vxworks)
3630 1.1 skrll {
3631 1.1 skrll int s, k, reloc_index;
3632 1.1 skrll
3633 1.1 skrll /* Create the R_386_32 relocation referencing the GOT
3634 1.10 christos for this PLT entry. */
3635 1.10 christos
3636 1.1 skrll /* S: Current slot number (zero-based). */
3637 1.6 christos s = ((h->plt.offset - htab->plt.plt_entry_size)
3638 1.1 skrll / htab->plt.plt_entry_size);
3639 1.1 skrll /* K: Number of relocations for PLTResolve. */
3640 1.1 skrll if (bfd_link_pic (info))
3641 1.1 skrll k = PLTRESOLVE_RELOCS_SHLIB;
3642 1.1 skrll else
3643 1.1 skrll k = PLTRESOLVE_RELOCS;
3644 1.1 skrll /* Skip the PLTresolve relocations, and the relocations for
3645 1.1 skrll the other PLT slots. */
3646 1.1 skrll reloc_index = k + s * PLT_NON_JUMP_SLOT_RELOCS;
3647 1.10 christos loc = (htab->srelplt2->contents + reloc_index
3648 1.10 christos * sizeof (Elf32_External_Rel));
3649 1.1 skrll
3650 1.1 skrll rel.r_offset = (plt->output_section->vma
3651 1.1 skrll + plt->output_offset
3652 1.1 skrll + h->plt.offset + 2),
3653 1.1 skrll rel.r_info = ELF32_R_INFO (htab->elf.hgot->indx, R_386_32);
3654 1.1 skrll bfd_elf32_swap_reloc_out (output_bfd, &rel, loc);
3655 1.4 christos
3656 1.4 christos /* Create the R_386_32 relocation referencing the beginning of
3657 1.1 skrll the PLT for this GOT entry. */
3658 1.1 skrll rel.r_offset = (htab->elf.sgotplt->output_section->vma
3659 1.1 skrll + htab->elf.sgotplt->output_offset
3660 1.6 christos + got_offset);
3661 1.1 skrll rel.r_info = ELF32_R_INFO (htab->elf.hplt->indx, R_386_32);
3662 1.1 skrll bfd_elf32_swap_reloc_out (output_bfd, &rel,
3663 1.1 skrll loc + sizeof (Elf32_External_Rel));
3664 1.1 skrll }
3665 1.1 skrll }
3666 1.10 christos else
3667 1.10 christos {
3668 1.4 christos bfd_put_32 (output_bfd, got_offset,
3669 1.1 skrll resolved_plt->contents + plt_offset
3670 1.9 christos + htab->plt.plt_got_offset);
3671 1.9 christos }
3672 1.9 christos
3673 1.9 christos /* Fill in the entry in the global offset table. Leave the entry
3674 1.9 christos as zero for undefined weak symbol in PIE. No PLT relocation
3675 1.10 christos against undefined weak symbol in PIE. */
3676 1.10 christos if (!local_undefweak)
3677 1.10 christos {
3678 1.10 christos if (htab->plt.has_plt0)
3679 1.10 christos bfd_put_32 (output_bfd,
3680 1.10 christos (plt->output_section->vma
3681 1.10 christos + plt->output_offset
3682 1.1 skrll + h->plt.offset
3683 1.9 christos + htab->lazy_plt->plt_lazy_offset),
3684 1.9 christos gotplt->contents + got_offset);
3685 1.9 christos
3686 1.9 christos /* Fill in the entry in the .rel.plt section. */
3687 1.10 christos rel.r_offset = (gotplt->output_section->vma
3688 1.9 christos + gotplt->output_offset
3689 1.10 christos + got_offset);
3690 1.10 christos if (PLT_LOCAL_IFUNC_P (info, h))
3691 1.10 christos {
3692 1.10 christos info->callbacks->minfo (_("Local IFUNC function `%s' in %B\n"),
3693 1.9 christos h->root.root.string,
3694 1.9 christos h->root.u.def.section->owner);
3695 1.9 christos
3696 1.9 christos /* If an STT_GNU_IFUNC symbol is locally defined, generate
3697 1.9 christos R_386_IRELATIVE instead of R_386_JUMP_SLOT. Store addend
3698 1.9 christos in the .got.plt section. */
3699 1.9 christos bfd_put_32 (output_bfd,
3700 1.9 christos (h->root.u.def.value
3701 1.9 christos + h->root.u.def.section->output_section->vma
3702 1.9 christos + h->root.u.def.section->output_offset),
3703 1.9 christos gotplt->contents + got_offset);
3704 1.9 christos rel.r_info = ELF32_R_INFO (0, R_386_IRELATIVE);
3705 1.9 christos /* R_386_IRELATIVE comes last. */
3706 1.9 christos plt_index = htab->next_irelative_index--;
3707 1.9 christos }
3708 1.9 christos else
3709 1.9 christos {
3710 1.9 christos rel.r_info = ELF32_R_INFO (h->dynindx, R_386_JUMP_SLOT);
3711 1.9 christos plt_index = htab->next_jump_slot_index++;
3712 1.9 christos }
3713 1.9 christos
3714 1.10 christos loc = relplt->contents + plt_index * sizeof (Elf32_External_Rel);
3715 1.10 christos bfd_elf32_swap_reloc_out (output_bfd, &rel, loc);
3716 1.10 christos
3717 1.9 christos /* Don't fill the second and third slots in PLT entry for
3718 1.9 christos static executables nor without PLT0. */
3719 1.9 christos if (plt == htab->elf.splt && htab->plt.has_plt0)
3720 1.9 christos {
3721 1.10 christos bfd_put_32 (output_bfd,
3722 1.10 christos plt_index * sizeof (Elf32_External_Rel),
3723 1.10 christos plt->contents + h->plt.offset
3724 1.10 christos + htab->lazy_plt->plt_reloc_offset);
3725 1.10 christos bfd_put_32 (output_bfd,
3726 1.10 christos - (h->plt.offset
3727 1.9 christos + htab->lazy_plt->plt_plt_offset + 4),
3728 1.5 christos (plt->contents + h->plt.offset
3729 1.6 christos + htab->lazy_plt->plt_plt_offset));
3730 1.6 christos }
3731 1.6 christos }
3732 1.6 christos }
3733 1.6 christos else if (eh->plt_got.offset != (bfd_vma) -1)
3734 1.6 christos {
3735 1.6 christos bfd_vma got_offset, plt_offset;
3736 1.6 christos asection *plt, *got, *gotplt;
3737 1.6 christos const bfd_byte *got_plt_entry;
3738 1.6 christos
3739 1.6 christos /* Set the entry in the GOT procedure linkage table. */
3740 1.6 christos plt = htab->plt_got;
3741 1.6 christos got = htab->elf.sgot;
3742 1.6 christos gotplt = htab->elf.sgotplt;
3743 1.6 christos got_offset = h->got.offset;
3744 1.6 christos
3745 1.6 christos if (got_offset == (bfd_vma) -1
3746 1.6 christos || plt == NULL
3747 1.5 christos || got == NULL
3748 1.6 christos || gotplt == NULL)
3749 1.6 christos abort ();
3750 1.1 skrll
3751 1.10 christos /* Fill in the entry in the GOT procedure linkage table. */
3752 1.6 christos if (! bfd_link_pic (info))
3753 1.1 skrll {
3754 1.6 christos got_plt_entry = htab->non_lazy_plt->plt_entry;
3755 1.6 christos got_offset += got->output_section->vma + got->output_offset;
3756 1.10 christos }
3757 1.6 christos else
3758 1.6 christos {
3759 1.6 christos got_plt_entry = htab->non_lazy_plt->pic_plt_entry;
3760 1.6 christos got_offset += (got->output_section->vma
3761 1.6 christos + got->output_offset
3762 1.6 christos - gotplt->output_section->vma
3763 1.6 christos - gotplt->output_offset);
3764 1.6 christos }
3765 1.10 christos
3766 1.6 christos plt_offset = eh->plt_got.offset;
3767 1.10 christos memcpy (plt->contents + plt_offset, got_plt_entry,
3768 1.10 christos htab->non_lazy_plt->plt_entry_size);
3769 1.6 christos bfd_put_32 (output_bfd, got_offset,
3770 1.6 christos (plt->contents + plt_offset
3771 1.9 christos + htab->non_lazy_plt->plt_got_offset));
3772 1.9 christos }
3773 1.6 christos
3774 1.6 christos if (!local_undefweak
3775 1.6 christos && !h->def_regular
3776 1.6 christos && (h->plt.offset != (bfd_vma) -1
3777 1.6 christos || eh->plt_got.offset != (bfd_vma) -1))
3778 1.6 christos {
3779 1.6 christos /* Mark the symbol as undefined, rather than as defined in
3780 1.6 christos the .plt section. Leave the value if there were any
3781 1.6 christos relocations where pointer equality matters (this is a clue
3782 1.6 christos for the dynamic linker, to make function pointer
3783 1.6 christos comparisons work between an application and shared
3784 1.6 christos library), otherwise set it to zero. If a function is only
3785 1.6 christos called from a binary, there is no need to slow down
3786 1.6 christos shared libraries because of that. */
3787 1.1 skrll sym->st_shndx = SHN_UNDEF;
3788 1.1 skrll if (!h->pointer_equality_needed)
3789 1.9 christos sym->st_value = 0;
3790 1.9 christos }
3791 1.1 skrll
3792 1.10 christos /* Don't generate dynamic GOT relocation against undefined weak
3793 1.10 christos symbol in executable. */
3794 1.9 christos if (h->got.offset != (bfd_vma) -1
3795 1.1 skrll && ! GOT_TLS_GD_ANY_P (elf_x86_hash_entry(h)->tls_type)
3796 1.1 skrll && (elf_x86_hash_entry(h)->tls_type & GOT_TLS_IE) == 0
3797 1.9 christos && !local_undefweak)
3798 1.1 skrll {
3799 1.1 skrll Elf_Internal_Rela rel;
3800 1.1 skrll asection *relgot = htab->elf.srelgot;
3801 1.1 skrll
3802 1.4 christos /* This symbol has an entry in the global offset table. Set it
3803 1.1 skrll up. */
3804 1.1 skrll
3805 1.4 christos if (htab->elf.sgot == NULL || htab->elf.srelgot == NULL)
3806 1.4 christos abort ();
3807 1.1 skrll
3808 1.1 skrll rel.r_offset = (htab->elf.sgot->output_section->vma
3809 1.1 skrll + htab->elf.sgot->output_offset
3810 1.1 skrll + (h->got.offset & ~(bfd_vma) 1));
3811 1.1 skrll
3812 1.1 skrll /* If this is a static link, or it is a -Bsymbolic link and the
3813 1.1 skrll symbol is defined locally or was forced to be local because
3814 1.4 christos of a version file, we just want to emit a RELATIVE reloc.
3815 1.4 christos The entry in the global offset table will already have been
3816 1.4 christos initialized in the relocate_section function. */
3817 1.9 christos if (h->def_regular
3818 1.9 christos && h->type == STT_GNU_IFUNC)
3819 1.9 christos {
3820 1.9 christos if (h->plt.offset == (bfd_vma) -1)
3821 1.9 christos {
3822 1.9 christos /* STT_GNU_IFUNC is referenced without PLT. */
3823 1.9 christos if (htab->elf.splt == NULL)
3824 1.9 christos {
3825 1.9 christos /* use .rel[a].iplt section to store .got relocations
3826 1.10 christos in static executable. */
3827 1.9 christos relgot = htab->elf.irelplt;
3828 1.10 christos }
3829 1.10 christos if (SYMBOL_REFERENCES_LOCAL_P (info, h))
3830 1.10 christos {
3831 1.10 christos info->callbacks->minfo (_("Local IFUNC function `%s' in %B\n"),
3832 1.9 christos h->root.root.string,
3833 1.9 christos h->root.u.def.section->owner);
3834 1.9 christos
3835 1.9 christos bfd_put_32 (output_bfd,
3836 1.9 christos (h->root.u.def.value
3837 1.9 christos + h->root.u.def.section->output_section->vma
3838 1.9 christos + h->root.u.def.section->output_offset),
3839 1.9 christos htab->elf.sgot->contents + h->got.offset);
3840 1.9 christos rel.r_info = ELF32_R_INFO (0, R_386_IRELATIVE);
3841 1.9 christos }
3842 1.9 christos else
3843 1.4 christos goto do_glob_dat;
3844 1.4 christos }
3845 1.4 christos else if (bfd_link_pic (info))
3846 1.4 christos {
3847 1.4 christos /* Generate R_386_GLOB_DAT. */
3848 1.4 christos goto do_glob_dat;
3849 1.4 christos }
3850 1.10 christos else
3851 1.4 christos {
3852 1.4 christos asection *plt;
3853 1.4 christos bfd_vma plt_offset;
3854 1.4 christos
3855 1.4 christos if (!h->pointer_equality_needed)
3856 1.4 christos abort ();
3857 1.4 christos
3858 1.10 christos /* For non-shared object, we can't use .got.plt, which
3859 1.10 christos contains the real function addres if we need pointer
3860 1.10 christos equality. We load the GOT entry with the PLT entry. */
3861 1.10 christos if (htab->plt_second != NULL)
3862 1.10 christos {
3863 1.10 christos plt = htab->plt_second;
3864 1.10 christos plt_offset = eh->plt_second.offset;
3865 1.10 christos }
3866 1.10 christos else
3867 1.10 christos {
3868 1.4 christos plt = htab->elf.splt ? htab->elf.splt : htab->elf.iplt;
3869 1.4 christos plt_offset = h->plt.offset;
3870 1.10 christos }
3871 1.4 christos bfd_put_32 (output_bfd,
3872 1.4 christos (plt->output_section->vma
3873 1.4 christos + plt->output_offset + plt_offset),
3874 1.4 christos htab->elf.sgot->contents + h->got.offset);
3875 1.6 christos return TRUE;
3876 1.10 christos }
3877 1.1 skrll }
3878 1.1 skrll else if (bfd_link_pic (info)
3879 1.1 skrll && SYMBOL_REFERENCES_LOCAL_P (info, h))
3880 1.1 skrll {
3881 1.1 skrll BFD_ASSERT((h->got.offset & 1) != 0);
3882 1.1 skrll rel.r_info = ELF32_R_INFO (0, R_386_RELATIVE);
3883 1.1 skrll }
3884 1.4 christos else
3885 1.1 skrll {
3886 1.4 christos BFD_ASSERT((h->got.offset & 1) == 0);
3887 1.1 skrll do_glob_dat:
3888 1.1 skrll bfd_put_32 (output_bfd, (bfd_vma) 0,
3889 1.1 skrll htab->elf.sgot->contents + h->got.offset);
3890 1.9 christos rel.r_info = ELF32_R_INFO (h->dynindx, R_386_GLOB_DAT);
3891 1.1 skrll }
3892 1.1 skrll
3893 1.1 skrll elf_append_rel (output_bfd, relgot, &rel);
3894 1.1 skrll }
3895 1.1 skrll
3896 1.10 christos if (h->needs_copy)
3897 1.1 skrll {
3898 1.1 skrll Elf_Internal_Rela rel;
3899 1.10 christos asection *s;
3900 1.1 skrll
3901 1.1 skrll /* This symbol needs a copy reloc. Set it up. */
3902 1.1 skrll VERIFY_COPY_RELOC (h, htab)
3903 1.1 skrll
3904 1.1 skrll rel.r_offset = (h->root.u.def.value
3905 1.10 christos + h->root.u.def.section->output_section->vma
3906 1.10 christos + h->root.u.def.section->output_offset);
3907 1.10 christos rel.r_info = ELF32_R_INFO (h->dynindx, R_386_COPY);
3908 1.10 christos if (h->root.u.def.section == htab->elf.sdynrelro)
3909 1.10 christos s = htab->elf.sreldynrelro;
3910 1.1 skrll else
3911 1.1 skrll s = htab->elf.srelbss;
3912 1.1 skrll elf_append_rel (output_bfd, s, &rel);
3913 1.1 skrll }
3914 1.1 skrll
3915 1.4 christos return TRUE;
3916 1.4 christos }
3917 1.4 christos
3918 1.4 christos /* Finish up local dynamic symbol handling. We set the contents of
3919 1.4 christos various dynamic sections here. */
3920 1.4 christos
3921 1.4 christos static bfd_boolean
3922 1.4 christos elf_i386_finish_local_dynamic_symbol (void **slot, void *inf)
3923 1.4 christos {
3924 1.5 christos struct elf_link_hash_entry *h
3925 1.4 christos = (struct elf_link_hash_entry *) *slot;
3926 1.4 christos struct bfd_link_info *info
3927 1.4 christos = (struct bfd_link_info *) inf;
3928 1.4 christos
3929 1.4 christos return elf_i386_finish_dynamic_symbol (info->output_bfd, info,
3930 1.9 christos h, NULL);
3931 1.9 christos }
3932 1.9 christos
3933 1.9 christos /* Finish up undefined weak symbol handling in PIE. Fill its PLT entry
3934 1.9 christos here since undefined weak symbol may not be dynamic and may not be
3935 1.9 christos called for elf_i386_finish_dynamic_symbol. */
3936 1.9 christos
3937 1.9 christos static bfd_boolean
3938 1.9 christos elf_i386_pie_finish_undefweak_symbol (struct bfd_hash_entry *bh,
3939 1.9 christos void *inf)
3940 1.9 christos {
3941 1.9 christos struct elf_link_hash_entry *h = (struct elf_link_hash_entry *) bh;
3942 1.9 christos struct bfd_link_info *info = (struct bfd_link_info *) inf;
3943 1.9 christos
3944 1.9 christos if (h->root.type != bfd_link_hash_undefweak
3945 1.9 christos || h->dynindx != -1)
3946 1.10 christos return TRUE;
3947 1.9 christos
3948 1.9 christos return elf_i386_finish_dynamic_symbol (info->output_bfd,
3949 1.1 skrll info, h, NULL);
3950 1.1 skrll }
3951 1.1 skrll
3952 1.1 skrll /* Used to decide how to sort relocs in an optimal manner for the
3953 1.6 christos dynamic linker, before writing them out. */
3954 1.6 christos
3955 1.6 christos static enum elf_reloc_type_class
3956 1.1 skrll elf_i386_reloc_type_class (const struct bfd_link_info *info,
3957 1.6 christos const asection *rel_sec ATTRIBUTE_UNUSED,
3958 1.6 christos const Elf_Internal_Rela *rela)
3959 1.6 christos {
3960 1.6 christos bfd *abfd = info->output_bfd;
3961 1.8 christos const struct elf_backend_data *bed = get_elf_backend_data (abfd);
3962 1.8 christos struct elf_link_hash_table *htab = elf_hash_table (info);
3963 1.8 christos
3964 1.8 christos if (htab->dynsym != NULL
3965 1.10 christos && htab->dynsym->contents != NULL)
3966 1.8 christos {
3967 1.9 christos /* Check relocation against STT_GNU_IFUNC symbol if there are
3968 1.9 christos dynamic symbols. */
3969 1.9 christos unsigned long r_symndx = ELF32_R_SYM (rela->r_info);
3970 1.9 christos if (r_symndx != STN_UNDEF)
3971 1.9 christos {
3972 1.9 christos Elf_Internal_Sym sym;
3973 1.9 christos if (!bed->s->swap_symbol_in (abfd,
3974 1.9 christos (htab->dynsym->contents
3975 1.6 christos + r_symndx * sizeof (Elf32_External_Sym)),
3976 1.9 christos 0, &sym))
3977 1.9 christos abort ();
3978 1.9 christos
3979 1.8 christos if (ELF32_ST_TYPE (sym.st_info) == STT_GNU_IFUNC)
3980 1.6 christos return reloc_class_ifunc;
3981 1.1 skrll }
3982 1.1 skrll }
3983 1.9 christos
3984 1.9 christos switch (ELF32_R_TYPE (rela->r_info))
3985 1.1 skrll {
3986 1.1 skrll case R_386_IRELATIVE:
3987 1.1 skrll return reloc_class_ifunc;
3988 1.1 skrll case R_386_RELATIVE:
3989 1.1 skrll return reloc_class_relative;
3990 1.1 skrll case R_386_JUMP_SLOT:
3991 1.1 skrll return reloc_class_plt;
3992 1.1 skrll case R_386_COPY:
3993 1.1 skrll return reloc_class_copy;
3994 1.1 skrll default:
3995 1.1 skrll return reloc_class_normal;
3996 1.1 skrll }
3997 1.1 skrll }
3998 1.1 skrll
3999 1.1 skrll /* Finish up the dynamic sections. */
4000 1.1 skrll
4001 1.1 skrll static bfd_boolean
4002 1.10 christos elf_i386_finish_dynamic_sections (bfd *output_bfd,
4003 1.1 skrll struct bfd_link_info *info)
4004 1.10 christos {
4005 1.4 christos struct elf_x86_link_hash_table *htab;
4006 1.4 christos
4007 1.4 christos htab = _bfd_x86_elf_finish_dynamic_sections (output_bfd, info);
4008 1.10 christos if (htab == NULL)
4009 1.10 christos return FALSE;
4010 1.1 skrll
4011 1.10 christos if (!htab->elf.dynamic_sections_created)
4012 1.1 skrll return TRUE;
4013 1.10 christos
4014 1.10 christos if (htab->elf.splt && htab->elf.splt->size > 0)
4015 1.10 christos {
4016 1.10 christos /* UnixWare sets the entsize of .plt to 4, although that doesn't
4017 1.1 skrll really seem like the right value. */
4018 1.10 christos elf_section_data (htab->elf.splt->output_section)
4019 1.1 skrll ->this_hdr.sh_entsize = 4;
4020 1.10 christos
4021 1.10 christos if (htab->plt.has_plt0)
4022 1.10 christos {
4023 1.10 christos /* Fill in the special first entry in the procedure linkage
4024 1.10 christos table. */
4025 1.10 christos memcpy (htab->elf.splt->contents, htab->plt.plt0_entry,
4026 1.10 christos htab->lazy_plt->plt0_entry_size);
4027 1.10 christos memset (htab->elf.splt->contents + htab->lazy_plt->plt0_entry_size,
4028 1.1 skrll htab->plt0_pad_byte,
4029 1.1 skrll htab->plt.plt_entry_size - htab->lazy_plt->plt0_entry_size);
4030 1.4 christos if (!bfd_link_pic (info))
4031 1.4 christos {
4032 1.1 skrll bfd_put_32 (output_bfd,
4033 1.5 christos (htab->elf.sgotplt->output_section->vma
4034 1.10 christos + htab->elf.sgotplt->output_offset
4035 1.1 skrll + 4),
4036 1.4 christos htab->elf.splt->contents
4037 1.4 christos + htab->lazy_plt->plt0_got1_offset);
4038 1.1 skrll bfd_put_32 (output_bfd,
4039 1.5 christos (htab->elf.sgotplt->output_section->vma
4040 1.10 christos + htab->elf.sgotplt->output_offset
4041 1.1 skrll + 8),
4042 1.10 christos htab->elf.splt->contents
4043 1.1 skrll + htab->lazy_plt->plt0_got2_offset);
4044 1.1 skrll
4045 1.10 christos if (htab->target_os == is_vxworks)
4046 1.10 christos {
4047 1.10 christos Elf_Internal_Rela rel;
4048 1.10 christos int num_plts = (htab->elf.splt->size
4049 1.10 christos / htab->plt.plt_entry_size) - 1;
4050 1.10 christos unsigned char *p;
4051 1.10 christos asection *srelplt2 = htab->srelplt2;
4052 1.10 christos
4053 1.4 christos /* Generate a relocation for _GLOBAL_OFFSET_TABLE_
4054 1.4 christos + 4. On IA32 we use REL relocations so the
4055 1.10 christos addend goes in the PLT directly. */
4056 1.10 christos rel.r_offset = (htab->elf.splt->output_section->vma
4057 1.10 christos + htab->elf.splt->output_offset
4058 1.1 skrll + htab->lazy_plt->plt0_got1_offset);
4059 1.10 christos rel.r_info = ELF32_R_INFO (htab->elf.hgot->indx,
4060 1.10 christos R_386_32);
4061 1.10 christos bfd_elf32_swap_reloc_out (output_bfd, &rel,
4062 1.4 christos srelplt2->contents);
4063 1.4 christos /* Generate a relocation for _GLOBAL_OFFSET_TABLE_
4064 1.10 christos + 8. */
4065 1.10 christos rel.r_offset = (htab->elf.splt->output_section->vma
4066 1.10 christos + htab->elf.splt->output_offset
4067 1.1 skrll + htab->lazy_plt->plt0_got2_offset);
4068 1.10 christos rel.r_info = ELF32_R_INFO (htab->elf.hgot->indx,
4069 1.1 skrll R_386_32);
4070 1.10 christos bfd_elf32_swap_reloc_out (output_bfd, &rel,
4071 1.10 christos srelplt2->contents +
4072 1.10 christos sizeof (Elf32_External_Rel));
4073 1.10 christos /* Correct the .rel.plt.unloaded relocations. */
4074 1.10 christos p = srelplt2->contents;
4075 1.10 christos if (bfd_link_pic (info))
4076 1.1 skrll p += PLTRESOLVE_RELOCS_SHLIB * sizeof (Elf32_External_Rel);
4077 1.10 christos else
4078 1.10 christos p += PLTRESOLVE_RELOCS * sizeof (Elf32_External_Rel);
4079 1.10 christos
4080 1.10 christos for (; num_plts; num_plts--)
4081 1.10 christos {
4082 1.10 christos bfd_elf32_swap_reloc_in (output_bfd, p, &rel);
4083 1.10 christos rel.r_info = ELF32_R_INFO (htab->elf.hgot->indx,
4084 1.10 christos R_386_32);
4085 1.10 christos bfd_elf32_swap_reloc_out (output_bfd, &rel, p);
4086 1.10 christos p += sizeof (Elf32_External_Rel);
4087 1.10 christos
4088 1.10 christos bfd_elf32_swap_reloc_in (output_bfd, p, &rel);
4089 1.10 christos rel.r_info = ELF32_R_INFO (htab->elf.hplt->indx,
4090 1.10 christos R_386_32);
4091 1.1 skrll bfd_elf32_swap_reloc_out (output_bfd, &rel, p);
4092 1.1 skrll p += sizeof (Elf32_External_Rel);
4093 1.1 skrll }
4094 1.1 skrll }
4095 1.1 skrll }
4096 1.9 christos }
4097 1.9 christos }
4098 1.9 christos
4099 1.9 christos /* Fill PLT entries for undefined weak symbols in PIE. */
4100 1.9 christos if (bfd_link_pie (info))
4101 1.9 christos bfd_hash_traverse (&info->hash->table,
4102 1.9 christos elf_i386_pie_finish_undefweak_symbol,
4103 1.9 christos info);
4104 1.9 christos
4105 1.9 christos return TRUE;
4106 1.9 christos }
4107 1.9 christos
4108 1.9 christos /* Fill PLT/GOT entries and allocate dynamic relocations for local
4109 1.9 christos STT_GNU_IFUNC symbols, which aren't in the ELF linker hash table.
4110 1.9 christos It has to be done before elf_link_sort_relocs is called so that
4111 1.9 christos dynamic relocations are properly sorted. */
4112 1.9 christos
4113 1.9 christos static bfd_boolean
4114 1.9 christos elf_i386_output_arch_local_syms
4115 1.9 christos (bfd *output_bfd ATTRIBUTE_UNUSED,
4116 1.9 christos struct bfd_link_info *info,
4117 1.9 christos void *flaginfo ATTRIBUTE_UNUSED,
4118 1.9 christos int (*func) (void *, const char *,
4119 1.9 christos Elf_Internal_Sym *,
4120 1.10 christos asection *,
4121 1.10 christos struct elf_link_hash_entry *) ATTRIBUTE_UNUSED)
4122 1.9 christos {
4123 1.9 christos struct elf_x86_link_hash_table *htab
4124 1.9 christos = elf_x86_hash_table (info, I386_ELF_DATA);
4125 1.4 christos if (htab == NULL)
4126 1.4 christos return FALSE;
4127 1.4 christos
4128 1.4 christos /* Fill PLT and GOT entries for local STT_GNU_IFUNC symbols. */
4129 1.1 skrll htab_traverse (htab->loc_hash_table,
4130 1.1 skrll elf_i386_finish_local_dynamic_symbol,
4131 1.1 skrll info);
4132 1.1 skrll
4133 1.10 christos return TRUE;
4134 1.10 christos }
4135 1.6 christos
4136 1.10 christos /* Forward declaration. */
4137 1.10 christos static const struct elf_x86_lazy_plt_layout elf_i386_nacl_plt;
4138 1.10 christos
4139 1.10 christos /* Similar to _bfd_elf_get_synthetic_symtab. Support PLTs with all
4140 1.10 christos dynamic relocations. */
4141 1.10 christos
4142 1.10 christos static long
4143 1.10 christos elf_i386_get_synthetic_symtab (bfd *abfd,
4144 1.10 christos long symcount ATTRIBUTE_UNUSED,
4145 1.10 christos asymbol **syms ATTRIBUTE_UNUSED,
4146 1.10 christos long dynsymcount,
4147 1.10 christos asymbol **dynsyms,
4148 1.10 christos asymbol **ret)
4149 1.6 christos {
4150 1.10 christos long count, i, n;
4151 1.10 christos int j;
4152 1.10 christos bfd_byte *plt_contents;
4153 1.10 christos long relsize;
4154 1.10 christos const struct elf_x86_lazy_plt_layout *lazy_plt;
4155 1.10 christos const struct elf_x86_non_lazy_plt_layout *non_lazy_plt;
4156 1.10 christos const struct elf_x86_lazy_plt_layout *lazy_ibt_plt;
4157 1.10 christos const struct elf_x86_non_lazy_plt_layout *non_lazy_ibt_plt;
4158 1.10 christos asection *plt;
4159 1.10 christos bfd_vma got_addr;
4160 1.10 christos enum elf_x86_plt_type plt_type;
4161 1.10 christos struct elf_x86_plt plts[] =
4162 1.10 christos {
4163 1.10 christos { ".plt", NULL, NULL, plt_unknown, 0, 0, 0, 0 },
4164 1.10 christos { ".plt.got", NULL, NULL, plt_non_lazy, 0, 0, 0, 0 },
4165 1.10 christos { ".plt.sec", NULL, NULL, plt_second, 0, 0, 0, 0 },
4166 1.10 christos { NULL, NULL, NULL, plt_non_lazy, 0, 0, 0, 0 }
4167 1.10 christos };
4168 1.10 christos
4169 1.10 christos *ret = NULL;
4170 1.10 christos
4171 1.10 christos if ((abfd->flags & (DYNAMIC | EXEC_P)) == 0)
4172 1.10 christos return 0;
4173 1.10 christos
4174 1.10 christos if (dynsymcount <= 0)
4175 1.10 christos return 0;
4176 1.10 christos
4177 1.10 christos relsize = bfd_get_dynamic_reloc_upper_bound (abfd);
4178 1.10 christos if (relsize <= 0)
4179 1.10 christos return -1;
4180 1.10 christos
4181 1.10 christos non_lazy_plt = NULL;
4182 1.10 christos /* Silence GCC 6. */
4183 1.10 christos lazy_plt = NULL;
4184 1.10 christos non_lazy_ibt_plt = NULL;
4185 1.10 christos lazy_ibt_plt = NULL;
4186 1.10 christos switch (get_elf_x86_backend_data (abfd)->target_os)
4187 1.10 christos {
4188 1.10 christos case is_normal:
4189 1.10 christos non_lazy_plt = &elf_i386_non_lazy_plt;
4190 1.10 christos lazy_ibt_plt = &elf_i386_lazy_ibt_plt;
4191 1.10 christos non_lazy_ibt_plt = &elf_i386_non_lazy_ibt_plt;
4192 1.10 christos /* Fall through */
4193 1.10 christos case is_vxworks:
4194 1.10 christos lazy_plt = &elf_i386_lazy_plt;
4195 1.10 christos break;
4196 1.6 christos case is_nacl:
4197 1.6 christos lazy_plt = &elf_i386_nacl_plt;
4198 1.10 christos break;
4199 1.10 christos }
4200 1.10 christos
4201 1.10 christos got_addr = 0;
4202 1.6 christos
4203 1.10 christos count = 0;
4204 1.10 christos for (j = 0; plts[j].name != NULL; j++)
4205 1.10 christos {
4206 1.10 christos plt = bfd_get_section_by_name (abfd, plts[j].name);
4207 1.10 christos if (plt == NULL || plt->size == 0)
4208 1.10 christos continue;
4209 1.10 christos
4210 1.10 christos /* Get the PLT section contents. */
4211 1.10 christos plt_contents = (bfd_byte *) bfd_malloc (plt->size);
4212 1.10 christos if (plt_contents == NULL)
4213 1.10 christos break;
4214 1.10 christos if (!bfd_get_section_contents (abfd, (asection *) plt,
4215 1.10 christos plt_contents, 0, plt->size))
4216 1.10 christos {
4217 1.6 christos free (plt_contents);
4218 1.10 christos break;
4219 1.10 christos }
4220 1.10 christos
4221 1.10 christos /* Check what kind of PLT it is. */
4222 1.10 christos plt_type = plt_unknown;
4223 1.10 christos if (plts[j].type == plt_unknown
4224 1.10 christos && (plt->size >= (lazy_plt->plt0_entry_size
4225 1.10 christos + lazy_plt->plt_entry_size)))
4226 1.10 christos {
4227 1.10 christos /* Match lazy PLT first. */
4228 1.10 christos if (memcmp (plt_contents, lazy_plt->plt0_entry,
4229 1.10 christos lazy_plt->plt0_got1_offset) == 0)
4230 1.10 christos {
4231 1.10 christos /* The fist entry in the lazy IBT PLT is the same as the
4232 1.10 christos normal lazy PLT. */
4233 1.10 christos if (lazy_ibt_plt != NULL
4234 1.10 christos && (memcmp (plt_contents + lazy_ibt_plt->plt0_entry_size,
4235 1.10 christos lazy_ibt_plt->plt_entry,
4236 1.10 christos lazy_ibt_plt->plt_got_offset) == 0))
4237 1.10 christos plt_type = plt_lazy | plt_second;
4238 1.10 christos else
4239 1.10 christos plt_type = plt_lazy;
4240 1.10 christos }
4241 1.10 christos else if (memcmp (plt_contents, lazy_plt->pic_plt0_entry,
4242 1.10 christos lazy_plt->plt0_got1_offset) == 0)
4243 1.10 christos {
4244 1.10 christos /* The fist entry in the PIC lazy IBT PLT is the same as
4245 1.10 christos the normal PIC lazy PLT. */
4246 1.10 christos if (lazy_ibt_plt != NULL
4247 1.10 christos && (memcmp (plt_contents + lazy_ibt_plt->plt0_entry_size,
4248 1.10 christos lazy_ibt_plt->pic_plt_entry,
4249 1.10 christos lazy_ibt_plt->plt_got_offset) == 0))
4250 1.10 christos plt_type = plt_lazy | plt_pic | plt_second;
4251 1.10 christos else
4252 1.10 christos plt_type = plt_lazy | plt_pic;
4253 1.10 christos }
4254 1.10 christos }
4255 1.10 christos
4256 1.10 christos if (non_lazy_plt != NULL
4257 1.10 christos && (plt_type == plt_unknown || plt_type == plt_non_lazy)
4258 1.10 christos && plt->size >= non_lazy_plt->plt_entry_size)
4259 1.10 christos {
4260 1.10 christos /* Match non-lazy PLT. */
4261 1.10 christos if (memcmp (plt_contents, non_lazy_plt->plt_entry,
4262 1.10 christos non_lazy_plt->plt_got_offset) == 0)
4263 1.10 christos plt_type = plt_non_lazy;
4264 1.10 christos else if (memcmp (plt_contents, non_lazy_plt->pic_plt_entry,
4265 1.10 christos non_lazy_plt->plt_got_offset) == 0)
4266 1.10 christos plt_type = plt_pic;
4267 1.10 christos }
4268 1.10 christos
4269 1.10 christos if ((non_lazy_ibt_plt != NULL)
4270 1.10 christos && (plt_type == plt_unknown || plt_type == plt_second)
4271 1.10 christos && plt->size >= non_lazy_ibt_plt->plt_entry_size)
4272 1.10 christos {
4273 1.10 christos if (memcmp (plt_contents,
4274 1.10 christos non_lazy_ibt_plt->plt_entry,
4275 1.10 christos non_lazy_ibt_plt->plt_got_offset) == 0)
4276 1.10 christos {
4277 1.10 christos /* Match IBT PLT. */
4278 1.10 christos plt_type = plt_second;
4279 1.10 christos non_lazy_plt = non_lazy_ibt_plt;
4280 1.10 christos }
4281 1.10 christos else if (memcmp (plt_contents,
4282 1.10 christos non_lazy_ibt_plt->pic_plt_entry,
4283 1.10 christos non_lazy_ibt_plt->plt_got_offset) == 0)
4284 1.10 christos {
4285 1.10 christos /* Match PIC IBT PLT. */
4286 1.10 christos plt_type = plt_second | plt_pic;
4287 1.10 christos non_lazy_plt = non_lazy_ibt_plt;
4288 1.10 christos }
4289 1.10 christos }
4290 1.10 christos
4291 1.10 christos if (plt_type == plt_unknown)
4292 1.10 christos {
4293 1.10 christos free (plt_contents);
4294 1.10 christos continue;
4295 1.10 christos }
4296 1.10 christos
4297 1.10 christos plts[j].sec = plt;
4298 1.10 christos plts[j].type = plt_type;
4299 1.10 christos
4300 1.10 christos if ((plt_type & plt_lazy))
4301 1.10 christos {
4302 1.10 christos plts[j].plt_got_offset = lazy_plt->plt_got_offset;
4303 1.10 christos plts[j].plt_entry_size = lazy_plt->plt_entry_size;
4304 1.10 christos /* Skip PLT0 in lazy PLT. */
4305 1.10 christos i = 1;
4306 1.10 christos }
4307 1.10 christos else
4308 1.10 christos {
4309 1.10 christos plts[j].plt_got_offset = non_lazy_plt->plt_got_offset;
4310 1.10 christos plts[j].plt_entry_size = non_lazy_plt->plt_entry_size;
4311 1.10 christos i = 0;
4312 1.10 christos }
4313 1.10 christos
4314 1.10 christos /* Skip lazy PLT when the second PLT is used. */
4315 1.10 christos if ((plt_type & (plt_lazy | plt_second))
4316 1.10 christos == (plt_lazy | plt_second))
4317 1.10 christos plts[j].count = 0;
4318 1.10 christos else
4319 1.10 christos {
4320 1.10 christos n = plt->size / plts[j].plt_entry_size;
4321 1.6 christos plts[j].count = n;
4322 1.10 christos count += n - i;
4323 1.6 christos }
4324 1.10 christos
4325 1.10 christos plts[j].contents = plt_contents;
4326 1.10 christos
4327 1.6 christos /* The _GLOBAL_OFFSET_TABLE_ address is needed. */
4328 1.6 christos if ((plt_type & plt_pic))
4329 1.10 christos got_addr = (bfd_vma) -1;
4330 1.10 christos }
4331 1.10 christos
4332 1.6 christos return _bfd_x86_elf_get_synthetic_symtab (abfd, count, relsize,
4333 1.6 christos got_addr, plts, dynsyms,
4334 1.10 christos ret);
4335 1.10 christos }
4336 1.1 skrll
4337 1.10 christos /* Set up i386 GNU properties. Return the first relocatable ELF input
4338 1.10 christos with GNU properties if found. Otherwise, return NULL. */
4339 1.6 christos
4340 1.10 christos static bfd *
4341 1.1 skrll elf_i386_link_setup_gnu_properties (struct bfd_link_info *info)
4342 1.10 christos {
4343 1.10 christos struct elf_x86_init_table init_table;
4344 1.10 christos
4345 1.10 christos switch (get_elf_x86_backend_data (info->output_bfd)->target_os)
4346 1.10 christos {
4347 1.10 christos case is_normal:
4348 1.10 christos init_table.plt0_pad_byte = 0x0;
4349 1.10 christos init_table.lazy_plt = &elf_i386_lazy_plt;
4350 1.10 christos init_table.non_lazy_plt = &elf_i386_non_lazy_plt;
4351 1.10 christos init_table.lazy_ibt_plt = &elf_i386_lazy_ibt_plt;
4352 1.10 christos init_table.non_lazy_ibt_plt = &elf_i386_non_lazy_ibt_plt;
4353 1.10 christos break;
4354 1.10 christos case is_vxworks:
4355 1.10 christos init_table.plt0_pad_byte = 0x90;
4356 1.10 christos init_table.lazy_plt = &elf_i386_lazy_plt;
4357 1.10 christos init_table.non_lazy_plt = NULL;
4358 1.10 christos init_table.lazy_ibt_plt = NULL;
4359 1.10 christos init_table.non_lazy_ibt_plt = NULL;
4360 1.10 christos break;
4361 1.10 christos case is_nacl:
4362 1.10 christos init_table.plt0_pad_byte = 0x90;
4363 1.10 christos init_table.lazy_plt = &elf_i386_nacl_plt;
4364 1.10 christos init_table.non_lazy_plt = NULL;
4365 1.10 christos init_table.lazy_ibt_plt = NULL;
4366 1.1 skrll init_table.non_lazy_ibt_plt = NULL;
4367 1.10 christos break;
4368 1.10 christos }
4369 1.1 skrll
4370 1.10 christos init_table.r_info = elf32_r_info;
4371 1.1 skrll init_table.r_sym = elf32_r_sym;
4372 1.1 skrll
4373 1.6 christos return _bfd_x86_elf_link_setup_gnu_properties (info, &init_table);
4374 1.1 skrll }
4375 1.1 skrll
4376 1.4 christos #define TARGET_LITTLE_SYM i386_elf32_vec
4377 1.1 skrll #define TARGET_LITTLE_NAME "elf32-i386"
4378 1.1 skrll #define ELF_ARCH bfd_arch_i386
4379 1.1 skrll #define ELF_TARGET_ID I386_ELF_DATA
4380 1.1 skrll #define ELF_MACHINE_CODE EM_386
4381 1.1 skrll #define ELF_MAXPAGESIZE 0x1000
4382 1.1 skrll
4383 1.1 skrll #define elf_backend_can_gc_sections 1
4384 1.1 skrll #define elf_backend_can_refcount 1
4385 1.1 skrll #define elf_backend_want_got_plt 1
4386 1.5 christos #define elf_backend_plt_readonly 1
4387 1.10 christos #define elf_backend_want_plt_sym 0
4388 1.6 christos #define elf_backend_got_header_size 12
4389 1.9 christos #define elf_backend_plt_alignment 4
4390 1.10 christos #define elf_backend_dtrel_excludes_plt 1
4391 1.1 skrll #define elf_backend_extern_protected_data 1
4392 1.1 skrll #define elf_backend_caches_rawsize 1
4393 1.1 skrll #define elf_backend_want_dynrelro 1
4394 1.1 skrll
4395 1.1 skrll /* Support RELA for objdump of prelink objects. */
4396 1.1 skrll #define elf_info_to_howto elf_i386_info_to_howto_rel
4397 1.1 skrll #define elf_info_to_howto_rel elf_i386_info_to_howto_rel
4398 1.1 skrll
4399 1.6 christos #define bfd_elf32_bfd_is_local_label_name elf_i386_is_local_label_name
4400 1.1 skrll #define bfd_elf32_bfd_reloc_type_lookup elf_i386_reloc_type_lookup
4401 1.1 skrll #define bfd_elf32_bfd_reloc_name_lookup elf_i386_reloc_name_lookup
4402 1.1 skrll #define bfd_elf32_get_synthetic_symtab elf_i386_get_synthetic_symtab
4403 1.10 christos
4404 1.1 skrll #define elf_backend_relocs_compatible _bfd_elf_relocs_compatible
4405 1.1 skrll #define elf_backend_check_relocs elf_i386_check_relocs
4406 1.1 skrll #define elf_backend_create_dynamic_sections _bfd_elf_create_dynamic_sections
4407 1.9 christos #define elf_backend_fake_sections elf_i386_fake_sections
4408 1.1 skrll #define elf_backend_finish_dynamic_sections elf_i386_finish_dynamic_sections
4409 1.1 skrll #define elf_backend_finish_dynamic_symbol elf_i386_finish_dynamic_symbol
4410 1.1 skrll #define elf_backend_output_arch_local_syms elf_i386_output_arch_local_syms
4411 1.1 skrll #define elf_backend_grok_prstatus elf_i386_grok_prstatus
4412 1.10 christos #define elf_backend_grok_psinfo elf_i386_grok_psinfo
4413 1.10 christos #define elf_backend_reloc_type_class elf_i386_reloc_type_class
4414 1.10 christos #define elf_backend_relocate_section elf_i386_relocate_section
4415 1.10 christos #define elf_backend_setup_gnu_properties elf_i386_link_setup_gnu_properties
4416 1.1 skrll #define elf_backend_hide_symbol _bfd_x86_elf_hide_symbol
4417 1.1 skrll
4418 1.1 skrll #define elf_backend_linux_prpsinfo32_ugid16 TRUE
4419 1.1 skrll
4420 1.1 skrll #include "elf32-target.h"
4421 1.1 skrll
4422 1.6 christos /* FreeBSD support. */
4423 1.1 skrll
4424 1.1 skrll #undef TARGET_LITTLE_SYM
4425 1.1 skrll #define TARGET_LITTLE_SYM i386_elf32_fbsd_vec
4426 1.1 skrll #undef TARGET_LITTLE_NAME
4427 1.1 skrll #define TARGET_LITTLE_NAME "elf32-i386-freebsd"
4428 1.1 skrll #undef ELF_OSABI
4429 1.1 skrll #define ELF_OSABI ELFOSABI_FREEBSD
4430 1.1 skrll
4431 1.1 skrll /* The kernel recognizes executables as valid only if they carry a
4432 1.1 skrll "FreeBSD" label in the ELF header. So we put this label on all
4433 1.4 christos executables and (for simplicity) also all other object files. */
4434 1.1 skrll
4435 1.6 christos static void
4436 1.1 skrll elf_i386_fbsd_post_process_headers (bfd *abfd, struct bfd_link_info *info)
4437 1.1 skrll {
4438 1.6 christos _bfd_elf_post_process_headers (abfd, info);
4439 1.6 christos
4440 1.6 christos #ifdef OLD_FREEBSD_ABI_LABEL
4441 1.6 christos {
4442 1.6 christos /* The ABI label supported by FreeBSD <= 4.0 is quite nonstandard. */
4443 1.1 skrll Elf_Internal_Ehdr *i_ehdrp = elf_elfheader (abfd);
4444 1.1 skrll memcpy (&i_ehdrp->e_ident[EI_ABIVERSION], "FreeBSD", 8);
4445 1.1 skrll }
4446 1.1 skrll #endif
4447 1.4 christos }
4448 1.1 skrll
4449 1.1 skrll #undef elf_backend_post_process_headers
4450 1.1 skrll #define elf_backend_post_process_headers elf_i386_fbsd_post_process_headers
4451 1.4 christos #undef elf32_bed
4452 1.4 christos #define elf32_bed elf32_i386_fbsd_bed
4453 1.4 christos
4454 1.4 christos #undef elf_backend_add_symbol_hook
4455 1.4 christos
4456 1.4 christos #include "elf32-target.h"
4457 1.4 christos
4458 1.6 christos /* Solaris 2. */
4459 1.4 christos
4460 1.4 christos #undef TARGET_LITTLE_SYM
4461 1.4 christos #define TARGET_LITTLE_SYM i386_elf32_sol2_vec
4462 1.6 christos #undef TARGET_LITTLE_NAME
4463 1.6 christos #define TARGET_LITTLE_NAME "elf32-i386-sol2"
4464 1.4 christos
4465 1.4 christos #undef elf_backend_post_process_headers
4466 1.4 christos
4467 1.4 christos /* Restore default: we cannot use ELFOSABI_SOLARIS, otherwise ELFOSABI_NONE
4468 1.4 christos objects won't be recognized. */
4469 1.4 christos #undef ELF_OSABI
4470 1.4 christos
4471 1.4 christos #undef elf32_bed
4472 1.4 christos #define elf32_bed elf32_i386_sol2_bed
4473 1.9 christos
4474 1.4 christos /* The 32-bit static TLS arena size is rounded to the nearest 8-byte
4475 1.4 christos boundary. */
4476 1.4 christos #undef elf_backend_static_tls_alignment
4477 1.4 christos #define elf_backend_static_tls_alignment 8
4478 1.4 christos
4479 1.4 christos /* The Solaris 2 ABI requires a plt symbol on all platforms.
4480 1.9 christos
4481 1.4 christos Cf. Linker and Libraries Guide, Ch. 2, Link-Editor, Generating the Output
4482 1.4 christos File, p.63. */
4483 1.9 christos #undef elf_backend_want_plt_sym
4484 1.9 christos #define elf_backend_want_plt_sym 1
4485 1.9 christos
4486 1.9 christos #undef elf_backend_strtab_flags
4487 1.10 christos #define elf_backend_strtab_flags SHF_STRINGS
4488 1.9 christos
4489 1.9 christos /* Called to set the sh_flags, sh_link and sh_info fields of OSECTION which
4490 1.9 christos has a type >= SHT_LOOS. Returns TRUE if these fields were initialised
4491 1.9 christos FALSE otherwise. ISECTION is the best guess matching section from the
4492 1.9 christos input bfd IBFD, but it might be NULL. */
4493 1.9 christos
4494 1.9 christos static bfd_boolean
4495 1.9 christos elf32_i386_copy_solaris_special_section_fields (const bfd *ibfd ATTRIBUTE_UNUSED,
4496 1.9 christos bfd *obfd ATTRIBUTE_UNUSED,
4497 1.9 christos const Elf_Internal_Shdr *isection ATTRIBUTE_UNUSED,
4498 1.9 christos Elf_Internal_Shdr *osection ATTRIBUTE_UNUSED)
4499 1.9 christos {
4500 1.9 christos /* PR 19938: FIXME: Need to add code for setting the sh_info
4501 1.9 christos and sh_link fields of Solaris specific section types. */
4502 1.9 christos return FALSE;
4503 1.9 christos
4504 1.9 christos /* Based upon Oracle Solaris 11.3 Linkers and Libraries Guide, Ch. 13,
4505 1.9 christos Object File Format, Table 13-9 ELF sh_link and sh_info Interpretation:
4506 1.9 christos
4507 1.10 christos http://docs.oracle.com/cd/E53394_01/html/E54813/chapter6-94076.html#scrolltoc
4508 1.10 christos
4509 1.9 christos The following values should be set:
4510 1.9 christos
4511 1.10 christos Type Link Info
4512 1.10 christos -----------------------------------------------------------------------------
4513 1.9 christos SHT_SUNW_ancillary The section header index of 0
4514 1.10 christos [0x6fffffee] the associated string table.
4515 1.10 christos
4516 1.9 christos SHT_SUNW_capinfo The section header index of For a dynamic object, the
4517 1.9 christos [0x6ffffff0] the associated symbol table. section header index of
4518 1.9 christos the associated
4519 1.9 christos SHT_SUNW_capchain table,
4520 1.10 christos otherwise 0.
4521 1.9 christos
4522 1.9 christos SHT_SUNW_symsort The section header index of 0
4523 1.10 christos [0x6ffffff1] the associated symbol table.
4524 1.10 christos
4525 1.10 christos SHT_SUNW_tlssort The section header index of 0
4526 1.10 christos [0x6ffffff2] the associated symbol table.
4527 1.10 christos
4528 1.9 christos SHT_SUNW_LDYNSYM The section header index of One greater than the
4529 1.10 christos [0x6ffffff3] the associated string table. symbol table index of the
4530 1.10 christos This index is the same string last local symbol,
4531 1.9 christos table used by the SHT_DYNSYM STB_LOCAL. Since
4532 1.9 christos section. SHT_SUNW_LDYNSYM only
4533 1.9 christos contains local symbols,
4534 1.9 christos sh_info is equivalent to
4535 1.10 christos the number of symbols in
4536 1.10 christos the table.
4537 1.10 christos
4538 1.10 christos SHT_SUNW_cap If symbol capabilities exist, If any capabilities refer
4539 1.10 christos [0x6ffffff5] the section header index of to named strings, the
4540 1.10 christos the associated section header index of
4541 1.10 christos SHT_SUNW_capinfo table, the associated string
4542 1.10 christos otherwise 0. table, otherwise 0.
4543 1.10 christos
4544 1.10 christos SHT_SUNW_move The section header index of 0
4545 1.9 christos [0x6ffffffa] the associated symbol table.
4546 1.9 christos
4547 1.9 christos SHT_SUNW_COMDAT 0 0
4548 1.10 christos [0x6ffffffb]
4549 1.10 christos
4550 1.9 christos SHT_SUNW_syminfo The section header index of The section header index
4551 1.10 christos [0x6ffffffc] the associated symbol table. of the associated
4552 1.10 christos .dynamic section.
4553 1.10 christos
4554 1.9 christos SHT_SUNW_verdef The section header index of The number of version
4555 1.9 christos [0x6ffffffd] the associated string table. definitions within the
4556 1.10 christos section.
4557 1.10 christos
4558 1.9 christos SHT_SUNW_verneed The section header index of The number of version
4559 1.10 christos [0x6ffffffe] the associated string table. dependencies within the
4560 1.10 christos section.
4561 1.9 christos
4562 1.9 christos SHT_SUNW_versym The section header index of 0
4563 1.9 christos [0x6fffffff] the associated symbol table. */
4564 1.9 christos }
4565 1.9 christos
4566 1.1 skrll #undef elf_backend_copy_special_section_fields
4567 1.1 skrll #define elf_backend_copy_special_section_fields elf32_i386_copy_solaris_special_section_fields
4568 1.6 christos
4569 1.6 christos #include "elf32-target.h"
4570 1.6 christos
4571 1.6 christos /* Intel MCU support. */
4572 1.6 christos
4573 1.6 christos static bfd_boolean
4574 1.6 christos elf32_iamcu_elf_object_p (bfd *abfd)
4575 1.6 christos {
4576 1.6 christos /* Set the right machine number for an IAMCU elf32 file. */
4577 1.6 christos bfd_default_set_arch_mach (abfd, bfd_arch_iamcu, bfd_mach_i386_iamcu);
4578 1.6 christos return TRUE;
4579 1.6 christos }
4580 1.6 christos
4581 1.6 christos #undef TARGET_LITTLE_SYM
4582 1.9 christos #define TARGET_LITTLE_SYM iamcu_elf32_vec
4583 1.6 christos #undef TARGET_LITTLE_NAME
4584 1.6 christos #define TARGET_LITTLE_NAME "elf32-iamcu"
4585 1.6 christos #undef ELF_ARCH
4586 1.6 christos #define ELF_ARCH bfd_arch_iamcu
4587 1.6 christos
4588 1.6 christos #undef ELF_MACHINE_CODE
4589 1.6 christos #define ELF_MACHINE_CODE EM_IAMCU
4590 1.6 christos
4591 1.6 christos #undef ELF_OSABI
4592 1.6 christos
4593 1.6 christos #undef elf32_bed
4594 1.6 christos #define elf32_bed elf32_iamcu_bed
4595 1.6 christos
4596 1.6 christos #undef elf_backend_object_p
4597 1.6 christos #define elf_backend_object_p elf32_iamcu_elf_object_p
4598 1.6 christos
4599 1.10 christos #undef elf_backend_static_tls_alignment
4600 1.6 christos
4601 1.9 christos #undef elf_backend_want_plt_sym
4602 1.9 christos #define elf_backend_want_plt_sym 0
4603 1.9 christos
4604 1.6 christos #undef elf_backend_strtab_flags
4605 1.6 christos #undef elf_backend_copy_special_section_fields
4606 1.6 christos
4607 1.6 christos #include "elf32-target.h"
4608 1.6 christos
4609 1.6 christos /* Restore defaults. */
4610 1.6 christos #undef ELF_ARCH
4611 1.6 christos #define ELF_ARCH bfd_arch_i386
4612 1.5 christos #undef ELF_MACHINE_CODE
4613 1.5 christos #define ELF_MACHINE_CODE EM_386
4614 1.5 christos
4615 1.6 christos /* Native Client support. */
4616 1.5 christos
4617 1.5 christos #undef TARGET_LITTLE_SYM
4618 1.5 christos #define TARGET_LITTLE_SYM i386_elf32_nacl_vec
4619 1.5 christos #undef TARGET_LITTLE_NAME
4620 1.5 christos #define TARGET_LITTLE_NAME "elf32-i386-nacl"
4621 1.5 christos #undef elf32_bed
4622 1.5 christos #define elf32_bed elf32_i386_nacl_bed
4623 1.5 christos
4624 1.5 christos #undef ELF_MAXPAGESIZE
4625 1.5 christos #define ELF_MAXPAGESIZE 0x10000
4626 1.5 christos
4627 1.5 christos /* Restore defaults. */
4628 1.5 christos #undef ELF_OSABI
4629 1.5 christos #undef elf_backend_want_plt_sym
4630 1.5 christos #define elf_backend_want_plt_sym 0
4631 1.5 christos #undef elf_backend_post_process_headers
4632 1.5 christos #undef elf_backend_static_tls_alignment
4633 1.5 christos
4634 1.5 christos /* NaCl uses substantially different PLT entries for the same effects. */
4635 1.5 christos
4636 1.5 christos #undef elf_backend_plt_alignment
4637 1.5 christos #define elf_backend_plt_alignment 5
4638 1.5 christos #define NACL_PLT_ENTRY_SIZE 64
4639 1.5 christos #define NACLMASK 0xe0 /* 32-byte alignment mask. */
4640 1.5 christos
4641 1.10 christos static const bfd_byte elf_i386_nacl_plt0_entry[] =
4642 1.10 christos {
4643 1.10 christos 0xff, 0x35, /* pushl contents of address */
4644 1.5 christos 0, 0, 0, 0, /* replaced with address of .got + 4. */
4645 1.5 christos 0x8b, 0x0d, /* movl contents of address, %ecx */
4646 1.5 christos 0, 0, 0, 0, /* replaced with address of .got + 8. */
4647 1.5 christos 0x83, 0xe1, NACLMASK, /* andl $NACLMASK, %ecx */
4648 1.5 christos 0xff, 0xe1 /* jmp *%ecx */
4649 1.5 christos };
4650 1.5 christos
4651 1.5 christos static const bfd_byte elf_i386_nacl_plt_entry[NACL_PLT_ENTRY_SIZE] =
4652 1.5 christos {
4653 1.5 christos 0x8b, 0x0d, /* movl contents of address, %ecx */
4654 1.5 christos 0, 0, 0, 0, /* replaced with GOT slot address. */
4655 1.10 christos 0x83, 0xe1, NACLMASK, /* andl $NACLMASK, %ecx */
4656 1.5 christos 0xff, 0xe1, /* jmp *%ecx */
4657 1.5 christos
4658 1.5 christos /* Pad to the next 32-byte boundary with nop instructions. */
4659 1.5 christos 0x90,
4660 1.5 christos 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90,
4661 1.5 christos 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90,
4662 1.5 christos
4663 1.5 christos /* Lazy GOT entries point here (32-byte aligned). */
4664 1.10 christos 0x68, /* pushl immediate */
4665 1.5 christos 0, 0, 0, 0, /* replaced with reloc offset. */
4666 1.10 christos 0xe9, /* jmp relative */
4667 1.5 christos 0, 0, 0, 0, /* replaced with offset to .plt. */
4668 1.5 christos
4669 1.5 christos /* Pad to the next 32-byte boundary with nop instructions. */
4670 1.5 christos 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90,
4671 1.5 christos 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90,
4672 1.5 christos 0x90, 0x90
4673 1.5 christos };
4674 1.5 christos
4675 1.5 christos static const bfd_byte
4676 1.5 christos elf_i386_nacl_pic_plt0_entry[sizeof (elf_i386_nacl_plt0_entry)] =
4677 1.5 christos {
4678 1.5 christos 0xff, 0x73, 0x04, /* pushl 4(%ebx) */
4679 1.5 christos 0x8b, 0x4b, 0x08, /* mov 0x8(%ebx), %ecx */
4680 1.5 christos 0x83, 0xe1, 0xe0, /* and $NACLMASK, %ecx */
4681 1.5 christos 0xff, 0xe1, /* jmp *%ecx */
4682 1.5 christos
4683 1.5 christos /* This is expected to be the same size as elf_i386_nacl_plt0_entry,
4684 1.5 christos so pad to that size with nop instructions. */
4685 1.5 christos 0x90, 0x90, 0x90, 0x90, 0x90, 0x90
4686 1.5 christos };
4687 1.10 christos
4688 1.10 christos static const bfd_byte elf_i386_nacl_pic_plt_entry[NACL_PLT_ENTRY_SIZE] =
4689 1.10 christos {
4690 1.10 christos 0x8b, 0x8b, /* movl offset(%ebx), %ecx */
4691 1.5 christos 0, 0, 0, 0, /* replaced with offset of this symbol in .got. */
4692 1.10 christos 0x83, 0xe1, 0xe0, /* andl $NACLMASK, %ecx */
4693 1.5 christos 0xff, 0xe1, /* jmp *%ecx */
4694 1.5 christos
4695 1.5 christos /* Pad to the next 32-byte boundary with nop instructions. */
4696 1.5 christos 0x90,
4697 1.5 christos 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90,
4698 1.10 christos 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90,
4699 1.10 christos
4700 1.10 christos /* Lazy GOT entries point here (32-byte aligned). */
4701 1.10 christos 0x68, /* pushl immediate */
4702 1.5 christos 0, 0, 0, 0, /* replaced with offset into relocation table. */
4703 1.10 christos 0xe9, /* jmp relative */
4704 1.5 christos 0, 0, 0, 0, /* replaced with offset to start of .plt. */
4705 1.5 christos
4706 1.5 christos /* Pad to the next 32-byte boundary with nop instructions. */
4707 1.5 christos 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90,
4708 1.5 christos 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90,
4709 1.5 christos 0x90, 0x90
4710 1.5 christos };
4711 1.10 christos
4712 1.10 christos static const bfd_byte elf_i386_nacl_eh_frame_plt[] =
4713 1.10 christos {
4714 1.5 christos #if (PLT_CIE_LENGTH != 20 \
4715 1.10 christos || PLT_FDE_LENGTH != 36 \
4716 1.5 christos || PLT_FDE_START_OFFSET != 4 + PLT_CIE_LENGTH + 8 \
4717 1.5 christos || PLT_FDE_LEN_OFFSET != 4 + PLT_CIE_LENGTH + 12)
4718 1.10 christos # error "Need elf_x86_backend_data parameters for eh_frame_plt offsets!"
4719 1.10 christos #endif
4720 1.10 christos PLT_CIE_LENGTH, 0, 0, 0, /* CIE length */
4721 1.10 christos 0, 0, 0, 0, /* CIE ID */
4722 1.10 christos 1, /* CIE version */
4723 1.10 christos 'z', 'R', 0, /* Augmentation string */
4724 1.5 christos 1, /* Code alignment factor */
4725 1.5 christos 0x7c, /* Data alignment factor: -4 */
4726 1.5 christos 8, /* Return address column */
4727 1.5 christos 1, /* Augmentation size */
4728 1.5 christos DW_EH_PE_pcrel | DW_EH_PE_sdata4, /* FDE encoding */
4729 1.5 christos DW_CFA_def_cfa, 4, 4, /* DW_CFA_def_cfa: r4 (esp) ofs 4 */
4730 1.10 christos DW_CFA_offset + 8, 1, /* DW_CFA_offset: r8 (eip) at cfa-4 */
4731 1.5 christos DW_CFA_nop, DW_CFA_nop,
4732 1.10 christos
4733 1.10 christos PLT_FDE_LENGTH, 0, 0, 0, /* FDE length */
4734 1.10 christos PLT_CIE_LENGTH + 8, 0, 0, 0, /* CIE pointer */
4735 1.10 christos 0, 0, 0, 0, /* R_386_PC32 .plt goes here */
4736 1.10 christos 0, 0, 0, 0, /* .plt size goes here */
4737 1.10 christos 0, /* Augmentation size */
4738 1.10 christos DW_CFA_def_cfa_offset, 8, /* DW_CFA_def_cfa_offset: 8 */
4739 1.10 christos DW_CFA_advance_loc + 6, /* DW_CFA_advance_loc: 6 to __PLT__+6 */
4740 1.10 christos DW_CFA_def_cfa_offset, 12, /* DW_CFA_def_cfa_offset: 12 */
4741 1.10 christos DW_CFA_advance_loc + 58, /* DW_CFA_advance_loc: 58 to __PLT__+64 */
4742 1.10 christos DW_CFA_def_cfa_expression, /* DW_CFA_def_cfa_expression */
4743 1.5 christos 13, /* Block length */
4744 1.5 christos DW_OP_breg4, 4, /* DW_OP_breg4 (esp): 4 */
4745 1.5 christos DW_OP_breg8, 0, /* DW_OP_breg8 (eip): 0 */
4746 1.5 christos DW_OP_const1u, 63, DW_OP_and, DW_OP_const1u, 37, DW_OP_ge,
4747 1.5 christos DW_OP_lit2, DW_OP_shl, DW_OP_plus,
4748 1.10 christos DW_CFA_nop, DW_CFA_nop
4749 1.5 christos };
4750 1.5 christos
4751 1.5 christos static const struct elf_x86_lazy_plt_layout elf_i386_nacl_plt =
4752 1.10 christos {
4753 1.10 christos elf_i386_nacl_plt0_entry, /* plt0_entry */
4754 1.5 christos sizeof (elf_i386_nacl_plt0_entry), /* plt0_entry_size */
4755 1.5 christos elf_i386_nacl_plt_entry, /* plt_entry */
4756 1.10 christos NACL_PLT_ENTRY_SIZE, /* plt_entry_size */
4757 1.5 christos 2, /* plt0_got1_offset */
4758 1.5 christos 8, /* plt0_got2_offset */
4759 1.5 christos 0, /* plt0_got2_insn_end */
4760 1.10 christos 2, /* plt_got_offset */
4761 1.10 christos 33, /* plt_reloc_offset */
4762 1.5 christos 38, /* plt_plt_offset */
4763 1.5 christos 0, /* plt_got_insn_size */
4764 1.5 christos 0, /* plt_plt_insn_end */
4765 1.5 christos 32, /* plt_lazy_offset */
4766 1.10 christos elf_i386_nacl_pic_plt0_entry, /* pic_plt0_entry */
4767 1.5 christos elf_i386_nacl_pic_plt_entry, /* pic_plt_entry */
4768 1.5 christos elf_i386_nacl_eh_frame_plt, /* eh_frame_plt */
4769 1.10 christos sizeof (elf_i386_nacl_eh_frame_plt) /* eh_frame_plt_size */
4770 1.5 christos };
4771 1.10 christos
4772 1.5 christos static const struct elf_x86_backend_data elf_i386_nacl_arch_bed =
4773 1.5 christos {
4774 1.6 christos is_nacl /* os */
4775 1.6 christos };
4776 1.6 christos
4777 1.6 christos static bfd_boolean
4778 1.6 christos elf32_i386_nacl_elf_object_p (bfd *abfd)
4779 1.6 christos {
4780 1.6 christos /* Set the right machine number for a NaCl i386 ELF32 file. */
4781 1.6 christos bfd_default_set_arch_mach (abfd, bfd_arch_i386, bfd_mach_i386_i386_nacl);
4782 1.5 christos return TRUE;
4783 1.5 christos }
4784 1.5 christos
4785 1.6 christos #undef elf_backend_arch_data
4786 1.6 christos #define elf_backend_arch_data &elf_i386_nacl_arch_bed
4787 1.5 christos
4788 1.5 christos #undef elf_backend_object_p
4789 1.5 christos #define elf_backend_object_p elf32_i386_nacl_elf_object_p
4790 1.5 christos #undef elf_backend_modify_segment_map
4791 1.6 christos #define elf_backend_modify_segment_map nacl_modify_segment_map
4792 1.6 christos #undef elf_backend_modify_program_headers
4793 1.5 christos #define elf_backend_modify_program_headers nacl_modify_program_headers
4794 1.5 christos #undef elf_backend_final_write_processing
4795 1.5 christos #define elf_backend_final_write_processing nacl_final_write_processing
4796 1.5 christos
4797 1.6 christos #include "elf32-target.h"
4798 1.5 christos
4799 1.5 christos /* Restore defaults. */
4800 1.6 christos #undef elf_backend_object_p
4801 1.5 christos #undef elf_backend_modify_segment_map
4802 1.1 skrll #undef elf_backend_modify_program_headers
4803 1.1 skrll #undef elf_backend_final_write_processing
4804 1.1 skrll
4805 1.6 christos /* VxWorks support. */
4806 1.1 skrll
4807 1.1 skrll #undef TARGET_LITTLE_SYM
4808 1.1 skrll #define TARGET_LITTLE_SYM i386_elf32_vxworks_vec
4809 1.10 christos #undef TARGET_LITTLE_NAME
4810 1.10 christos #define TARGET_LITTLE_NAME "elf32-i386-vxworks"
4811 1.5 christos #undef ELF_OSABI
4812 1.5 christos #undef ELF_MAXPAGESIZE
4813 1.1 skrll #define ELF_MAXPAGESIZE 0x1000
4814 1.10 christos #undef elf_backend_plt_alignment
4815 1.5 christos #define elf_backend_plt_alignment 4
4816 1.10 christos
4817 1.5 christos static const struct elf_x86_backend_data elf_i386_vxworks_arch_bed =
4818 1.1 skrll {
4819 1.5 christos is_vxworks /* os */
4820 1.5 christos };
4821 1.1 skrll
4822 1.1 skrll #undef elf_backend_arch_data
4823 1.1 skrll #define elf_backend_arch_data &elf_i386_vxworks_arch_bed
4824 1.1 skrll
4825 1.1 skrll #undef elf_backend_relocs_compatible
4826 1.1 skrll #undef elf_backend_add_symbol_hook
4827 1.1 skrll #define elf_backend_add_symbol_hook \
4828 1.1 skrll elf_vxworks_add_symbol_hook
4829 1.1 skrll #undef elf_backend_link_output_symbol_hook
4830 1.1 skrll #define elf_backend_link_output_symbol_hook \
4831 1.1 skrll elf_vxworks_link_output_symbol_hook
4832 1.1 skrll #undef elf_backend_emit_relocs
4833 1.1 skrll #define elf_backend_emit_relocs elf_vxworks_emit_relocs
4834 1.4 christos #undef elf_backend_final_write_processing
4835 1.1 skrll #define elf_backend_final_write_processing \
4836 1.1 skrll elf_vxworks_final_write_processing
4837 1.1 skrll #undef elf_backend_static_tls_alignment
4838 1.1 skrll
4839 1.1 skrll /* On VxWorks, we emit relocations against _PROCEDURE_LINKAGE_TABLE_, so
4840 1.1 skrll define it. */
4841 1.1 skrll #undef elf_backend_want_plt_sym
4842 1.1 skrll #define elf_backend_want_plt_sym 1
4843 1.1 skrll
4844 1.1 skrll #undef elf32_bed
4845 #define elf32_bed elf32_i386_vxworks_bed
4846
4847 #include "elf32-target.h"
4848